diff options
Diffstat (limited to 'drivers')
388 files changed, 15683 insertions, 3095 deletions
diff --git a/drivers/ata/ata_piix.c b/drivers/ata/ata_piix.c index 19136a7e1064..6f3f2257d0f0 100644 --- a/drivers/ata/ata_piix.c +++ b/drivers/ata/ata_piix.c | |||
@@ -329,7 +329,7 @@ static struct ata_port_operations ich_pata_ops = { | |||
329 | }; | 329 | }; |
330 | 330 | ||
331 | static struct ata_port_operations piix_sata_ops = { | 331 | static struct ata_port_operations piix_sata_ops = { |
332 | .inherits = &ata_bmdma_port_ops, | 332 | .inherits = &ata_bmdma32_port_ops, |
333 | }; | 333 | }; |
334 | 334 | ||
335 | static struct ata_port_operations piix_sidpr_sata_ops = { | 335 | static struct ata_port_operations piix_sidpr_sata_ops = { |
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index 22ff51bdbc8a..6728328f3bea 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c | |||
@@ -3790,21 +3790,45 @@ int sata_link_debounce(struct ata_link *link, const unsigned long *params, | |||
3790 | int sata_link_resume(struct ata_link *link, const unsigned long *params, | 3790 | int sata_link_resume(struct ata_link *link, const unsigned long *params, |
3791 | unsigned long deadline) | 3791 | unsigned long deadline) |
3792 | { | 3792 | { |
3793 | int tries = ATA_LINK_RESUME_TRIES; | ||
3793 | u32 scontrol, serror; | 3794 | u32 scontrol, serror; |
3794 | int rc; | 3795 | int rc; |
3795 | 3796 | ||
3796 | if ((rc = sata_scr_read(link, SCR_CONTROL, &scontrol))) | 3797 | if ((rc = sata_scr_read(link, SCR_CONTROL, &scontrol))) |
3797 | return rc; | 3798 | return rc; |
3798 | 3799 | ||
3799 | scontrol = (scontrol & 0x0f0) | 0x300; | 3800 | /* |
3801 | * Writes to SControl sometimes get ignored under certain | ||
3802 | * controllers (ata_piix SIDPR). Make sure DET actually is | ||
3803 | * cleared. | ||
3804 | */ | ||
3805 | do { | ||
3806 | scontrol = (scontrol & 0x0f0) | 0x300; | ||
3807 | if ((rc = sata_scr_write(link, SCR_CONTROL, scontrol))) | ||
3808 | return rc; | ||
3809 | /* | ||
3810 | * Some PHYs react badly if SStatus is pounded | ||
3811 | * immediately after resuming. Delay 200ms before | ||
3812 | * debouncing. | ||
3813 | */ | ||
3814 | msleep(200); | ||
3800 | 3815 | ||
3801 | if ((rc = sata_scr_write(link, SCR_CONTROL, scontrol))) | 3816 | /* is SControl restored correctly? */ |
3802 | return rc; | 3817 | if ((rc = sata_scr_read(link, SCR_CONTROL, &scontrol))) |
3818 | return rc; | ||
3819 | } while ((scontrol & 0xf0f) != 0x300 && --tries); | ||
3803 | 3820 | ||
3804 | /* Some PHYs react badly if SStatus is pounded immediately | 3821 | if ((scontrol & 0xf0f) != 0x300) { |
3805 | * after resuming. Delay 200ms before debouncing. | 3822 | ata_link_printk(link, KERN_ERR, |
3806 | */ | 3823 | "failed to resume link (SControl %X)\n", |
3807 | msleep(200); | 3824 | scontrol); |
3825 | return 0; | ||
3826 | } | ||
3827 | |||
3828 | if (tries < ATA_LINK_RESUME_TRIES) | ||
3829 | ata_link_printk(link, KERN_WARNING, | ||
3830 | "link resume succeeded after %d retries\n", | ||
3831 | ATA_LINK_RESUME_TRIES - tries); | ||
3808 | 3832 | ||
3809 | if ((rc = sata_link_debounce(link, params, deadline))) | 3833 | if ((rc = sata_link_debounce(link, params, deadline))) |
3810 | return rc; | 3834 | return rc; |
diff --git a/drivers/ata/sata_promise.c b/drivers/ata/sata_promise.c index 07d8d00b4d34..63306285c843 100644 --- a/drivers/ata/sata_promise.c +++ b/drivers/ata/sata_promise.c | |||
@@ -862,7 +862,7 @@ static void pdc_error_intr(struct ata_port *ap, struct ata_queued_cmd *qc, | |||
862 | if (port_status & PDC_DRIVE_ERR) | 862 | if (port_status & PDC_DRIVE_ERR) |
863 | ac_err_mask |= AC_ERR_DEV; | 863 | ac_err_mask |= AC_ERR_DEV; |
864 | if (port_status & (PDC_OVERRUN_ERR | PDC_UNDERRUN_ERR)) | 864 | if (port_status & (PDC_OVERRUN_ERR | PDC_UNDERRUN_ERR)) |
865 | ac_err_mask |= AC_ERR_HSM; | 865 | ac_err_mask |= AC_ERR_OTHER; |
866 | if (port_status & (PDC2_ATA_HBA_ERR | PDC2_ATA_DMA_CNT_ERR)) | 866 | if (port_status & (PDC2_ATA_HBA_ERR | PDC2_ATA_DMA_CNT_ERR)) |
867 | ac_err_mask |= AC_ERR_ATA_BUS; | 867 | ac_err_mask |= AC_ERR_ATA_BUS; |
868 | if (port_status & (PDC_PH_ERR | PDC_SH_ERR | PDC_DH_ERR | PDC2_HTO_ERR | 868 | if (port_status & (PDC_PH_ERR | PDC_SH_ERR | PDC_DH_ERR | PDC2_HTO_ERR |
diff --git a/drivers/base/memory.c b/drivers/base/memory.c index d7d77d4a402c..ae6b6c43cff9 100644 --- a/drivers/base/memory.c +++ b/drivers/base/memory.c | |||
@@ -309,17 +309,19 @@ static SYSDEV_ATTR(removable, 0444, show_mem_removable, NULL); | |||
309 | * Block size attribute stuff | 309 | * Block size attribute stuff |
310 | */ | 310 | */ |
311 | static ssize_t | 311 | static ssize_t |
312 | print_block_size(struct class *class, char *buf) | 312 | print_block_size(struct sysdev_class *class, |
313 | struct sysdev_class_attribute *class_attr, | ||
314 | char *buf) | ||
313 | { | 315 | { |
314 | return sprintf(buf, "%lx\n", (unsigned long)PAGES_PER_SECTION * PAGE_SIZE); | 316 | return sprintf(buf, "%#lx\n", (unsigned long)PAGES_PER_SECTION * PAGE_SIZE); |
315 | } | 317 | } |
316 | 318 | ||
317 | static CLASS_ATTR(block_size_bytes, 0444, print_block_size, NULL); | 319 | static SYSDEV_CLASS_ATTR(block_size_bytes, 0444, print_block_size, NULL); |
318 | 320 | ||
319 | static int block_size_init(void) | 321 | static int block_size_init(void) |
320 | { | 322 | { |
321 | return sysfs_create_file(&memory_sysdev_class.kset.kobj, | 323 | return sysfs_create_file(&memory_sysdev_class.kset.kobj, |
322 | &class_attr_block_size_bytes.attr); | 324 | &attr_block_size_bytes.attr); |
323 | } | 325 | } |
324 | 326 | ||
325 | /* | 327 | /* |
@@ -330,7 +332,9 @@ static int block_size_init(void) | |||
330 | */ | 332 | */ |
331 | #ifdef CONFIG_ARCH_MEMORY_PROBE | 333 | #ifdef CONFIG_ARCH_MEMORY_PROBE |
332 | static ssize_t | 334 | static ssize_t |
333 | memory_probe_store(struct class *class, const char *buf, size_t count) | 335 | memory_probe_store(struct sysdev_class *class, |
336 | struct sysdev_class_attribute *class_attr, | ||
337 | const char *buf, size_t count) | ||
334 | { | 338 | { |
335 | u64 phys_addr; | 339 | u64 phys_addr; |
336 | int nid; | 340 | int nid; |
@@ -346,12 +350,12 @@ memory_probe_store(struct class *class, const char *buf, size_t count) | |||
346 | 350 | ||
347 | return count; | 351 | return count; |
348 | } | 352 | } |
349 | static CLASS_ATTR(probe, S_IWUSR, NULL, memory_probe_store); | 353 | static SYSDEV_CLASS_ATTR(probe, S_IWUSR, NULL, memory_probe_store); |
350 | 354 | ||
351 | static int memory_probe_init(void) | 355 | static int memory_probe_init(void) |
352 | { | 356 | { |
353 | return sysfs_create_file(&memory_sysdev_class.kset.kobj, | 357 | return sysfs_create_file(&memory_sysdev_class.kset.kobj, |
354 | &class_attr_probe.attr); | 358 | &attr_probe.attr); |
355 | } | 359 | } |
356 | #else | 360 | #else |
357 | static inline int memory_probe_init(void) | 361 | static inline int memory_probe_init(void) |
@@ -367,7 +371,9 @@ static inline int memory_probe_init(void) | |||
367 | 371 | ||
368 | /* Soft offline a page */ | 372 | /* Soft offline a page */ |
369 | static ssize_t | 373 | static ssize_t |
370 | store_soft_offline_page(struct class *class, const char *buf, size_t count) | 374 | store_soft_offline_page(struct sysdev_class *class, |
375 | struct sysdev_class_attribute *class_attr, | ||
376 | const char *buf, size_t count) | ||
371 | { | 377 | { |
372 | int ret; | 378 | int ret; |
373 | u64 pfn; | 379 | u64 pfn; |
@@ -384,7 +390,9 @@ store_soft_offline_page(struct class *class, const char *buf, size_t count) | |||
384 | 390 | ||
385 | /* Forcibly offline a page, including killing processes. */ | 391 | /* Forcibly offline a page, including killing processes. */ |
386 | static ssize_t | 392 | static ssize_t |
387 | store_hard_offline_page(struct class *class, const char *buf, size_t count) | 393 | store_hard_offline_page(struct sysdev_class *class, |
394 | struct sysdev_class_attribute *class_attr, | ||
395 | const char *buf, size_t count) | ||
388 | { | 396 | { |
389 | int ret; | 397 | int ret; |
390 | u64 pfn; | 398 | u64 pfn; |
@@ -397,18 +405,18 @@ store_hard_offline_page(struct class *class, const char *buf, size_t count) | |||
397 | return ret ? ret : count; | 405 | return ret ? ret : count; |
398 | } | 406 | } |
399 | 407 | ||
400 | static CLASS_ATTR(soft_offline_page, 0644, NULL, store_soft_offline_page); | 408 | static SYSDEV_CLASS_ATTR(soft_offline_page, 0644, NULL, store_soft_offline_page); |
401 | static CLASS_ATTR(hard_offline_page, 0644, NULL, store_hard_offline_page); | 409 | static SYSDEV_CLASS_ATTR(hard_offline_page, 0644, NULL, store_hard_offline_page); |
402 | 410 | ||
403 | static __init int memory_fail_init(void) | 411 | static __init int memory_fail_init(void) |
404 | { | 412 | { |
405 | int err; | 413 | int err; |
406 | 414 | ||
407 | err = sysfs_create_file(&memory_sysdev_class.kset.kobj, | 415 | err = sysfs_create_file(&memory_sysdev_class.kset.kobj, |
408 | &class_attr_soft_offline_page.attr); | 416 | &attr_soft_offline_page.attr); |
409 | if (!err) | 417 | if (!err) |
410 | err = sysfs_create_file(&memory_sysdev_class.kset.kobj, | 418 | err = sysfs_create_file(&memory_sysdev_class.kset.kobj, |
411 | &class_attr_hard_offline_page.attr); | 419 | &attr_hard_offline_page.attr); |
412 | return err; | 420 | return err; |
413 | } | 421 | } |
414 | #else | 422 | #else |
diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c index 48adf80926a0..a5142bddef41 100644 --- a/drivers/base/power/main.c +++ b/drivers/base/power/main.c | |||
@@ -446,8 +446,8 @@ EXPORT_SYMBOL_GPL(dpm_resume_noirq); | |||
446 | 446 | ||
447 | /** | 447 | /** |
448 | * legacy_resume - Execute a legacy (bus or class) resume callback for device. | 448 | * legacy_resume - Execute a legacy (bus or class) resume callback for device. |
449 | * dev: Device to resume. | 449 | * @dev: Device to resume. |
450 | * cb: Resume callback to execute. | 450 | * @cb: Resume callback to execute. |
451 | */ | 451 | */ |
452 | static int legacy_resume(struct device *dev, int (*cb)(struct device *dev)) | 452 | static int legacy_resume(struct device *dev, int (*cb)(struct device *dev)) |
453 | { | 453 | { |
@@ -711,8 +711,9 @@ EXPORT_SYMBOL_GPL(dpm_suspend_noirq); | |||
711 | 711 | ||
712 | /** | 712 | /** |
713 | * legacy_suspend - Execute a legacy (bus or class) suspend callback for device. | 713 | * legacy_suspend - Execute a legacy (bus or class) suspend callback for device. |
714 | * dev: Device to suspend. | 714 | * @dev: Device to suspend. |
715 | * cb: Suspend callback to execute. | 715 | * @state: PM transition of the system being carried out. |
716 | * @cb: Suspend callback to execute. | ||
716 | */ | 717 | */ |
717 | static int legacy_suspend(struct device *dev, pm_message_t state, | 718 | static int legacy_suspend(struct device *dev, pm_message_t state, |
718 | int (*cb)(struct device *dev, pm_message_t state)) | 719 | int (*cb)(struct device *dev, pm_message_t state)) |
diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig index 31be3ac2e21b..e023682be2c4 100644 --- a/drivers/char/Kconfig +++ b/drivers/char/Kconfig | |||
@@ -669,7 +669,7 @@ config VIRTIO_CONSOLE | |||
669 | 669 | ||
670 | config HVCS | 670 | config HVCS |
671 | tristate "IBM Hypervisor Virtual Console Server support" | 671 | tristate "IBM Hypervisor Virtual Console Server support" |
672 | depends on PPC_PSERIES | 672 | depends on PPC_PSERIES && HVC_CONSOLE |
673 | help | 673 | help |
674 | Partitionable IBM Power5 ppc64 machines allow hosting of | 674 | Partitionable IBM Power5 ppc64 machines allow hosting of |
675 | firmware virtual consoles from one Linux partition by | 675 | firmware virtual consoles from one Linux partition by |
diff --git a/drivers/char/agp/amd64-agp.c b/drivers/char/agp/amd64-agp.c index 5aa7a586a7ff..1afb8968a342 100644 --- a/drivers/char/agp/amd64-agp.c +++ b/drivers/char/agp/amd64-agp.c | |||
@@ -725,12 +725,11 @@ static struct pci_driver agp_amd64_pci_driver = { | |||
725 | int __init agp_amd64_init(void) | 725 | int __init agp_amd64_init(void) |
726 | { | 726 | { |
727 | int err = 0; | 727 | int err = 0; |
728 | static int done = 0; | ||
729 | 728 | ||
730 | if (agp_off) | 729 | if (agp_off) |
731 | return -EINVAL; | 730 | return -EINVAL; |
732 | 731 | ||
733 | if (done++) | 732 | if (gart_iommu_aperture) |
734 | return agp_bridges_found ? 0 : -ENODEV; | 733 | return agp_bridges_found ? 0 : -ENODEV; |
735 | 734 | ||
736 | err = pci_register_driver(&agp_amd64_pci_driver); | 735 | err = pci_register_driver(&agp_amd64_pci_driver); |
@@ -771,6 +770,8 @@ int __init agp_amd64_init(void) | |||
771 | 770 | ||
772 | static void __exit agp_amd64_cleanup(void) | 771 | static void __exit agp_amd64_cleanup(void) |
773 | { | 772 | { |
773 | if (gart_iommu_aperture) | ||
774 | return; | ||
774 | if (aperture_resource) | 775 | if (aperture_resource) |
775 | release_resource(aperture_resource); | 776 | release_resource(aperture_resource); |
776 | pci_unregister_driver(&agp_amd64_pci_driver); | 777 | pci_unregister_driver(&agp_amd64_pci_driver); |
diff --git a/drivers/char/agp/backend.c b/drivers/char/agp/backend.c index a56ca080e108..c3ab46da51a3 100644 --- a/drivers/char/agp/backend.c +++ b/drivers/char/agp/backend.c | |||
@@ -285,18 +285,22 @@ int agp_add_bridge(struct agp_bridge_data *bridge) | |||
285 | { | 285 | { |
286 | int error; | 286 | int error; |
287 | 287 | ||
288 | if (agp_off) | 288 | if (agp_off) { |
289 | return -ENODEV; | 289 | error = -ENODEV; |
290 | goto err_put_bridge; | ||
291 | } | ||
290 | 292 | ||
291 | if (!bridge->dev) { | 293 | if (!bridge->dev) { |
292 | printk (KERN_DEBUG PFX "Erk, registering with no pci_dev!\n"); | 294 | printk (KERN_DEBUG PFX "Erk, registering with no pci_dev!\n"); |
293 | return -EINVAL; | 295 | error = -EINVAL; |
296 | goto err_put_bridge; | ||
294 | } | 297 | } |
295 | 298 | ||
296 | /* Grab reference on the chipset driver. */ | 299 | /* Grab reference on the chipset driver. */ |
297 | if (!try_module_get(bridge->driver->owner)) { | 300 | if (!try_module_get(bridge->driver->owner)) { |
298 | dev_info(&bridge->dev->dev, "can't lock chipset driver\n"); | 301 | dev_info(&bridge->dev->dev, "can't lock chipset driver\n"); |
299 | return -EINVAL; | 302 | error = -EINVAL; |
303 | goto err_put_bridge; | ||
300 | } | 304 | } |
301 | 305 | ||
302 | error = agp_backend_initialize(bridge); | 306 | error = agp_backend_initialize(bridge); |
@@ -326,6 +330,7 @@ frontend_err: | |||
326 | agp_backend_cleanup(bridge); | 330 | agp_backend_cleanup(bridge); |
327 | err_out: | 331 | err_out: |
328 | module_put(bridge->driver->owner); | 332 | module_put(bridge->driver->owner); |
333 | err_put_bridge: | ||
329 | agp_put_bridge(bridge); | 334 | agp_put_bridge(bridge); |
330 | return error; | 335 | return error; |
331 | } | 336 | } |
diff --git a/drivers/char/agp/hp-agp.c b/drivers/char/agp/hp-agp.c index 9047b2714653..58752b70efea 100644 --- a/drivers/char/agp/hp-agp.c +++ b/drivers/char/agp/hp-agp.c | |||
@@ -488,9 +488,8 @@ zx1_gart_probe (acpi_handle obj, u32 depth, void *context, void **ret) | |||
488 | handle = obj; | 488 | handle = obj; |
489 | do { | 489 | do { |
490 | status = acpi_get_object_info(handle, &info); | 490 | status = acpi_get_object_info(handle, &info); |
491 | if (ACPI_SUCCESS(status)) { | 491 | if (ACPI_SUCCESS(status) && (info->valid & ACPI_VALID_HID)) { |
492 | /* TBD check _CID also */ | 492 | /* TBD check _CID also */ |
493 | info->hardware_id.string[sizeof(info->hardware_id.length)-1] = '\0'; | ||
494 | match = (strcmp(info->hardware_id.string, "HWP0001") == 0); | 493 | match = (strcmp(info->hardware_id.string, "HWP0001") == 0); |
495 | kfree(info); | 494 | kfree(info); |
496 | if (match) { | 495 | if (match) { |
@@ -509,6 +508,9 @@ zx1_gart_probe (acpi_handle obj, u32 depth, void *context, void **ret) | |||
509 | handle = parent; | 508 | handle = parent; |
510 | } while (ACPI_SUCCESS(status)); | 509 | } while (ACPI_SUCCESS(status)); |
511 | 510 | ||
511 | if (ACPI_FAILURE(status)) | ||
512 | return AE_OK; /* found no enclosing IOC */ | ||
513 | |||
512 | if (hp_zx1_setup(sba_hpa + HP_ZX1_IOC_OFFSET, lba_hpa)) | 514 | if (hp_zx1_setup(sba_hpa + HP_ZX1_IOC_OFFSET, lba_hpa)) |
513 | return AE_OK; | 515 | return AE_OK; |
514 | 516 | ||
diff --git a/drivers/char/agp/intel-agp.c b/drivers/char/agp/intel-agp.c index 30c36ac2cd00..3999a5f25f38 100644 --- a/drivers/char/agp/intel-agp.c +++ b/drivers/char/agp/intel-agp.c | |||
@@ -2460,10 +2460,14 @@ static int __devinit agp_intel_probe(struct pci_dev *pdev, | |||
2460 | &bridge->mode); | 2460 | &bridge->mode); |
2461 | } | 2461 | } |
2462 | 2462 | ||
2463 | if (bridge->driver->mask_memory == intel_i965_mask_memory) | 2463 | if (bridge->driver->mask_memory == intel_i965_mask_memory) { |
2464 | if (pci_set_dma_mask(intel_private.pcidev, DMA_BIT_MASK(36))) | 2464 | if (pci_set_dma_mask(intel_private.pcidev, DMA_BIT_MASK(36))) |
2465 | dev_err(&intel_private.pcidev->dev, | 2465 | dev_err(&intel_private.pcidev->dev, |
2466 | "set gfx device dma mask 36bit failed!\n"); | 2466 | "set gfx device dma mask 36bit failed!\n"); |
2467 | else | ||
2468 | pci_set_consistent_dma_mask(intel_private.pcidev, | ||
2469 | DMA_BIT_MASK(36)); | ||
2470 | } | ||
2467 | 2471 | ||
2468 | pci_set_drvdata(pdev, bridge); | 2472 | pci_set_drvdata(pdev, bridge); |
2469 | return agp_add_bridge(bridge); | 2473 | return agp_add_bridge(bridge); |
diff --git a/drivers/char/hw_random/virtio-rng.c b/drivers/char/hw_random/virtio-rng.c index bdaef8e94021..64fe0a793efd 100644 --- a/drivers/char/hw_random/virtio-rng.c +++ b/drivers/char/hw_random/virtio-rng.c | |||
@@ -114,7 +114,7 @@ static struct virtio_device_id id_table[] = { | |||
114 | { 0 }, | 114 | { 0 }, |
115 | }; | 115 | }; |
116 | 116 | ||
117 | static struct virtio_driver virtio_rng = { | 117 | static struct virtio_driver virtio_rng_driver = { |
118 | .driver.name = KBUILD_MODNAME, | 118 | .driver.name = KBUILD_MODNAME, |
119 | .driver.owner = THIS_MODULE, | 119 | .driver.owner = THIS_MODULE, |
120 | .id_table = id_table, | 120 | .id_table = id_table, |
@@ -124,12 +124,12 @@ static struct virtio_driver virtio_rng = { | |||
124 | 124 | ||
125 | static int __init init(void) | 125 | static int __init init(void) |
126 | { | 126 | { |
127 | return register_virtio_driver(&virtio_rng); | 127 | return register_virtio_driver(&virtio_rng_driver); |
128 | } | 128 | } |
129 | 129 | ||
130 | static void __exit fini(void) | 130 | static void __exit fini(void) |
131 | { | 131 | { |
132 | unregister_virtio_driver(&virtio_rng); | 132 | unregister_virtio_driver(&virtio_rng_driver); |
133 | } | 133 | } |
134 | module_init(init); | 134 | module_init(init); |
135 | module_exit(fini); | 135 | module_exit(fini); |
diff --git a/drivers/cpuidle/governors/menu.c b/drivers/cpuidle/governors/menu.c index 68104434ebb5..73655aeb3a60 100644 --- a/drivers/cpuidle/governors/menu.c +++ b/drivers/cpuidle/governors/menu.c | |||
@@ -18,6 +18,7 @@ | |||
18 | #include <linux/hrtimer.h> | 18 | #include <linux/hrtimer.h> |
19 | #include <linux/tick.h> | 19 | #include <linux/tick.h> |
20 | #include <linux/sched.h> | 20 | #include <linux/sched.h> |
21 | #include <linux/math64.h> | ||
21 | 22 | ||
22 | #define BUCKETS 12 | 23 | #define BUCKETS 12 |
23 | #define RESOLUTION 1024 | 24 | #define RESOLUTION 1024 |
@@ -169,6 +170,12 @@ static DEFINE_PER_CPU(struct menu_device, menu_devices); | |||
169 | 170 | ||
170 | static void menu_update(struct cpuidle_device *dev); | 171 | static void menu_update(struct cpuidle_device *dev); |
171 | 172 | ||
173 | /* This implements DIV_ROUND_CLOSEST but avoids 64 bit division */ | ||
174 | static u64 div_round64(u64 dividend, u32 divisor) | ||
175 | { | ||
176 | return div_u64(dividend + (divisor / 2), divisor); | ||
177 | } | ||
178 | |||
172 | /** | 179 | /** |
173 | * menu_select - selects the next idle state to enter | 180 | * menu_select - selects the next idle state to enter |
174 | * @dev: the CPU | 181 | * @dev: the CPU |
@@ -209,9 +216,8 @@ static int menu_select(struct cpuidle_device *dev) | |||
209 | data->correction_factor[data->bucket] = RESOLUTION * DECAY; | 216 | data->correction_factor[data->bucket] = RESOLUTION * DECAY; |
210 | 217 | ||
211 | /* Make sure to round up for half microseconds */ | 218 | /* Make sure to round up for half microseconds */ |
212 | data->predicted_us = DIV_ROUND_CLOSEST( | 219 | data->predicted_us = div_round64(data->expected_us * data->correction_factor[data->bucket], |
213 | data->expected_us * data->correction_factor[data->bucket], | 220 | RESOLUTION * DECAY); |
214 | RESOLUTION * DECAY); | ||
215 | 221 | ||
216 | /* | 222 | /* |
217 | * We want to default to C1 (hlt), not to busy polling | 223 | * We want to default to C1 (hlt), not to busy polling |
diff --git a/drivers/edac/amd64_edac.c b/drivers/edac/amd64_edac.c index c5facd951dda..000dc67b85b7 100644 --- a/drivers/edac/amd64_edac.c +++ b/drivers/edac/amd64_edac.c | |||
@@ -197,7 +197,7 @@ static int amd64_get_scrub_rate(struct mem_ctl_info *mci, u32 *bw) | |||
197 | edac_printk(KERN_DEBUG, EDAC_MC, | 197 | edac_printk(KERN_DEBUG, EDAC_MC, |
198 | "pci-read, sdram scrub control value: %d \n", scrubval); | 198 | "pci-read, sdram scrub control value: %d \n", scrubval); |
199 | 199 | ||
200 | for (i = 0; ARRAY_SIZE(scrubrates); i++) { | 200 | for (i = 0; i < ARRAY_SIZE(scrubrates); i++) { |
201 | if (scrubrates[i].scrubval == scrubval) { | 201 | if (scrubrates[i].scrubval == scrubval) { |
202 | *bw = scrubrates[i].bandwidth; | 202 | *bw = scrubrates[i].bandwidth; |
203 | status = 0; | 203 | status = 0; |
diff --git a/drivers/edac/i5000_edac.c b/drivers/edac/i5000_edac.c index 77a9579d7167..adc10a2ac5f6 100644 --- a/drivers/edac/i5000_edac.c +++ b/drivers/edac/i5000_edac.c | |||
@@ -577,7 +577,13 @@ static void i5000_process_nonfatal_error_info(struct mem_ctl_info *mci, | |||
577 | debugf0("\tUncorrected bits= 0x%x\n", ue_errors); | 577 | debugf0("\tUncorrected bits= 0x%x\n", ue_errors); |
578 | 578 | ||
579 | branch = EXTRACT_FBDCHAN_INDX(info->ferr_nf_fbd); | 579 | branch = EXTRACT_FBDCHAN_INDX(info->ferr_nf_fbd); |
580 | channel = branch; | 580 | |
581 | /* | ||
582 | * According with i5000 datasheet, bit 28 has no significance | ||
583 | * for errors M4Err-M12Err and M17Err-M21Err, on FERR_NF_FBD | ||
584 | */ | ||
585 | channel = branch & 2; | ||
586 | |||
581 | bank = NREC_BANK(info->nrecmema); | 587 | bank = NREC_BANK(info->nrecmema); |
582 | rank = NREC_RANK(info->nrecmema); | 588 | rank = NREC_RANK(info->nrecmema); |
583 | rdwr = NREC_RDWR(info->nrecmema); | 589 | rdwr = NREC_RDWR(info->nrecmema); |
diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig index a019b49ecc9b..1f1d88ae68d6 100644 --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig | |||
@@ -172,6 +172,15 @@ config GPIO_ADP5520 | |||
172 | To compile this driver as a module, choose M here: the module will | 172 | To compile this driver as a module, choose M here: the module will |
173 | be called adp5520-gpio. | 173 | be called adp5520-gpio. |
174 | 174 | ||
175 | config GPIO_ADP5588 | ||
176 | tristate "ADP5588 I2C GPIO expander" | ||
177 | depends on I2C | ||
178 | help | ||
179 | This option enables support for 18 GPIOs found | ||
180 | on Analog Devices ADP5588 GPIO Expanders. | ||
181 | To compile this driver as a module, choose M here: the module will be | ||
182 | called adp5588-gpio. | ||
183 | |||
175 | comment "PCI GPIO expanders:" | 184 | comment "PCI GPIO expanders:" |
176 | 185 | ||
177 | config GPIO_CS5535 | 186 | config GPIO_CS5535 |
diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile index 52fe4cf734c7..48687238edb1 100644 --- a/drivers/gpio/Makefile +++ b/drivers/gpio/Makefile | |||
@@ -5,6 +5,7 @@ ccflags-$(CONFIG_DEBUG_GPIO) += -DDEBUG | |||
5 | obj-$(CONFIG_GPIOLIB) += gpiolib.o | 5 | obj-$(CONFIG_GPIOLIB) += gpiolib.o |
6 | 6 | ||
7 | obj-$(CONFIG_GPIO_ADP5520) += adp5520-gpio.o | 7 | obj-$(CONFIG_GPIO_ADP5520) += adp5520-gpio.o |
8 | obj-$(CONFIG_GPIO_ADP5588) += adp5588-gpio.o | ||
8 | obj-$(CONFIG_GPIO_LANGWELL) += langwell_gpio.o | 9 | obj-$(CONFIG_GPIO_LANGWELL) += langwell_gpio.o |
9 | obj-$(CONFIG_GPIO_MAX7301) += max7301.o | 10 | obj-$(CONFIG_GPIO_MAX7301) += max7301.o |
10 | obj-$(CONFIG_GPIO_MAX732X) += max732x.o | 11 | obj-$(CONFIG_GPIO_MAX732X) += max732x.o |
diff --git a/drivers/gpio/adp5588-gpio.c b/drivers/gpio/adp5588-gpio.c new file mode 100644 index 000000000000..afc097a16b33 --- /dev/null +++ b/drivers/gpio/adp5588-gpio.c | |||
@@ -0,0 +1,266 @@ | |||
1 | /* | ||
2 | * GPIO Chip driver for Analog Devices | ||
3 | * ADP5588 I/O Expander and QWERTY Keypad Controller | ||
4 | * | ||
5 | * Copyright 2009 Analog Devices Inc. | ||
6 | * | ||
7 | * Licensed under the GPL-2 or later. | ||
8 | */ | ||
9 | |||
10 | #include <linux/module.h> | ||
11 | #include <linux/kernel.h> | ||
12 | #include <linux/init.h> | ||
13 | #include <linux/i2c.h> | ||
14 | #include <linux/gpio.h> | ||
15 | |||
16 | #include <linux/i2c/adp5588.h> | ||
17 | |||
18 | #define DRV_NAME "adp5588-gpio" | ||
19 | #define MAXGPIO 18 | ||
20 | #define ADP_BANK(offs) ((offs) >> 3) | ||
21 | #define ADP_BIT(offs) (1u << ((offs) & 0x7)) | ||
22 | |||
23 | struct adp5588_gpio { | ||
24 | struct i2c_client *client; | ||
25 | struct gpio_chip gpio_chip; | ||
26 | struct mutex lock; /* protect cached dir, dat_out */ | ||
27 | unsigned gpio_start; | ||
28 | uint8_t dat_out[3]; | ||
29 | uint8_t dir[3]; | ||
30 | }; | ||
31 | |||
32 | static int adp5588_gpio_read(struct i2c_client *client, u8 reg) | ||
33 | { | ||
34 | int ret = i2c_smbus_read_byte_data(client, reg); | ||
35 | |||
36 | if (ret < 0) | ||
37 | dev_err(&client->dev, "Read Error\n"); | ||
38 | |||
39 | return ret; | ||
40 | } | ||
41 | |||
42 | static int adp5588_gpio_write(struct i2c_client *client, u8 reg, u8 val) | ||
43 | { | ||
44 | int ret = i2c_smbus_write_byte_data(client, reg, val); | ||
45 | |||
46 | if (ret < 0) | ||
47 | dev_err(&client->dev, "Write Error\n"); | ||
48 | |||
49 | return ret; | ||
50 | } | ||
51 | |||
52 | static int adp5588_gpio_get_value(struct gpio_chip *chip, unsigned off) | ||
53 | { | ||
54 | struct adp5588_gpio *dev = | ||
55 | container_of(chip, struct adp5588_gpio, gpio_chip); | ||
56 | |||
57 | return !!(adp5588_gpio_read(dev->client, GPIO_DAT_STAT1 + ADP_BANK(off)) | ||
58 | & ADP_BIT(off)); | ||
59 | } | ||
60 | |||
61 | static void adp5588_gpio_set_value(struct gpio_chip *chip, | ||
62 | unsigned off, int val) | ||
63 | { | ||
64 | unsigned bank, bit; | ||
65 | struct adp5588_gpio *dev = | ||
66 | container_of(chip, struct adp5588_gpio, gpio_chip); | ||
67 | |||
68 | bank = ADP_BANK(off); | ||
69 | bit = ADP_BIT(off); | ||
70 | |||
71 | mutex_lock(&dev->lock); | ||
72 | if (val) | ||
73 | dev->dat_out[bank] |= bit; | ||
74 | else | ||
75 | dev->dat_out[bank] &= ~bit; | ||
76 | |||
77 | adp5588_gpio_write(dev->client, GPIO_DAT_OUT1 + bank, | ||
78 | dev->dat_out[bank]); | ||
79 | mutex_unlock(&dev->lock); | ||
80 | } | ||
81 | |||
82 | static int adp5588_gpio_direction_input(struct gpio_chip *chip, unsigned off) | ||
83 | { | ||
84 | int ret; | ||
85 | unsigned bank; | ||
86 | struct adp5588_gpio *dev = | ||
87 | container_of(chip, struct adp5588_gpio, gpio_chip); | ||
88 | |||
89 | bank = ADP_BANK(off); | ||
90 | |||
91 | mutex_lock(&dev->lock); | ||
92 | dev->dir[bank] &= ~ADP_BIT(off); | ||
93 | ret = adp5588_gpio_write(dev->client, GPIO_DIR1 + bank, dev->dir[bank]); | ||
94 | mutex_unlock(&dev->lock); | ||
95 | |||
96 | return ret; | ||
97 | } | ||
98 | |||
99 | static int adp5588_gpio_direction_output(struct gpio_chip *chip, | ||
100 | unsigned off, int val) | ||
101 | { | ||
102 | int ret; | ||
103 | unsigned bank, bit; | ||
104 | struct adp5588_gpio *dev = | ||
105 | container_of(chip, struct adp5588_gpio, gpio_chip); | ||
106 | |||
107 | bank = ADP_BANK(off); | ||
108 | bit = ADP_BIT(off); | ||
109 | |||
110 | mutex_lock(&dev->lock); | ||
111 | dev->dir[bank] |= bit; | ||
112 | |||
113 | if (val) | ||
114 | dev->dat_out[bank] |= bit; | ||
115 | else | ||
116 | dev->dat_out[bank] &= ~bit; | ||
117 | |||
118 | ret = adp5588_gpio_write(dev->client, GPIO_DAT_OUT1 + bank, | ||
119 | dev->dat_out[bank]); | ||
120 | ret |= adp5588_gpio_write(dev->client, GPIO_DIR1 + bank, | ||
121 | dev->dir[bank]); | ||
122 | mutex_unlock(&dev->lock); | ||
123 | |||
124 | return ret; | ||
125 | } | ||
126 | |||
127 | static int __devinit adp5588_gpio_probe(struct i2c_client *client, | ||
128 | const struct i2c_device_id *id) | ||
129 | { | ||
130 | struct adp5588_gpio_platform_data *pdata = client->dev.platform_data; | ||
131 | struct adp5588_gpio *dev; | ||
132 | struct gpio_chip *gc; | ||
133 | int ret, i, revid; | ||
134 | |||
135 | if (pdata == NULL) { | ||
136 | dev_err(&client->dev, "missing platform data\n"); | ||
137 | return -ENODEV; | ||
138 | } | ||
139 | |||
140 | if (!i2c_check_functionality(client->adapter, | ||
141 | I2C_FUNC_SMBUS_BYTE_DATA)) { | ||
142 | dev_err(&client->dev, "SMBUS Byte Data not Supported\n"); | ||
143 | return -EIO; | ||
144 | } | ||
145 | |||
146 | dev = kzalloc(sizeof(*dev), GFP_KERNEL); | ||
147 | if (dev == NULL) { | ||
148 | dev_err(&client->dev, "failed to alloc memory\n"); | ||
149 | return -ENOMEM; | ||
150 | } | ||
151 | |||
152 | dev->client = client; | ||
153 | |||
154 | gc = &dev->gpio_chip; | ||
155 | gc->direction_input = adp5588_gpio_direction_input; | ||
156 | gc->direction_output = adp5588_gpio_direction_output; | ||
157 | gc->get = adp5588_gpio_get_value; | ||
158 | gc->set = adp5588_gpio_set_value; | ||
159 | gc->can_sleep = 1; | ||
160 | |||
161 | gc->base = pdata->gpio_start; | ||
162 | gc->ngpio = MAXGPIO; | ||
163 | gc->label = client->name; | ||
164 | gc->owner = THIS_MODULE; | ||
165 | |||
166 | mutex_init(&dev->lock); | ||
167 | |||
168 | |||
169 | ret = adp5588_gpio_read(dev->client, DEV_ID); | ||
170 | if (ret < 0) | ||
171 | goto err; | ||
172 | |||
173 | revid = ret & ADP5588_DEVICE_ID_MASK; | ||
174 | |||
175 | for (i = 0, ret = 0; i <= ADP_BANK(MAXGPIO); i++) { | ||
176 | dev->dat_out[i] = adp5588_gpio_read(client, GPIO_DAT_OUT1 + i); | ||
177 | dev->dir[i] = adp5588_gpio_read(client, GPIO_DIR1 + i); | ||
178 | ret |= adp5588_gpio_write(client, KP_GPIO1 + i, 0); | ||
179 | ret |= adp5588_gpio_write(client, GPIO_PULL1 + i, | ||
180 | (pdata->pullup_dis_mask >> (8 * i)) & 0xFF); | ||
181 | |||
182 | if (ret) | ||
183 | goto err; | ||
184 | } | ||
185 | |||
186 | ret = gpiochip_add(&dev->gpio_chip); | ||
187 | if (ret) | ||
188 | goto err; | ||
189 | |||
190 | dev_info(&client->dev, "gpios %d..%d on a %s Rev. %d\n", | ||
191 | gc->base, gc->base + gc->ngpio - 1, | ||
192 | client->name, revid); | ||
193 | |||
194 | if (pdata->setup) { | ||
195 | ret = pdata->setup(client, gc->base, gc->ngpio, pdata->context); | ||
196 | if (ret < 0) | ||
197 | dev_warn(&client->dev, "setup failed, %d\n", ret); | ||
198 | } | ||
199 | |||
200 | i2c_set_clientdata(client, dev); | ||
201 | return 0; | ||
202 | |||
203 | err: | ||
204 | kfree(dev); | ||
205 | return ret; | ||
206 | } | ||
207 | |||
208 | static int __devexit adp5588_gpio_remove(struct i2c_client *client) | ||
209 | { | ||
210 | struct adp5588_gpio_platform_data *pdata = client->dev.platform_data; | ||
211 | struct adp5588_gpio *dev = i2c_get_clientdata(client); | ||
212 | int ret; | ||
213 | |||
214 | if (pdata->teardown) { | ||
215 | ret = pdata->teardown(client, | ||
216 | dev->gpio_chip.base, dev->gpio_chip.ngpio, | ||
217 | pdata->context); | ||
218 | if (ret < 0) { | ||
219 | dev_err(&client->dev, "teardown failed %d\n", ret); | ||
220 | return ret; | ||
221 | } | ||
222 | } | ||
223 | |||
224 | ret = gpiochip_remove(&dev->gpio_chip); | ||
225 | if (ret) { | ||
226 | dev_err(&client->dev, "gpiochip_remove failed %d\n", ret); | ||
227 | return ret; | ||
228 | } | ||
229 | |||
230 | kfree(dev); | ||
231 | return 0; | ||
232 | } | ||
233 | |||
234 | static const struct i2c_device_id adp5588_gpio_id[] = { | ||
235 | {DRV_NAME, 0}, | ||
236 | {} | ||
237 | }; | ||
238 | |||
239 | MODULE_DEVICE_TABLE(i2c, adp5588_gpio_id); | ||
240 | |||
241 | static struct i2c_driver adp5588_gpio_driver = { | ||
242 | .driver = { | ||
243 | .name = DRV_NAME, | ||
244 | }, | ||
245 | .probe = adp5588_gpio_probe, | ||
246 | .remove = __devexit_p(adp5588_gpio_remove), | ||
247 | .id_table = adp5588_gpio_id, | ||
248 | }; | ||
249 | |||
250 | static int __init adp5588_gpio_init(void) | ||
251 | { | ||
252 | return i2c_add_driver(&adp5588_gpio_driver); | ||
253 | } | ||
254 | |||
255 | module_init(adp5588_gpio_init); | ||
256 | |||
257 | static void __exit adp5588_gpio_exit(void) | ||
258 | { | ||
259 | i2c_del_driver(&adp5588_gpio_driver); | ||
260 | } | ||
261 | |||
262 | module_exit(adp5588_gpio_exit); | ||
263 | |||
264 | MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>"); | ||
265 | MODULE_DESCRIPTION("GPIO ADP5588 Driver"); | ||
266 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index a25ad284a272..350842ad3632 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c | |||
@@ -858,8 +858,6 @@ int gpio_sysfs_set_active_low(unsigned gpio, int value) | |||
858 | desc = &gpio_desc[gpio]; | 858 | desc = &gpio_desc[gpio]; |
859 | 859 | ||
860 | if (test_bit(FLAG_EXPORT, &desc->flags)) { | 860 | if (test_bit(FLAG_EXPORT, &desc->flags)) { |
861 | struct device *dev; | ||
862 | |||
863 | dev = class_find_device(&gpio_class, NULL, desc, match_export); | 861 | dev = class_find_device(&gpio_class, NULL, desc, match_export); |
864 | if (dev == NULL) { | 862 | if (dev == NULL) { |
865 | status = -ENODEV; | 863 | status = -ENODEV; |
diff --git a/drivers/gpu/drm/ati_pcigart.c b/drivers/gpu/drm/ati_pcigart.c index 628eae3e9b83..a1fce68e3bbe 100644 --- a/drivers/gpu/drm/ati_pcigart.c +++ b/drivers/gpu/drm/ati_pcigart.c | |||
@@ -39,8 +39,7 @@ static int drm_ati_alloc_pcigart_table(struct drm_device *dev, | |||
39 | struct drm_ati_pcigart_info *gart_info) | 39 | struct drm_ati_pcigart_info *gart_info) |
40 | { | 40 | { |
41 | gart_info->table_handle = drm_pci_alloc(dev, gart_info->table_size, | 41 | gart_info->table_handle = drm_pci_alloc(dev, gart_info->table_size, |
42 | PAGE_SIZE, | 42 | PAGE_SIZE); |
43 | gart_info->table_mask); | ||
44 | if (gart_info->table_handle == NULL) | 43 | if (gart_info->table_handle == NULL) |
45 | return -ENOMEM; | 44 | return -ENOMEM; |
46 | 45 | ||
@@ -112,6 +111,13 @@ int drm_ati_pcigart_init(struct drm_device *dev, struct drm_ati_pcigart_info *ga | |||
112 | if (gart_info->gart_table_location == DRM_ATI_GART_MAIN) { | 111 | if (gart_info->gart_table_location == DRM_ATI_GART_MAIN) { |
113 | DRM_DEBUG("PCI: no table in VRAM: using normal RAM\n"); | 112 | DRM_DEBUG("PCI: no table in VRAM: using normal RAM\n"); |
114 | 113 | ||
114 | if (pci_set_dma_mask(dev->pdev, gart_info->table_mask)) { | ||
115 | DRM_ERROR("fail to set dma mask to 0x%Lx\n", | ||
116 | gart_info->table_mask); | ||
117 | ret = 1; | ||
118 | goto done; | ||
119 | } | ||
120 | |||
115 | ret = drm_ati_alloc_pcigart_table(dev, gart_info); | 121 | ret = drm_ati_alloc_pcigart_table(dev, gart_info); |
116 | if (ret) { | 122 | if (ret) { |
117 | DRM_ERROR("cannot allocate PCI GART page!\n"); | 123 | DRM_ERROR("cannot allocate PCI GART page!\n"); |
diff --git a/drivers/gpu/drm/drm_bufs.c b/drivers/gpu/drm/drm_bufs.c index 3d09e304f6f4..8417cc4c43f1 100644 --- a/drivers/gpu/drm/drm_bufs.c +++ b/drivers/gpu/drm/drm_bufs.c | |||
@@ -326,7 +326,7 @@ static int drm_addmap_core(struct drm_device * dev, resource_size_t offset, | |||
326 | * As we're limiting the address to 2^32-1 (or less), | 326 | * As we're limiting the address to 2^32-1 (or less), |
327 | * casting it down to 32 bits is no problem, but we | 327 | * casting it down to 32 bits is no problem, but we |
328 | * need to point to a 64bit variable first. */ | 328 | * need to point to a 64bit variable first. */ |
329 | dmah = drm_pci_alloc(dev, map->size, map->size, 0xffffffffUL); | 329 | dmah = drm_pci_alloc(dev, map->size, map->size); |
330 | if (!dmah) { | 330 | if (!dmah) { |
331 | kfree(map); | 331 | kfree(map); |
332 | return -ENOMEM; | 332 | return -ENOMEM; |
@@ -885,7 +885,7 @@ int drm_addbufs_pci(struct drm_device * dev, struct drm_buf_desc * request) | |||
885 | 885 | ||
886 | while (entry->buf_count < count) { | 886 | while (entry->buf_count < count) { |
887 | 887 | ||
888 | dmah = drm_pci_alloc(dev, PAGE_SIZE << page_order, 0x1000, 0xfffffffful); | 888 | dmah = drm_pci_alloc(dev, PAGE_SIZE << page_order, 0x1000); |
889 | 889 | ||
890 | if (!dmah) { | 890 | if (!dmah) { |
891 | /* Set count correctly so we free the proper amount. */ | 891 | /* Set count correctly so we free the proper amount. */ |
diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c index 5124401f266a..d91fb8c0b7b3 100644 --- a/drivers/gpu/drm/drm_crtc.c +++ b/drivers/gpu/drm/drm_crtc.c | |||
@@ -158,6 +158,7 @@ static struct drm_conn_prop_enum_list drm_connector_enum_list[] = | |||
158 | { DRM_MODE_CONNECTOR_HDMIA, "HDMI Type A", 0 }, | 158 | { DRM_MODE_CONNECTOR_HDMIA, "HDMI Type A", 0 }, |
159 | { DRM_MODE_CONNECTOR_HDMIB, "HDMI Type B", 0 }, | 159 | { DRM_MODE_CONNECTOR_HDMIB, "HDMI Type B", 0 }, |
160 | { DRM_MODE_CONNECTOR_TV, "TV", 0 }, | 160 | { DRM_MODE_CONNECTOR_TV, "TV", 0 }, |
161 | { DRM_MODE_CONNECTOR_eDP, "Embedded DisplayPort", 0 }, | ||
161 | }; | 162 | }; |
162 | 163 | ||
163 | static struct drm_prop_enum_list drm_encoder_enum_list[] = | 164 | static struct drm_prop_enum_list drm_encoder_enum_list[] = |
diff --git a/drivers/gpu/drm/drm_crtc_helper.c b/drivers/gpu/drm/drm_crtc_helper.c index 4231d6db72ec..7d0f00a935fa 100644 --- a/drivers/gpu/drm/drm_crtc_helper.c +++ b/drivers/gpu/drm/drm_crtc_helper.c | |||
@@ -216,7 +216,7 @@ bool drm_helper_crtc_in_use(struct drm_crtc *crtc) | |||
216 | EXPORT_SYMBOL(drm_helper_crtc_in_use); | 216 | EXPORT_SYMBOL(drm_helper_crtc_in_use); |
217 | 217 | ||
218 | /** | 218 | /** |
219 | * drm_disable_unused_functions - disable unused objects | 219 | * drm_helper_disable_unused_functions - disable unused objects |
220 | * @dev: DRM device | 220 | * @dev: DRM device |
221 | * | 221 | * |
222 | * LOCKING: | 222 | * LOCKING: |
@@ -702,7 +702,7 @@ bool drm_crtc_helper_set_mode(struct drm_crtc *crtc, | |||
702 | if (encoder->crtc != crtc) | 702 | if (encoder->crtc != crtc) |
703 | continue; | 703 | continue; |
704 | 704 | ||
705 | DRM_INFO("%s: set mode %s %x\n", drm_get_encoder_name(encoder), | 705 | DRM_DEBUG("%s: set mode %s %x\n", drm_get_encoder_name(encoder), |
706 | mode->name, mode->base.id); | 706 | mode->name, mode->base.id); |
707 | encoder_funcs = encoder->helper_private; | 707 | encoder_funcs = encoder->helper_private; |
708 | encoder_funcs->mode_set(encoder, mode, adjusted_mode); | 708 | encoder_funcs->mode_set(encoder, mode, adjusted_mode); |
@@ -1032,7 +1032,8 @@ bool drm_helper_initial_config(struct drm_device *dev) | |||
1032 | /* | 1032 | /* |
1033 | * we shouldn't end up with no modes here. | 1033 | * we shouldn't end up with no modes here. |
1034 | */ | 1034 | */ |
1035 | WARN(!count, "No connectors reported connected with modes\n"); | 1035 | if (count == 0) |
1036 | printk(KERN_INFO "No connectors reported connected with modes\n"); | ||
1036 | 1037 | ||
1037 | drm_setup_crtcs(dev); | 1038 | drm_setup_crtcs(dev); |
1038 | 1039 | ||
@@ -1162,6 +1163,9 @@ EXPORT_SYMBOL(drm_helper_mode_fill_fb_struct); | |||
1162 | int drm_helper_resume_force_mode(struct drm_device *dev) | 1163 | int drm_helper_resume_force_mode(struct drm_device *dev) |
1163 | { | 1164 | { |
1164 | struct drm_crtc *crtc; | 1165 | struct drm_crtc *crtc; |
1166 | struct drm_encoder *encoder; | ||
1167 | struct drm_encoder_helper_funcs *encoder_funcs; | ||
1168 | struct drm_crtc_helper_funcs *crtc_funcs; | ||
1165 | int ret; | 1169 | int ret; |
1166 | 1170 | ||
1167 | list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { | 1171 | list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { |
@@ -1174,6 +1178,25 @@ int drm_helper_resume_force_mode(struct drm_device *dev) | |||
1174 | 1178 | ||
1175 | if (ret == false) | 1179 | if (ret == false) |
1176 | DRM_ERROR("failed to set mode on crtc %p\n", crtc); | 1180 | DRM_ERROR("failed to set mode on crtc %p\n", crtc); |
1181 | |||
1182 | /* Turn off outputs that were already powered off */ | ||
1183 | if (drm_helper_choose_crtc_dpms(crtc)) { | ||
1184 | list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { | ||
1185 | |||
1186 | if(encoder->crtc != crtc) | ||
1187 | continue; | ||
1188 | |||
1189 | encoder_funcs = encoder->helper_private; | ||
1190 | if (encoder_funcs->dpms) | ||
1191 | (*encoder_funcs->dpms) (encoder, | ||
1192 | drm_helper_choose_encoder_dpms(encoder)); | ||
1193 | |||
1194 | crtc_funcs = crtc->helper_private; | ||
1195 | if (crtc_funcs->dpms) | ||
1196 | (*crtc_funcs->dpms) (crtc, | ||
1197 | drm_helper_choose_crtc_dpms(crtc)); | ||
1198 | } | ||
1199 | } | ||
1177 | } | 1200 | } |
1178 | /* disable the unused connectors while restoring the modesetting */ | 1201 | /* disable the unused connectors while restoring the modesetting */ |
1179 | drm_helper_disable_unused_functions(dev); | 1202 | drm_helper_disable_unused_functions(dev); |
diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c index 5c9f79877cbf..defcaf108460 100644 --- a/drivers/gpu/drm/drm_edid.c +++ b/drivers/gpu/drm/drm_edid.c | |||
@@ -911,23 +911,27 @@ static int drm_cvt_modes(struct drm_connector *connector, | |||
911 | struct drm_device *dev = connector->dev; | 911 | struct drm_device *dev = connector->dev; |
912 | struct cvt_timing *cvt; | 912 | struct cvt_timing *cvt; |
913 | const int rates[] = { 60, 85, 75, 60, 50 }; | 913 | const int rates[] = { 60, 85, 75, 60, 50 }; |
914 | const u8 empty[3] = { 0, 0, 0 }; | ||
914 | 915 | ||
915 | for (i = 0; i < 4; i++) { | 916 | for (i = 0; i < 4; i++) { |
916 | int uninitialized_var(width), height; | 917 | int uninitialized_var(width), height; |
917 | cvt = &(timing->data.other_data.data.cvt[i]); | 918 | cvt = &(timing->data.other_data.data.cvt[i]); |
918 | 919 | ||
919 | height = (cvt->code[0] + ((cvt->code[1] & 0xf0) << 8) + 1) * 2; | 920 | if (!memcmp(cvt->code, empty, 3)) |
920 | switch (cvt->code[1] & 0xc0) { | 921 | continue; |
922 | |||
923 | height = (cvt->code[0] + ((cvt->code[1] & 0xf0) << 4) + 1) * 2; | ||
924 | switch (cvt->code[1] & 0x0c) { | ||
921 | case 0x00: | 925 | case 0x00: |
922 | width = height * 4 / 3; | 926 | width = height * 4 / 3; |
923 | break; | 927 | break; |
924 | case 0x40: | 928 | case 0x04: |
925 | width = height * 16 / 9; | 929 | width = height * 16 / 9; |
926 | break; | 930 | break; |
927 | case 0x80: | 931 | case 0x08: |
928 | width = height * 16 / 10; | 932 | width = height * 16 / 10; |
929 | break; | 933 | break; |
930 | case 0xc0: | 934 | case 0x0c: |
931 | width = height * 15 / 9; | 935 | width = height * 15 / 9; |
932 | break; | 936 | break; |
933 | } | 937 | } |
diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c index 1b49fa055f4f..1c2b7d44ec05 100644 --- a/drivers/gpu/drm/drm_fb_helper.c +++ b/drivers/gpu/drm/drm_fb_helper.c | |||
@@ -156,7 +156,7 @@ static bool drm_fb_helper_connector_parse_command_line(struct drm_connector *con | |||
156 | force = DRM_FORCE_ON; | 156 | force = DRM_FORCE_ON; |
157 | break; | 157 | break; |
158 | case 'D': | 158 | case 'D': |
159 | if ((connector->connector_type != DRM_MODE_CONNECTOR_DVII) || | 159 | if ((connector->connector_type != DRM_MODE_CONNECTOR_DVII) && |
160 | (connector->connector_type != DRM_MODE_CONNECTOR_HDMIB)) | 160 | (connector->connector_type != DRM_MODE_CONNECTOR_HDMIB)) |
161 | force = DRM_FORCE_ON; | 161 | force = DRM_FORCE_ON; |
162 | else | 162 | else |
@@ -606,11 +606,10 @@ int drm_fb_helper_check_var(struct fb_var_screeninfo *var, | |||
606 | return -EINVAL; | 606 | return -EINVAL; |
607 | 607 | ||
608 | /* Need to resize the fb object !!! */ | 608 | /* Need to resize the fb object !!! */ |
609 | if (var->xres > fb->width || var->yres > fb->height) { | 609 | if (var->bits_per_pixel > fb->bits_per_pixel || var->xres > fb->width || var->yres > fb->height) { |
610 | DRM_ERROR("Requested width/height is greater than current fb " | 610 | DRM_DEBUG("fb userspace requested width/height/bpp is greater than current fb " |
611 | "object %dx%d > %dx%d\n", var->xres, var->yres, | 611 | "object %dx%d-%d > %dx%d-%d\n", var->xres, var->yres, var->bits_per_pixel, |
612 | fb->width, fb->height); | 612 | fb->width, fb->height, fb->bits_per_pixel); |
613 | DRM_ERROR("Need resizing code.\n"); | ||
614 | return -EINVAL; | 613 | return -EINVAL; |
615 | } | 614 | } |
616 | 615 | ||
diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c index 7998ee66b317..b98384dbd9a7 100644 --- a/drivers/gpu/drm/drm_irq.c +++ b/drivers/gpu/drm/drm_irq.c | |||
@@ -115,6 +115,7 @@ void drm_vblank_cleanup(struct drm_device *dev) | |||
115 | 115 | ||
116 | dev->num_crtcs = 0; | 116 | dev->num_crtcs = 0; |
117 | } | 117 | } |
118 | EXPORT_SYMBOL(drm_vblank_cleanup); | ||
118 | 119 | ||
119 | int drm_vblank_init(struct drm_device *dev, int num_crtcs) | 120 | int drm_vblank_init(struct drm_device *dev, int num_crtcs) |
120 | { | 121 | { |
@@ -163,7 +164,6 @@ int drm_vblank_init(struct drm_device *dev, int num_crtcs) | |||
163 | } | 164 | } |
164 | 165 | ||
165 | dev->vblank_disable_allowed = 0; | 166 | dev->vblank_disable_allowed = 0; |
166 | |||
167 | return 0; | 167 | return 0; |
168 | 168 | ||
169 | err: | 169 | err: |
@@ -493,6 +493,9 @@ EXPORT_SYMBOL(drm_vblank_off); | |||
493 | */ | 493 | */ |
494 | void drm_vblank_pre_modeset(struct drm_device *dev, int crtc) | 494 | void drm_vblank_pre_modeset(struct drm_device *dev, int crtc) |
495 | { | 495 | { |
496 | /* vblank is not initialized (IRQ not installed ?) */ | ||
497 | if (!dev->num_crtcs) | ||
498 | return; | ||
496 | /* | 499 | /* |
497 | * To avoid all the problems that might happen if interrupts | 500 | * To avoid all the problems that might happen if interrupts |
498 | * were enabled/disabled around or between these calls, we just | 501 | * were enabled/disabled around or between these calls, we just |
diff --git a/drivers/gpu/drm/drm_modes.c b/drivers/gpu/drm/drm_modes.c index 6d81a02463a3..76d63394c776 100644 --- a/drivers/gpu/drm/drm_modes.c +++ b/drivers/gpu/drm/drm_modes.c | |||
@@ -1,9 +1,4 @@ | |||
1 | /* | 1 | /* |
2 | * The list_sort function is (presumably) licensed under the GPL (see the | ||
3 | * top level "COPYING" file for details). | ||
4 | * | ||
5 | * The remainder of this file is: | ||
6 | * | ||
7 | * Copyright © 1997-2003 by The XFree86 Project, Inc. | 2 | * Copyright © 1997-2003 by The XFree86 Project, Inc. |
8 | * Copyright © 2007 Dave Airlie | 3 | * Copyright © 2007 Dave Airlie |
9 | * Copyright © 2007-2008 Intel Corporation | 4 | * Copyright © 2007-2008 Intel Corporation |
@@ -36,6 +31,7 @@ | |||
36 | */ | 31 | */ |
37 | 32 | ||
38 | #include <linux/list.h> | 33 | #include <linux/list.h> |
34 | #include <linux/list_sort.h> | ||
39 | #include "drmP.h" | 35 | #include "drmP.h" |
40 | #include "drm.h" | 36 | #include "drm.h" |
41 | #include "drm_crtc.h" | 37 | #include "drm_crtc.h" |
@@ -855,6 +851,7 @@ EXPORT_SYMBOL(drm_mode_prune_invalid); | |||
855 | 851 | ||
856 | /** | 852 | /** |
857 | * drm_mode_compare - compare modes for favorability | 853 | * drm_mode_compare - compare modes for favorability |
854 | * @priv: unused | ||
858 | * @lh_a: list_head for first mode | 855 | * @lh_a: list_head for first mode |
859 | * @lh_b: list_head for second mode | 856 | * @lh_b: list_head for second mode |
860 | * | 857 | * |
@@ -868,7 +865,7 @@ EXPORT_SYMBOL(drm_mode_prune_invalid); | |||
868 | * Negative if @lh_a is better than @lh_b, zero if they're equivalent, or | 865 | * Negative if @lh_a is better than @lh_b, zero if they're equivalent, or |
869 | * positive if @lh_b is better than @lh_a. | 866 | * positive if @lh_b is better than @lh_a. |
870 | */ | 867 | */ |
871 | static int drm_mode_compare(struct list_head *lh_a, struct list_head *lh_b) | 868 | static int drm_mode_compare(void *priv, struct list_head *lh_a, struct list_head *lh_b) |
872 | { | 869 | { |
873 | struct drm_display_mode *a = list_entry(lh_a, struct drm_display_mode, head); | 870 | struct drm_display_mode *a = list_entry(lh_a, struct drm_display_mode, head); |
874 | struct drm_display_mode *b = list_entry(lh_b, struct drm_display_mode, head); | 871 | struct drm_display_mode *b = list_entry(lh_b, struct drm_display_mode, head); |
@@ -885,85 +882,6 @@ static int drm_mode_compare(struct list_head *lh_a, struct list_head *lh_b) | |||
885 | return diff; | 882 | return diff; |
886 | } | 883 | } |
887 | 884 | ||
888 | /* FIXME: what we don't have a list sort function? */ | ||
889 | /* list sort from Mark J Roberts (mjr@znex.org) */ | ||
890 | void list_sort(struct list_head *head, | ||
891 | int (*cmp)(struct list_head *a, struct list_head *b)) | ||
892 | { | ||
893 | struct list_head *p, *q, *e, *list, *tail, *oldhead; | ||
894 | int insize, nmerges, psize, qsize, i; | ||
895 | |||
896 | list = head->next; | ||
897 | list_del(head); | ||
898 | insize = 1; | ||
899 | for (;;) { | ||
900 | p = oldhead = list; | ||
901 | list = tail = NULL; | ||
902 | nmerges = 0; | ||
903 | |||
904 | while (p) { | ||
905 | nmerges++; | ||
906 | q = p; | ||
907 | psize = 0; | ||
908 | for (i = 0; i < insize; i++) { | ||
909 | psize++; | ||
910 | q = q->next == oldhead ? NULL : q->next; | ||
911 | if (!q) | ||
912 | break; | ||
913 | } | ||
914 | |||
915 | qsize = insize; | ||
916 | while (psize > 0 || (qsize > 0 && q)) { | ||
917 | if (!psize) { | ||
918 | e = q; | ||
919 | q = q->next; | ||
920 | qsize--; | ||
921 | if (q == oldhead) | ||
922 | q = NULL; | ||
923 | } else if (!qsize || !q) { | ||
924 | e = p; | ||
925 | p = p->next; | ||
926 | psize--; | ||
927 | if (p == oldhead) | ||
928 | p = NULL; | ||
929 | } else if (cmp(p, q) <= 0) { | ||
930 | e = p; | ||
931 | p = p->next; | ||
932 | psize--; | ||
933 | if (p == oldhead) | ||
934 | p = NULL; | ||
935 | } else { | ||
936 | e = q; | ||
937 | q = q->next; | ||
938 | qsize--; | ||
939 | if (q == oldhead) | ||
940 | q = NULL; | ||
941 | } | ||
942 | if (tail) | ||
943 | tail->next = e; | ||
944 | else | ||
945 | list = e; | ||
946 | e->prev = tail; | ||
947 | tail = e; | ||
948 | } | ||
949 | p = q; | ||
950 | } | ||
951 | |||
952 | tail->next = list; | ||
953 | list->prev = tail; | ||
954 | |||
955 | if (nmerges <= 1) | ||
956 | break; | ||
957 | |||
958 | insize *= 2; | ||
959 | } | ||
960 | |||
961 | head->next = list; | ||
962 | head->prev = list->prev; | ||
963 | list->prev->next = head; | ||
964 | list->prev = head; | ||
965 | } | ||
966 | |||
967 | /** | 885 | /** |
968 | * drm_mode_sort - sort mode list | 886 | * drm_mode_sort - sort mode list |
969 | * @mode_list: list to sort | 887 | * @mode_list: list to sort |
@@ -975,7 +893,7 @@ void list_sort(struct list_head *head, | |||
975 | */ | 893 | */ |
976 | void drm_mode_sort(struct list_head *mode_list) | 894 | void drm_mode_sort(struct list_head *mode_list) |
977 | { | 895 | { |
978 | list_sort(mode_list, drm_mode_compare); | 896 | list_sort(NULL, mode_list, drm_mode_compare); |
979 | } | 897 | } |
980 | EXPORT_SYMBOL(drm_mode_sort); | 898 | EXPORT_SYMBOL(drm_mode_sort); |
981 | 899 | ||
diff --git a/drivers/gpu/drm/drm_pci.c b/drivers/gpu/drm/drm_pci.c index 577094fb1995..e68ebf92fa2a 100644 --- a/drivers/gpu/drm/drm_pci.c +++ b/drivers/gpu/drm/drm_pci.c | |||
@@ -47,8 +47,7 @@ | |||
47 | /** | 47 | /** |
48 | * \brief Allocate a PCI consistent memory block, for DMA. | 48 | * \brief Allocate a PCI consistent memory block, for DMA. |
49 | */ | 49 | */ |
50 | drm_dma_handle_t *drm_pci_alloc(struct drm_device * dev, size_t size, size_t align, | 50 | drm_dma_handle_t *drm_pci_alloc(struct drm_device * dev, size_t size, size_t align) |
51 | dma_addr_t maxaddr) | ||
52 | { | 51 | { |
53 | drm_dma_handle_t *dmah; | 52 | drm_dma_handle_t *dmah; |
54 | #if 1 | 53 | #if 1 |
@@ -63,11 +62,6 @@ drm_dma_handle_t *drm_pci_alloc(struct drm_device * dev, size_t size, size_t ali | |||
63 | if (align > size) | 62 | if (align > size) |
64 | return NULL; | 63 | return NULL; |
65 | 64 | ||
66 | if (pci_set_dma_mask(dev->pdev, maxaddr) != 0) { | ||
67 | DRM_ERROR("Setting pci dma mask failed\n"); | ||
68 | return NULL; | ||
69 | } | ||
70 | |||
71 | dmah = kmalloc(sizeof(drm_dma_handle_t), GFP_KERNEL); | 65 | dmah = kmalloc(sizeof(drm_dma_handle_t), GFP_KERNEL); |
72 | if (!dmah) | 66 | if (!dmah) |
73 | return NULL; | 67 | return NULL; |
diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index 18476bf0b580..9c9998c4dceb 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c | |||
@@ -272,7 +272,7 @@ static void i915_dump_pages(struct seq_file *m, struct page **pages, int page_co | |||
272 | mem = kmap_atomic(pages[page], KM_USER0); | 272 | mem = kmap_atomic(pages[page], KM_USER0); |
273 | for (i = 0; i < PAGE_SIZE; i += 4) | 273 | for (i = 0; i < PAGE_SIZE; i += 4) |
274 | seq_printf(m, "%08x : %08x\n", i, mem[i / 4]); | 274 | seq_printf(m, "%08x : %08x\n", i, mem[i / 4]); |
275 | kunmap_atomic(pages[page], KM_USER0); | 275 | kunmap_atomic(mem, KM_USER0); |
276 | } | 276 | } |
277 | } | 277 | } |
278 | 278 | ||
@@ -386,34 +386,6 @@ out: | |||
386 | return 0; | 386 | return 0; |
387 | } | 387 | } |
388 | 388 | ||
389 | static int i915_registers_info(struct seq_file *m, void *data) { | ||
390 | struct drm_info_node *node = (struct drm_info_node *) m->private; | ||
391 | struct drm_device *dev = node->minor->dev; | ||
392 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
393 | uint32_t reg; | ||
394 | |||
395 | #define DUMP_RANGE(start, end) \ | ||
396 | for (reg=start; reg < end; reg += 4) \ | ||
397 | seq_printf(m, "%08x\t%08x\n", reg, I915_READ(reg)); | ||
398 | |||
399 | DUMP_RANGE(0x00000, 0x00fff); /* VGA registers */ | ||
400 | DUMP_RANGE(0x02000, 0x02fff); /* instruction, memory, interrupt control registers */ | ||
401 | DUMP_RANGE(0x03000, 0x031ff); /* FENCE and PPGTT control registers */ | ||
402 | DUMP_RANGE(0x03200, 0x03fff); /* frame buffer compression registers */ | ||
403 | DUMP_RANGE(0x05000, 0x05fff); /* I/O control registers */ | ||
404 | DUMP_RANGE(0x06000, 0x06fff); /* clock control registers */ | ||
405 | DUMP_RANGE(0x07000, 0x07fff); /* 3D internal debug registers */ | ||
406 | DUMP_RANGE(0x07400, 0x088ff); /* GPE debug registers */ | ||
407 | DUMP_RANGE(0x0a000, 0x0afff); /* display palette registers */ | ||
408 | DUMP_RANGE(0x10000, 0x13fff); /* MMIO MCHBAR */ | ||
409 | DUMP_RANGE(0x30000, 0x3ffff); /* overlay registers */ | ||
410 | DUMP_RANGE(0x60000, 0x6ffff); /* display engine pipeline registers */ | ||
411 | DUMP_RANGE(0x70000, 0x72fff); /* display and cursor registers */ | ||
412 | DUMP_RANGE(0x73000, 0x73fff); /* performance counters */ | ||
413 | |||
414 | return 0; | ||
415 | } | ||
416 | |||
417 | static int | 389 | static int |
418 | i915_wedged_open(struct inode *inode, | 390 | i915_wedged_open(struct inode *inode, |
419 | struct file *filp) | 391 | struct file *filp) |
@@ -519,7 +491,6 @@ static int i915_wedged_create(struct dentry *root, struct drm_minor *minor) | |||
519 | } | 491 | } |
520 | 492 | ||
521 | static struct drm_info_list i915_debugfs_list[] = { | 493 | static struct drm_info_list i915_debugfs_list[] = { |
522 | {"i915_regs", i915_registers_info, 0}, | ||
523 | {"i915_gem_active", i915_gem_object_list_info, 0, (void *) ACTIVE_LIST}, | 494 | {"i915_gem_active", i915_gem_object_list_info, 0, (void *) ACTIVE_LIST}, |
524 | {"i915_gem_flushing", i915_gem_object_list_info, 0, (void *) FLUSHING_LIST}, | 495 | {"i915_gem_flushing", i915_gem_object_list_info, 0, (void *) FLUSHING_LIST}, |
525 | {"i915_gem_inactive", i915_gem_object_list_info, 0, (void *) INACTIVE_LIST}, | 496 | {"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 701bfeac7f57..e660ac07f3b2 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c | |||
@@ -123,7 +123,7 @@ static int i915_init_phys_hws(struct drm_device *dev) | |||
123 | drm_i915_private_t *dev_priv = dev->dev_private; | 123 | drm_i915_private_t *dev_priv = dev->dev_private; |
124 | /* Program Hardware Status Page */ | 124 | /* Program Hardware Status Page */ |
125 | dev_priv->status_page_dmah = | 125 | dev_priv->status_page_dmah = |
126 | drm_pci_alloc(dev, PAGE_SIZE, PAGE_SIZE, 0xffffffff); | 126 | drm_pci_alloc(dev, PAGE_SIZE, PAGE_SIZE); |
127 | 127 | ||
128 | if (!dev_priv->status_page_dmah) { | 128 | if (!dev_priv->status_page_dmah) { |
129 | DRM_ERROR("Can not allocate hardware status page\n"); | 129 | DRM_ERROR("Can not allocate hardware status page\n"); |
@@ -134,6 +134,10 @@ static int i915_init_phys_hws(struct drm_device *dev) | |||
134 | 134 | ||
135 | memset(dev_priv->hw_status_page, 0, PAGE_SIZE); | 135 | memset(dev_priv->hw_status_page, 0, PAGE_SIZE); |
136 | 136 | ||
137 | if (IS_I965G(dev)) | ||
138 | dev_priv->dma_status_page |= (dev_priv->dma_status_page >> 28) & | ||
139 | 0xf0; | ||
140 | |||
137 | I915_WRITE(HWS_PGA, dev_priv->dma_status_page); | 141 | I915_WRITE(HWS_PGA, dev_priv->dma_status_page); |
138 | DRM_DEBUG_DRIVER("Enabled hardware status page\n"); | 142 | DRM_DEBUG_DRIVER("Enabled hardware status page\n"); |
139 | return 0; | 143 | return 0; |
@@ -813,9 +817,13 @@ static int i915_getparam(struct drm_device *dev, void *data, | |||
813 | case I915_PARAM_HAS_PAGEFLIPPING: | 817 | case I915_PARAM_HAS_PAGEFLIPPING: |
814 | value = 1; | 818 | value = 1; |
815 | break; | 819 | break; |
820 | case I915_PARAM_HAS_EXECBUF2: | ||
821 | /* depends on GEM */ | ||
822 | value = dev_priv->has_gem; | ||
823 | break; | ||
816 | default: | 824 | default: |
817 | DRM_DEBUG_DRIVER("Unknown parameter %d\n", | 825 | DRM_DEBUG_DRIVER("Unknown parameter %d\n", |
818 | param->param); | 826 | param->param); |
819 | return -EINVAL; | 827 | return -EINVAL; |
820 | } | 828 | } |
821 | 829 | ||
@@ -1117,7 +1125,8 @@ static void i915_setup_compression(struct drm_device *dev, int size) | |||
1117 | { | 1125 | { |
1118 | struct drm_i915_private *dev_priv = dev->dev_private; | 1126 | struct drm_i915_private *dev_priv = dev->dev_private; |
1119 | struct drm_mm_node *compressed_fb, *compressed_llb; | 1127 | struct drm_mm_node *compressed_fb, *compressed_llb; |
1120 | unsigned long cfb_base, ll_base; | 1128 | unsigned long cfb_base; |
1129 | unsigned long ll_base = 0; | ||
1121 | 1130 | ||
1122 | /* Leave 1M for line length buffer & misc. */ | 1131 | /* Leave 1M for line length buffer & misc. */ |
1123 | compressed_fb = drm_mm_search_free(&dev_priv->vram, size, 4096, 0); | 1132 | compressed_fb = drm_mm_search_free(&dev_priv->vram, size, 4096, 0); |
@@ -1200,14 +1209,6 @@ static int i915_load_modeset_init(struct drm_device *dev, | |||
1200 | dev->mode_config.fb_base = drm_get_resource_start(dev, fb_bar) & | 1209 | dev->mode_config.fb_base = drm_get_resource_start(dev, fb_bar) & |
1201 | 0xff000000; | 1210 | 0xff000000; |
1202 | 1211 | ||
1203 | if (IS_MOBILE(dev) || IS_I9XX(dev)) | ||
1204 | dev_priv->cursor_needs_physical = true; | ||
1205 | else | ||
1206 | dev_priv->cursor_needs_physical = false; | ||
1207 | |||
1208 | if (IS_I965G(dev) || IS_G33(dev)) | ||
1209 | dev_priv->cursor_needs_physical = false; | ||
1210 | |||
1211 | /* Basic memrange allocator for stolen space (aka vram) */ | 1212 | /* Basic memrange allocator for stolen space (aka vram) */ |
1212 | drm_mm_init(&dev_priv->vram, 0, prealloc_size); | 1213 | drm_mm_init(&dev_priv->vram, 0, prealloc_size); |
1213 | DRM_INFO("set up %ldM of stolen space\n", prealloc_size / (1024*1024)); | 1214 | DRM_INFO("set up %ldM of stolen space\n", prealloc_size / (1024*1024)); |
@@ -1257,6 +1258,8 @@ static int i915_load_modeset_init(struct drm_device *dev, | |||
1257 | if (ret) | 1258 | if (ret) |
1258 | goto destroy_ringbuffer; | 1259 | goto destroy_ringbuffer; |
1259 | 1260 | ||
1261 | intel_modeset_init(dev); | ||
1262 | |||
1260 | ret = drm_irq_install(dev); | 1263 | ret = drm_irq_install(dev); |
1261 | if (ret) | 1264 | if (ret) |
1262 | goto destroy_ringbuffer; | 1265 | goto destroy_ringbuffer; |
@@ -1271,8 +1274,6 @@ static int i915_load_modeset_init(struct drm_device *dev, | |||
1271 | 1274 | ||
1272 | I915_WRITE(INSTPM, (1 << 5) | (1 << 21)); | 1275 | I915_WRITE(INSTPM, (1 << 5) | (1 << 21)); |
1273 | 1276 | ||
1274 | intel_modeset_init(dev); | ||
1275 | |||
1276 | drm_helper_initial_config(dev); | 1277 | drm_helper_initial_config(dev); |
1277 | 1278 | ||
1278 | return 0; | 1279 | return 0; |
@@ -1360,7 +1361,7 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) | |||
1360 | { | 1361 | { |
1361 | struct drm_i915_private *dev_priv = dev->dev_private; | 1362 | struct drm_i915_private *dev_priv = dev->dev_private; |
1362 | resource_size_t base, size; | 1363 | resource_size_t base, size; |
1363 | int ret = 0, mmio_bar = IS_I9XX(dev) ? 0 : 1; | 1364 | int ret = 0, mmio_bar; |
1364 | uint32_t agp_size, prealloc_size, prealloc_start; | 1365 | uint32_t agp_size, prealloc_size, prealloc_start; |
1365 | 1366 | ||
1366 | /* i915 has 4 more counters */ | 1367 | /* i915 has 4 more counters */ |
@@ -1376,8 +1377,10 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) | |||
1376 | 1377 | ||
1377 | dev->dev_private = (void *)dev_priv; | 1378 | dev->dev_private = (void *)dev_priv; |
1378 | dev_priv->dev = dev; | 1379 | dev_priv->dev = dev; |
1380 | dev_priv->info = (struct intel_device_info *) flags; | ||
1379 | 1381 | ||
1380 | /* Add register map (needed for suspend/resume) */ | 1382 | /* Add register map (needed for suspend/resume) */ |
1383 | mmio_bar = IS_I9XX(dev) ? 0 : 1; | ||
1381 | base = drm_get_resource_start(dev, mmio_bar); | 1384 | base = drm_get_resource_start(dev, mmio_bar); |
1382 | size = drm_get_resource_len(dev, mmio_bar); | 1385 | size = drm_get_resource_len(dev, mmio_bar); |
1383 | 1386 | ||
@@ -1652,6 +1655,7 @@ struct drm_ioctl_desc i915_ioctls[] = { | |||
1652 | DRM_IOCTL_DEF(DRM_I915_HWS_ADDR, i915_set_status_page, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), | 1655 | DRM_IOCTL_DEF(DRM_I915_HWS_ADDR, i915_set_status_page, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), |
1653 | DRM_IOCTL_DEF(DRM_I915_GEM_INIT, i915_gem_init_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), | 1656 | DRM_IOCTL_DEF(DRM_I915_GEM_INIT, i915_gem_init_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), |
1654 | DRM_IOCTL_DEF(DRM_I915_GEM_EXECBUFFER, i915_gem_execbuffer, DRM_AUTH), | 1657 | DRM_IOCTL_DEF(DRM_I915_GEM_EXECBUFFER, i915_gem_execbuffer, DRM_AUTH), |
1658 | DRM_IOCTL_DEF(DRM_I915_GEM_EXECBUFFER2, i915_gem_execbuffer2, DRM_AUTH), | ||
1655 | DRM_IOCTL_DEF(DRM_I915_GEM_PIN, i915_gem_pin_ioctl, DRM_AUTH|DRM_ROOT_ONLY), | 1659 | DRM_IOCTL_DEF(DRM_I915_GEM_PIN, i915_gem_pin_ioctl, DRM_AUTH|DRM_ROOT_ONLY), |
1656 | DRM_IOCTL_DEF(DRM_I915_GEM_UNPIN, i915_gem_unpin_ioctl, DRM_AUTH|DRM_ROOT_ONLY), | 1660 | DRM_IOCTL_DEF(DRM_I915_GEM_UNPIN, i915_gem_unpin_ioctl, DRM_AUTH|DRM_ROOT_ONLY), |
1657 | DRM_IOCTL_DEF(DRM_I915_GEM_BUSY, i915_gem_busy_ioctl, DRM_AUTH), | 1661 | DRM_IOCTL_DEF(DRM_I915_GEM_BUSY, i915_gem_busy_ioctl, DRM_AUTH), |
diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index 24286ca168fc..46d88965852a 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c | |||
@@ -33,7 +33,6 @@ | |||
33 | #include "i915_drm.h" | 33 | #include "i915_drm.h" |
34 | #include "i915_drv.h" | 34 | #include "i915_drv.h" |
35 | 35 | ||
36 | #include "drm_pciids.h" | ||
37 | #include <linux/console.h> | 36 | #include <linux/console.h> |
38 | #include "drm_crtc_helper.h" | 37 | #include "drm_crtc_helper.h" |
39 | 38 | ||
@@ -46,10 +45,129 @@ module_param_named(fbpercrtc, i915_fbpercrtc, int, 0400); | |||
46 | unsigned int i915_powersave = 1; | 45 | unsigned int i915_powersave = 1; |
47 | module_param_named(powersave, i915_powersave, int, 0400); | 46 | module_param_named(powersave, i915_powersave, int, 0400); |
48 | 47 | ||
48 | unsigned int i915_lvds_downclock = 0; | ||
49 | module_param_named(lvds_downclock, i915_lvds_downclock, int, 0400); | ||
50 | |||
49 | static struct drm_driver driver; | 51 | static struct drm_driver driver; |
50 | 52 | ||
51 | static struct pci_device_id pciidlist[] = { | 53 | #define INTEL_VGA_DEVICE(id, info) { \ |
52 | i915_PCI_IDS | 54 | .class = PCI_CLASS_DISPLAY_VGA << 8, \ |
55 | .class_mask = 0xffff00, \ | ||
56 | .vendor = 0x8086, \ | ||
57 | .device = id, \ | ||
58 | .subvendor = PCI_ANY_ID, \ | ||
59 | .subdevice = PCI_ANY_ID, \ | ||
60 | .driver_data = (unsigned long) info } | ||
61 | |||
62 | const static struct intel_device_info intel_i830_info = { | ||
63 | .is_i8xx = 1, .is_mobile = 1, .cursor_needs_physical = 1, | ||
64 | }; | ||
65 | |||
66 | const static struct intel_device_info intel_845g_info = { | ||
67 | .is_i8xx = 1, | ||
68 | }; | ||
69 | |||
70 | const static struct intel_device_info intel_i85x_info = { | ||
71 | .is_i8xx = 1, .is_mobile = 1, .cursor_needs_physical = 1, | ||
72 | }; | ||
73 | |||
74 | const static struct intel_device_info intel_i865g_info = { | ||
75 | .is_i8xx = 1, | ||
76 | }; | ||
77 | |||
78 | const static struct intel_device_info intel_i915g_info = { | ||
79 | .is_i915g = 1, .is_i9xx = 1, .cursor_needs_physical = 1, | ||
80 | }; | ||
81 | const static struct intel_device_info intel_i915gm_info = { | ||
82 | .is_i9xx = 1, .is_mobile = 1, .has_fbc = 1, | ||
83 | .cursor_needs_physical = 1, | ||
84 | }; | ||
85 | const static struct intel_device_info intel_i945g_info = { | ||
86 | .is_i9xx = 1, .has_hotplug = 1, .cursor_needs_physical = 1, | ||
87 | }; | ||
88 | const static struct intel_device_info intel_i945gm_info = { | ||
89 | .is_i945gm = 1, .is_i9xx = 1, .is_mobile = 1, .has_fbc = 1, | ||
90 | .has_hotplug = 1, .cursor_needs_physical = 1, | ||
91 | }; | ||
92 | |||
93 | const static struct intel_device_info intel_i965g_info = { | ||
94 | .is_i965g = 1, .is_i9xx = 1, .has_hotplug = 1, | ||
95 | }; | ||
96 | |||
97 | const static struct intel_device_info intel_i965gm_info = { | ||
98 | .is_i965g = 1, .is_mobile = 1, .is_i965gm = 1, .is_i9xx = 1, | ||
99 | .is_mobile = 1, .has_fbc = 1, .has_rc6 = 1, | ||
100 | .has_hotplug = 1, | ||
101 | }; | ||
102 | |||
103 | const static struct intel_device_info intel_g33_info = { | ||
104 | .is_g33 = 1, .is_i9xx = 1, .need_gfx_hws = 1, | ||
105 | .has_hotplug = 1, | ||
106 | }; | ||
107 | |||
108 | const static struct intel_device_info intel_g45_info = { | ||
109 | .is_i965g = 1, .is_g4x = 1, .is_i9xx = 1, .need_gfx_hws = 1, | ||
110 | .has_pipe_cxsr = 1, | ||
111 | .has_hotplug = 1, | ||
112 | }; | ||
113 | |||
114 | const static struct intel_device_info intel_gm45_info = { | ||
115 | .is_i965g = 1, .is_mobile = 1, .is_g4x = 1, .is_i9xx = 1, | ||
116 | .is_mobile = 1, .need_gfx_hws = 1, .has_fbc = 1, .has_rc6 = 1, | ||
117 | .has_pipe_cxsr = 1, | ||
118 | .has_hotplug = 1, | ||
119 | }; | ||
120 | |||
121 | const static struct intel_device_info intel_pineview_info = { | ||
122 | .is_g33 = 1, .is_pineview = 1, .is_mobile = 1, .is_i9xx = 1, | ||
123 | .has_pipe_cxsr = 1, | ||
124 | .has_hotplug = 1, | ||
125 | }; | ||
126 | |||
127 | const static struct intel_device_info intel_ironlake_d_info = { | ||
128 | .is_ironlake = 1, .is_i965g = 1, .is_i9xx = 1, .need_gfx_hws = 1, | ||
129 | .has_pipe_cxsr = 1, | ||
130 | .has_hotplug = 1, | ||
131 | }; | ||
132 | |||
133 | const static struct intel_device_info intel_ironlake_m_info = { | ||
134 | .is_ironlake = 1, .is_mobile = 1, .is_i965g = 1, .is_i9xx = 1, | ||
135 | .need_gfx_hws = 1, .has_rc6 = 1, | ||
136 | .has_hotplug = 1, | ||
137 | }; | ||
138 | |||
139 | const static struct pci_device_id pciidlist[] = { | ||
140 | INTEL_VGA_DEVICE(0x3577, &intel_i830_info), | ||
141 | INTEL_VGA_DEVICE(0x2562, &intel_845g_info), | ||
142 | INTEL_VGA_DEVICE(0x3582, &intel_i85x_info), | ||
143 | INTEL_VGA_DEVICE(0x35e8, &intel_i85x_info), | ||
144 | INTEL_VGA_DEVICE(0x2572, &intel_i865g_info), | ||
145 | INTEL_VGA_DEVICE(0x2582, &intel_i915g_info), | ||
146 | INTEL_VGA_DEVICE(0x258a, &intel_i915g_info), | ||
147 | INTEL_VGA_DEVICE(0x2592, &intel_i915gm_info), | ||
148 | INTEL_VGA_DEVICE(0x2772, &intel_i945g_info), | ||
149 | INTEL_VGA_DEVICE(0x27a2, &intel_i945gm_info), | ||
150 | INTEL_VGA_DEVICE(0x27ae, &intel_i945gm_info), | ||
151 | INTEL_VGA_DEVICE(0x2972, &intel_i965g_info), | ||
152 | INTEL_VGA_DEVICE(0x2982, &intel_i965g_info), | ||
153 | INTEL_VGA_DEVICE(0x2992, &intel_i965g_info), | ||
154 | INTEL_VGA_DEVICE(0x29a2, &intel_i965g_info), | ||
155 | INTEL_VGA_DEVICE(0x29b2, &intel_g33_info), | ||
156 | INTEL_VGA_DEVICE(0x29c2, &intel_g33_info), | ||
157 | INTEL_VGA_DEVICE(0x29d2, &intel_g33_info), | ||
158 | INTEL_VGA_DEVICE(0x2a02, &intel_i965gm_info), | ||
159 | INTEL_VGA_DEVICE(0x2a12, &intel_i965gm_info), | ||
160 | INTEL_VGA_DEVICE(0x2a42, &intel_gm45_info), | ||
161 | INTEL_VGA_DEVICE(0x2e02, &intel_g45_info), | ||
162 | INTEL_VGA_DEVICE(0x2e12, &intel_g45_info), | ||
163 | INTEL_VGA_DEVICE(0x2e22, &intel_g45_info), | ||
164 | INTEL_VGA_DEVICE(0x2e32, &intel_g45_info), | ||
165 | INTEL_VGA_DEVICE(0x2e42, &intel_g45_info), | ||
166 | INTEL_VGA_DEVICE(0xa001, &intel_pineview_info), | ||
167 | INTEL_VGA_DEVICE(0xa011, &intel_pineview_info), | ||
168 | INTEL_VGA_DEVICE(0x0042, &intel_ironlake_d_info), | ||
169 | INTEL_VGA_DEVICE(0x0046, &intel_ironlake_m_info), | ||
170 | {0, 0, 0} | ||
53 | }; | 171 | }; |
54 | 172 | ||
55 | #if defined(CONFIG_DRM_I915_KMS) | 173 | #if defined(CONFIG_DRM_I915_KMS) |
@@ -284,6 +402,52 @@ i915_pci_resume(struct pci_dev *pdev) | |||
284 | return i915_resume(dev); | 402 | return i915_resume(dev); |
285 | } | 403 | } |
286 | 404 | ||
405 | static int | ||
406 | i915_pm_suspend(struct device *dev) | ||
407 | { | ||
408 | return i915_pci_suspend(to_pci_dev(dev), PMSG_SUSPEND); | ||
409 | } | ||
410 | |||
411 | static int | ||
412 | i915_pm_resume(struct device *dev) | ||
413 | { | ||
414 | return i915_pci_resume(to_pci_dev(dev)); | ||
415 | } | ||
416 | |||
417 | static int | ||
418 | i915_pm_freeze(struct device *dev) | ||
419 | { | ||
420 | return i915_pci_suspend(to_pci_dev(dev), PMSG_FREEZE); | ||
421 | } | ||
422 | |||
423 | static int | ||
424 | i915_pm_thaw(struct device *dev) | ||
425 | { | ||
426 | /* thaw during hibernate, do nothing! */ | ||
427 | return 0; | ||
428 | } | ||
429 | |||
430 | static int | ||
431 | i915_pm_poweroff(struct device *dev) | ||
432 | { | ||
433 | return i915_pci_suspend(to_pci_dev(dev), PMSG_HIBERNATE); | ||
434 | } | ||
435 | |||
436 | static int | ||
437 | i915_pm_restore(struct device *dev) | ||
438 | { | ||
439 | return i915_pci_resume(to_pci_dev(dev)); | ||
440 | } | ||
441 | |||
442 | const struct dev_pm_ops i915_pm_ops = { | ||
443 | .suspend = i915_pm_suspend, | ||
444 | .resume = i915_pm_resume, | ||
445 | .freeze = i915_pm_freeze, | ||
446 | .thaw = i915_pm_thaw, | ||
447 | .poweroff = i915_pm_poweroff, | ||
448 | .restore = i915_pm_restore, | ||
449 | }; | ||
450 | |||
287 | static struct vm_operations_struct i915_gem_vm_ops = { | 451 | static struct vm_operations_struct i915_gem_vm_ops = { |
288 | .fault = i915_gem_fault, | 452 | .fault = i915_gem_fault, |
289 | .open = drm_gem_vm_open, | 453 | .open = drm_gem_vm_open, |
@@ -303,8 +467,11 @@ static struct drm_driver driver = { | |||
303 | .lastclose = i915_driver_lastclose, | 467 | .lastclose = i915_driver_lastclose, |
304 | .preclose = i915_driver_preclose, | 468 | .preclose = i915_driver_preclose, |
305 | .postclose = i915_driver_postclose, | 469 | .postclose = i915_driver_postclose, |
470 | |||
471 | /* Used in place of i915_pm_ops for non-DRIVER_MODESET */ | ||
306 | .suspend = i915_suspend, | 472 | .suspend = i915_suspend, |
307 | .resume = i915_resume, | 473 | .resume = i915_resume, |
474 | |||
308 | .device_is_agp = i915_driver_device_is_agp, | 475 | .device_is_agp = i915_driver_device_is_agp, |
309 | .enable_vblank = i915_enable_vblank, | 476 | .enable_vblank = i915_enable_vblank, |
310 | .disable_vblank = i915_disable_vblank, | 477 | .disable_vblank = i915_disable_vblank, |
@@ -344,10 +511,7 @@ static struct drm_driver driver = { | |||
344 | .id_table = pciidlist, | 511 | .id_table = pciidlist, |
345 | .probe = i915_pci_probe, | 512 | .probe = i915_pci_probe, |
346 | .remove = i915_pci_remove, | 513 | .remove = i915_pci_remove, |
347 | #ifdef CONFIG_PM | 514 | .driver.pm = &i915_pm_ops, |
348 | .resume = i915_pci_resume, | ||
349 | .suspend = i915_pci_suspend, | ||
350 | #endif | ||
351 | }, | 515 | }, |
352 | 516 | ||
353 | .name = DRIVER_NAME, | 517 | .name = DRIVER_NAME, |
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index fbecac72f5bb..2c1669488b5a 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h | |||
@@ -172,9 +172,31 @@ struct drm_i915_display_funcs { | |||
172 | 172 | ||
173 | struct intel_overlay; | 173 | struct intel_overlay; |
174 | 174 | ||
175 | struct intel_device_info { | ||
176 | u8 is_mobile : 1; | ||
177 | u8 is_i8xx : 1; | ||
178 | u8 is_i915g : 1; | ||
179 | u8 is_i9xx : 1; | ||
180 | u8 is_i945gm : 1; | ||
181 | u8 is_i965g : 1; | ||
182 | u8 is_i965gm : 1; | ||
183 | u8 is_g33 : 1; | ||
184 | u8 need_gfx_hws : 1; | ||
185 | u8 is_g4x : 1; | ||
186 | u8 is_pineview : 1; | ||
187 | u8 is_ironlake : 1; | ||
188 | u8 has_fbc : 1; | ||
189 | u8 has_rc6 : 1; | ||
190 | u8 has_pipe_cxsr : 1; | ||
191 | u8 has_hotplug : 1; | ||
192 | u8 cursor_needs_physical : 1; | ||
193 | }; | ||
194 | |||
175 | typedef struct drm_i915_private { | 195 | typedef struct drm_i915_private { |
176 | struct drm_device *dev; | 196 | struct drm_device *dev; |
177 | 197 | ||
198 | const struct intel_device_info *info; | ||
199 | |||
178 | int has_gem; | 200 | int has_gem; |
179 | 201 | ||
180 | void __iomem *regs; | 202 | void __iomem *regs; |
@@ -232,8 +254,6 @@ typedef struct drm_i915_private { | |||
232 | int hangcheck_count; | 254 | int hangcheck_count; |
233 | uint32_t last_acthd; | 255 | uint32_t last_acthd; |
234 | 256 | ||
235 | bool cursor_needs_physical; | ||
236 | |||
237 | struct drm_mm vram; | 257 | struct drm_mm vram; |
238 | 258 | ||
239 | unsigned long cfb_size; | 259 | unsigned long cfb_size; |
@@ -263,6 +283,7 @@ typedef struct drm_i915_private { | |||
263 | unsigned int lvds_use_ssc:1; | 283 | unsigned int lvds_use_ssc:1; |
264 | unsigned int edp_support:1; | 284 | unsigned int edp_support:1; |
265 | int lvds_ssc_freq; | 285 | int lvds_ssc_freq; |
286 | int edp_bpp; | ||
266 | 287 | ||
267 | struct notifier_block lid_notifier; | 288 | struct notifier_block lid_notifier; |
268 | 289 | ||
@@ -287,8 +308,6 @@ typedef struct drm_i915_private { | |||
287 | u32 saveDSPACNTR; | 308 | u32 saveDSPACNTR; |
288 | u32 saveDSPBCNTR; | 309 | u32 saveDSPBCNTR; |
289 | u32 saveDSPARB; | 310 | u32 saveDSPARB; |
290 | u32 saveRENDERSTANDBY; | ||
291 | u32 savePWRCTXA; | ||
292 | u32 saveHWS; | 311 | u32 saveHWS; |
293 | u32 savePIPEACONF; | 312 | u32 savePIPEACONF; |
294 | u32 savePIPEBCONF; | 313 | u32 savePIPEBCONF; |
@@ -561,6 +580,7 @@ typedef struct drm_i915_private { | |||
561 | u16 orig_clock; | 580 | u16 orig_clock; |
562 | int child_dev_num; | 581 | int child_dev_num; |
563 | struct child_device_config *child_dev; | 582 | struct child_device_config *child_dev; |
583 | struct drm_connector *int_lvds_connector; | ||
564 | } drm_i915_private_t; | 584 | } drm_i915_private_t; |
565 | 585 | ||
566 | /** driver private structure attached to each drm_gem_object */ | 586 | /** driver private structure attached to each drm_gem_object */ |
@@ -703,6 +723,7 @@ extern struct drm_ioctl_desc i915_ioctls[]; | |||
703 | extern int i915_max_ioctl; | 723 | extern int i915_max_ioctl; |
704 | extern unsigned int i915_fbpercrtc; | 724 | extern unsigned int i915_fbpercrtc; |
705 | extern unsigned int i915_powersave; | 725 | extern unsigned int i915_powersave; |
726 | extern unsigned int i915_lvds_downclock; | ||
706 | 727 | ||
707 | extern void i915_save_display(struct drm_device *dev); | 728 | extern void i915_save_display(struct drm_device *dev); |
708 | extern void i915_restore_display(struct drm_device *dev); | 729 | extern void i915_restore_display(struct drm_device *dev); |
@@ -794,6 +815,8 @@ int i915_gem_sw_finish_ioctl(struct drm_device *dev, void *data, | |||
794 | struct drm_file *file_priv); | 815 | struct drm_file *file_priv); |
795 | int i915_gem_execbuffer(struct drm_device *dev, void *data, | 816 | int i915_gem_execbuffer(struct drm_device *dev, void *data, |
796 | struct drm_file *file_priv); | 817 | struct drm_file *file_priv); |
818 | int i915_gem_execbuffer2(struct drm_device *dev, void *data, | ||
819 | struct drm_file *file_priv); | ||
797 | int i915_gem_pin_ioctl(struct drm_device *dev, void *data, | 820 | int i915_gem_pin_ioctl(struct drm_device *dev, void *data, |
798 | struct drm_file *file_priv); | 821 | struct drm_file *file_priv); |
799 | int i915_gem_unpin_ioctl(struct drm_device *dev, void *data, | 822 | int i915_gem_unpin_ioctl(struct drm_device *dev, void *data, |
@@ -843,6 +866,7 @@ int i915_do_wait_request(struct drm_device *dev, uint32_t seqno, int interruptib | |||
843 | int i915_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf); | 866 | int i915_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf); |
844 | int i915_gem_object_set_to_gtt_domain(struct drm_gem_object *obj, | 867 | int i915_gem_object_set_to_gtt_domain(struct drm_gem_object *obj, |
845 | int write); | 868 | int write); |
869 | int i915_gem_object_set_to_display_plane(struct drm_gem_object *obj); | ||
846 | int i915_gem_attach_phys_object(struct drm_device *dev, | 870 | int i915_gem_attach_phys_object(struct drm_device *dev, |
847 | struct drm_gem_object *obj, int id); | 871 | struct drm_gem_object *obj, int id); |
848 | void i915_gem_detach_phys_object(struct drm_device *dev, | 872 | void i915_gem_detach_phys_object(struct drm_device *dev, |
@@ -860,6 +884,9 @@ void i915_gem_shrinker_exit(void); | |||
860 | void i915_gem_detect_bit_6_swizzle(struct drm_device *dev); | 884 | void i915_gem_detect_bit_6_swizzle(struct drm_device *dev); |
861 | void i915_gem_object_do_bit_17_swizzle(struct drm_gem_object *obj); | 885 | void i915_gem_object_do_bit_17_swizzle(struct drm_gem_object *obj); |
862 | void i915_gem_object_save_bit_17_swizzle(struct drm_gem_object *obj); | 886 | void i915_gem_object_save_bit_17_swizzle(struct drm_gem_object *obj); |
887 | bool i915_tiling_ok(struct drm_device *dev, int stride, int size, | ||
888 | int tiling_mode); | ||
889 | bool i915_obj_fenceable(struct drm_device *dev, struct drm_gem_object *obj); | ||
863 | 890 | ||
864 | /* i915_gem_debug.c */ | 891 | /* i915_gem_debug.c */ |
865 | void i915_gem_dump_object(struct drm_gem_object *obj, int len, | 892 | void i915_gem_dump_object(struct drm_gem_object *obj, int len, |
@@ -982,67 +1009,33 @@ extern void g4x_disable_fbc(struct drm_device *dev); | |||
982 | extern int i915_wrap_ring(struct drm_device * dev); | 1009 | extern int i915_wrap_ring(struct drm_device * dev); |
983 | extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller); | 1010 | extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller); |
984 | 1011 | ||
985 | #define IS_I830(dev) ((dev)->pci_device == 0x3577) | 1012 | #define INTEL_INFO(dev) (((struct drm_i915_private *) (dev)->dev_private)->info) |
986 | #define IS_845G(dev) ((dev)->pci_device == 0x2562) | 1013 | |
987 | #define IS_I85X(dev) ((dev)->pci_device == 0x3582) | 1014 | #define IS_I830(dev) ((dev)->pci_device == 0x3577) |
988 | #define IS_I865G(dev) ((dev)->pci_device == 0x2572) | 1015 | #define IS_845G(dev) ((dev)->pci_device == 0x2562) |
989 | #define IS_I8XX(dev) (IS_I830(dev) || IS_845G(dev) || IS_I85X(dev) || IS_I865G(dev)) | 1016 | #define IS_I85X(dev) ((dev)->pci_device == 0x3582) |
990 | 1017 | #define IS_I865G(dev) ((dev)->pci_device == 0x2572) | |
991 | #define IS_I915G(dev) ((dev)->pci_device == 0x2582 || (dev)->pci_device == 0x258a) | 1018 | #define IS_I8XX(dev) (INTEL_INFO(dev)->is_i8xx) |
992 | #define IS_I915GM(dev) ((dev)->pci_device == 0x2592) | 1019 | #define IS_I915G(dev) (INTEL_INFO(dev)->is_i915g) |
993 | #define IS_I945G(dev) ((dev)->pci_device == 0x2772) | 1020 | #define IS_I915GM(dev) ((dev)->pci_device == 0x2592) |
994 | #define IS_I945GM(dev) ((dev)->pci_device == 0x27A2 ||\ | 1021 | #define IS_I945G(dev) ((dev)->pci_device == 0x2772) |
995 | (dev)->pci_device == 0x27AE) | 1022 | #define IS_I945GM(dev) (INTEL_INFO(dev)->is_i945gm) |
996 | #define IS_I965G(dev) ((dev)->pci_device == 0x2972 || \ | 1023 | #define IS_I965G(dev) (INTEL_INFO(dev)->is_i965g) |
997 | (dev)->pci_device == 0x2982 || \ | 1024 | #define IS_I965GM(dev) (INTEL_INFO(dev)->is_i965gm) |
998 | (dev)->pci_device == 0x2992 || \ | 1025 | #define IS_GM45(dev) ((dev)->pci_device == 0x2A42) |
999 | (dev)->pci_device == 0x29A2 || \ | 1026 | #define IS_G4X(dev) (INTEL_INFO(dev)->is_g4x) |
1000 | (dev)->pci_device == 0x2A02 || \ | 1027 | #define IS_PINEVIEW_G(dev) ((dev)->pci_device == 0xa001) |
1001 | (dev)->pci_device == 0x2A12 || \ | 1028 | #define IS_PINEVIEW_M(dev) ((dev)->pci_device == 0xa011) |
1002 | (dev)->pci_device == 0x2A42 || \ | 1029 | #define IS_PINEVIEW(dev) (INTEL_INFO(dev)->is_pineview) |
1003 | (dev)->pci_device == 0x2E02 || \ | 1030 | #define IS_G33(dev) (INTEL_INFO(dev)->is_g33) |
1004 | (dev)->pci_device == 0x2E12 || \ | ||
1005 | (dev)->pci_device == 0x2E22 || \ | ||
1006 | (dev)->pci_device == 0x2E32 || \ | ||
1007 | (dev)->pci_device == 0x2E42 || \ | ||
1008 | (dev)->pci_device == 0x0042 || \ | ||
1009 | (dev)->pci_device == 0x0046) | ||
1010 | |||
1011 | #define IS_I965GM(dev) ((dev)->pci_device == 0x2A02 || \ | ||
1012 | (dev)->pci_device == 0x2A12) | ||
1013 | |||
1014 | #define IS_GM45(dev) ((dev)->pci_device == 0x2A42) | ||
1015 | |||
1016 | #define IS_G4X(dev) ((dev)->pci_device == 0x2E02 || \ | ||
1017 | (dev)->pci_device == 0x2E12 || \ | ||
1018 | (dev)->pci_device == 0x2E22 || \ | ||
1019 | (dev)->pci_device == 0x2E32 || \ | ||
1020 | (dev)->pci_device == 0x2E42 || \ | ||
1021 | IS_GM45(dev)) | ||
1022 | |||
1023 | #define IS_PINEVIEW_G(dev) ((dev)->pci_device == 0xa001) | ||
1024 | #define IS_PINEVIEW_M(dev) ((dev)->pci_device == 0xa011) | ||
1025 | #define IS_PINEVIEW(dev) (IS_PINEVIEW_G(dev) || IS_PINEVIEW_M(dev)) | ||
1026 | |||
1027 | #define IS_G33(dev) ((dev)->pci_device == 0x29C2 || \ | ||
1028 | (dev)->pci_device == 0x29B2 || \ | ||
1029 | (dev)->pci_device == 0x29D2 || \ | ||
1030 | (IS_PINEVIEW(dev))) | ||
1031 | |||
1032 | #define IS_IRONLAKE_D(dev) ((dev)->pci_device == 0x0042) | 1031 | #define IS_IRONLAKE_D(dev) ((dev)->pci_device == 0x0042) |
1033 | #define IS_IRONLAKE_M(dev) ((dev)->pci_device == 0x0046) | 1032 | #define IS_IRONLAKE_M(dev) ((dev)->pci_device == 0x0046) |
1034 | #define IS_IRONLAKE(dev) (IS_IRONLAKE_D(dev) || IS_IRONLAKE_M(dev)) | 1033 | #define IS_IRONLAKE(dev) (INTEL_INFO(dev)->is_ironlake) |
1035 | 1034 | #define IS_I9XX(dev) (INTEL_INFO(dev)->is_i9xx) | |
1036 | #define IS_I9XX(dev) (IS_I915G(dev) || IS_I915GM(dev) || IS_I945G(dev) || \ | 1035 | #define IS_MOBILE(dev) (INTEL_INFO(dev)->is_mobile) |
1037 | IS_I945GM(dev) || IS_I965G(dev) || IS_G33(dev) || \ | ||
1038 | IS_IRONLAKE(dev)) | ||
1039 | 1036 | ||
1040 | #define IS_MOBILE(dev) (IS_I830(dev) || IS_I85X(dev) || IS_I915GM(dev) || \ | 1037 | #define I915_NEED_GFX_HWS(dev) (INTEL_INFO(dev)->need_gfx_hws) |
1041 | IS_I945GM(dev) || IS_I965GM(dev) || IS_GM45(dev) || \ | ||
1042 | IS_PINEVIEW(dev) || IS_IRONLAKE_M(dev)) | ||
1043 | 1038 | ||
1044 | #define I915_NEED_GFX_HWS(dev) (IS_G33(dev) || IS_GM45(dev) || IS_G4X(dev) || \ | ||
1045 | IS_IRONLAKE(dev)) | ||
1046 | /* With the 945 and later, Y tiling got adjusted so that it was 32 128-byte | 1039 | /* With the 945 and later, Y tiling got adjusted so that it was 32 128-byte |
1047 | * rows, which changed the alignment requirements and fence programming. | 1040 | * rows, which changed the alignment requirements and fence programming. |
1048 | */ | 1041 | */ |
@@ -1054,17 +1047,14 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller); | |||
1054 | #define SUPPORTS_EDP(dev) (IS_IRONLAKE_M(dev)) | 1047 | #define SUPPORTS_EDP(dev) (IS_IRONLAKE_M(dev)) |
1055 | #define SUPPORTS_TV(dev) (IS_I9XX(dev) && IS_MOBILE(dev) && \ | 1048 | #define SUPPORTS_TV(dev) (IS_I9XX(dev) && IS_MOBILE(dev) && \ |
1056 | !IS_IRONLAKE(dev) && !IS_PINEVIEW(dev)) | 1049 | !IS_IRONLAKE(dev) && !IS_PINEVIEW(dev)) |
1057 | #define I915_HAS_HOTPLUG(dev) (IS_I945G(dev) || IS_I945GM(dev) || IS_G33(dev) || IS_I965G(dev)) | 1050 | #define I915_HAS_HOTPLUG(dev) (INTEL_INFO(dev)->has_hotplug) |
1058 | /* dsparb controlled by hw only */ | 1051 | /* dsparb controlled by hw only */ |
1059 | #define DSPARB_HWCONTROL(dev) (IS_G4X(dev) || IS_IRONLAKE(dev)) | 1052 | #define DSPARB_HWCONTROL(dev) (IS_G4X(dev) || IS_IRONLAKE(dev)) |
1060 | 1053 | ||
1061 | #define HAS_FW_BLC(dev) (IS_I9XX(dev) || IS_G4X(dev) || IS_IRONLAKE(dev)) | 1054 | #define HAS_FW_BLC(dev) (IS_I9XX(dev) || IS_G4X(dev) || IS_IRONLAKE(dev)) |
1062 | #define HAS_PIPE_CXSR(dev) (IS_G4X(dev) || IS_IRONLAKE(dev)) | 1055 | #define HAS_PIPE_CXSR(dev) (INTEL_INFO(dev)->has_pipe_cxsr) |
1063 | #define I915_HAS_FBC(dev) (IS_MOBILE(dev) && \ | 1056 | #define I915_HAS_FBC(dev) (INTEL_INFO(dev)->has_fbc) |
1064 | (IS_I9XX(dev) || IS_GM45(dev)) && \ | 1057 | #define I915_HAS_RC6(dev) (INTEL_INFO(dev)->has_rc6) |
1065 | !IS_PINEVIEW(dev) && \ | ||
1066 | !IS_IRONLAKE(dev)) | ||
1067 | #define I915_HAS_RC6(dev) (IS_I965GM(dev) || IS_GM45(dev) || IS_IRONLAKE_M(dev)) | ||
1068 | 1058 | ||
1069 | #define PRIMARY_RINGBUFFER_SIZE (128*1024) | 1059 | #define PRIMARY_RINGBUFFER_SIZE (128*1024) |
1070 | 1060 | ||
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 8c463cf2050a..0c67924ca80c 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c | |||
@@ -2021,9 +2021,6 @@ i915_gem_object_unbind(struct drm_gem_object *obj) | |||
2021 | /* blow away mappings if mapped through GTT */ | 2021 | /* blow away mappings if mapped through GTT */ |
2022 | i915_gem_release_mmap(obj); | 2022 | i915_gem_release_mmap(obj); |
2023 | 2023 | ||
2024 | if (obj_priv->fence_reg != I915_FENCE_REG_NONE) | ||
2025 | i915_gem_clear_fence_reg(obj); | ||
2026 | |||
2027 | /* Move the object to the CPU domain to ensure that | 2024 | /* Move the object to the CPU domain to ensure that |
2028 | * any possible CPU writes while it's not in the GTT | 2025 | * any possible CPU writes while it's not in the GTT |
2029 | * are flushed when we go to remap it. This will | 2026 | * are flushed when we go to remap it. This will |
@@ -2039,6 +2036,10 @@ i915_gem_object_unbind(struct drm_gem_object *obj) | |||
2039 | 2036 | ||
2040 | BUG_ON(obj_priv->active); | 2037 | BUG_ON(obj_priv->active); |
2041 | 2038 | ||
2039 | /* release the fence reg _after_ flushing */ | ||
2040 | if (obj_priv->fence_reg != I915_FENCE_REG_NONE) | ||
2041 | i915_gem_clear_fence_reg(obj); | ||
2042 | |||
2042 | if (obj_priv->agp_mem != NULL) { | 2043 | if (obj_priv->agp_mem != NULL) { |
2043 | drm_unbind_agp(obj_priv->agp_mem); | 2044 | drm_unbind_agp(obj_priv->agp_mem); |
2044 | drm_free_agp(obj_priv->agp_mem, obj->size / PAGE_SIZE); | 2045 | drm_free_agp(obj_priv->agp_mem, obj->size / PAGE_SIZE); |
@@ -2581,9 +2582,6 @@ i915_gem_object_bind_to_gtt(struct drm_gem_object *obj, unsigned alignment) | |||
2581 | bool retry_alloc = false; | 2582 | bool retry_alloc = false; |
2582 | int ret; | 2583 | int ret; |
2583 | 2584 | ||
2584 | if (dev_priv->mm.suspended) | ||
2585 | return -EBUSY; | ||
2586 | |||
2587 | if (obj_priv->madv != I915_MADV_WILLNEED) { | 2585 | if (obj_priv->madv != I915_MADV_WILLNEED) { |
2588 | DRM_ERROR("Attempting to bind a purgeable object\n"); | 2586 | DRM_ERROR("Attempting to bind a purgeable object\n"); |
2589 | return -EINVAL; | 2587 | return -EINVAL; |
@@ -2839,6 +2837,57 @@ i915_gem_object_set_to_gtt_domain(struct drm_gem_object *obj, int write) | |||
2839 | return 0; | 2837 | return 0; |
2840 | } | 2838 | } |
2841 | 2839 | ||
2840 | /* | ||
2841 | * Prepare buffer for display plane. Use uninterruptible for possible flush | ||
2842 | * wait, as in modesetting process we're not supposed to be interrupted. | ||
2843 | */ | ||
2844 | int | ||
2845 | i915_gem_object_set_to_display_plane(struct drm_gem_object *obj) | ||
2846 | { | ||
2847 | struct drm_device *dev = obj->dev; | ||
2848 | struct drm_i915_gem_object *obj_priv = obj->driver_private; | ||
2849 | uint32_t old_write_domain, old_read_domains; | ||
2850 | int ret; | ||
2851 | |||
2852 | /* Not valid to be called on unbound objects. */ | ||
2853 | if (obj_priv->gtt_space == NULL) | ||
2854 | return -EINVAL; | ||
2855 | |||
2856 | i915_gem_object_flush_gpu_write_domain(obj); | ||
2857 | |||
2858 | /* Wait on any GPU rendering and flushing to occur. */ | ||
2859 | if (obj_priv->active) { | ||
2860 | #if WATCH_BUF | ||
2861 | DRM_INFO("%s: object %p wait for seqno %08x\n", | ||
2862 | __func__, obj, obj_priv->last_rendering_seqno); | ||
2863 | #endif | ||
2864 | ret = i915_do_wait_request(dev, obj_priv->last_rendering_seqno, 0); | ||
2865 | if (ret != 0) | ||
2866 | return ret; | ||
2867 | } | ||
2868 | |||
2869 | old_write_domain = obj->write_domain; | ||
2870 | old_read_domains = obj->read_domains; | ||
2871 | |||
2872 | obj->read_domains &= I915_GEM_DOMAIN_GTT; | ||
2873 | |||
2874 | i915_gem_object_flush_cpu_write_domain(obj); | ||
2875 | |||
2876 | /* It should now be out of any other write domains, and we can update | ||
2877 | * the domain values for our changes. | ||
2878 | */ | ||
2879 | BUG_ON((obj->write_domain & ~I915_GEM_DOMAIN_GTT) != 0); | ||
2880 | obj->read_domains |= I915_GEM_DOMAIN_GTT; | ||
2881 | obj->write_domain = I915_GEM_DOMAIN_GTT; | ||
2882 | obj_priv->dirty = 1; | ||
2883 | |||
2884 | trace_i915_gem_object_change_domain(obj, | ||
2885 | old_read_domains, | ||
2886 | old_write_domain); | ||
2887 | |||
2888 | return 0; | ||
2889 | } | ||
2890 | |||
2842 | /** | 2891 | /** |
2843 | * Moves a single object to the CPU read, and possibly write domain. | 2892 | * Moves a single object to the CPU read, and possibly write domain. |
2844 | * | 2893 | * |
@@ -3198,7 +3247,7 @@ i915_gem_object_set_cpu_read_domain_range(struct drm_gem_object *obj, | |||
3198 | static int | 3247 | static int |
3199 | i915_gem_object_pin_and_relocate(struct drm_gem_object *obj, | 3248 | i915_gem_object_pin_and_relocate(struct drm_gem_object *obj, |
3200 | struct drm_file *file_priv, | 3249 | struct drm_file *file_priv, |
3201 | struct drm_i915_gem_exec_object *entry, | 3250 | struct drm_i915_gem_exec_object2 *entry, |
3202 | struct drm_i915_gem_relocation_entry *relocs) | 3251 | struct drm_i915_gem_relocation_entry *relocs) |
3203 | { | 3252 | { |
3204 | struct drm_device *dev = obj->dev; | 3253 | struct drm_device *dev = obj->dev; |
@@ -3206,12 +3255,35 @@ i915_gem_object_pin_and_relocate(struct drm_gem_object *obj, | |||
3206 | struct drm_i915_gem_object *obj_priv = obj->driver_private; | 3255 | struct drm_i915_gem_object *obj_priv = obj->driver_private; |
3207 | int i, ret; | 3256 | int i, ret; |
3208 | void __iomem *reloc_page; | 3257 | void __iomem *reloc_page; |
3258 | bool need_fence; | ||
3259 | |||
3260 | need_fence = entry->flags & EXEC_OBJECT_NEEDS_FENCE && | ||
3261 | obj_priv->tiling_mode != I915_TILING_NONE; | ||
3262 | |||
3263 | /* Check fence reg constraints and rebind if necessary */ | ||
3264 | if (need_fence && !i915_obj_fenceable(dev, obj)) | ||
3265 | i915_gem_object_unbind(obj); | ||
3209 | 3266 | ||
3210 | /* Choose the GTT offset for our buffer and put it there. */ | 3267 | /* Choose the GTT offset for our buffer and put it there. */ |
3211 | ret = i915_gem_object_pin(obj, (uint32_t) entry->alignment); | 3268 | ret = i915_gem_object_pin(obj, (uint32_t) entry->alignment); |
3212 | if (ret) | 3269 | if (ret) |
3213 | return ret; | 3270 | return ret; |
3214 | 3271 | ||
3272 | /* | ||
3273 | * Pre-965 chips need a fence register set up in order to | ||
3274 | * properly handle blits to/from tiled surfaces. | ||
3275 | */ | ||
3276 | if (need_fence) { | ||
3277 | ret = i915_gem_object_get_fence_reg(obj); | ||
3278 | if (ret != 0) { | ||
3279 | if (ret != -EBUSY && ret != -ERESTARTSYS) | ||
3280 | DRM_ERROR("Failure to install fence: %d\n", | ||
3281 | ret); | ||
3282 | i915_gem_object_unpin(obj); | ||
3283 | return ret; | ||
3284 | } | ||
3285 | } | ||
3286 | |||
3215 | entry->offset = obj_priv->gtt_offset; | 3287 | entry->offset = obj_priv->gtt_offset; |
3216 | 3288 | ||
3217 | /* Apply the relocations, using the GTT aperture to avoid cache | 3289 | /* Apply the relocations, using the GTT aperture to avoid cache |
@@ -3373,7 +3445,7 @@ i915_gem_object_pin_and_relocate(struct drm_gem_object *obj, | |||
3373 | */ | 3445 | */ |
3374 | static int | 3446 | static int |
3375 | i915_dispatch_gem_execbuffer(struct drm_device *dev, | 3447 | i915_dispatch_gem_execbuffer(struct drm_device *dev, |
3376 | struct drm_i915_gem_execbuffer *exec, | 3448 | struct drm_i915_gem_execbuffer2 *exec, |
3377 | struct drm_clip_rect *cliprects, | 3449 | struct drm_clip_rect *cliprects, |
3378 | uint64_t exec_offset) | 3450 | uint64_t exec_offset) |
3379 | { | 3451 | { |
@@ -3463,7 +3535,7 @@ i915_gem_ring_throttle(struct drm_device *dev, struct drm_file *file_priv) | |||
3463 | } | 3535 | } |
3464 | 3536 | ||
3465 | static int | 3537 | static int |
3466 | i915_gem_get_relocs_from_user(struct drm_i915_gem_exec_object *exec_list, | 3538 | i915_gem_get_relocs_from_user(struct drm_i915_gem_exec_object2 *exec_list, |
3467 | uint32_t buffer_count, | 3539 | uint32_t buffer_count, |
3468 | struct drm_i915_gem_relocation_entry **relocs) | 3540 | struct drm_i915_gem_relocation_entry **relocs) |
3469 | { | 3541 | { |
@@ -3478,8 +3550,10 @@ i915_gem_get_relocs_from_user(struct drm_i915_gem_exec_object *exec_list, | |||
3478 | } | 3550 | } |
3479 | 3551 | ||
3480 | *relocs = drm_calloc_large(reloc_count, sizeof(**relocs)); | 3552 | *relocs = drm_calloc_large(reloc_count, sizeof(**relocs)); |
3481 | if (*relocs == NULL) | 3553 | if (*relocs == NULL) { |
3554 | DRM_ERROR("failed to alloc relocs, count %d\n", reloc_count); | ||
3482 | return -ENOMEM; | 3555 | return -ENOMEM; |
3556 | } | ||
3483 | 3557 | ||
3484 | for (i = 0; i < buffer_count; i++) { | 3558 | for (i = 0; i < buffer_count; i++) { |
3485 | struct drm_i915_gem_relocation_entry __user *user_relocs; | 3559 | struct drm_i915_gem_relocation_entry __user *user_relocs; |
@@ -3503,7 +3577,7 @@ i915_gem_get_relocs_from_user(struct drm_i915_gem_exec_object *exec_list, | |||
3503 | } | 3577 | } |
3504 | 3578 | ||
3505 | static int | 3579 | static int |
3506 | i915_gem_put_relocs_to_user(struct drm_i915_gem_exec_object *exec_list, | 3580 | i915_gem_put_relocs_to_user(struct drm_i915_gem_exec_object2 *exec_list, |
3507 | uint32_t buffer_count, | 3581 | uint32_t buffer_count, |
3508 | struct drm_i915_gem_relocation_entry *relocs) | 3582 | struct drm_i915_gem_relocation_entry *relocs) |
3509 | { | 3583 | { |
@@ -3536,7 +3610,7 @@ err: | |||
3536 | } | 3610 | } |
3537 | 3611 | ||
3538 | static int | 3612 | static int |
3539 | i915_gem_check_execbuffer (struct drm_i915_gem_execbuffer *exec, | 3613 | i915_gem_check_execbuffer (struct drm_i915_gem_execbuffer2 *exec, |
3540 | uint64_t exec_offset) | 3614 | uint64_t exec_offset) |
3541 | { | 3615 | { |
3542 | uint32_t exec_start, exec_len; | 3616 | uint32_t exec_start, exec_len; |
@@ -3589,18 +3663,18 @@ i915_gem_wait_for_pending_flip(struct drm_device *dev, | |||
3589 | } | 3663 | } |
3590 | 3664 | ||
3591 | int | 3665 | int |
3592 | i915_gem_execbuffer(struct drm_device *dev, void *data, | 3666 | i915_gem_do_execbuffer(struct drm_device *dev, void *data, |
3593 | struct drm_file *file_priv) | 3667 | struct drm_file *file_priv, |
3668 | struct drm_i915_gem_execbuffer2 *args, | ||
3669 | struct drm_i915_gem_exec_object2 *exec_list) | ||
3594 | { | 3670 | { |
3595 | drm_i915_private_t *dev_priv = dev->dev_private; | 3671 | drm_i915_private_t *dev_priv = dev->dev_private; |
3596 | struct drm_i915_gem_execbuffer *args = data; | ||
3597 | struct drm_i915_gem_exec_object *exec_list = NULL; | ||
3598 | struct drm_gem_object **object_list = NULL; | 3672 | struct drm_gem_object **object_list = NULL; |
3599 | struct drm_gem_object *batch_obj; | 3673 | struct drm_gem_object *batch_obj; |
3600 | struct drm_i915_gem_object *obj_priv; | 3674 | struct drm_i915_gem_object *obj_priv; |
3601 | struct drm_clip_rect *cliprects = NULL; | 3675 | struct drm_clip_rect *cliprects = NULL; |
3602 | struct drm_i915_gem_relocation_entry *relocs; | 3676 | struct drm_i915_gem_relocation_entry *relocs; |
3603 | int ret, ret2, i, pinned = 0; | 3677 | int ret = 0, ret2, i, pinned = 0; |
3604 | uint64_t exec_offset; | 3678 | uint64_t exec_offset; |
3605 | uint32_t seqno, flush_domains, reloc_index; | 3679 | uint32_t seqno, flush_domains, reloc_index; |
3606 | int pin_tries, flips; | 3680 | int pin_tries, flips; |
@@ -3614,25 +3688,13 @@ i915_gem_execbuffer(struct drm_device *dev, void *data, | |||
3614 | DRM_ERROR("execbuf with %d buffers\n", args->buffer_count); | 3688 | DRM_ERROR("execbuf with %d buffers\n", args->buffer_count); |
3615 | return -EINVAL; | 3689 | return -EINVAL; |
3616 | } | 3690 | } |
3617 | /* Copy in the exec list from userland */ | ||
3618 | exec_list = drm_malloc_ab(sizeof(*exec_list), args->buffer_count); | ||
3619 | object_list = drm_malloc_ab(sizeof(*object_list), args->buffer_count); | 3691 | object_list = drm_malloc_ab(sizeof(*object_list), args->buffer_count); |
3620 | if (exec_list == NULL || object_list == NULL) { | 3692 | if (object_list == NULL) { |
3621 | DRM_ERROR("Failed to allocate exec or object list " | 3693 | DRM_ERROR("Failed to allocate object list for %d buffers\n", |
3622 | "for %d buffers\n", | ||
3623 | args->buffer_count); | 3694 | args->buffer_count); |
3624 | ret = -ENOMEM; | 3695 | ret = -ENOMEM; |
3625 | goto pre_mutex_err; | 3696 | goto pre_mutex_err; |
3626 | } | 3697 | } |
3627 | ret = copy_from_user(exec_list, | ||
3628 | (struct drm_i915_relocation_entry __user *) | ||
3629 | (uintptr_t) args->buffers_ptr, | ||
3630 | sizeof(*exec_list) * args->buffer_count); | ||
3631 | if (ret != 0) { | ||
3632 | DRM_ERROR("copy %d exec entries failed %d\n", | ||
3633 | args->buffer_count, ret); | ||
3634 | goto pre_mutex_err; | ||
3635 | } | ||
3636 | 3698 | ||
3637 | if (args->num_cliprects != 0) { | 3699 | if (args->num_cliprects != 0) { |
3638 | cliprects = kcalloc(args->num_cliprects, sizeof(*cliprects), | 3700 | cliprects = kcalloc(args->num_cliprects, sizeof(*cliprects), |
@@ -3884,20 +3946,6 @@ err: | |||
3884 | 3946 | ||
3885 | mutex_unlock(&dev->struct_mutex); | 3947 | mutex_unlock(&dev->struct_mutex); |
3886 | 3948 | ||
3887 | if (!ret) { | ||
3888 | /* Copy the new buffer offsets back to the user's exec list. */ | ||
3889 | ret = copy_to_user((struct drm_i915_relocation_entry __user *) | ||
3890 | (uintptr_t) args->buffers_ptr, | ||
3891 | exec_list, | ||
3892 | sizeof(*exec_list) * args->buffer_count); | ||
3893 | if (ret) { | ||
3894 | ret = -EFAULT; | ||
3895 | DRM_ERROR("failed to copy %d exec entries " | ||
3896 | "back to user (%d)\n", | ||
3897 | args->buffer_count, ret); | ||
3898 | } | ||
3899 | } | ||
3900 | |||
3901 | /* Copy the updated relocations out regardless of current error | 3949 | /* Copy the updated relocations out regardless of current error |
3902 | * state. Failure to update the relocs would mean that the next | 3950 | * state. Failure to update the relocs would mean that the next |
3903 | * time userland calls execbuf, it would do so with presumed offset | 3951 | * time userland calls execbuf, it would do so with presumed offset |
@@ -3914,12 +3962,156 @@ err: | |||
3914 | 3962 | ||
3915 | pre_mutex_err: | 3963 | pre_mutex_err: |
3916 | drm_free_large(object_list); | 3964 | drm_free_large(object_list); |
3917 | drm_free_large(exec_list); | ||
3918 | kfree(cliprects); | 3965 | kfree(cliprects); |
3919 | 3966 | ||
3920 | return ret; | 3967 | return ret; |
3921 | } | 3968 | } |
3922 | 3969 | ||
3970 | /* | ||
3971 | * Legacy execbuffer just creates an exec2 list from the original exec object | ||
3972 | * list array and passes it to the real function. | ||
3973 | */ | ||
3974 | int | ||
3975 | i915_gem_execbuffer(struct drm_device *dev, void *data, | ||
3976 | struct drm_file *file_priv) | ||
3977 | { | ||
3978 | struct drm_i915_gem_execbuffer *args = data; | ||
3979 | struct drm_i915_gem_execbuffer2 exec2; | ||
3980 | struct drm_i915_gem_exec_object *exec_list = NULL; | ||
3981 | struct drm_i915_gem_exec_object2 *exec2_list = NULL; | ||
3982 | int ret, i; | ||
3983 | |||
3984 | #if WATCH_EXEC | ||
3985 | DRM_INFO("buffers_ptr %d buffer_count %d len %08x\n", | ||
3986 | (int) args->buffers_ptr, args->buffer_count, args->batch_len); | ||
3987 | #endif | ||
3988 | |||
3989 | if (args->buffer_count < 1) { | ||
3990 | DRM_ERROR("execbuf with %d buffers\n", args->buffer_count); | ||
3991 | return -EINVAL; | ||
3992 | } | ||
3993 | |||
3994 | /* Copy in the exec list from userland */ | ||
3995 | exec_list = drm_malloc_ab(sizeof(*exec_list), args->buffer_count); | ||
3996 | exec2_list = drm_malloc_ab(sizeof(*exec2_list), args->buffer_count); | ||
3997 | if (exec_list == NULL || exec2_list == NULL) { | ||
3998 | DRM_ERROR("Failed to allocate exec list for %d buffers\n", | ||
3999 | args->buffer_count); | ||
4000 | drm_free_large(exec_list); | ||
4001 | drm_free_large(exec2_list); | ||
4002 | return -ENOMEM; | ||
4003 | } | ||
4004 | ret = copy_from_user(exec_list, | ||
4005 | (struct drm_i915_relocation_entry __user *) | ||
4006 | (uintptr_t) args->buffers_ptr, | ||
4007 | sizeof(*exec_list) * args->buffer_count); | ||
4008 | if (ret != 0) { | ||
4009 | DRM_ERROR("copy %d exec entries failed %d\n", | ||
4010 | args->buffer_count, ret); | ||
4011 | drm_free_large(exec_list); | ||
4012 | drm_free_large(exec2_list); | ||
4013 | return -EFAULT; | ||
4014 | } | ||
4015 | |||
4016 | for (i = 0; i < args->buffer_count; i++) { | ||
4017 | exec2_list[i].handle = exec_list[i].handle; | ||
4018 | exec2_list[i].relocation_count = exec_list[i].relocation_count; | ||
4019 | exec2_list[i].relocs_ptr = exec_list[i].relocs_ptr; | ||
4020 | exec2_list[i].alignment = exec_list[i].alignment; | ||
4021 | exec2_list[i].offset = exec_list[i].offset; | ||
4022 | if (!IS_I965G(dev)) | ||
4023 | exec2_list[i].flags = EXEC_OBJECT_NEEDS_FENCE; | ||
4024 | else | ||
4025 | exec2_list[i].flags = 0; | ||
4026 | } | ||
4027 | |||
4028 | exec2.buffers_ptr = args->buffers_ptr; | ||
4029 | exec2.buffer_count = args->buffer_count; | ||
4030 | exec2.batch_start_offset = args->batch_start_offset; | ||
4031 | exec2.batch_len = args->batch_len; | ||
4032 | exec2.DR1 = args->DR1; | ||
4033 | exec2.DR4 = args->DR4; | ||
4034 | exec2.num_cliprects = args->num_cliprects; | ||
4035 | exec2.cliprects_ptr = args->cliprects_ptr; | ||
4036 | exec2.flags = 0; | ||
4037 | |||
4038 | ret = i915_gem_do_execbuffer(dev, data, file_priv, &exec2, exec2_list); | ||
4039 | if (!ret) { | ||
4040 | /* Copy the new buffer offsets back to the user's exec list. */ | ||
4041 | for (i = 0; i < args->buffer_count; i++) | ||
4042 | exec_list[i].offset = exec2_list[i].offset; | ||
4043 | /* ... and back out to userspace */ | ||
4044 | ret = copy_to_user((struct drm_i915_relocation_entry __user *) | ||
4045 | (uintptr_t) args->buffers_ptr, | ||
4046 | exec_list, | ||
4047 | sizeof(*exec_list) * args->buffer_count); | ||
4048 | if (ret) { | ||
4049 | ret = -EFAULT; | ||
4050 | DRM_ERROR("failed to copy %d exec entries " | ||
4051 | "back to user (%d)\n", | ||
4052 | args->buffer_count, ret); | ||
4053 | } | ||
4054 | } | ||
4055 | |||
4056 | drm_free_large(exec_list); | ||
4057 | drm_free_large(exec2_list); | ||
4058 | return ret; | ||
4059 | } | ||
4060 | |||
4061 | int | ||
4062 | i915_gem_execbuffer2(struct drm_device *dev, void *data, | ||
4063 | struct drm_file *file_priv) | ||
4064 | { | ||
4065 | struct drm_i915_gem_execbuffer2 *args = data; | ||
4066 | struct drm_i915_gem_exec_object2 *exec2_list = NULL; | ||
4067 | int ret; | ||
4068 | |||
4069 | #if WATCH_EXEC | ||
4070 | DRM_INFO("buffers_ptr %d buffer_count %d len %08x\n", | ||
4071 | (int) args->buffers_ptr, args->buffer_count, args->batch_len); | ||
4072 | #endif | ||
4073 | |||
4074 | if (args->buffer_count < 1) { | ||
4075 | DRM_ERROR("execbuf2 with %d buffers\n", args->buffer_count); | ||
4076 | return -EINVAL; | ||
4077 | } | ||
4078 | |||
4079 | exec2_list = drm_malloc_ab(sizeof(*exec2_list), args->buffer_count); | ||
4080 | if (exec2_list == NULL) { | ||
4081 | DRM_ERROR("Failed to allocate exec list for %d buffers\n", | ||
4082 | args->buffer_count); | ||
4083 | return -ENOMEM; | ||
4084 | } | ||
4085 | ret = copy_from_user(exec2_list, | ||
4086 | (struct drm_i915_relocation_entry __user *) | ||
4087 | (uintptr_t) args->buffers_ptr, | ||
4088 | sizeof(*exec2_list) * args->buffer_count); | ||
4089 | if (ret != 0) { | ||
4090 | DRM_ERROR("copy %d exec entries failed %d\n", | ||
4091 | args->buffer_count, ret); | ||
4092 | drm_free_large(exec2_list); | ||
4093 | return -EFAULT; | ||
4094 | } | ||
4095 | |||
4096 | ret = i915_gem_do_execbuffer(dev, data, file_priv, args, exec2_list); | ||
4097 | if (!ret) { | ||
4098 | /* Copy the new buffer offsets back to the user's exec list. */ | ||
4099 | ret = copy_to_user((struct drm_i915_relocation_entry __user *) | ||
4100 | (uintptr_t) args->buffers_ptr, | ||
4101 | exec2_list, | ||
4102 | sizeof(*exec2_list) * args->buffer_count); | ||
4103 | if (ret) { | ||
4104 | ret = -EFAULT; | ||
4105 | DRM_ERROR("failed to copy %d exec entries " | ||
4106 | "back to user (%d)\n", | ||
4107 | args->buffer_count, ret); | ||
4108 | } | ||
4109 | } | ||
4110 | |||
4111 | drm_free_large(exec2_list); | ||
4112 | return ret; | ||
4113 | } | ||
4114 | |||
3923 | int | 4115 | int |
3924 | i915_gem_object_pin(struct drm_gem_object *obj, uint32_t alignment) | 4116 | i915_gem_object_pin(struct drm_gem_object *obj, uint32_t alignment) |
3925 | { | 4117 | { |
@@ -3933,19 +4125,7 @@ i915_gem_object_pin(struct drm_gem_object *obj, uint32_t alignment) | |||
3933 | if (ret) | 4125 | if (ret) |
3934 | return ret; | 4126 | return ret; |
3935 | } | 4127 | } |
3936 | /* | 4128 | |
3937 | * Pre-965 chips need a fence register set up in order to | ||
3938 | * properly handle tiled surfaces. | ||
3939 | */ | ||
3940 | if (!IS_I965G(dev) && obj_priv->tiling_mode != I915_TILING_NONE) { | ||
3941 | ret = i915_gem_object_get_fence_reg(obj); | ||
3942 | if (ret != 0) { | ||
3943 | if (ret != -EBUSY && ret != -ERESTARTSYS) | ||
3944 | DRM_ERROR("Failure to install fence: %d\n", | ||
3945 | ret); | ||
3946 | return ret; | ||
3947 | } | ||
3948 | } | ||
3949 | obj_priv->pin_count++; | 4129 | obj_priv->pin_count++; |
3950 | 4130 | ||
3951 | /* If the object is not active and not pending a flush, | 4131 | /* If the object is not active and not pending a flush, |
@@ -4708,7 +4888,7 @@ int i915_gem_init_phys_object(struct drm_device *dev, | |||
4708 | 4888 | ||
4709 | phys_obj->id = id; | 4889 | phys_obj->id = id; |
4710 | 4890 | ||
4711 | phys_obj->handle = drm_pci_alloc(dev, size, 0, 0xffffffff); | 4891 | phys_obj->handle = drm_pci_alloc(dev, size, 0); |
4712 | if (!phys_obj->handle) { | 4892 | if (!phys_obj->handle) { |
4713 | ret = -ENOMEM; | 4893 | ret = -ENOMEM; |
4714 | goto kfree_obj; | 4894 | goto kfree_obj; |
diff --git a/drivers/gpu/drm/i915/i915_gem_tiling.c b/drivers/gpu/drm/i915/i915_gem_tiling.c index 30d6af6c09bb..df278b2685bf 100644 --- a/drivers/gpu/drm/i915/i915_gem_tiling.c +++ b/drivers/gpu/drm/i915/i915_gem_tiling.c | |||
@@ -304,35 +304,39 @@ i915_gem_detect_bit_6_swizzle(struct drm_device *dev) | |||
304 | 304 | ||
305 | 305 | ||
306 | /** | 306 | /** |
307 | * Returns the size of the fence for a tiled object of the given size. | 307 | * Returns whether an object is currently fenceable. If not, it may need |
308 | * to be unbound and have its pitch adjusted. | ||
308 | */ | 309 | */ |
309 | static int | 310 | bool |
310 | i915_get_fence_size(struct drm_device *dev, int size) | 311 | i915_obj_fenceable(struct drm_device *dev, struct drm_gem_object *obj) |
311 | { | 312 | { |
312 | int i; | 313 | struct drm_i915_gem_object *obj_priv = obj->driver_private; |
313 | int start; | ||
314 | 314 | ||
315 | if (IS_I965G(dev)) { | 315 | if (IS_I965G(dev)) { |
316 | /* The 965 can have fences at any page boundary. */ | 316 | /* The 965 can have fences at any page boundary. */ |
317 | return ALIGN(size, 4096); | 317 | if (obj->size & 4095) |
318 | return false; | ||
319 | return true; | ||
320 | } else if (IS_I9XX(dev)) { | ||
321 | if (obj_priv->gtt_offset & ~I915_FENCE_START_MASK) | ||
322 | return false; | ||
318 | } else { | 323 | } else { |
319 | /* Align the size to a power of two greater than the smallest | 324 | if (obj_priv->gtt_offset & ~I830_FENCE_START_MASK) |
320 | * fence size. | 325 | return false; |
321 | */ | 326 | } |
322 | if (IS_I9XX(dev)) | ||
323 | start = 1024 * 1024; | ||
324 | else | ||
325 | start = 512 * 1024; | ||
326 | 327 | ||
327 | for (i = start; i < size; i <<= 1) | 328 | /* Power of two sized... */ |
328 | ; | 329 | if (obj->size & (obj->size - 1)) |
330 | return false; | ||
329 | 331 | ||
330 | return i; | 332 | /* Objects must be size aligned as well */ |
331 | } | 333 | if (obj_priv->gtt_offset & (obj->size - 1)) |
334 | return false; | ||
335 | return true; | ||
332 | } | 336 | } |
333 | 337 | ||
334 | /* Check pitch constriants for all chips & tiling formats */ | 338 | /* Check pitch constriants for all chips & tiling formats */ |
335 | static bool | 339 | bool |
336 | i915_tiling_ok(struct drm_device *dev, int stride, int size, int tiling_mode) | 340 | i915_tiling_ok(struct drm_device *dev, int stride, int size, int tiling_mode) |
337 | { | 341 | { |
338 | int tile_width; | 342 | int tile_width; |
@@ -384,12 +388,6 @@ i915_tiling_ok(struct drm_device *dev, int stride, int size, int tiling_mode) | |||
384 | if (stride & (stride - 1)) | 388 | if (stride & (stride - 1)) |
385 | return false; | 389 | return false; |
386 | 390 | ||
387 | /* We don't 0handle the aperture area covered by the fence being bigger | ||
388 | * than the object size. | ||
389 | */ | ||
390 | if (i915_get_fence_size(dev, size) != size) | ||
391 | return false; | ||
392 | |||
393 | return true; | 391 | return true; |
394 | } | 392 | } |
395 | 393 | ||
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 85f4c5de97e2..89a071a3e6fb 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c | |||
@@ -274,7 +274,6 @@ irqreturn_t ironlake_irq_handler(struct drm_device *dev) | |||
274 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; | 274 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; |
275 | int ret = IRQ_NONE; | 275 | int ret = IRQ_NONE; |
276 | u32 de_iir, gt_iir, de_ier, pch_iir; | 276 | u32 de_iir, gt_iir, de_ier, pch_iir; |
277 | u32 new_de_iir, new_gt_iir, new_pch_iir; | ||
278 | struct drm_i915_master_private *master_priv; | 277 | struct drm_i915_master_private *master_priv; |
279 | 278 | ||
280 | /* disable master interrupt before clearing iir */ | 279 | /* disable master interrupt before clearing iir */ |
@@ -286,49 +285,42 @@ irqreturn_t ironlake_irq_handler(struct drm_device *dev) | |||
286 | gt_iir = I915_READ(GTIIR); | 285 | gt_iir = I915_READ(GTIIR); |
287 | pch_iir = I915_READ(SDEIIR); | 286 | pch_iir = I915_READ(SDEIIR); |
288 | 287 | ||
289 | for (;;) { | 288 | if (de_iir == 0 && gt_iir == 0 && pch_iir == 0) |
290 | if (de_iir == 0 && gt_iir == 0 && pch_iir == 0) | 289 | goto done; |
291 | break; | ||
292 | |||
293 | ret = IRQ_HANDLED; | ||
294 | 290 | ||
295 | /* should clear PCH hotplug event before clear CPU irq */ | 291 | ret = IRQ_HANDLED; |
296 | I915_WRITE(SDEIIR, pch_iir); | ||
297 | new_pch_iir = I915_READ(SDEIIR); | ||
298 | |||
299 | I915_WRITE(DEIIR, de_iir); | ||
300 | new_de_iir = I915_READ(DEIIR); | ||
301 | I915_WRITE(GTIIR, gt_iir); | ||
302 | new_gt_iir = I915_READ(GTIIR); | ||
303 | |||
304 | if (dev->primary->master) { | ||
305 | master_priv = dev->primary->master->driver_priv; | ||
306 | if (master_priv->sarea_priv) | ||
307 | master_priv->sarea_priv->last_dispatch = | ||
308 | READ_BREADCRUMB(dev_priv); | ||
309 | } | ||
310 | 292 | ||
311 | if (gt_iir & GT_USER_INTERRUPT) { | 293 | if (dev->primary->master) { |
312 | u32 seqno = i915_get_gem_seqno(dev); | 294 | master_priv = dev->primary->master->driver_priv; |
313 | dev_priv->mm.irq_gem_seqno = seqno; | 295 | if (master_priv->sarea_priv) |
314 | trace_i915_gem_request_complete(dev, seqno); | 296 | master_priv->sarea_priv->last_dispatch = |
315 | DRM_WAKEUP(&dev_priv->irq_queue); | 297 | READ_BREADCRUMB(dev_priv); |
316 | } | 298 | } |
317 | 299 | ||
318 | if (de_iir & DE_GSE) | 300 | if (gt_iir & GT_USER_INTERRUPT) { |
319 | ironlake_opregion_gse_intr(dev); | 301 | u32 seqno = i915_get_gem_seqno(dev); |
302 | dev_priv->mm.irq_gem_seqno = seqno; | ||
303 | trace_i915_gem_request_complete(dev, seqno); | ||
304 | DRM_WAKEUP(&dev_priv->irq_queue); | ||
305 | dev_priv->hangcheck_count = 0; | ||
306 | mod_timer(&dev_priv->hangcheck_timer, jiffies + DRM_I915_HANGCHECK_PERIOD); | ||
307 | } | ||
320 | 308 | ||
321 | /* check event from PCH */ | 309 | if (de_iir & DE_GSE) |
322 | if ((de_iir & DE_PCH_EVENT) && | 310 | ironlake_opregion_gse_intr(dev); |
323 | (pch_iir & SDE_HOTPLUG_MASK)) { | ||
324 | queue_work(dev_priv->wq, &dev_priv->hotplug_work); | ||
325 | } | ||
326 | 311 | ||
327 | de_iir = new_de_iir; | 312 | /* check event from PCH */ |
328 | gt_iir = new_gt_iir; | 313 | if ((de_iir & DE_PCH_EVENT) && |
329 | pch_iir = new_pch_iir; | 314 | (pch_iir & SDE_HOTPLUG_MASK)) { |
315 | queue_work(dev_priv->wq, &dev_priv->hotplug_work); | ||
330 | } | 316 | } |
331 | 317 | ||
318 | /* should clear PCH hotplug event before clear CPU irq */ | ||
319 | I915_WRITE(SDEIIR, pch_iir); | ||
320 | I915_WRITE(GTIIR, gt_iir); | ||
321 | I915_WRITE(DEIIR, de_iir); | ||
322 | |||
323 | done: | ||
332 | I915_WRITE(DEIER, de_ier); | 324 | I915_WRITE(DEIER, de_ier); |
333 | (void)I915_READ(DEIER); | 325 | (void)I915_READ(DEIER); |
334 | 326 | ||
@@ -1084,6 +1076,10 @@ void i915_driver_irq_preinstall(struct drm_device * dev) | |||
1084 | (void) I915_READ(IER); | 1076 | (void) I915_READ(IER); |
1085 | } | 1077 | } |
1086 | 1078 | ||
1079 | /* | ||
1080 | * Must be called after intel_modeset_init or hotplug interrupts won't be | ||
1081 | * enabled correctly. | ||
1082 | */ | ||
1087 | int i915_driver_irq_postinstall(struct drm_device *dev) | 1083 | int i915_driver_irq_postinstall(struct drm_device *dev) |
1088 | { | 1084 | { |
1089 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; | 1085 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; |
@@ -1106,19 +1102,23 @@ int i915_driver_irq_postinstall(struct drm_device *dev) | |||
1106 | if (I915_HAS_HOTPLUG(dev)) { | 1102 | if (I915_HAS_HOTPLUG(dev)) { |
1107 | u32 hotplug_en = I915_READ(PORT_HOTPLUG_EN); | 1103 | u32 hotplug_en = I915_READ(PORT_HOTPLUG_EN); |
1108 | 1104 | ||
1109 | /* Leave other bits alone */ | 1105 | /* Note HDMI and DP share bits */ |
1110 | hotplug_en |= HOTPLUG_EN_MASK; | 1106 | if (dev_priv->hotplug_supported_mask & HDMIB_HOTPLUG_INT_STATUS) |
1107 | hotplug_en |= HDMIB_HOTPLUG_INT_EN; | ||
1108 | if (dev_priv->hotplug_supported_mask & HDMIC_HOTPLUG_INT_STATUS) | ||
1109 | hotplug_en |= HDMIC_HOTPLUG_INT_EN; | ||
1110 | if (dev_priv->hotplug_supported_mask & HDMID_HOTPLUG_INT_STATUS) | ||
1111 | hotplug_en |= HDMID_HOTPLUG_INT_EN; | ||
1112 | if (dev_priv->hotplug_supported_mask & SDVOC_HOTPLUG_INT_STATUS) | ||
1113 | hotplug_en |= SDVOC_HOTPLUG_INT_EN; | ||
1114 | if (dev_priv->hotplug_supported_mask & SDVOB_HOTPLUG_INT_STATUS) | ||
1115 | hotplug_en |= SDVOB_HOTPLUG_INT_EN; | ||
1116 | if (dev_priv->hotplug_supported_mask & CRT_HOTPLUG_INT_STATUS) | ||
1117 | hotplug_en |= CRT_HOTPLUG_INT_EN; | ||
1118 | /* Ignore TV since it's buggy */ | ||
1119 | |||
1111 | I915_WRITE(PORT_HOTPLUG_EN, hotplug_en); | 1120 | I915_WRITE(PORT_HOTPLUG_EN, hotplug_en); |
1112 | 1121 | ||
1113 | dev_priv->hotplug_supported_mask = CRT_HOTPLUG_INT_STATUS | | ||
1114 | TV_HOTPLUG_INT_STATUS | SDVOC_HOTPLUG_INT_STATUS | | ||
1115 | SDVOB_HOTPLUG_INT_STATUS; | ||
1116 | if (IS_G4X(dev)) { | ||
1117 | dev_priv->hotplug_supported_mask |= | ||
1118 | HDMIB_HOTPLUG_INT_STATUS | | ||
1119 | HDMIC_HOTPLUG_INT_STATUS | | ||
1120 | HDMID_HOTPLUG_INT_STATUS; | ||
1121 | } | ||
1122 | /* Enable in IER... */ | 1122 | /* Enable in IER... */ |
1123 | enable_mask |= I915_DISPLAY_PORT_INTERRUPT; | 1123 | enable_mask |= I915_DISPLAY_PORT_INTERRUPT; |
1124 | /* and unmask in IMR */ | 1124 | /* and unmask in IMR */ |
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 974b3cf70618..847006c5218e 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h | |||
@@ -879,13 +879,6 @@ | |||
879 | #define CRT_HOTPLUG_DETECT_VOLTAGE_475MV (1 << 2) | 879 | #define CRT_HOTPLUG_DETECT_VOLTAGE_475MV (1 << 2) |
880 | #define CRT_HOTPLUG_MASK (0x3fc) /* Bits 9-2 */ | 880 | #define CRT_HOTPLUG_MASK (0x3fc) /* Bits 9-2 */ |
881 | #define CRT_FORCE_HOTPLUG_MASK 0xfffffe1f | 881 | #define CRT_FORCE_HOTPLUG_MASK 0xfffffe1f |
882 | #define HOTPLUG_EN_MASK (HDMIB_HOTPLUG_INT_EN | \ | ||
883 | HDMIC_HOTPLUG_INT_EN | \ | ||
884 | HDMID_HOTPLUG_INT_EN | \ | ||
885 | SDVOB_HOTPLUG_INT_EN | \ | ||
886 | SDVOC_HOTPLUG_INT_EN | \ | ||
887 | CRT_HOTPLUG_INT_EN) | ||
888 | |||
889 | 882 | ||
890 | #define PORT_HOTPLUG_STAT 0x61114 | 883 | #define PORT_HOTPLUG_STAT 0x61114 |
891 | #define HDMIB_HOTPLUG_INT_STATUS (1 << 29) | 884 | #define HDMIB_HOTPLUG_INT_STATUS (1 << 29) |
@@ -982,6 +975,8 @@ | |||
982 | #define LVDS_PORT_EN (1 << 31) | 975 | #define LVDS_PORT_EN (1 << 31) |
983 | /* Selects pipe B for LVDS data. Must be set on pre-965. */ | 976 | /* Selects pipe B for LVDS data. Must be set on pre-965. */ |
984 | #define LVDS_PIPEB_SELECT (1 << 30) | 977 | #define LVDS_PIPEB_SELECT (1 << 30) |
978 | /* LVDS dithering flag on 965/g4x platform */ | ||
979 | #define LVDS_ENABLE_DITHER (1 << 25) | ||
985 | /* Enable border for unscaled (or aspect-scaled) display */ | 980 | /* Enable border for unscaled (or aspect-scaled) display */ |
986 | #define LVDS_BORDER_ENABLE (1 << 15) | 981 | #define LVDS_BORDER_ENABLE (1 << 15) |
987 | /* | 982 | /* |
@@ -1751,6 +1746,8 @@ | |||
1751 | 1746 | ||
1752 | /* Display & cursor control */ | 1747 | /* Display & cursor control */ |
1753 | 1748 | ||
1749 | /* dithering flag on Ironlake */ | ||
1750 | #define PIPE_ENABLE_DITHER (1 << 4) | ||
1754 | /* Pipe A */ | 1751 | /* Pipe A */ |
1755 | #define PIPEADSL 0x70000 | 1752 | #define PIPEADSL 0x70000 |
1756 | #define PIPEACONF 0x70008 | 1753 | #define PIPEACONF 0x70008 |
@@ -1818,7 +1815,7 @@ | |||
1818 | #define DSPFW_PLANEB_SHIFT 8 | 1815 | #define DSPFW_PLANEB_SHIFT 8 |
1819 | #define DSPFW2 0x70038 | 1816 | #define DSPFW2 0x70038 |
1820 | #define DSPFW_CURSORA_MASK 0x00003f00 | 1817 | #define DSPFW_CURSORA_MASK 0x00003f00 |
1821 | #define DSPFW_CURSORA_SHIFT 16 | 1818 | #define DSPFW_CURSORA_SHIFT 8 |
1822 | #define DSPFW3 0x7003c | 1819 | #define DSPFW3 0x7003c |
1823 | #define DSPFW_HPLL_SR_EN (1<<31) | 1820 | #define DSPFW_HPLL_SR_EN (1<<31) |
1824 | #define DSPFW_CURSOR_SR_SHIFT 24 | 1821 | #define DSPFW_CURSOR_SR_SHIFT 24 |
diff --git a/drivers/gpu/drm/i915/i915_suspend.c b/drivers/gpu/drm/i915/i915_suspend.c index d5ebb00a9d49..a3b90c9561dc 100644 --- a/drivers/gpu/drm/i915/i915_suspend.c +++ b/drivers/gpu/drm/i915/i915_suspend.c | |||
@@ -732,12 +732,6 @@ int i915_save_state(struct drm_device *dev) | |||
732 | 732 | ||
733 | pci_read_config_byte(dev->pdev, LBB, &dev_priv->saveLBB); | 733 | pci_read_config_byte(dev->pdev, LBB, &dev_priv->saveLBB); |
734 | 734 | ||
735 | /* Render Standby */ | ||
736 | if (I915_HAS_RC6(dev)) { | ||
737 | dev_priv->saveRENDERSTANDBY = I915_READ(MCHBAR_RENDER_STANDBY); | ||
738 | dev_priv->savePWRCTXA = I915_READ(PWRCTXA); | ||
739 | } | ||
740 | |||
741 | /* Hardware status page */ | 735 | /* Hardware status page */ |
742 | dev_priv->saveHWS = I915_READ(HWS_PGA); | 736 | dev_priv->saveHWS = I915_READ(HWS_PGA); |
743 | 737 | ||
@@ -793,12 +787,6 @@ int i915_restore_state(struct drm_device *dev) | |||
793 | 787 | ||
794 | pci_write_config_byte(dev->pdev, LBB, dev_priv->saveLBB); | 788 | pci_write_config_byte(dev->pdev, LBB, dev_priv->saveLBB); |
795 | 789 | ||
796 | /* Render Standby */ | ||
797 | if (I915_HAS_RC6(dev)) { | ||
798 | I915_WRITE(MCHBAR_RENDER_STANDBY, dev_priv->saveRENDERSTANDBY); | ||
799 | I915_WRITE(PWRCTXA, dev_priv->savePWRCTXA); | ||
800 | } | ||
801 | |||
802 | /* Hardware status page */ | 790 | /* Hardware status page */ |
803 | I915_WRITE(HWS_PGA, dev_priv->saveHWS); | 791 | I915_WRITE(HWS_PGA, dev_priv->saveHWS); |
804 | 792 | ||
diff --git a/drivers/gpu/drm/i915/intel_bios.c b/drivers/gpu/drm/i915/intel_bios.c index f27567747580..15fbc1b5a83e 100644 --- a/drivers/gpu/drm/i915/intel_bios.c +++ b/drivers/gpu/drm/i915/intel_bios.c | |||
@@ -33,6 +33,8 @@ | |||
33 | #define SLAVE_ADDR1 0x70 | 33 | #define SLAVE_ADDR1 0x70 |
34 | #define SLAVE_ADDR2 0x72 | 34 | #define SLAVE_ADDR2 0x72 |
35 | 35 | ||
36 | static int panel_type; | ||
37 | |||
36 | static void * | 38 | static void * |
37 | find_section(struct bdb_header *bdb, int section_id) | 39 | find_section(struct bdb_header *bdb, int section_id) |
38 | { | 40 | { |
@@ -128,6 +130,7 @@ parse_lfp_panel_data(struct drm_i915_private *dev_priv, | |||
128 | dev_priv->lvds_dither = lvds_options->pixel_dither; | 130 | dev_priv->lvds_dither = lvds_options->pixel_dither; |
129 | if (lvds_options->panel_type == 0xff) | 131 | if (lvds_options->panel_type == 0xff) |
130 | return; | 132 | return; |
133 | panel_type = lvds_options->panel_type; | ||
131 | 134 | ||
132 | lvds_lfp_data = find_section(bdb, BDB_LVDS_LFP_DATA); | 135 | lvds_lfp_data = find_section(bdb, BDB_LVDS_LFP_DATA); |
133 | if (!lvds_lfp_data) | 136 | if (!lvds_lfp_data) |
@@ -197,7 +200,8 @@ parse_lfp_panel_data(struct drm_i915_private *dev_priv, | |||
197 | memset(temp_mode, 0, sizeof(*temp_mode)); | 200 | memset(temp_mode, 0, sizeof(*temp_mode)); |
198 | } | 201 | } |
199 | kfree(temp_mode); | 202 | kfree(temp_mode); |
200 | if (temp_downclock < panel_fixed_mode->clock) { | 203 | if (temp_downclock < panel_fixed_mode->clock && |
204 | i915_lvds_downclock) { | ||
201 | dev_priv->lvds_downclock_avail = 1; | 205 | dev_priv->lvds_downclock_avail = 1; |
202 | dev_priv->lvds_downclock = temp_downclock; | 206 | dev_priv->lvds_downclock = temp_downclock; |
203 | DRM_DEBUG_KMS("LVDS downclock is found in VBT. ", | 207 | DRM_DEBUG_KMS("LVDS downclock is found in VBT. ", |
@@ -405,6 +409,34 @@ parse_driver_features(struct drm_i915_private *dev_priv, | |||
405 | } | 409 | } |
406 | 410 | ||
407 | static void | 411 | static void |
412 | parse_edp(struct drm_i915_private *dev_priv, struct bdb_header *bdb) | ||
413 | { | ||
414 | struct bdb_edp *edp; | ||
415 | |||
416 | edp = find_section(bdb, BDB_EDP); | ||
417 | if (!edp) { | ||
418 | if (SUPPORTS_EDP(dev_priv->dev) && dev_priv->edp_support) { | ||
419 | DRM_DEBUG_KMS("No eDP BDB found but eDP panel supported,\ | ||
420 | assume 18bpp panel color depth.\n"); | ||
421 | dev_priv->edp_bpp = 18; | ||
422 | } | ||
423 | return; | ||
424 | } | ||
425 | |||
426 | switch ((edp->color_depth >> (panel_type * 2)) & 3) { | ||
427 | case EDP_18BPP: | ||
428 | dev_priv->edp_bpp = 18; | ||
429 | break; | ||
430 | case EDP_24BPP: | ||
431 | dev_priv->edp_bpp = 24; | ||
432 | break; | ||
433 | case EDP_30BPP: | ||
434 | dev_priv->edp_bpp = 30; | ||
435 | break; | ||
436 | } | ||
437 | } | ||
438 | |||
439 | static void | ||
408 | parse_device_mapping(struct drm_i915_private *dev_priv, | 440 | parse_device_mapping(struct drm_i915_private *dev_priv, |
409 | struct bdb_header *bdb) | 441 | struct bdb_header *bdb) |
410 | { | 442 | { |
@@ -521,6 +553,7 @@ intel_init_bios(struct drm_device *dev) | |||
521 | parse_sdvo_device_mapping(dev_priv, bdb); | 553 | parse_sdvo_device_mapping(dev_priv, bdb); |
522 | parse_device_mapping(dev_priv, bdb); | 554 | parse_device_mapping(dev_priv, bdb); |
523 | parse_driver_features(dev_priv, bdb); | 555 | parse_driver_features(dev_priv, bdb); |
556 | parse_edp(dev_priv, bdb); | ||
524 | 557 | ||
525 | pci_unmap_rom(pdev, bios); | 558 | pci_unmap_rom(pdev, bios); |
526 | 559 | ||
diff --git a/drivers/gpu/drm/i915/intel_bios.h b/drivers/gpu/drm/i915/intel_bios.h index 425ac9d7f724..4c18514f6f80 100644 --- a/drivers/gpu/drm/i915/intel_bios.h +++ b/drivers/gpu/drm/i915/intel_bios.h | |||
@@ -98,6 +98,7 @@ struct vbios_data { | |||
98 | #define BDB_SDVO_LVDS_PNP_IDS 24 | 98 | #define BDB_SDVO_LVDS_PNP_IDS 24 |
99 | #define BDB_SDVO_LVDS_POWER_SEQ 25 | 99 | #define BDB_SDVO_LVDS_POWER_SEQ 25 |
100 | #define BDB_TV_OPTIONS 26 | 100 | #define BDB_TV_OPTIONS 26 |
101 | #define BDB_EDP 27 | ||
101 | #define BDB_LVDS_OPTIONS 40 | 102 | #define BDB_LVDS_OPTIONS 40 |
102 | #define BDB_LVDS_LFP_DATA_PTRS 41 | 103 | #define BDB_LVDS_LFP_DATA_PTRS 41 |
103 | #define BDB_LVDS_LFP_DATA 42 | 104 | #define BDB_LVDS_LFP_DATA 42 |
@@ -426,6 +427,45 @@ struct bdb_driver_features { | |||
426 | u8 custom_vbt_version; | 427 | u8 custom_vbt_version; |
427 | } __attribute__((packed)); | 428 | } __attribute__((packed)); |
428 | 429 | ||
430 | #define EDP_18BPP 0 | ||
431 | #define EDP_24BPP 1 | ||
432 | #define EDP_30BPP 2 | ||
433 | #define EDP_RATE_1_62 0 | ||
434 | #define EDP_RATE_2_7 1 | ||
435 | #define EDP_LANE_1 0 | ||
436 | #define EDP_LANE_2 1 | ||
437 | #define EDP_LANE_4 3 | ||
438 | #define EDP_PREEMPHASIS_NONE 0 | ||
439 | #define EDP_PREEMPHASIS_3_5dB 1 | ||
440 | #define EDP_PREEMPHASIS_6dB 2 | ||
441 | #define EDP_PREEMPHASIS_9_5dB 3 | ||
442 | #define EDP_VSWING_0_4V 0 | ||
443 | #define EDP_VSWING_0_6V 1 | ||
444 | #define EDP_VSWING_0_8V 2 | ||
445 | #define EDP_VSWING_1_2V 3 | ||
446 | |||
447 | struct edp_power_seq { | ||
448 | u16 t3; | ||
449 | u16 t7; | ||
450 | u16 t9; | ||
451 | u16 t10; | ||
452 | u16 t12; | ||
453 | } __attribute__ ((packed)); | ||
454 | |||
455 | struct edp_link_params { | ||
456 | u8 rate:4; | ||
457 | u8 lanes:4; | ||
458 | u8 preemphasis:4; | ||
459 | u8 vswing:4; | ||
460 | } __attribute__ ((packed)); | ||
461 | |||
462 | struct bdb_edp { | ||
463 | struct edp_power_seq power_seqs[16]; | ||
464 | u32 color_depth; | ||
465 | u32 sdrrs_msa_timing_delay; | ||
466 | struct edp_link_params link_params[16]; | ||
467 | } __attribute__ ((packed)); | ||
468 | |||
429 | bool intel_init_bios(struct drm_device *dev); | 469 | bool intel_init_bios(struct drm_device *dev); |
430 | 470 | ||
431 | /* | 471 | /* |
diff --git a/drivers/gpu/drm/i915/intel_crt.c b/drivers/gpu/drm/i915/intel_crt.c index 9f3d3e563414..ddefc871edfe 100644 --- a/drivers/gpu/drm/i915/intel_crt.c +++ b/drivers/gpu/drm/i915/intel_crt.c | |||
@@ -548,4 +548,6 @@ void intel_crt_init(struct drm_device *dev) | |||
548 | drm_connector_helper_add(connector, &intel_crt_connector_helper_funcs); | 548 | drm_connector_helper_add(connector, &intel_crt_connector_helper_funcs); |
549 | 549 | ||
550 | drm_sysfs_connector_add(connector); | 550 | drm_sysfs_connector_add(connector); |
551 | |||
552 | dev_priv->hotplug_supported_mask |= CRT_HOTPLUG_INT_STATUS; | ||
551 | } | 553 | } |
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 52cd9b006da2..45da78ef4a92 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c | |||
@@ -70,8 +70,6 @@ struct intel_limit { | |||
70 | intel_p2_t p2; | 70 | intel_p2_t p2; |
71 | bool (* find_pll)(const intel_limit_t *, struct drm_crtc *, | 71 | bool (* find_pll)(const intel_limit_t *, struct drm_crtc *, |
72 | int, int, intel_clock_t *); | 72 | int, int, intel_clock_t *); |
73 | bool (* find_reduced_pll)(const intel_limit_t *, struct drm_crtc *, | ||
74 | int, int, intel_clock_t *); | ||
75 | }; | 73 | }; |
76 | 74 | ||
77 | #define I8XX_DOT_MIN 25000 | 75 | #define I8XX_DOT_MIN 25000 |
@@ -243,11 +241,11 @@ struct intel_limit { | |||
243 | #define IRONLAKE_VCO_MIN 1760000 | 241 | #define IRONLAKE_VCO_MIN 1760000 |
244 | #define IRONLAKE_VCO_MAX 3510000 | 242 | #define IRONLAKE_VCO_MAX 3510000 |
245 | #define IRONLAKE_N_MIN 1 | 243 | #define IRONLAKE_N_MIN 1 |
246 | #define IRONLAKE_N_MAX 5 | 244 | #define IRONLAKE_N_MAX 6 |
247 | #define IRONLAKE_M_MIN 79 | 245 | #define IRONLAKE_M_MIN 79 |
248 | #define IRONLAKE_M_MAX 118 | 246 | #define IRONLAKE_M_MAX 127 |
249 | #define IRONLAKE_M1_MIN 12 | 247 | #define IRONLAKE_M1_MIN 12 |
250 | #define IRONLAKE_M1_MAX 23 | 248 | #define IRONLAKE_M1_MAX 22 |
251 | #define IRONLAKE_M2_MIN 5 | 249 | #define IRONLAKE_M2_MIN 5 |
252 | #define IRONLAKE_M2_MAX 9 | 250 | #define IRONLAKE_M2_MAX 9 |
253 | #define IRONLAKE_P_SDVO_DAC_MIN 5 | 251 | #define IRONLAKE_P_SDVO_DAC_MIN 5 |
@@ -262,18 +260,20 @@ struct intel_limit { | |||
262 | #define IRONLAKE_P2_LVDS_FAST 7 /* double channel */ | 260 | #define IRONLAKE_P2_LVDS_FAST 7 /* double channel */ |
263 | #define IRONLAKE_P2_DOT_LIMIT 225000 /* 225Mhz */ | 261 | #define IRONLAKE_P2_DOT_LIMIT 225000 /* 225Mhz */ |
264 | 262 | ||
263 | #define IRONLAKE_P_DISPLAY_PORT_MIN 10 | ||
264 | #define IRONLAKE_P_DISPLAY_PORT_MAX 20 | ||
265 | #define IRONLAKE_P2_DISPLAY_PORT_FAST 10 | ||
266 | #define IRONLAKE_P2_DISPLAY_PORT_SLOW 10 | ||
267 | #define IRONLAKE_P2_DISPLAY_PORT_LIMIT 0 | ||
268 | #define IRONLAKE_P1_DISPLAY_PORT_MIN 1 | ||
269 | #define IRONLAKE_P1_DISPLAY_PORT_MAX 2 | ||
270 | |||
265 | static bool | 271 | static bool |
266 | intel_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc, | 272 | intel_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc, |
267 | int target, int refclk, intel_clock_t *best_clock); | 273 | int target, int refclk, intel_clock_t *best_clock); |
268 | static bool | 274 | static bool |
269 | intel_find_best_reduced_PLL(const intel_limit_t *limit, struct drm_crtc *crtc, | ||
270 | int target, int refclk, intel_clock_t *best_clock); | ||
271 | static bool | ||
272 | intel_g4x_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc, | 275 | intel_g4x_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc, |
273 | int target, int refclk, intel_clock_t *best_clock); | 276 | int target, int refclk, intel_clock_t *best_clock); |
274 | static bool | ||
275 | intel_ironlake_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc, | ||
276 | int target, int refclk, intel_clock_t *best_clock); | ||
277 | 277 | ||
278 | static bool | 278 | static bool |
279 | intel_find_pll_g4x_dp(const intel_limit_t *, struct drm_crtc *crtc, | 279 | intel_find_pll_g4x_dp(const intel_limit_t *, struct drm_crtc *crtc, |
@@ -294,7 +294,6 @@ static const intel_limit_t intel_limits_i8xx_dvo = { | |||
294 | .p2 = { .dot_limit = I8XX_P2_SLOW_LIMIT, | 294 | .p2 = { .dot_limit = I8XX_P2_SLOW_LIMIT, |
295 | .p2_slow = I8XX_P2_SLOW, .p2_fast = I8XX_P2_FAST }, | 295 | .p2_slow = I8XX_P2_SLOW, .p2_fast = I8XX_P2_FAST }, |
296 | .find_pll = intel_find_best_PLL, | 296 | .find_pll = intel_find_best_PLL, |
297 | .find_reduced_pll = intel_find_best_reduced_PLL, | ||
298 | }; | 297 | }; |
299 | 298 | ||
300 | static const intel_limit_t intel_limits_i8xx_lvds = { | 299 | static const intel_limit_t intel_limits_i8xx_lvds = { |
@@ -309,7 +308,6 @@ static const intel_limit_t intel_limits_i8xx_lvds = { | |||
309 | .p2 = { .dot_limit = I8XX_P2_SLOW_LIMIT, | 308 | .p2 = { .dot_limit = I8XX_P2_SLOW_LIMIT, |
310 | .p2_slow = I8XX_P2_LVDS_SLOW, .p2_fast = I8XX_P2_LVDS_FAST }, | 309 | .p2_slow = I8XX_P2_LVDS_SLOW, .p2_fast = I8XX_P2_LVDS_FAST }, |
311 | .find_pll = intel_find_best_PLL, | 310 | .find_pll = intel_find_best_PLL, |
312 | .find_reduced_pll = intel_find_best_reduced_PLL, | ||
313 | }; | 311 | }; |
314 | 312 | ||
315 | static const intel_limit_t intel_limits_i9xx_sdvo = { | 313 | static const intel_limit_t intel_limits_i9xx_sdvo = { |
@@ -324,7 +322,6 @@ static const intel_limit_t intel_limits_i9xx_sdvo = { | |||
324 | .p2 = { .dot_limit = I9XX_P2_SDVO_DAC_SLOW_LIMIT, | 322 | .p2 = { .dot_limit = I9XX_P2_SDVO_DAC_SLOW_LIMIT, |
325 | .p2_slow = I9XX_P2_SDVO_DAC_SLOW, .p2_fast = I9XX_P2_SDVO_DAC_FAST }, | 323 | .p2_slow = I9XX_P2_SDVO_DAC_SLOW, .p2_fast = I9XX_P2_SDVO_DAC_FAST }, |
326 | .find_pll = intel_find_best_PLL, | 324 | .find_pll = intel_find_best_PLL, |
327 | .find_reduced_pll = intel_find_best_reduced_PLL, | ||
328 | }; | 325 | }; |
329 | 326 | ||
330 | static const intel_limit_t intel_limits_i9xx_lvds = { | 327 | static const intel_limit_t intel_limits_i9xx_lvds = { |
@@ -342,7 +339,6 @@ static const intel_limit_t intel_limits_i9xx_lvds = { | |||
342 | .p2 = { .dot_limit = I9XX_P2_LVDS_SLOW_LIMIT, | 339 | .p2 = { .dot_limit = I9XX_P2_LVDS_SLOW_LIMIT, |
343 | .p2_slow = I9XX_P2_LVDS_SLOW, .p2_fast = I9XX_P2_LVDS_FAST }, | 340 | .p2_slow = I9XX_P2_LVDS_SLOW, .p2_fast = I9XX_P2_LVDS_FAST }, |
344 | .find_pll = intel_find_best_PLL, | 341 | .find_pll = intel_find_best_PLL, |
345 | .find_reduced_pll = intel_find_best_reduced_PLL, | ||
346 | }; | 342 | }; |
347 | 343 | ||
348 | /* below parameter and function is for G4X Chipset Family*/ | 344 | /* below parameter and function is for G4X Chipset Family*/ |
@@ -360,7 +356,6 @@ static const intel_limit_t intel_limits_g4x_sdvo = { | |||
360 | .p2_fast = G4X_P2_SDVO_FAST | 356 | .p2_fast = G4X_P2_SDVO_FAST |
361 | }, | 357 | }, |
362 | .find_pll = intel_g4x_find_best_PLL, | 358 | .find_pll = intel_g4x_find_best_PLL, |
363 | .find_reduced_pll = intel_g4x_find_best_PLL, | ||
364 | }; | 359 | }; |
365 | 360 | ||
366 | static const intel_limit_t intel_limits_g4x_hdmi = { | 361 | static const intel_limit_t intel_limits_g4x_hdmi = { |
@@ -377,7 +372,6 @@ static const intel_limit_t intel_limits_g4x_hdmi = { | |||
377 | .p2_fast = G4X_P2_HDMI_DAC_FAST | 372 | .p2_fast = G4X_P2_HDMI_DAC_FAST |
378 | }, | 373 | }, |
379 | .find_pll = intel_g4x_find_best_PLL, | 374 | .find_pll = intel_g4x_find_best_PLL, |
380 | .find_reduced_pll = intel_g4x_find_best_PLL, | ||
381 | }; | 375 | }; |
382 | 376 | ||
383 | static const intel_limit_t intel_limits_g4x_single_channel_lvds = { | 377 | static const intel_limit_t intel_limits_g4x_single_channel_lvds = { |
@@ -402,7 +396,6 @@ static const intel_limit_t intel_limits_g4x_single_channel_lvds = { | |||
402 | .p2_fast = G4X_P2_SINGLE_CHANNEL_LVDS_FAST | 396 | .p2_fast = G4X_P2_SINGLE_CHANNEL_LVDS_FAST |
403 | }, | 397 | }, |
404 | .find_pll = intel_g4x_find_best_PLL, | 398 | .find_pll = intel_g4x_find_best_PLL, |
405 | .find_reduced_pll = intel_g4x_find_best_PLL, | ||
406 | }; | 399 | }; |
407 | 400 | ||
408 | static const intel_limit_t intel_limits_g4x_dual_channel_lvds = { | 401 | static const intel_limit_t intel_limits_g4x_dual_channel_lvds = { |
@@ -427,7 +420,6 @@ static const intel_limit_t intel_limits_g4x_dual_channel_lvds = { | |||
427 | .p2_fast = G4X_P2_DUAL_CHANNEL_LVDS_FAST | 420 | .p2_fast = G4X_P2_DUAL_CHANNEL_LVDS_FAST |
428 | }, | 421 | }, |
429 | .find_pll = intel_g4x_find_best_PLL, | 422 | .find_pll = intel_g4x_find_best_PLL, |
430 | .find_reduced_pll = intel_g4x_find_best_PLL, | ||
431 | }; | 423 | }; |
432 | 424 | ||
433 | static const intel_limit_t intel_limits_g4x_display_port = { | 425 | static const intel_limit_t intel_limits_g4x_display_port = { |
@@ -465,7 +457,6 @@ static const intel_limit_t intel_limits_pineview_sdvo = { | |||
465 | .p2 = { .dot_limit = I9XX_P2_SDVO_DAC_SLOW_LIMIT, | 457 | .p2 = { .dot_limit = I9XX_P2_SDVO_DAC_SLOW_LIMIT, |
466 | .p2_slow = I9XX_P2_SDVO_DAC_SLOW, .p2_fast = I9XX_P2_SDVO_DAC_FAST }, | 458 | .p2_slow = I9XX_P2_SDVO_DAC_SLOW, .p2_fast = I9XX_P2_SDVO_DAC_FAST }, |
467 | .find_pll = intel_find_best_PLL, | 459 | .find_pll = intel_find_best_PLL, |
468 | .find_reduced_pll = intel_find_best_reduced_PLL, | ||
469 | }; | 460 | }; |
470 | 461 | ||
471 | static const intel_limit_t intel_limits_pineview_lvds = { | 462 | static const intel_limit_t intel_limits_pineview_lvds = { |
@@ -481,7 +472,6 @@ static const intel_limit_t intel_limits_pineview_lvds = { | |||
481 | .p2 = { .dot_limit = I9XX_P2_LVDS_SLOW_LIMIT, | 472 | .p2 = { .dot_limit = I9XX_P2_LVDS_SLOW_LIMIT, |
482 | .p2_slow = I9XX_P2_LVDS_SLOW, .p2_fast = I9XX_P2_LVDS_SLOW }, | 473 | .p2_slow = I9XX_P2_LVDS_SLOW, .p2_fast = I9XX_P2_LVDS_SLOW }, |
483 | .find_pll = intel_find_best_PLL, | 474 | .find_pll = intel_find_best_PLL, |
484 | .find_reduced_pll = intel_find_best_reduced_PLL, | ||
485 | }; | 475 | }; |
486 | 476 | ||
487 | static const intel_limit_t intel_limits_ironlake_sdvo = { | 477 | static const intel_limit_t intel_limits_ironlake_sdvo = { |
@@ -496,7 +486,7 @@ static const intel_limit_t intel_limits_ironlake_sdvo = { | |||
496 | .p2 = { .dot_limit = IRONLAKE_P2_DOT_LIMIT, | 486 | .p2 = { .dot_limit = IRONLAKE_P2_DOT_LIMIT, |
497 | .p2_slow = IRONLAKE_P2_SDVO_DAC_SLOW, | 487 | .p2_slow = IRONLAKE_P2_SDVO_DAC_SLOW, |
498 | .p2_fast = IRONLAKE_P2_SDVO_DAC_FAST }, | 488 | .p2_fast = IRONLAKE_P2_SDVO_DAC_FAST }, |
499 | .find_pll = intel_ironlake_find_best_PLL, | 489 | .find_pll = intel_g4x_find_best_PLL, |
500 | }; | 490 | }; |
501 | 491 | ||
502 | static const intel_limit_t intel_limits_ironlake_lvds = { | 492 | static const intel_limit_t intel_limits_ironlake_lvds = { |
@@ -511,7 +501,30 @@ static const intel_limit_t intel_limits_ironlake_lvds = { | |||
511 | .p2 = { .dot_limit = IRONLAKE_P2_DOT_LIMIT, | 501 | .p2 = { .dot_limit = IRONLAKE_P2_DOT_LIMIT, |
512 | .p2_slow = IRONLAKE_P2_LVDS_SLOW, | 502 | .p2_slow = IRONLAKE_P2_LVDS_SLOW, |
513 | .p2_fast = IRONLAKE_P2_LVDS_FAST }, | 503 | .p2_fast = IRONLAKE_P2_LVDS_FAST }, |
514 | .find_pll = intel_ironlake_find_best_PLL, | 504 | .find_pll = intel_g4x_find_best_PLL, |
505 | }; | ||
506 | |||
507 | static const intel_limit_t intel_limits_ironlake_display_port = { | ||
508 | .dot = { .min = IRONLAKE_DOT_MIN, | ||
509 | .max = IRONLAKE_DOT_MAX }, | ||
510 | .vco = { .min = IRONLAKE_VCO_MIN, | ||
511 | .max = IRONLAKE_VCO_MAX}, | ||
512 | .n = { .min = IRONLAKE_N_MIN, | ||
513 | .max = IRONLAKE_N_MAX }, | ||
514 | .m = { .min = IRONLAKE_M_MIN, | ||
515 | .max = IRONLAKE_M_MAX }, | ||
516 | .m1 = { .min = IRONLAKE_M1_MIN, | ||
517 | .max = IRONLAKE_M1_MAX }, | ||
518 | .m2 = { .min = IRONLAKE_M2_MIN, | ||
519 | .max = IRONLAKE_M2_MAX }, | ||
520 | .p = { .min = IRONLAKE_P_DISPLAY_PORT_MIN, | ||
521 | .max = IRONLAKE_P_DISPLAY_PORT_MAX }, | ||
522 | .p1 = { .min = IRONLAKE_P1_DISPLAY_PORT_MIN, | ||
523 | .max = IRONLAKE_P1_DISPLAY_PORT_MAX}, | ||
524 | .p2 = { .dot_limit = IRONLAKE_P2_DISPLAY_PORT_LIMIT, | ||
525 | .p2_slow = IRONLAKE_P2_DISPLAY_PORT_SLOW, | ||
526 | .p2_fast = IRONLAKE_P2_DISPLAY_PORT_FAST }, | ||
527 | .find_pll = intel_find_pll_ironlake_dp, | ||
515 | }; | 528 | }; |
516 | 529 | ||
517 | static const intel_limit_t *intel_ironlake_limit(struct drm_crtc *crtc) | 530 | static const intel_limit_t *intel_ironlake_limit(struct drm_crtc *crtc) |
@@ -519,6 +532,9 @@ static const intel_limit_t *intel_ironlake_limit(struct drm_crtc *crtc) | |||
519 | const intel_limit_t *limit; | 532 | const intel_limit_t *limit; |
520 | if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)) | 533 | if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)) |
521 | limit = &intel_limits_ironlake_lvds; | 534 | limit = &intel_limits_ironlake_lvds; |
535 | else if (intel_pipe_has_type(crtc, INTEL_OUTPUT_DISPLAYPORT) || | ||
536 | HAS_eDP) | ||
537 | limit = &intel_limits_ironlake_display_port; | ||
522 | else | 538 | else |
523 | limit = &intel_limits_ironlake_sdvo; | 539 | limit = &intel_limits_ironlake_sdvo; |
524 | 540 | ||
@@ -737,46 +753,6 @@ intel_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc, | |||
737 | return (err != target); | 753 | return (err != target); |
738 | } | 754 | } |
739 | 755 | ||
740 | |||
741 | static bool | ||
742 | intel_find_best_reduced_PLL(const intel_limit_t *limit, struct drm_crtc *crtc, | ||
743 | int target, int refclk, intel_clock_t *best_clock) | ||
744 | |||
745 | { | ||
746 | struct drm_device *dev = crtc->dev; | ||
747 | intel_clock_t clock; | ||
748 | int err = target; | ||
749 | bool found = false; | ||
750 | |||
751 | memcpy(&clock, best_clock, sizeof(intel_clock_t)); | ||
752 | |||
753 | for (clock.m1 = limit->m1.min; clock.m1 <= limit->m1.max; clock.m1++) { | ||
754 | for (clock.m2 = limit->m2.min; clock.m2 <= limit->m2.max; clock.m2++) { | ||
755 | /* m1 is always 0 in Pineview */ | ||
756 | if (clock.m2 >= clock.m1 && !IS_PINEVIEW(dev)) | ||
757 | break; | ||
758 | for (clock.n = limit->n.min; clock.n <= limit->n.max; | ||
759 | clock.n++) { | ||
760 | int this_err; | ||
761 | |||
762 | intel_clock(dev, refclk, &clock); | ||
763 | |||
764 | if (!intel_PLL_is_valid(crtc, &clock)) | ||
765 | continue; | ||
766 | |||
767 | this_err = abs(clock.dot - target); | ||
768 | if (this_err < err) { | ||
769 | *best_clock = clock; | ||
770 | err = this_err; | ||
771 | found = true; | ||
772 | } | ||
773 | } | ||
774 | } | ||
775 | } | ||
776 | |||
777 | return found; | ||
778 | } | ||
779 | |||
780 | static bool | 756 | static bool |
781 | intel_g4x_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc, | 757 | intel_g4x_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc, |
782 | int target, int refclk, intel_clock_t *best_clock) | 758 | int target, int refclk, intel_clock_t *best_clock) |
@@ -791,7 +767,13 @@ intel_g4x_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc, | |||
791 | found = false; | 767 | found = false; |
792 | 768 | ||
793 | if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)) { | 769 | if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)) { |
794 | if ((I915_READ(LVDS) & LVDS_CLKB_POWER_MASK) == | 770 | int lvds_reg; |
771 | |||
772 | if (IS_IRONLAKE(dev)) | ||
773 | lvds_reg = PCH_LVDS; | ||
774 | else | ||
775 | lvds_reg = LVDS; | ||
776 | if ((I915_READ(lvds_reg) & LVDS_CLKB_POWER_MASK) == | ||
795 | LVDS_CLKB_POWER_UP) | 777 | LVDS_CLKB_POWER_UP) |
796 | clock.p2 = limit->p2.p2_fast; | 778 | clock.p2 = limit->p2.p2_fast; |
797 | else | 779 | else |
@@ -839,6 +821,11 @@ intel_find_pll_ironlake_dp(const intel_limit_t *limit, struct drm_crtc *crtc, | |||
839 | { | 821 | { |
840 | struct drm_device *dev = crtc->dev; | 822 | struct drm_device *dev = crtc->dev; |
841 | intel_clock_t clock; | 823 | intel_clock_t clock; |
824 | |||
825 | /* return directly when it is eDP */ | ||
826 | if (HAS_eDP) | ||
827 | return true; | ||
828 | |||
842 | if (target < 200000) { | 829 | if (target < 200000) { |
843 | clock.n = 1; | 830 | clock.n = 1; |
844 | clock.p1 = 2; | 831 | clock.p1 = 2; |
@@ -857,68 +844,6 @@ intel_find_pll_ironlake_dp(const intel_limit_t *limit, struct drm_crtc *crtc, | |||
857 | return true; | 844 | return true; |
858 | } | 845 | } |
859 | 846 | ||
860 | static bool | ||
861 | intel_ironlake_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc, | ||
862 | int target, int refclk, intel_clock_t *best_clock) | ||
863 | { | ||
864 | struct drm_device *dev = crtc->dev; | ||
865 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
866 | intel_clock_t clock; | ||
867 | int err_most = 47; | ||
868 | int err_min = 10000; | ||
869 | |||
870 | /* eDP has only 2 clock choice, no n/m/p setting */ | ||
871 | if (HAS_eDP) | ||
872 | return true; | ||
873 | |||
874 | if (intel_pipe_has_type(crtc, INTEL_OUTPUT_DISPLAYPORT)) | ||
875 | return intel_find_pll_ironlake_dp(limit, crtc, target, | ||
876 | refclk, best_clock); | ||
877 | |||
878 | if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)) { | ||
879 | if ((I915_READ(PCH_LVDS) & LVDS_CLKB_POWER_MASK) == | ||
880 | LVDS_CLKB_POWER_UP) | ||
881 | clock.p2 = limit->p2.p2_fast; | ||
882 | else | ||
883 | clock.p2 = limit->p2.p2_slow; | ||
884 | } else { | ||
885 | if (target < limit->p2.dot_limit) | ||
886 | clock.p2 = limit->p2.p2_slow; | ||
887 | else | ||
888 | clock.p2 = limit->p2.p2_fast; | ||
889 | } | ||
890 | |||
891 | memset(best_clock, 0, sizeof(*best_clock)); | ||
892 | for (clock.p1 = limit->p1.max; clock.p1 >= limit->p1.min; clock.p1--) { | ||
893 | /* based on hardware requriment prefer smaller n to precision */ | ||
894 | for (clock.n = limit->n.min; clock.n <= limit->n.max; clock.n++) { | ||
895 | /* based on hardware requirment prefere larger m1,m2 */ | ||
896 | for (clock.m1 = limit->m1.max; | ||
897 | clock.m1 >= limit->m1.min; clock.m1--) { | ||
898 | for (clock.m2 = limit->m2.max; | ||
899 | clock.m2 >= limit->m2.min; clock.m2--) { | ||
900 | int this_err; | ||
901 | |||
902 | intel_clock(dev, refclk, &clock); | ||
903 | if (!intel_PLL_is_valid(crtc, &clock)) | ||
904 | continue; | ||
905 | this_err = abs((10000 - (target*10000/clock.dot))); | ||
906 | if (this_err < err_most) { | ||
907 | *best_clock = clock; | ||
908 | /* found on first matching */ | ||
909 | goto out; | ||
910 | } else if (this_err < err_min) { | ||
911 | *best_clock = clock; | ||
912 | err_min = this_err; | ||
913 | } | ||
914 | } | ||
915 | } | ||
916 | } | ||
917 | } | ||
918 | out: | ||
919 | return true; | ||
920 | } | ||
921 | |||
922 | /* DisplayPort has only two frequencies, 162MHz and 270MHz */ | 847 | /* DisplayPort has only two frequencies, 162MHz and 270MHz */ |
923 | static bool | 848 | static bool |
924 | intel_find_pll_g4x_dp(const intel_limit_t *limit, struct drm_crtc *crtc, | 849 | intel_find_pll_g4x_dp(const intel_limit_t *limit, struct drm_crtc *crtc, |
@@ -1282,7 +1207,7 @@ intel_pipe_set_base(struct drm_crtc *crtc, int x, int y, | |||
1282 | return ret; | 1207 | return ret; |
1283 | } | 1208 | } |
1284 | 1209 | ||
1285 | ret = i915_gem_object_set_to_gtt_domain(obj, 1); | 1210 | ret = i915_gem_object_set_to_display_plane(obj); |
1286 | if (ret != 0) { | 1211 | if (ret != 0) { |
1287 | i915_gem_object_unpin(obj); | 1212 | i915_gem_object_unpin(obj); |
1288 | mutex_unlock(&dev->struct_mutex); | 1213 | mutex_unlock(&dev->struct_mutex); |
@@ -1493,6 +1418,10 @@ static void ironlake_crtc_dpms(struct drm_crtc *crtc, int mode) | |||
1493 | int trans_vsync_reg = (pipe == 0) ? TRANS_VSYNC_A : TRANS_VSYNC_B; | 1418 | int trans_vsync_reg = (pipe == 0) ? TRANS_VSYNC_A : TRANS_VSYNC_B; |
1494 | u32 temp; | 1419 | u32 temp; |
1495 | int tries = 5, j, n; | 1420 | int tries = 5, j, n; |
1421 | u32 pipe_bpc; | ||
1422 | |||
1423 | temp = I915_READ(pipeconf_reg); | ||
1424 | pipe_bpc = temp & PIPE_BPC_MASK; | ||
1496 | 1425 | ||
1497 | /* XXX: When our outputs are all unaware of DPMS modes other than off | 1426 | /* XXX: When our outputs are all unaware of DPMS modes other than off |
1498 | * and on, we should map those modes to DRM_MODE_DPMS_OFF in the CRTC. | 1427 | * and on, we should map those modes to DRM_MODE_DPMS_OFF in the CRTC. |
@@ -1524,6 +1453,12 @@ static void ironlake_crtc_dpms(struct drm_crtc *crtc, int mode) | |||
1524 | 1453 | ||
1525 | /* enable PCH FDI RX PLL, wait warmup plus DMI latency */ | 1454 | /* enable PCH FDI RX PLL, wait warmup plus DMI latency */ |
1526 | temp = I915_READ(fdi_rx_reg); | 1455 | temp = I915_READ(fdi_rx_reg); |
1456 | /* | ||
1457 | * make the BPC in FDI Rx be consistent with that in | ||
1458 | * pipeconf reg. | ||
1459 | */ | ||
1460 | temp &= ~(0x7 << 16); | ||
1461 | temp |= (pipe_bpc << 11); | ||
1527 | I915_WRITE(fdi_rx_reg, temp | FDI_RX_PLL_ENABLE | | 1462 | I915_WRITE(fdi_rx_reg, temp | FDI_RX_PLL_ENABLE | |
1528 | FDI_SEL_PCDCLK | | 1463 | FDI_SEL_PCDCLK | |
1529 | FDI_DP_PORT_WIDTH_X4); /* default 4 lanes */ | 1464 | FDI_DP_PORT_WIDTH_X4); /* default 4 lanes */ |
@@ -1666,6 +1601,12 @@ static void ironlake_crtc_dpms(struct drm_crtc *crtc, int mode) | |||
1666 | 1601 | ||
1667 | /* enable PCH transcoder */ | 1602 | /* enable PCH transcoder */ |
1668 | temp = I915_READ(transconf_reg); | 1603 | temp = I915_READ(transconf_reg); |
1604 | /* | ||
1605 | * make the BPC in transcoder be consistent with | ||
1606 | * that in pipeconf reg. | ||
1607 | */ | ||
1608 | temp &= ~PIPE_BPC_MASK; | ||
1609 | temp |= pipe_bpc; | ||
1669 | I915_WRITE(transconf_reg, temp | TRANS_ENABLE); | 1610 | I915_WRITE(transconf_reg, temp | TRANS_ENABLE); |
1670 | I915_READ(transconf_reg); | 1611 | I915_READ(transconf_reg); |
1671 | 1612 | ||
@@ -1745,6 +1686,9 @@ static void ironlake_crtc_dpms(struct drm_crtc *crtc, int mode) | |||
1745 | I915_READ(fdi_tx_reg); | 1686 | I915_READ(fdi_tx_reg); |
1746 | 1687 | ||
1747 | temp = I915_READ(fdi_rx_reg); | 1688 | temp = I915_READ(fdi_rx_reg); |
1689 | /* BPC in FDI rx is consistent with that in pipeconf */ | ||
1690 | temp &= ~(0x07 << 16); | ||
1691 | temp |= (pipe_bpc << 11); | ||
1748 | I915_WRITE(fdi_rx_reg, temp & ~FDI_RX_ENABLE); | 1692 | I915_WRITE(fdi_rx_reg, temp & ~FDI_RX_ENABLE); |
1749 | I915_READ(fdi_rx_reg); | 1693 | I915_READ(fdi_rx_reg); |
1750 | 1694 | ||
@@ -1789,7 +1733,12 @@ static void ironlake_crtc_dpms(struct drm_crtc *crtc, int mode) | |||
1789 | } | 1733 | } |
1790 | } | 1734 | } |
1791 | } | 1735 | } |
1792 | 1736 | temp = I915_READ(transconf_reg); | |
1737 | /* BPC in transcoder is consistent with that in pipeconf */ | ||
1738 | temp &= ~PIPE_BPC_MASK; | ||
1739 | temp |= pipe_bpc; | ||
1740 | I915_WRITE(transconf_reg, temp); | ||
1741 | I915_READ(transconf_reg); | ||
1793 | udelay(100); | 1742 | udelay(100); |
1794 | 1743 | ||
1795 | /* disable PCH DPLL */ | 1744 | /* disable PCH DPLL */ |
@@ -2448,7 +2397,7 @@ static void pineview_enable_cxsr(struct drm_device *dev, unsigned long clock, | |||
2448 | * A value of 5us seems to be a good balance; safe for very low end | 2397 | * A value of 5us seems to be a good balance; safe for very low end |
2449 | * platforms but not overly aggressive on lower latency configs. | 2398 | * platforms but not overly aggressive on lower latency configs. |
2450 | */ | 2399 | */ |
2451 | const static int latency_ns = 5000; | 2400 | static const int latency_ns = 5000; |
2452 | 2401 | ||
2453 | static int i9xx_get_fifo_size(struct drm_device *dev, int plane) | 2402 | static int i9xx_get_fifo_size(struct drm_device *dev, int plane) |
2454 | { | 2403 | { |
@@ -2559,7 +2508,7 @@ static void g4x_update_wm(struct drm_device *dev, int planea_clock, | |||
2559 | /* Calc sr entries for one plane configs */ | 2508 | /* Calc sr entries for one plane configs */ |
2560 | if (sr_hdisplay && (!planea_clock || !planeb_clock)) { | 2509 | if (sr_hdisplay && (!planea_clock || !planeb_clock)) { |
2561 | /* self-refresh has much higher latency */ | 2510 | /* self-refresh has much higher latency */ |
2562 | const static int sr_latency_ns = 12000; | 2511 | static const int sr_latency_ns = 12000; |
2563 | 2512 | ||
2564 | sr_clock = planea_clock ? planea_clock : planeb_clock; | 2513 | sr_clock = planea_clock ? planea_clock : planeb_clock; |
2565 | line_time_us = ((sr_hdisplay * 1000) / sr_clock); | 2514 | line_time_us = ((sr_hdisplay * 1000) / sr_clock); |
@@ -2598,7 +2547,7 @@ static void i965_update_wm(struct drm_device *dev, int planea_clock, | |||
2598 | /* Calc sr entries for one plane configs */ | 2547 | /* Calc sr entries for one plane configs */ |
2599 | if (sr_hdisplay && (!planea_clock || !planeb_clock)) { | 2548 | if (sr_hdisplay && (!planea_clock || !planeb_clock)) { |
2600 | /* self-refresh has much higher latency */ | 2549 | /* self-refresh has much higher latency */ |
2601 | const static int sr_latency_ns = 12000; | 2550 | static const int sr_latency_ns = 12000; |
2602 | 2551 | ||
2603 | sr_clock = planea_clock ? planea_clock : planeb_clock; | 2552 | sr_clock = planea_clock ? planea_clock : planeb_clock; |
2604 | line_time_us = ((sr_hdisplay * 1000) / sr_clock); | 2553 | line_time_us = ((sr_hdisplay * 1000) / sr_clock); |
@@ -2667,7 +2616,7 @@ static void i9xx_update_wm(struct drm_device *dev, int planea_clock, | |||
2667 | if (HAS_FW_BLC(dev) && sr_hdisplay && | 2616 | if (HAS_FW_BLC(dev) && sr_hdisplay && |
2668 | (!planea_clock || !planeb_clock)) { | 2617 | (!planea_clock || !planeb_clock)) { |
2669 | /* self-refresh has much higher latency */ | 2618 | /* self-refresh has much higher latency */ |
2670 | const static int sr_latency_ns = 6000; | 2619 | static const int sr_latency_ns = 6000; |
2671 | 2620 | ||
2672 | sr_clock = planea_clock ? planea_clock : planeb_clock; | 2621 | sr_clock = planea_clock ? planea_clock : planeb_clock; |
2673 | line_time_us = ((sr_hdisplay * 1000) / sr_clock); | 2622 | line_time_us = ((sr_hdisplay * 1000) / sr_clock); |
@@ -2906,10 +2855,8 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, | |||
2906 | return -EINVAL; | 2855 | return -EINVAL; |
2907 | } | 2856 | } |
2908 | 2857 | ||
2909 | if (is_lvds && limit->find_reduced_pll && | 2858 | if (is_lvds && dev_priv->lvds_downclock_avail) { |
2910 | dev_priv->lvds_downclock_avail) { | 2859 | has_reduced_clock = limit->find_pll(limit, crtc, |
2911 | memcpy(&reduced_clock, &clock, sizeof(intel_clock_t)); | ||
2912 | has_reduced_clock = limit->find_reduced_pll(limit, crtc, | ||
2913 | dev_priv->lvds_downclock, | 2860 | dev_priv->lvds_downclock, |
2914 | refclk, | 2861 | refclk, |
2915 | &reduced_clock); | 2862 | &reduced_clock); |
@@ -2969,6 +2916,33 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, | |||
2969 | 2916 | ||
2970 | /* determine panel color depth */ | 2917 | /* determine panel color depth */ |
2971 | temp = I915_READ(pipeconf_reg); | 2918 | temp = I915_READ(pipeconf_reg); |
2919 | temp &= ~PIPE_BPC_MASK; | ||
2920 | if (is_lvds) { | ||
2921 | int lvds_reg = I915_READ(PCH_LVDS); | ||
2922 | /* the BPC will be 6 if it is 18-bit LVDS panel */ | ||
2923 | if ((lvds_reg & LVDS_A3_POWER_MASK) == LVDS_A3_POWER_UP) | ||
2924 | temp |= PIPE_8BPC; | ||
2925 | else | ||
2926 | temp |= PIPE_6BPC; | ||
2927 | } else if (is_edp) { | ||
2928 | switch (dev_priv->edp_bpp/3) { | ||
2929 | case 8: | ||
2930 | temp |= PIPE_8BPC; | ||
2931 | break; | ||
2932 | case 10: | ||
2933 | temp |= PIPE_10BPC; | ||
2934 | break; | ||
2935 | case 6: | ||
2936 | temp |= PIPE_6BPC; | ||
2937 | break; | ||
2938 | case 12: | ||
2939 | temp |= PIPE_12BPC; | ||
2940 | break; | ||
2941 | } | ||
2942 | } else | ||
2943 | temp |= PIPE_8BPC; | ||
2944 | I915_WRITE(pipeconf_reg, temp); | ||
2945 | I915_READ(pipeconf_reg); | ||
2972 | 2946 | ||
2973 | switch (temp & PIPE_BPC_MASK) { | 2947 | switch (temp & PIPE_BPC_MASK) { |
2974 | case PIPE_8BPC: | 2948 | case PIPE_8BPC: |
@@ -3195,7 +3169,20 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, | |||
3195 | * appropriately here, but we need to look more thoroughly into how | 3169 | * appropriately here, but we need to look more thoroughly into how |
3196 | * panels behave in the two modes. | 3170 | * panels behave in the two modes. |
3197 | */ | 3171 | */ |
3198 | 3172 | /* set the dithering flag */ | |
3173 | if (IS_I965G(dev)) { | ||
3174 | if (dev_priv->lvds_dither) { | ||
3175 | if (IS_IRONLAKE(dev)) | ||
3176 | pipeconf |= PIPE_ENABLE_DITHER; | ||
3177 | else | ||
3178 | lvds |= LVDS_ENABLE_DITHER; | ||
3179 | } else { | ||
3180 | if (IS_IRONLAKE(dev)) | ||
3181 | pipeconf &= ~PIPE_ENABLE_DITHER; | ||
3182 | else | ||
3183 | lvds &= ~LVDS_ENABLE_DITHER; | ||
3184 | } | ||
3185 | } | ||
3199 | I915_WRITE(lvds_reg, lvds); | 3186 | I915_WRITE(lvds_reg, lvds); |
3200 | I915_READ(lvds_reg); | 3187 | I915_READ(lvds_reg); |
3201 | } | 3188 | } |
@@ -3385,7 +3372,7 @@ static int intel_crtc_cursor_set(struct drm_crtc *crtc, | |||
3385 | 3372 | ||
3386 | /* we only need to pin inside GTT if cursor is non-phy */ | 3373 | /* we only need to pin inside GTT if cursor is non-phy */ |
3387 | mutex_lock(&dev->struct_mutex); | 3374 | mutex_lock(&dev->struct_mutex); |
3388 | if (!dev_priv->cursor_needs_physical) { | 3375 | if (!dev_priv->info->cursor_needs_physical) { |
3389 | ret = i915_gem_object_pin(bo, PAGE_SIZE); | 3376 | ret = i915_gem_object_pin(bo, PAGE_SIZE); |
3390 | if (ret) { | 3377 | if (ret) { |
3391 | DRM_ERROR("failed to pin cursor bo\n"); | 3378 | DRM_ERROR("failed to pin cursor bo\n"); |
@@ -3420,7 +3407,7 @@ static int intel_crtc_cursor_set(struct drm_crtc *crtc, | |||
3420 | I915_WRITE(base, addr); | 3407 | I915_WRITE(base, addr); |
3421 | 3408 | ||
3422 | if (intel_crtc->cursor_bo) { | 3409 | if (intel_crtc->cursor_bo) { |
3423 | if (dev_priv->cursor_needs_physical) { | 3410 | if (dev_priv->info->cursor_needs_physical) { |
3424 | if (intel_crtc->cursor_bo != bo) | 3411 | if (intel_crtc->cursor_bo != bo) |
3425 | i915_gem_detach_phys_object(dev, intel_crtc->cursor_bo); | 3412 | i915_gem_detach_phys_object(dev, intel_crtc->cursor_bo); |
3426 | } else | 3413 | } else |
@@ -3779,125 +3766,6 @@ static void intel_gpu_idle_timer(unsigned long arg) | |||
3779 | queue_work(dev_priv->wq, &dev_priv->idle_work); | 3766 | queue_work(dev_priv->wq, &dev_priv->idle_work); |
3780 | } | 3767 | } |
3781 | 3768 | ||
3782 | void intel_increase_renderclock(struct drm_device *dev, bool schedule) | ||
3783 | { | ||
3784 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
3785 | |||
3786 | if (IS_IRONLAKE(dev)) | ||
3787 | return; | ||
3788 | |||
3789 | if (!dev_priv->render_reclock_avail) { | ||
3790 | DRM_DEBUG_DRIVER("not reclocking render clock\n"); | ||
3791 | return; | ||
3792 | } | ||
3793 | |||
3794 | /* Restore render clock frequency to original value */ | ||
3795 | if (IS_G4X(dev) || IS_I9XX(dev)) | ||
3796 | pci_write_config_word(dev->pdev, GCFGC, dev_priv->orig_clock); | ||
3797 | else if (IS_I85X(dev)) | ||
3798 | pci_write_config_word(dev->pdev, HPLLCC, dev_priv->orig_clock); | ||
3799 | DRM_DEBUG_DRIVER("increasing render clock frequency\n"); | ||
3800 | |||
3801 | /* Schedule downclock */ | ||
3802 | if (schedule) | ||
3803 | mod_timer(&dev_priv->idle_timer, jiffies + | ||
3804 | msecs_to_jiffies(GPU_IDLE_TIMEOUT)); | ||
3805 | } | ||
3806 | |||
3807 | void intel_decrease_renderclock(struct drm_device *dev) | ||
3808 | { | ||
3809 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
3810 | |||
3811 | if (IS_IRONLAKE(dev)) | ||
3812 | return; | ||
3813 | |||
3814 | if (!dev_priv->render_reclock_avail) { | ||
3815 | DRM_DEBUG_DRIVER("not reclocking render clock\n"); | ||
3816 | return; | ||
3817 | } | ||
3818 | |||
3819 | if (IS_G4X(dev)) { | ||
3820 | u16 gcfgc; | ||
3821 | |||
3822 | /* Adjust render clock... */ | ||
3823 | pci_read_config_word(dev->pdev, GCFGC, &gcfgc); | ||
3824 | |||
3825 | /* Down to minimum... */ | ||
3826 | gcfgc &= ~GM45_GC_RENDER_CLOCK_MASK; | ||
3827 | gcfgc |= GM45_GC_RENDER_CLOCK_266_MHZ; | ||
3828 | |||
3829 | pci_write_config_word(dev->pdev, GCFGC, gcfgc); | ||
3830 | } else if (IS_I965G(dev)) { | ||
3831 | u16 gcfgc; | ||
3832 | |||
3833 | /* Adjust render clock... */ | ||
3834 | pci_read_config_word(dev->pdev, GCFGC, &gcfgc); | ||
3835 | |||
3836 | /* Down to minimum... */ | ||
3837 | gcfgc &= ~I965_GC_RENDER_CLOCK_MASK; | ||
3838 | gcfgc |= I965_GC_RENDER_CLOCK_267_MHZ; | ||
3839 | |||
3840 | pci_write_config_word(dev->pdev, GCFGC, gcfgc); | ||
3841 | } else if (IS_I945G(dev) || IS_I945GM(dev)) { | ||
3842 | u16 gcfgc; | ||
3843 | |||
3844 | /* Adjust render clock... */ | ||
3845 | pci_read_config_word(dev->pdev, GCFGC, &gcfgc); | ||
3846 | |||
3847 | /* Down to minimum... */ | ||
3848 | gcfgc &= ~I945_GC_RENDER_CLOCK_MASK; | ||
3849 | gcfgc |= I945_GC_RENDER_CLOCK_166_MHZ; | ||
3850 | |||
3851 | pci_write_config_word(dev->pdev, GCFGC, gcfgc); | ||
3852 | } else if (IS_I915G(dev)) { | ||
3853 | u16 gcfgc; | ||
3854 | |||
3855 | /* Adjust render clock... */ | ||
3856 | pci_read_config_word(dev->pdev, GCFGC, &gcfgc); | ||
3857 | |||
3858 | /* Down to minimum... */ | ||
3859 | gcfgc &= ~I915_GC_RENDER_CLOCK_MASK; | ||
3860 | gcfgc |= I915_GC_RENDER_CLOCK_166_MHZ; | ||
3861 | |||
3862 | pci_write_config_word(dev->pdev, GCFGC, gcfgc); | ||
3863 | } else if (IS_I85X(dev)) { | ||
3864 | u16 hpllcc; | ||
3865 | |||
3866 | /* Adjust render clock... */ | ||
3867 | pci_read_config_word(dev->pdev, HPLLCC, &hpllcc); | ||
3868 | |||
3869 | /* Up to maximum... */ | ||
3870 | hpllcc &= ~GC_CLOCK_CONTROL_MASK; | ||
3871 | hpllcc |= GC_CLOCK_133_200; | ||
3872 | |||
3873 | pci_write_config_word(dev->pdev, HPLLCC, hpllcc); | ||
3874 | } | ||
3875 | DRM_DEBUG_DRIVER("decreasing render clock frequency\n"); | ||
3876 | } | ||
3877 | |||
3878 | /* Note that no increase function is needed for this - increase_renderclock() | ||
3879 | * will also rewrite these bits | ||
3880 | */ | ||
3881 | void intel_decrease_displayclock(struct drm_device *dev) | ||
3882 | { | ||
3883 | if (IS_IRONLAKE(dev)) | ||
3884 | return; | ||
3885 | |||
3886 | if (IS_I945G(dev) || IS_I945GM(dev) || IS_I915G(dev) || | ||
3887 | IS_I915GM(dev)) { | ||
3888 | u16 gcfgc; | ||
3889 | |||
3890 | /* Adjust render clock... */ | ||
3891 | pci_read_config_word(dev->pdev, GCFGC, &gcfgc); | ||
3892 | |||
3893 | /* Down to minimum... */ | ||
3894 | gcfgc &= ~0xf0; | ||
3895 | gcfgc |= 0x80; | ||
3896 | |||
3897 | pci_write_config_word(dev->pdev, GCFGC, gcfgc); | ||
3898 | } | ||
3899 | } | ||
3900 | |||
3901 | #define CRTC_IDLE_TIMEOUT 1000 /* ms */ | 3769 | #define CRTC_IDLE_TIMEOUT 1000 /* ms */ |
3902 | 3770 | ||
3903 | static void intel_crtc_idle_timer(unsigned long arg) | 3771 | static void intel_crtc_idle_timer(unsigned long arg) |
@@ -4011,12 +3879,6 @@ static void intel_idle_update(struct work_struct *work) | |||
4011 | 3879 | ||
4012 | mutex_lock(&dev->struct_mutex); | 3880 | mutex_lock(&dev->struct_mutex); |
4013 | 3881 | ||
4014 | /* GPU isn't processing, downclock it. */ | ||
4015 | if (!dev_priv->busy) { | ||
4016 | intel_decrease_renderclock(dev); | ||
4017 | intel_decrease_displayclock(dev); | ||
4018 | } | ||
4019 | |||
4020 | list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { | 3882 | list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { |
4021 | /* Skip inactive CRTCs */ | 3883 | /* Skip inactive CRTCs */ |
4022 | if (!crtc->fb) | 3884 | if (!crtc->fb) |
@@ -4050,13 +3912,11 @@ void intel_mark_busy(struct drm_device *dev, struct drm_gem_object *obj) | |||
4050 | if (!drm_core_check_feature(dev, DRIVER_MODESET)) | 3912 | if (!drm_core_check_feature(dev, DRIVER_MODESET)) |
4051 | return; | 3913 | return; |
4052 | 3914 | ||
4053 | if (!dev_priv->busy) { | 3915 | if (!dev_priv->busy) |
4054 | dev_priv->busy = true; | 3916 | dev_priv->busy = true; |
4055 | intel_increase_renderclock(dev, true); | 3917 | else |
4056 | } else { | ||
4057 | mod_timer(&dev_priv->idle_timer, jiffies + | 3918 | mod_timer(&dev_priv->idle_timer, jiffies + |
4058 | msecs_to_jiffies(GPU_IDLE_TIMEOUT)); | 3919 | msecs_to_jiffies(GPU_IDLE_TIMEOUT)); |
4059 | } | ||
4060 | 3920 | ||
4061 | list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { | 3921 | list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { |
4062 | if (!crtc->fb) | 3922 | if (!crtc->fb) |
@@ -4400,29 +4260,43 @@ static void intel_setup_outputs(struct drm_device *dev) | |||
4400 | bool found = false; | 4260 | bool found = false; |
4401 | 4261 | ||
4402 | if (I915_READ(SDVOB) & SDVO_DETECTED) { | 4262 | if (I915_READ(SDVOB) & SDVO_DETECTED) { |
4263 | DRM_DEBUG_KMS("probing SDVOB\n"); | ||
4403 | found = intel_sdvo_init(dev, SDVOB); | 4264 | found = intel_sdvo_init(dev, SDVOB); |
4404 | if (!found && SUPPORTS_INTEGRATED_HDMI(dev)) | 4265 | if (!found && SUPPORTS_INTEGRATED_HDMI(dev)) { |
4266 | DRM_DEBUG_KMS("probing HDMI on SDVOB\n"); | ||
4405 | intel_hdmi_init(dev, SDVOB); | 4267 | intel_hdmi_init(dev, SDVOB); |
4268 | } | ||
4406 | 4269 | ||
4407 | if (!found && SUPPORTS_INTEGRATED_DP(dev)) | 4270 | if (!found && SUPPORTS_INTEGRATED_DP(dev)) { |
4271 | DRM_DEBUG_KMS("probing DP_B\n"); | ||
4408 | intel_dp_init(dev, DP_B); | 4272 | intel_dp_init(dev, DP_B); |
4273 | } | ||
4409 | } | 4274 | } |
4410 | 4275 | ||
4411 | /* Before G4X SDVOC doesn't have its own detect register */ | 4276 | /* Before G4X SDVOC doesn't have its own detect register */ |
4412 | 4277 | ||
4413 | if (I915_READ(SDVOB) & SDVO_DETECTED) | 4278 | if (I915_READ(SDVOB) & SDVO_DETECTED) { |
4279 | DRM_DEBUG_KMS("probing SDVOC\n"); | ||
4414 | found = intel_sdvo_init(dev, SDVOC); | 4280 | found = intel_sdvo_init(dev, SDVOC); |
4281 | } | ||
4415 | 4282 | ||
4416 | if (!found && (I915_READ(SDVOC) & SDVO_DETECTED)) { | 4283 | if (!found && (I915_READ(SDVOC) & SDVO_DETECTED)) { |
4417 | 4284 | ||
4418 | if (SUPPORTS_INTEGRATED_HDMI(dev)) | 4285 | if (SUPPORTS_INTEGRATED_HDMI(dev)) { |
4286 | DRM_DEBUG_KMS("probing HDMI on SDVOC\n"); | ||
4419 | intel_hdmi_init(dev, SDVOC); | 4287 | intel_hdmi_init(dev, SDVOC); |
4420 | if (SUPPORTS_INTEGRATED_DP(dev)) | 4288 | } |
4289 | if (SUPPORTS_INTEGRATED_DP(dev)) { | ||
4290 | DRM_DEBUG_KMS("probing DP_C\n"); | ||
4421 | intel_dp_init(dev, DP_C); | 4291 | intel_dp_init(dev, DP_C); |
4292 | } | ||
4422 | } | 4293 | } |
4423 | 4294 | ||
4424 | if (SUPPORTS_INTEGRATED_DP(dev) && (I915_READ(DP_D) & DP_DETECTED)) | 4295 | if (SUPPORTS_INTEGRATED_DP(dev) && |
4296 | (I915_READ(DP_D) & DP_DETECTED)) { | ||
4297 | DRM_DEBUG_KMS("probing DP_D\n"); | ||
4425 | intel_dp_init(dev, DP_D); | 4298 | intel_dp_init(dev, DP_D); |
4299 | } | ||
4426 | } else if (IS_I8XX(dev)) | 4300 | } else if (IS_I8XX(dev)) |
4427 | intel_dvo_init(dev); | 4301 | intel_dvo_init(dev); |
4428 | 4302 | ||
@@ -4527,6 +4401,42 @@ static const struct drm_mode_config_funcs intel_mode_funcs = { | |||
4527 | .fb_changed = intelfb_probe, | 4401 | .fb_changed = intelfb_probe, |
4528 | }; | 4402 | }; |
4529 | 4403 | ||
4404 | static struct drm_gem_object * | ||
4405 | intel_alloc_power_context(struct drm_device *dev) | ||
4406 | { | ||
4407 | struct drm_gem_object *pwrctx; | ||
4408 | int ret; | ||
4409 | |||
4410 | pwrctx = drm_gem_object_alloc(dev, 4096); | ||
4411 | if (!pwrctx) { | ||
4412 | DRM_DEBUG("failed to alloc power context, RC6 disabled\n"); | ||
4413 | return NULL; | ||
4414 | } | ||
4415 | |||
4416 | mutex_lock(&dev->struct_mutex); | ||
4417 | ret = i915_gem_object_pin(pwrctx, 4096); | ||
4418 | if (ret) { | ||
4419 | DRM_ERROR("failed to pin power context: %d\n", ret); | ||
4420 | goto err_unref; | ||
4421 | } | ||
4422 | |||
4423 | ret = i915_gem_object_set_to_gtt_domain(pwrctx, 1); | ||
4424 | if (ret) { | ||
4425 | DRM_ERROR("failed to set-domain on power context: %d\n", ret); | ||
4426 | goto err_unpin; | ||
4427 | } | ||
4428 | mutex_unlock(&dev->struct_mutex); | ||
4429 | |||
4430 | return pwrctx; | ||
4431 | |||
4432 | err_unpin: | ||
4433 | i915_gem_object_unpin(pwrctx); | ||
4434 | err_unref: | ||
4435 | drm_gem_object_unreference(pwrctx); | ||
4436 | mutex_unlock(&dev->struct_mutex); | ||
4437 | return NULL; | ||
4438 | } | ||
4439 | |||
4530 | void intel_init_clock_gating(struct drm_device *dev) | 4440 | void intel_init_clock_gating(struct drm_device *dev) |
4531 | { | 4441 | { |
4532 | struct drm_i915_private *dev_priv = dev->dev_private; | 4442 | struct drm_i915_private *dev_priv = dev->dev_private; |
@@ -4579,42 +4489,27 @@ void intel_init_clock_gating(struct drm_device *dev) | |||
4579 | * GPU can automatically power down the render unit if given a page | 4489 | * GPU can automatically power down the render unit if given a page |
4580 | * to save state. | 4490 | * to save state. |
4581 | */ | 4491 | */ |
4582 | if (I915_HAS_RC6(dev)) { | 4492 | if (I915_HAS_RC6(dev) && drm_core_check_feature(dev, DRIVER_MODESET)) { |
4583 | struct drm_gem_object *pwrctx; | 4493 | struct drm_i915_gem_object *obj_priv = NULL; |
4584 | struct drm_i915_gem_object *obj_priv; | ||
4585 | int ret; | ||
4586 | 4494 | ||
4587 | if (dev_priv->pwrctx) { | 4495 | if (dev_priv->pwrctx) { |
4588 | obj_priv = dev_priv->pwrctx->driver_private; | 4496 | obj_priv = dev_priv->pwrctx->driver_private; |
4589 | } else { | 4497 | } else { |
4590 | pwrctx = drm_gem_object_alloc(dev, 4096); | 4498 | struct drm_gem_object *pwrctx; |
4591 | if (!pwrctx) { | ||
4592 | DRM_DEBUG("failed to alloc power context, " | ||
4593 | "RC6 disabled\n"); | ||
4594 | goto out; | ||
4595 | } | ||
4596 | 4499 | ||
4597 | ret = i915_gem_object_pin(pwrctx, 4096); | 4500 | pwrctx = intel_alloc_power_context(dev); |
4598 | if (ret) { | 4501 | if (pwrctx) { |
4599 | DRM_ERROR("failed to pin power context: %d\n", | 4502 | dev_priv->pwrctx = pwrctx; |
4600 | ret); | 4503 | obj_priv = pwrctx->driver_private; |
4601 | drm_gem_object_unreference(pwrctx); | ||
4602 | goto out; | ||
4603 | } | 4504 | } |
4604 | |||
4605 | i915_gem_object_set_to_gtt_domain(pwrctx, 1); | ||
4606 | |||
4607 | dev_priv->pwrctx = pwrctx; | ||
4608 | obj_priv = pwrctx->driver_private; | ||
4609 | } | 4505 | } |
4610 | 4506 | ||
4611 | I915_WRITE(PWRCTXA, obj_priv->gtt_offset | PWRCTX_EN); | 4507 | if (obj_priv) { |
4612 | I915_WRITE(MCHBAR_RENDER_STANDBY, | 4508 | I915_WRITE(PWRCTXA, obj_priv->gtt_offset | PWRCTX_EN); |
4613 | I915_READ(MCHBAR_RENDER_STANDBY) & ~RCX_SW_EXIT); | 4509 | I915_WRITE(MCHBAR_RENDER_STANDBY, |
4510 | I915_READ(MCHBAR_RENDER_STANDBY) & ~RCX_SW_EXIT); | ||
4511 | } | ||
4614 | } | 4512 | } |
4615 | |||
4616 | out: | ||
4617 | return; | ||
4618 | } | 4513 | } |
4619 | 4514 | ||
4620 | /* Set up chip specific display functions */ | 4515 | /* Set up chip specific display functions */ |
@@ -4770,7 +4665,6 @@ void intel_modeset_cleanup(struct drm_device *dev) | |||
4770 | del_timer_sync(&intel_crtc->idle_timer); | 4665 | del_timer_sync(&intel_crtc->idle_timer); |
4771 | } | 4666 | } |
4772 | 4667 | ||
4773 | intel_increase_renderclock(dev, false); | ||
4774 | del_timer_sync(&dev_priv->idle_timer); | 4668 | del_timer_sync(&dev_priv->idle_timer); |
4775 | 4669 | ||
4776 | if (dev_priv->display.disable_fbc) | 4670 | if (dev_priv->display.disable_fbc) |
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 4e7aa8b7b938..439506cefc14 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c | |||
@@ -125,9 +125,15 @@ intel_dp_link_clock(uint8_t link_bw) | |||
125 | 125 | ||
126 | /* I think this is a fiction */ | 126 | /* I think this is a fiction */ |
127 | static int | 127 | static int |
128 | intel_dp_link_required(int pixel_clock) | 128 | intel_dp_link_required(struct drm_device *dev, |
129 | struct intel_output *intel_output, int pixel_clock) | ||
129 | { | 130 | { |
130 | return pixel_clock * 3; | 131 | struct drm_i915_private *dev_priv = dev->dev_private; |
132 | |||
133 | if (IS_eDP(intel_output)) | ||
134 | return (pixel_clock * dev_priv->edp_bpp) / 8; | ||
135 | else | ||
136 | return pixel_clock * 3; | ||
131 | } | 137 | } |
132 | 138 | ||
133 | static int | 139 | static int |
@@ -138,7 +144,8 @@ intel_dp_mode_valid(struct drm_connector *connector, | |||
138 | int max_link_clock = intel_dp_link_clock(intel_dp_max_link_bw(intel_output)); | 144 | int max_link_clock = intel_dp_link_clock(intel_dp_max_link_bw(intel_output)); |
139 | int max_lanes = intel_dp_max_lane_count(intel_output); | 145 | int max_lanes = intel_dp_max_lane_count(intel_output); |
140 | 146 | ||
141 | if (intel_dp_link_required(mode->clock) > max_link_clock * max_lanes) | 147 | if (intel_dp_link_required(connector->dev, intel_output, mode->clock) |
148 | > max_link_clock * max_lanes) | ||
142 | return MODE_CLOCK_HIGH; | 149 | return MODE_CLOCK_HIGH; |
143 | 150 | ||
144 | if (mode->clock < 10000) | 151 | if (mode->clock < 10000) |
@@ -492,7 +499,8 @@ intel_dp_mode_fixup(struct drm_encoder *encoder, struct drm_display_mode *mode, | |||
492 | for (clock = 0; clock <= max_clock; clock++) { | 499 | for (clock = 0; clock <= max_clock; clock++) { |
493 | int link_avail = intel_dp_link_clock(bws[clock]) * lane_count; | 500 | int link_avail = intel_dp_link_clock(bws[clock]) * lane_count; |
494 | 501 | ||
495 | if (intel_dp_link_required(mode->clock) <= link_avail) { | 502 | if (intel_dp_link_required(encoder->dev, intel_output, mode->clock) |
503 | <= link_avail) { | ||
496 | dp_priv->link_bw = bws[clock]; | 504 | dp_priv->link_bw = bws[clock]; |
497 | dp_priv->lane_count = lane_count; | 505 | dp_priv->lane_count = lane_count; |
498 | adjusted_mode->clock = intel_dp_link_clock(dp_priv->link_bw); | 506 | adjusted_mode->clock = intel_dp_link_clock(dp_priv->link_bw); |
@@ -1289,53 +1297,7 @@ intel_dp_hot_plug(struct intel_output *intel_output) | |||
1289 | if (dp_priv->dpms_mode == DRM_MODE_DPMS_ON) | 1297 | if (dp_priv->dpms_mode == DRM_MODE_DPMS_ON) |
1290 | intel_dp_check_link_status(intel_output); | 1298 | intel_dp_check_link_status(intel_output); |
1291 | } | 1299 | } |
1292 | /* | 1300 | |
1293 | * Enumerate the child dev array parsed from VBT to check whether | ||
1294 | * the given DP is present. | ||
1295 | * If it is present, return 1. | ||
1296 | * If it is not present, return false. | ||
1297 | * If no child dev is parsed from VBT, it is assumed that the given | ||
1298 | * DP is present. | ||
1299 | */ | ||
1300 | static int dp_is_present_in_vbt(struct drm_device *dev, int dp_reg) | ||
1301 | { | ||
1302 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
1303 | struct child_device_config *p_child; | ||
1304 | int i, dp_port, ret; | ||
1305 | |||
1306 | if (!dev_priv->child_dev_num) | ||
1307 | return 1; | ||
1308 | |||
1309 | dp_port = 0; | ||
1310 | if (dp_reg == DP_B || dp_reg == PCH_DP_B) | ||
1311 | dp_port = PORT_IDPB; | ||
1312 | else if (dp_reg == DP_C || dp_reg == PCH_DP_C) | ||
1313 | dp_port = PORT_IDPC; | ||
1314 | else if (dp_reg == DP_D || dp_reg == PCH_DP_D) | ||
1315 | dp_port = PORT_IDPD; | ||
1316 | |||
1317 | ret = 0; | ||
1318 | for (i = 0; i < dev_priv->child_dev_num; i++) { | ||
1319 | p_child = dev_priv->child_dev + i; | ||
1320 | /* | ||
1321 | * If the device type is not DP, continue. | ||
1322 | */ | ||
1323 | if (p_child->device_type != DEVICE_TYPE_DP && | ||
1324 | p_child->device_type != DEVICE_TYPE_eDP) | ||
1325 | continue; | ||
1326 | /* Find the eDP port */ | ||
1327 | if (dp_reg == DP_A && p_child->device_type == DEVICE_TYPE_eDP) { | ||
1328 | ret = 1; | ||
1329 | break; | ||
1330 | } | ||
1331 | /* Find the DP port */ | ||
1332 | if (p_child->dvo_port == dp_port) { | ||
1333 | ret = 1; | ||
1334 | break; | ||
1335 | } | ||
1336 | } | ||
1337 | return ret; | ||
1338 | } | ||
1339 | void | 1301 | void |
1340 | intel_dp_init(struct drm_device *dev, int output_reg) | 1302 | intel_dp_init(struct drm_device *dev, int output_reg) |
1341 | { | 1303 | { |
@@ -1345,10 +1307,6 @@ intel_dp_init(struct drm_device *dev, int output_reg) | |||
1345 | struct intel_dp_priv *dp_priv; | 1307 | struct intel_dp_priv *dp_priv; |
1346 | const char *name = NULL; | 1308 | const char *name = NULL; |
1347 | 1309 | ||
1348 | if (!dp_is_present_in_vbt(dev, output_reg)) { | ||
1349 | DRM_DEBUG_KMS("DP is not present. Ignore it\n"); | ||
1350 | return; | ||
1351 | } | ||
1352 | intel_output = kcalloc(sizeof(struct intel_output) + | 1310 | intel_output = kcalloc(sizeof(struct intel_output) + |
1353 | sizeof(struct intel_dp_priv), 1, GFP_KERNEL); | 1311 | sizeof(struct intel_dp_priv), 1, GFP_KERNEL); |
1354 | if (!intel_output) | 1312 | if (!intel_output) |
@@ -1373,11 +1331,10 @@ intel_dp_init(struct drm_device *dev, int output_reg) | |||
1373 | else if (output_reg == DP_D || output_reg == PCH_DP_D) | 1331 | else if (output_reg == DP_D || output_reg == PCH_DP_D) |
1374 | intel_output->clone_mask = (1 << INTEL_DP_D_CLONE_BIT); | 1332 | intel_output->clone_mask = (1 << INTEL_DP_D_CLONE_BIT); |
1375 | 1333 | ||
1376 | if (IS_eDP(intel_output)) { | 1334 | if (IS_eDP(intel_output)) |
1377 | intel_output->crtc_mask = (1 << 1); | ||
1378 | intel_output->clone_mask = (1 << INTEL_EDP_CLONE_BIT); | 1335 | intel_output->clone_mask = (1 << INTEL_EDP_CLONE_BIT); |
1379 | } else | 1336 | |
1380 | intel_output->crtc_mask = (1 << 0) | (1 << 1); | 1337 | intel_output->crtc_mask = (1 << 0) | (1 << 1); |
1381 | connector->interlace_allowed = true; | 1338 | connector->interlace_allowed = true; |
1382 | connector->doublescan_allowed = 0; | 1339 | connector->doublescan_allowed = 0; |
1383 | 1340 | ||
@@ -1402,14 +1359,20 @@ intel_dp_init(struct drm_device *dev, int output_reg) | |||
1402 | break; | 1359 | break; |
1403 | case DP_B: | 1360 | case DP_B: |
1404 | case PCH_DP_B: | 1361 | case PCH_DP_B: |
1362 | dev_priv->hotplug_supported_mask |= | ||
1363 | HDMIB_HOTPLUG_INT_STATUS; | ||
1405 | name = "DPDDC-B"; | 1364 | name = "DPDDC-B"; |
1406 | break; | 1365 | break; |
1407 | case DP_C: | 1366 | case DP_C: |
1408 | case PCH_DP_C: | 1367 | case PCH_DP_C: |
1368 | dev_priv->hotplug_supported_mask |= | ||
1369 | HDMIC_HOTPLUG_INT_STATUS; | ||
1409 | name = "DPDDC-C"; | 1370 | name = "DPDDC-C"; |
1410 | break; | 1371 | break; |
1411 | case DP_D: | 1372 | case DP_D: |
1412 | case PCH_DP_D: | 1373 | case PCH_DP_D: |
1374 | dev_priv->hotplug_supported_mask |= | ||
1375 | HDMID_HOTPLUG_INT_STATUS; | ||
1413 | name = "DPDDC-D"; | 1376 | name = "DPDDC-D"; |
1414 | break; | 1377 | break; |
1415 | } | 1378 | } |
diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c index f04dbbe7d400..0e268deed761 100644 --- a/drivers/gpu/drm/i915/intel_hdmi.c +++ b/drivers/gpu/drm/i915/intel_hdmi.c | |||
@@ -225,52 +225,6 @@ static const struct drm_encoder_funcs intel_hdmi_enc_funcs = { | |||
225 | .destroy = intel_hdmi_enc_destroy, | 225 | .destroy = intel_hdmi_enc_destroy, |
226 | }; | 226 | }; |
227 | 227 | ||
228 | /* | ||
229 | * Enumerate the child dev array parsed from VBT to check whether | ||
230 | * the given HDMI is present. | ||
231 | * If it is present, return 1. | ||
232 | * If it is not present, return false. | ||
233 | * If no child dev is parsed from VBT, it assumes that the given | ||
234 | * HDMI is present. | ||
235 | */ | ||
236 | static int hdmi_is_present_in_vbt(struct drm_device *dev, int hdmi_reg) | ||
237 | { | ||
238 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
239 | struct child_device_config *p_child; | ||
240 | int i, hdmi_port, ret; | ||
241 | |||
242 | if (!dev_priv->child_dev_num) | ||
243 | return 1; | ||
244 | |||
245 | if (hdmi_reg == SDVOB) | ||
246 | hdmi_port = DVO_B; | ||
247 | else if (hdmi_reg == SDVOC) | ||
248 | hdmi_port = DVO_C; | ||
249 | else if (hdmi_reg == HDMIB) | ||
250 | hdmi_port = DVO_B; | ||
251 | else if (hdmi_reg == HDMIC) | ||
252 | hdmi_port = DVO_C; | ||
253 | else if (hdmi_reg == HDMID) | ||
254 | hdmi_port = DVO_D; | ||
255 | else | ||
256 | return 0; | ||
257 | |||
258 | ret = 0; | ||
259 | for (i = 0; i < dev_priv->child_dev_num; i++) { | ||
260 | p_child = dev_priv->child_dev + i; | ||
261 | /* | ||
262 | * If the device type is not HDMI, continue. | ||
263 | */ | ||
264 | if (p_child->device_type != DEVICE_TYPE_HDMI) | ||
265 | continue; | ||
266 | /* Find the HDMI port */ | ||
267 | if (p_child->dvo_port == hdmi_port) { | ||
268 | ret = 1; | ||
269 | break; | ||
270 | } | ||
271 | } | ||
272 | return ret; | ||
273 | } | ||
274 | void intel_hdmi_init(struct drm_device *dev, int sdvox_reg) | 228 | void intel_hdmi_init(struct drm_device *dev, int sdvox_reg) |
275 | { | 229 | { |
276 | struct drm_i915_private *dev_priv = dev->dev_private; | 230 | struct drm_i915_private *dev_priv = dev->dev_private; |
@@ -278,10 +232,6 @@ void intel_hdmi_init(struct drm_device *dev, int sdvox_reg) | |||
278 | struct intel_output *intel_output; | 232 | struct intel_output *intel_output; |
279 | struct intel_hdmi_priv *hdmi_priv; | 233 | struct intel_hdmi_priv *hdmi_priv; |
280 | 234 | ||
281 | if (!hdmi_is_present_in_vbt(dev, sdvox_reg)) { | ||
282 | DRM_DEBUG_KMS("HDMI is not present. Ignored it \n"); | ||
283 | return; | ||
284 | } | ||
285 | intel_output = kcalloc(sizeof(struct intel_output) + | 235 | intel_output = kcalloc(sizeof(struct intel_output) + |
286 | sizeof(struct intel_hdmi_priv), 1, GFP_KERNEL); | 236 | sizeof(struct intel_hdmi_priv), 1, GFP_KERNEL); |
287 | if (!intel_output) | 237 | if (!intel_output) |
@@ -303,21 +253,26 @@ void intel_hdmi_init(struct drm_device *dev, int sdvox_reg) | |||
303 | if (sdvox_reg == SDVOB) { | 253 | if (sdvox_reg == SDVOB) { |
304 | intel_output->clone_mask = (1 << INTEL_HDMIB_CLONE_BIT); | 254 | intel_output->clone_mask = (1 << INTEL_HDMIB_CLONE_BIT); |
305 | intel_output->ddc_bus = intel_i2c_create(dev, GPIOE, "HDMIB"); | 255 | intel_output->ddc_bus = intel_i2c_create(dev, GPIOE, "HDMIB"); |
256 | dev_priv->hotplug_supported_mask |= HDMIB_HOTPLUG_INT_STATUS; | ||
306 | } else if (sdvox_reg == SDVOC) { | 257 | } else if (sdvox_reg == SDVOC) { |
307 | intel_output->clone_mask = (1 << INTEL_HDMIC_CLONE_BIT); | 258 | intel_output->clone_mask = (1 << INTEL_HDMIC_CLONE_BIT); |
308 | intel_output->ddc_bus = intel_i2c_create(dev, GPIOD, "HDMIC"); | 259 | intel_output->ddc_bus = intel_i2c_create(dev, GPIOD, "HDMIC"); |
260 | dev_priv->hotplug_supported_mask |= HDMIC_HOTPLUG_INT_STATUS; | ||
309 | } else if (sdvox_reg == HDMIB) { | 261 | } else if (sdvox_reg == HDMIB) { |
310 | intel_output->clone_mask = (1 << INTEL_HDMID_CLONE_BIT); | 262 | intel_output->clone_mask = (1 << INTEL_HDMID_CLONE_BIT); |
311 | intel_output->ddc_bus = intel_i2c_create(dev, PCH_GPIOE, | 263 | intel_output->ddc_bus = intel_i2c_create(dev, PCH_GPIOE, |
312 | "HDMIB"); | 264 | "HDMIB"); |
265 | dev_priv->hotplug_supported_mask |= HDMIB_HOTPLUG_INT_STATUS; | ||
313 | } else if (sdvox_reg == HDMIC) { | 266 | } else if (sdvox_reg == HDMIC) { |
314 | intel_output->clone_mask = (1 << INTEL_HDMIE_CLONE_BIT); | 267 | intel_output->clone_mask = (1 << INTEL_HDMIE_CLONE_BIT); |
315 | intel_output->ddc_bus = intel_i2c_create(dev, PCH_GPIOD, | 268 | intel_output->ddc_bus = intel_i2c_create(dev, PCH_GPIOD, |
316 | "HDMIC"); | 269 | "HDMIC"); |
270 | dev_priv->hotplug_supported_mask |= HDMIC_HOTPLUG_INT_STATUS; | ||
317 | } else if (sdvox_reg == HDMID) { | 271 | } else if (sdvox_reg == HDMID) { |
318 | intel_output->clone_mask = (1 << INTEL_HDMIF_CLONE_BIT); | 272 | intel_output->clone_mask = (1 << INTEL_HDMIF_CLONE_BIT); |
319 | intel_output->ddc_bus = intel_i2c_create(dev, PCH_GPIOF, | 273 | intel_output->ddc_bus = intel_i2c_create(dev, PCH_GPIOF, |
320 | "HDMID"); | 274 | "HDMID"); |
275 | dev_priv->hotplug_supported_mask |= HDMID_HOTPLUG_INT_STATUS; | ||
321 | } | 276 | } |
322 | if (!intel_output->ddc_bus) | 277 | if (!intel_output->ddc_bus) |
323 | goto err_connector; | 278 | goto err_connector; |
diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c index 3118ce274e67..aa74e59bec61 100644 --- a/drivers/gpu/drm/i915/intel_lvds.c +++ b/drivers/gpu/drm/i915/intel_lvds.c | |||
@@ -602,12 +602,33 @@ static void intel_lvds_mode_set(struct drm_encoder *encoder, | |||
602 | /* Some lid devices report incorrect lid status, assume they're connected */ | 602 | /* Some lid devices report incorrect lid status, assume they're connected */ |
603 | static const struct dmi_system_id bad_lid_status[] = { | 603 | static const struct dmi_system_id bad_lid_status[] = { |
604 | { | 604 | { |
605 | .ident = "Compaq nx9020", | ||
606 | .matches = { | ||
607 | DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), | ||
608 | DMI_MATCH(DMI_BOARD_NAME, "3084"), | ||
609 | }, | ||
610 | }, | ||
611 | { | ||
612 | .ident = "Samsung SX20S", | ||
613 | .matches = { | ||
614 | DMI_MATCH(DMI_SYS_VENDOR, "Phoenix Technologies LTD"), | ||
615 | DMI_MATCH(DMI_BOARD_NAME, "SX20S"), | ||
616 | }, | ||
617 | }, | ||
618 | { | ||
605 | .ident = "Aspire One", | 619 | .ident = "Aspire One", |
606 | .matches = { | 620 | .matches = { |
607 | DMI_MATCH(DMI_SYS_VENDOR, "Acer"), | 621 | DMI_MATCH(DMI_SYS_VENDOR, "Acer"), |
608 | DMI_MATCH(DMI_PRODUCT_NAME, "Aspire one"), | 622 | DMI_MATCH(DMI_PRODUCT_NAME, "Aspire one"), |
609 | }, | 623 | }, |
610 | }, | 624 | }, |
625 | { | ||
626 | .ident = "PC-81005", | ||
627 | .matches = { | ||
628 | DMI_MATCH(DMI_SYS_VENDOR, "MALATA"), | ||
629 | DMI_MATCH(DMI_PRODUCT_NAME, "PC-81005"), | ||
630 | }, | ||
631 | }, | ||
611 | { } | 632 | { } |
612 | }; | 633 | }; |
613 | 634 | ||
@@ -679,7 +700,14 @@ static int intel_lid_notify(struct notifier_block *nb, unsigned long val, | |||
679 | struct drm_i915_private *dev_priv = | 700 | struct drm_i915_private *dev_priv = |
680 | container_of(nb, struct drm_i915_private, lid_notifier); | 701 | container_of(nb, struct drm_i915_private, lid_notifier); |
681 | struct drm_device *dev = dev_priv->dev; | 702 | struct drm_device *dev = dev_priv->dev; |
703 | struct drm_connector *connector = dev_priv->int_lvds_connector; | ||
682 | 704 | ||
705 | /* | ||
706 | * check and update the status of LVDS connector after receiving | ||
707 | * the LID nofication event. | ||
708 | */ | ||
709 | if (connector) | ||
710 | connector->status = connector->funcs->detect(connector); | ||
683 | if (!acpi_lid_open()) { | 711 | if (!acpi_lid_open()) { |
684 | dev_priv->modeset_on_lid = 1; | 712 | dev_priv->modeset_on_lid = 1; |
685 | return NOTIFY_OK; | 713 | return NOTIFY_OK; |
@@ -854,65 +882,6 @@ static const struct dmi_system_id intel_no_lvds[] = { | |||
854 | { } /* terminating entry */ | 882 | { } /* terminating entry */ |
855 | }; | 883 | }; |
856 | 884 | ||
857 | #ifdef CONFIG_ACPI | ||
858 | /* | ||
859 | * check_lid_device -- check whether @handle is an ACPI LID device. | ||
860 | * @handle: ACPI device handle | ||
861 | * @level : depth in the ACPI namespace tree | ||
862 | * @context: the number of LID device when we find the device | ||
863 | * @rv: a return value to fill if desired (Not use) | ||
864 | */ | ||
865 | static acpi_status | ||
866 | check_lid_device(acpi_handle handle, u32 level, void *context, | ||
867 | void **return_value) | ||
868 | { | ||
869 | struct acpi_device *acpi_dev; | ||
870 | int *lid_present = context; | ||
871 | |||
872 | acpi_dev = NULL; | ||
873 | /* Get the acpi device for device handle */ | ||
874 | if (acpi_bus_get_device(handle, &acpi_dev) || !acpi_dev) { | ||
875 | /* If there is no ACPI device for handle, return */ | ||
876 | return AE_OK; | ||
877 | } | ||
878 | |||
879 | if (!strncmp(acpi_device_hid(acpi_dev), "PNP0C0D", 7)) | ||
880 | *lid_present = 1; | ||
881 | |||
882 | return AE_OK; | ||
883 | } | ||
884 | |||
885 | /** | ||
886 | * check whether there exists the ACPI LID device by enumerating the ACPI | ||
887 | * device tree. | ||
888 | */ | ||
889 | static int intel_lid_present(void) | ||
890 | { | ||
891 | int lid_present = 0; | ||
892 | |||
893 | if (acpi_disabled) { | ||
894 | /* If ACPI is disabled, there is no ACPI device tree to | ||
895 | * check, so assume the LID device would have been present. | ||
896 | */ | ||
897 | return 1; | ||
898 | } | ||
899 | |||
900 | acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT, | ||
901 | ACPI_UINT32_MAX, | ||
902 | check_lid_device, NULL, &lid_present, NULL); | ||
903 | |||
904 | return lid_present; | ||
905 | } | ||
906 | #else | ||
907 | static int intel_lid_present(void) | ||
908 | { | ||
909 | /* In the absence of ACPI built in, assume that the LID device would | ||
910 | * have been present. | ||
911 | */ | ||
912 | return 1; | ||
913 | } | ||
914 | #endif | ||
915 | |||
916 | /** | 885 | /** |
917 | * intel_find_lvds_downclock - find the reduced downclock for LVDS in EDID | 886 | * intel_find_lvds_downclock - find the reduced downclock for LVDS in EDID |
918 | * @dev: drm device | 887 | * @dev: drm device |
@@ -957,7 +926,8 @@ static void intel_find_lvds_downclock(struct drm_device *dev, | |||
957 | } | 926 | } |
958 | } | 927 | } |
959 | mutex_unlock(&dev->mode_config.mutex); | 928 | mutex_unlock(&dev->mode_config.mutex); |
960 | if (temp_downclock < panel_fixed_mode->clock) { | 929 | if (temp_downclock < panel_fixed_mode->clock && |
930 | i915_lvds_downclock) { | ||
961 | /* We found the downclock for LVDS. */ | 931 | /* We found the downclock for LVDS. */ |
962 | dev_priv->lvds_downclock_avail = 1; | 932 | dev_priv->lvds_downclock_avail = 1; |
963 | dev_priv->lvds_downclock = temp_downclock; | 933 | dev_priv->lvds_downclock = temp_downclock; |
@@ -1031,12 +1001,8 @@ void intel_lvds_init(struct drm_device *dev) | |||
1031 | if (dmi_check_system(intel_no_lvds)) | 1001 | if (dmi_check_system(intel_no_lvds)) |
1032 | return; | 1002 | return; |
1033 | 1003 | ||
1034 | /* | 1004 | if (!lvds_is_present_in_vbt(dev)) { |
1035 | * Assume LVDS is present if there's an ACPI lid device or if the | 1005 | DRM_DEBUG_KMS("LVDS is not present in VBT\n"); |
1036 | * device is present in the VBT. | ||
1037 | */ | ||
1038 | if (!lvds_is_present_in_vbt(dev) && !intel_lid_present()) { | ||
1039 | DRM_DEBUG_KMS("LVDS is not present in VBT and no lid detected\n"); | ||
1040 | return; | 1006 | return; |
1041 | } | 1007 | } |
1042 | 1008 | ||
@@ -1180,6 +1146,8 @@ out: | |||
1180 | DRM_DEBUG_KMS("lid notifier registration failed\n"); | 1146 | DRM_DEBUG_KMS("lid notifier registration failed\n"); |
1181 | dev_priv->lid_notifier.notifier_call = NULL; | 1147 | dev_priv->lid_notifier.notifier_call = NULL; |
1182 | } | 1148 | } |
1149 | /* keep the LVDS connector */ | ||
1150 | dev_priv->int_lvds_connector = connector; | ||
1183 | drm_sysfs_connector_add(connector); | 1151 | drm_sysfs_connector_add(connector); |
1184 | return; | 1152 | return; |
1185 | 1153 | ||
diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c index 24a3dc99716c..eaacfd0920df 100644 --- a/drivers/gpu/drm/i915/intel_sdvo.c +++ b/drivers/gpu/drm/i915/intel_sdvo.c | |||
@@ -462,14 +462,63 @@ static int intel_sdvo_get_pixel_multiplier(struct drm_display_mode *mode) | |||
462 | } | 462 | } |
463 | 463 | ||
464 | /** | 464 | /** |
465 | * Don't check status code from this as it switches the bus back to the | 465 | * Try to read the response after issuie the DDC switch command. But it |
466 | * SDVO chips which defeats the purpose of doing a bus switch in the first | 466 | * is noted that we must do the action of reading response and issuing DDC |
467 | * place. | 467 | * switch command in one I2C transaction. Otherwise when we try to start |
468 | * another I2C transaction after issuing the DDC bus switch, it will be | ||
469 | * switched to the internal SDVO register. | ||
468 | */ | 470 | */ |
469 | static void intel_sdvo_set_control_bus_switch(struct intel_output *intel_output, | 471 | static void intel_sdvo_set_control_bus_switch(struct intel_output *intel_output, |
470 | u8 target) | 472 | u8 target) |
471 | { | 473 | { |
472 | intel_sdvo_write_cmd(intel_output, SDVO_CMD_SET_CONTROL_BUS_SWITCH, &target, 1); | 474 | struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv; |
475 | u8 out_buf[2], cmd_buf[2], ret_value[2], ret; | ||
476 | struct i2c_msg msgs[] = { | ||
477 | { | ||
478 | .addr = sdvo_priv->slave_addr >> 1, | ||
479 | .flags = 0, | ||
480 | .len = 2, | ||
481 | .buf = out_buf, | ||
482 | }, | ||
483 | /* the following two are to read the response */ | ||
484 | { | ||
485 | .addr = sdvo_priv->slave_addr >> 1, | ||
486 | .flags = 0, | ||
487 | .len = 1, | ||
488 | .buf = cmd_buf, | ||
489 | }, | ||
490 | { | ||
491 | .addr = sdvo_priv->slave_addr >> 1, | ||
492 | .flags = I2C_M_RD, | ||
493 | .len = 1, | ||
494 | .buf = ret_value, | ||
495 | }, | ||
496 | }; | ||
497 | |||
498 | intel_sdvo_debug_write(intel_output, SDVO_CMD_SET_CONTROL_BUS_SWITCH, | ||
499 | &target, 1); | ||
500 | /* write the DDC switch command argument */ | ||
501 | intel_sdvo_write_byte(intel_output, SDVO_I2C_ARG_0, target); | ||
502 | |||
503 | out_buf[0] = SDVO_I2C_OPCODE; | ||
504 | out_buf[1] = SDVO_CMD_SET_CONTROL_BUS_SWITCH; | ||
505 | cmd_buf[0] = SDVO_I2C_CMD_STATUS; | ||
506 | cmd_buf[1] = 0; | ||
507 | ret_value[0] = 0; | ||
508 | ret_value[1] = 0; | ||
509 | |||
510 | ret = i2c_transfer(intel_output->i2c_bus, msgs, 3); | ||
511 | if (ret != 3) { | ||
512 | /* failure in I2C transfer */ | ||
513 | DRM_DEBUG_KMS("I2c transfer returned %d\n", ret); | ||
514 | return; | ||
515 | } | ||
516 | if (ret_value[0] != SDVO_CMD_STATUS_SUCCESS) { | ||
517 | DRM_DEBUG_KMS("DDC switch command returns response %d\n", | ||
518 | ret_value[0]); | ||
519 | return; | ||
520 | } | ||
521 | return; | ||
473 | } | 522 | } |
474 | 523 | ||
475 | static bool intel_sdvo_set_target_input(struct intel_output *intel_output, bool target_0, bool target_1) | 524 | static bool intel_sdvo_set_target_input(struct intel_output *intel_output, bool target_0, bool target_1) |
@@ -1579,6 +1628,32 @@ intel_sdvo_hdmi_sink_detect(struct drm_connector *connector, u16 response) | |||
1579 | edid = drm_get_edid(&intel_output->base, | 1628 | edid = drm_get_edid(&intel_output->base, |
1580 | intel_output->ddc_bus); | 1629 | intel_output->ddc_bus); |
1581 | 1630 | ||
1631 | /* This is only applied to SDVO cards with multiple outputs */ | ||
1632 | if (edid == NULL && intel_sdvo_multifunc_encoder(intel_output)) { | ||
1633 | uint8_t saved_ddc, temp_ddc; | ||
1634 | saved_ddc = sdvo_priv->ddc_bus; | ||
1635 | temp_ddc = sdvo_priv->ddc_bus >> 1; | ||
1636 | /* | ||
1637 | * Don't use the 1 as the argument of DDC bus switch to get | ||
1638 | * the EDID. It is used for SDVO SPD ROM. | ||
1639 | */ | ||
1640 | while(temp_ddc > 1) { | ||
1641 | sdvo_priv->ddc_bus = temp_ddc; | ||
1642 | edid = drm_get_edid(&intel_output->base, | ||
1643 | intel_output->ddc_bus); | ||
1644 | if (edid) { | ||
1645 | /* | ||
1646 | * When we can get the EDID, maybe it is the | ||
1647 | * correct DDC bus. Update it. | ||
1648 | */ | ||
1649 | sdvo_priv->ddc_bus = temp_ddc; | ||
1650 | break; | ||
1651 | } | ||
1652 | temp_ddc >>= 1; | ||
1653 | } | ||
1654 | if (edid == NULL) | ||
1655 | sdvo_priv->ddc_bus = saved_ddc; | ||
1656 | } | ||
1582 | /* when there is no edid and no monitor is connected with VGA | 1657 | /* when there is no edid and no monitor is connected with VGA |
1583 | * port, try to use the CRT ddc to read the EDID for DVI-connector | 1658 | * port, try to use the CRT ddc to read the EDID for DVI-connector |
1584 | */ | 1659 | */ |
@@ -2662,6 +2737,7 @@ static void intel_sdvo_create_enhance_property(struct drm_connector *connector) | |||
2662 | 2737 | ||
2663 | bool intel_sdvo_init(struct drm_device *dev, int output_device) | 2738 | bool intel_sdvo_init(struct drm_device *dev, int output_device) |
2664 | { | 2739 | { |
2740 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
2665 | struct drm_connector *connector; | 2741 | struct drm_connector *connector; |
2666 | struct intel_output *intel_output; | 2742 | struct intel_output *intel_output; |
2667 | struct intel_sdvo_priv *sdvo_priv; | 2743 | struct intel_sdvo_priv *sdvo_priv; |
@@ -2708,10 +2784,12 @@ bool intel_sdvo_init(struct drm_device *dev, int output_device) | |||
2708 | intel_output->ddc_bus = intel_i2c_create(dev, GPIOE, "SDVOB DDC BUS"); | 2784 | intel_output->ddc_bus = intel_i2c_create(dev, GPIOE, "SDVOB DDC BUS"); |
2709 | sdvo_priv->analog_ddc_bus = intel_i2c_create(dev, GPIOA, | 2785 | sdvo_priv->analog_ddc_bus = intel_i2c_create(dev, GPIOA, |
2710 | "SDVOB/VGA DDC BUS"); | 2786 | "SDVOB/VGA DDC BUS"); |
2787 | dev_priv->hotplug_supported_mask |= SDVOB_HOTPLUG_INT_STATUS; | ||
2711 | } else { | 2788 | } else { |
2712 | intel_output->ddc_bus = intel_i2c_create(dev, GPIOE, "SDVOC DDC BUS"); | 2789 | intel_output->ddc_bus = intel_i2c_create(dev, GPIOE, "SDVOC DDC BUS"); |
2713 | sdvo_priv->analog_ddc_bus = intel_i2c_create(dev, GPIOA, | 2790 | sdvo_priv->analog_ddc_bus = intel_i2c_create(dev, GPIOA, |
2714 | "SDVOC/VGA DDC BUS"); | 2791 | "SDVOC/VGA DDC BUS"); |
2792 | dev_priv->hotplug_supported_mask |= SDVOC_HOTPLUG_INT_STATUS; | ||
2715 | } | 2793 | } |
2716 | 2794 | ||
2717 | if (intel_output->ddc_bus == NULL) | 2795 | if (intel_output->ddc_bus == NULL) |
diff --git a/drivers/gpu/drm/nouveau/Kconfig b/drivers/gpu/drm/nouveau/Kconfig index b1bc1ea182b8..1175429da102 100644 --- a/drivers/gpu/drm/nouveau/Kconfig +++ b/drivers/gpu/drm/nouveau/Kconfig | |||
@@ -30,12 +30,11 @@ config DRM_NOUVEAU_DEBUG | |||
30 | via debugfs. | 30 | via debugfs. |
31 | 31 | ||
32 | menu "I2C encoder or helper chips" | 32 | menu "I2C encoder or helper chips" |
33 | depends on DRM && I2C | 33 | depends on DRM && DRM_KMS_HELPER && I2C |
34 | 34 | ||
35 | config DRM_I2C_CH7006 | 35 | config DRM_I2C_CH7006 |
36 | tristate "Chrontel ch7006 TV encoder" | 36 | tristate "Chrontel ch7006 TV encoder" |
37 | depends on DRM_NOUVEAU | 37 | default m if DRM_NOUVEAU |
38 | default m | ||
39 | help | 38 | help |
40 | Support for Chrontel ch7006 and similar TV encoders, found | 39 | Support for Chrontel ch7006 and similar TV encoders, found |
41 | on some nVidia video cards. | 40 | on some nVidia video cards. |
diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.c b/drivers/gpu/drm/nouveau/nouveau_bo.c index 0cad6d834eb2..e342a418d434 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bo.c +++ b/drivers/gpu/drm/nouveau/nouveau_bo.c | |||
@@ -33,10 +33,13 @@ | |||
33 | #include "nouveau_drv.h" | 33 | #include "nouveau_drv.h" |
34 | #include "nouveau_dma.h" | 34 | #include "nouveau_dma.h" |
35 | 35 | ||
36 | #include <linux/log2.h> | ||
37 | |||
36 | static void | 38 | static void |
37 | nouveau_bo_del_ttm(struct ttm_buffer_object *bo) | 39 | nouveau_bo_del_ttm(struct ttm_buffer_object *bo) |
38 | { | 40 | { |
39 | struct drm_nouveau_private *dev_priv = nouveau_bdev(bo->bdev); | 41 | struct drm_nouveau_private *dev_priv = nouveau_bdev(bo->bdev); |
42 | struct drm_device *dev = dev_priv->dev; | ||
40 | struct nouveau_bo *nvbo = nouveau_bo(bo); | 43 | struct nouveau_bo *nvbo = nouveau_bo(bo); |
41 | 44 | ||
42 | ttm_bo_kunmap(&nvbo->kmap); | 45 | ttm_bo_kunmap(&nvbo->kmap); |
@@ -44,12 +47,87 @@ nouveau_bo_del_ttm(struct ttm_buffer_object *bo) | |||
44 | if (unlikely(nvbo->gem)) | 47 | if (unlikely(nvbo->gem)) |
45 | DRM_ERROR("bo %p still attached to GEM object\n", bo); | 48 | DRM_ERROR("bo %p still attached to GEM object\n", bo); |
46 | 49 | ||
50 | if (nvbo->tile) | ||
51 | nv10_mem_expire_tiling(dev, nvbo->tile, NULL); | ||
52 | |||
47 | spin_lock(&dev_priv->ttm.bo_list_lock); | 53 | spin_lock(&dev_priv->ttm.bo_list_lock); |
48 | list_del(&nvbo->head); | 54 | list_del(&nvbo->head); |
49 | spin_unlock(&dev_priv->ttm.bo_list_lock); | 55 | spin_unlock(&dev_priv->ttm.bo_list_lock); |
50 | kfree(nvbo); | 56 | kfree(nvbo); |
51 | } | 57 | } |
52 | 58 | ||
59 | static void | ||
60 | nouveau_bo_fixup_align(struct drm_device *dev, | ||
61 | uint32_t tile_mode, uint32_t tile_flags, | ||
62 | int *align, int *size) | ||
63 | { | ||
64 | struct drm_nouveau_private *dev_priv = dev->dev_private; | ||
65 | |||
66 | /* | ||
67 | * Some of the tile_flags have a periodic structure of N*4096 bytes, | ||
68 | * align to to that as well as the page size. Overallocate memory to | ||
69 | * avoid corruption of other buffer objects. | ||
70 | */ | ||
71 | if (dev_priv->card_type == NV_50) { | ||
72 | uint32_t block_size = nouveau_mem_fb_amount(dev) >> 15; | ||
73 | int i; | ||
74 | |||
75 | switch (tile_flags) { | ||
76 | case 0x1800: | ||
77 | case 0x2800: | ||
78 | case 0x4800: | ||
79 | case 0x7a00: | ||
80 | *size = roundup(*size, block_size); | ||
81 | if (is_power_of_2(block_size)) { | ||
82 | *size += 3 * block_size; | ||
83 | for (i = 1; i < 10; i++) { | ||
84 | *align = 12 * i * block_size; | ||
85 | if (!(*align % 65536)) | ||
86 | break; | ||
87 | } | ||
88 | } else { | ||
89 | *size += 6 * block_size; | ||
90 | for (i = 1; i < 10; i++) { | ||
91 | *align = 8 * i * block_size; | ||
92 | if (!(*align % 65536)) | ||
93 | break; | ||
94 | } | ||
95 | } | ||
96 | break; | ||
97 | default: | ||
98 | break; | ||
99 | } | ||
100 | |||
101 | } else { | ||
102 | if (tile_mode) { | ||
103 | if (dev_priv->chipset >= 0x40) { | ||
104 | *align = 65536; | ||
105 | *size = roundup(*size, 64 * tile_mode); | ||
106 | |||
107 | } else if (dev_priv->chipset >= 0x30) { | ||
108 | *align = 32768; | ||
109 | *size = roundup(*size, 64 * tile_mode); | ||
110 | |||
111 | } else if (dev_priv->chipset >= 0x20) { | ||
112 | *align = 16384; | ||
113 | *size = roundup(*size, 64 * tile_mode); | ||
114 | |||
115 | } else if (dev_priv->chipset >= 0x10) { | ||
116 | *align = 16384; | ||
117 | *size = roundup(*size, 32 * tile_mode); | ||
118 | } | ||
119 | } | ||
120 | } | ||
121 | |||
122 | /* ALIGN works only on powers of two. */ | ||
123 | *size = roundup(*size, PAGE_SIZE); | ||
124 | |||
125 | if (dev_priv->card_type == NV_50) { | ||
126 | *size = roundup(*size, 65536); | ||
127 | *align = max(65536, *align); | ||
128 | } | ||
129 | } | ||
130 | |||
53 | int | 131 | int |
54 | nouveau_bo_new(struct drm_device *dev, struct nouveau_channel *chan, | 132 | nouveau_bo_new(struct drm_device *dev, struct nouveau_channel *chan, |
55 | int size, int align, uint32_t flags, uint32_t tile_mode, | 133 | int size, int align, uint32_t flags, uint32_t tile_mode, |
@@ -58,7 +136,7 @@ nouveau_bo_new(struct drm_device *dev, struct nouveau_channel *chan, | |||
58 | { | 136 | { |
59 | struct drm_nouveau_private *dev_priv = dev->dev_private; | 137 | struct drm_nouveau_private *dev_priv = dev->dev_private; |
60 | struct nouveau_bo *nvbo; | 138 | struct nouveau_bo *nvbo; |
61 | int ret, n = 0; | 139 | int ret = 0; |
62 | 140 | ||
63 | nvbo = kzalloc(sizeof(struct nouveau_bo), GFP_KERNEL); | 141 | nvbo = kzalloc(sizeof(struct nouveau_bo), GFP_KERNEL); |
64 | if (!nvbo) | 142 | if (!nvbo) |
@@ -70,59 +148,14 @@ nouveau_bo_new(struct drm_device *dev, struct nouveau_channel *chan, | |||
70 | nvbo->tile_mode = tile_mode; | 148 | nvbo->tile_mode = tile_mode; |
71 | nvbo->tile_flags = tile_flags; | 149 | nvbo->tile_flags = tile_flags; |
72 | 150 | ||
73 | /* | 151 | nouveau_bo_fixup_align(dev, tile_mode, tile_flags, &align, &size); |
74 | * Some of the tile_flags have a periodic structure of N*4096 bytes, | ||
75 | * align to to that as well as the page size. Overallocate memory to | ||
76 | * avoid corruption of other buffer objects. | ||
77 | */ | ||
78 | switch (tile_flags) { | ||
79 | case 0x1800: | ||
80 | case 0x2800: | ||
81 | case 0x4800: | ||
82 | case 0x7a00: | ||
83 | if (dev_priv->chipset >= 0xA0) { | ||
84 | /* This is based on high end cards with 448 bits | ||
85 | * memory bus, could be different elsewhere.*/ | ||
86 | size += 6 * 28672; | ||
87 | /* 8 * 28672 is the actual alignment requirement, | ||
88 | * but we must also align to page size. */ | ||
89 | align = 2 * 8 * 28672; | ||
90 | } else if (dev_priv->chipset >= 0x90) { | ||
91 | size += 3 * 16384; | ||
92 | align = 12 * 16834; | ||
93 | } else { | ||
94 | size += 3 * 8192; | ||
95 | /* 12 * 8192 is the actual alignment requirement, | ||
96 | * but we must also align to page size. */ | ||
97 | align = 2 * 12 * 8192; | ||
98 | } | ||
99 | break; | ||
100 | default: | ||
101 | break; | ||
102 | } | ||
103 | |||
104 | align >>= PAGE_SHIFT; | 152 | align >>= PAGE_SHIFT; |
105 | 153 | ||
106 | size = (size + (PAGE_SIZE - 1)) & ~(PAGE_SIZE - 1); | ||
107 | if (dev_priv->card_type == NV_50) { | ||
108 | size = (size + 65535) & ~65535; | ||
109 | if (align < (65536 / PAGE_SIZE)) | ||
110 | align = (65536 / PAGE_SIZE); | ||
111 | } | ||
112 | |||
113 | if (flags & TTM_PL_FLAG_VRAM) | ||
114 | nvbo->placements[n++] = TTM_PL_FLAG_VRAM | TTM_PL_MASK_CACHING; | ||
115 | if (flags & TTM_PL_FLAG_TT) | ||
116 | nvbo->placements[n++] = TTM_PL_FLAG_TT | TTM_PL_MASK_CACHING; | ||
117 | nvbo->placement.fpfn = 0; | 154 | nvbo->placement.fpfn = 0; |
118 | nvbo->placement.lpfn = mappable ? dev_priv->fb_mappable_pages : 0; | 155 | nvbo->placement.lpfn = mappable ? dev_priv->fb_mappable_pages : 0; |
119 | nvbo->placement.placement = nvbo->placements; | 156 | nouveau_bo_placement_set(nvbo, flags); |
120 | nvbo->placement.busy_placement = nvbo->placements; | ||
121 | nvbo->placement.num_placement = n; | ||
122 | nvbo->placement.num_busy_placement = n; | ||
123 | 157 | ||
124 | nvbo->channel = chan; | 158 | nvbo->channel = chan; |
125 | nouveau_bo_placement_set(nvbo, flags); | ||
126 | ret = ttm_bo_init(&dev_priv->ttm.bdev, &nvbo->bo, size, | 159 | ret = ttm_bo_init(&dev_priv->ttm.bdev, &nvbo->bo, size, |
127 | ttm_bo_type_device, &nvbo->placement, align, 0, | 160 | ttm_bo_type_device, &nvbo->placement, align, 0, |
128 | false, NULL, size, nouveau_bo_del_ttm); | 161 | false, NULL, size, nouveau_bo_del_ttm); |
@@ -421,6 +454,7 @@ nouveau_bo_evict_flags(struct ttm_buffer_object *bo, struct ttm_placement *pl) | |||
421 | /* GPU-assisted copy using NV_MEMORY_TO_MEMORY_FORMAT, can access | 454 | /* GPU-assisted copy using NV_MEMORY_TO_MEMORY_FORMAT, can access |
422 | * TTM_PL_{VRAM,TT} directly. | 455 | * TTM_PL_{VRAM,TT} directly. |
423 | */ | 456 | */ |
457 | |||
424 | static int | 458 | static int |
425 | nouveau_bo_move_accel_cleanup(struct nouveau_channel *chan, | 459 | nouveau_bo_move_accel_cleanup(struct nouveau_channel *chan, |
426 | struct nouveau_bo *nvbo, bool evict, bool no_wait, | 460 | struct nouveau_bo *nvbo, bool evict, bool no_wait, |
@@ -455,11 +489,12 @@ nouveau_bo_mem_ctxdma(struct nouveau_bo *nvbo, struct nouveau_channel *chan, | |||
455 | } | 489 | } |
456 | 490 | ||
457 | static int | 491 | static int |
458 | nouveau_bo_move_m2mf(struct ttm_buffer_object *bo, int evict, int no_wait, | 492 | nouveau_bo_move_m2mf(struct ttm_buffer_object *bo, int evict, bool intr, |
459 | struct ttm_mem_reg *old_mem, struct ttm_mem_reg *new_mem) | 493 | int no_wait, struct ttm_mem_reg *new_mem) |
460 | { | 494 | { |
461 | struct nouveau_bo *nvbo = nouveau_bo(bo); | 495 | struct nouveau_bo *nvbo = nouveau_bo(bo); |
462 | struct drm_nouveau_private *dev_priv = nouveau_bdev(bo->bdev); | 496 | struct drm_nouveau_private *dev_priv = nouveau_bdev(bo->bdev); |
497 | struct ttm_mem_reg *old_mem = &bo->mem; | ||
463 | struct nouveau_channel *chan; | 498 | struct nouveau_channel *chan; |
464 | uint64_t src_offset, dst_offset; | 499 | uint64_t src_offset, dst_offset; |
465 | uint32_t page_count; | 500 | uint32_t page_count; |
@@ -547,7 +582,7 @@ nouveau_bo_move_flipd(struct ttm_buffer_object *bo, bool evict, bool intr, | |||
547 | 582 | ||
548 | placement.fpfn = placement.lpfn = 0; | 583 | placement.fpfn = placement.lpfn = 0; |
549 | placement.num_placement = placement.num_busy_placement = 1; | 584 | placement.num_placement = placement.num_busy_placement = 1; |
550 | placement.placement = &placement_memtype; | 585 | placement.placement = placement.busy_placement = &placement_memtype; |
551 | 586 | ||
552 | tmp_mem = *new_mem; | 587 | tmp_mem = *new_mem; |
553 | tmp_mem.mm_node = NULL; | 588 | tmp_mem.mm_node = NULL; |
@@ -559,7 +594,7 @@ nouveau_bo_move_flipd(struct ttm_buffer_object *bo, bool evict, bool intr, | |||
559 | if (ret) | 594 | if (ret) |
560 | goto out; | 595 | goto out; |
561 | 596 | ||
562 | ret = nouveau_bo_move_m2mf(bo, true, no_wait, &bo->mem, &tmp_mem); | 597 | ret = nouveau_bo_move_m2mf(bo, true, intr, no_wait, &tmp_mem); |
563 | if (ret) | 598 | if (ret) |
564 | goto out; | 599 | goto out; |
565 | 600 | ||
@@ -585,7 +620,7 @@ nouveau_bo_move_flips(struct ttm_buffer_object *bo, bool evict, bool intr, | |||
585 | 620 | ||
586 | placement.fpfn = placement.lpfn = 0; | 621 | placement.fpfn = placement.lpfn = 0; |
587 | placement.num_placement = placement.num_busy_placement = 1; | 622 | placement.num_placement = placement.num_busy_placement = 1; |
588 | placement.placement = &placement_memtype; | 623 | placement.placement = placement.busy_placement = &placement_memtype; |
589 | 624 | ||
590 | tmp_mem = *new_mem; | 625 | tmp_mem = *new_mem; |
591 | tmp_mem.mm_node = NULL; | 626 | tmp_mem.mm_node = NULL; |
@@ -597,7 +632,7 @@ nouveau_bo_move_flips(struct ttm_buffer_object *bo, bool evict, bool intr, | |||
597 | if (ret) | 632 | if (ret) |
598 | goto out; | 633 | goto out; |
599 | 634 | ||
600 | ret = nouveau_bo_move_m2mf(bo, true, no_wait, &bo->mem, new_mem); | 635 | ret = nouveau_bo_move_m2mf(bo, evict, intr, no_wait, new_mem); |
601 | if (ret) | 636 | if (ret) |
602 | goto out; | 637 | goto out; |
603 | 638 | ||
@@ -612,52 +647,106 @@ out: | |||
612 | } | 647 | } |
613 | 648 | ||
614 | static int | 649 | static int |
615 | nouveau_bo_move(struct ttm_buffer_object *bo, bool evict, bool intr, | 650 | nouveau_bo_vm_bind(struct ttm_buffer_object *bo, struct ttm_mem_reg *new_mem, |
616 | bool no_wait, struct ttm_mem_reg *new_mem) | 651 | struct nouveau_tile_reg **new_tile) |
617 | { | 652 | { |
618 | struct drm_nouveau_private *dev_priv = nouveau_bdev(bo->bdev); | 653 | struct drm_nouveau_private *dev_priv = nouveau_bdev(bo->bdev); |
619 | struct nouveau_bo *nvbo = nouveau_bo(bo); | ||
620 | struct drm_device *dev = dev_priv->dev; | 654 | struct drm_device *dev = dev_priv->dev; |
621 | struct ttm_mem_reg *old_mem = &bo->mem; | 655 | struct nouveau_bo *nvbo = nouveau_bo(bo); |
656 | uint64_t offset; | ||
622 | int ret; | 657 | int ret; |
623 | 658 | ||
624 | if (dev_priv->card_type == NV_50 && new_mem->mem_type == TTM_PL_VRAM && | 659 | if (nvbo->no_vm || new_mem->mem_type != TTM_PL_VRAM) { |
625 | !nvbo->no_vm) { | 660 | /* Nothing to do. */ |
626 | uint64_t offset = new_mem->mm_node->start << PAGE_SHIFT; | 661 | *new_tile = NULL; |
662 | return 0; | ||
663 | } | ||
664 | |||
665 | offset = new_mem->mm_node->start << PAGE_SHIFT; | ||
627 | 666 | ||
667 | if (dev_priv->card_type == NV_50) { | ||
628 | ret = nv50_mem_vm_bind_linear(dev, | 668 | ret = nv50_mem_vm_bind_linear(dev, |
629 | offset + dev_priv->vm_vram_base, | 669 | offset + dev_priv->vm_vram_base, |
630 | new_mem->size, nvbo->tile_flags, | 670 | new_mem->size, nvbo->tile_flags, |
631 | offset); | 671 | offset); |
632 | if (ret) | 672 | if (ret) |
633 | return ret; | 673 | return ret; |
674 | |||
675 | } else if (dev_priv->card_type >= NV_10) { | ||
676 | *new_tile = nv10_mem_set_tiling(dev, offset, new_mem->size, | ||
677 | nvbo->tile_mode); | ||
634 | } | 678 | } |
635 | 679 | ||
680 | return 0; | ||
681 | } | ||
682 | |||
683 | static void | ||
684 | nouveau_bo_vm_cleanup(struct ttm_buffer_object *bo, | ||
685 | struct nouveau_tile_reg *new_tile, | ||
686 | struct nouveau_tile_reg **old_tile) | ||
687 | { | ||
688 | struct drm_nouveau_private *dev_priv = nouveau_bdev(bo->bdev); | ||
689 | struct drm_device *dev = dev_priv->dev; | ||
690 | |||
691 | if (dev_priv->card_type >= NV_10 && | ||
692 | dev_priv->card_type < NV_50) { | ||
693 | if (*old_tile) | ||
694 | nv10_mem_expire_tiling(dev, *old_tile, bo->sync_obj); | ||
695 | |||
696 | *old_tile = new_tile; | ||
697 | } | ||
698 | } | ||
699 | |||
700 | static int | ||
701 | nouveau_bo_move(struct ttm_buffer_object *bo, bool evict, bool intr, | ||
702 | bool no_wait, struct ttm_mem_reg *new_mem) | ||
703 | { | ||
704 | struct drm_nouveau_private *dev_priv = nouveau_bdev(bo->bdev); | ||
705 | struct nouveau_bo *nvbo = nouveau_bo(bo); | ||
706 | struct ttm_mem_reg *old_mem = &bo->mem; | ||
707 | struct nouveau_tile_reg *new_tile = NULL; | ||
708 | int ret = 0; | ||
709 | |||
710 | ret = nouveau_bo_vm_bind(bo, new_mem, &new_tile); | ||
711 | if (ret) | ||
712 | return ret; | ||
713 | |||
714 | /* Software copy if the card isn't up and running yet. */ | ||
636 | if (dev_priv->init_state != NOUVEAU_CARD_INIT_DONE || | 715 | if (dev_priv->init_state != NOUVEAU_CARD_INIT_DONE || |
637 | !dev_priv->channel) | 716 | !dev_priv->channel) { |
638 | return ttm_bo_move_memcpy(bo, evict, no_wait, new_mem); | 717 | ret = ttm_bo_move_memcpy(bo, evict, no_wait, new_mem); |
718 | goto out; | ||
719 | } | ||
639 | 720 | ||
721 | /* Fake bo copy. */ | ||
640 | if (old_mem->mem_type == TTM_PL_SYSTEM && !bo->ttm) { | 722 | if (old_mem->mem_type == TTM_PL_SYSTEM && !bo->ttm) { |
641 | BUG_ON(bo->mem.mm_node != NULL); | 723 | BUG_ON(bo->mem.mm_node != NULL); |
642 | bo->mem = *new_mem; | 724 | bo->mem = *new_mem; |
643 | new_mem->mm_node = NULL; | 725 | new_mem->mm_node = NULL; |
644 | return 0; | 726 | goto out; |
645 | } | 727 | } |
646 | 728 | ||
647 | if (new_mem->mem_type == TTM_PL_SYSTEM) { | 729 | /* Hardware assisted copy. */ |
648 | if (old_mem->mem_type == TTM_PL_SYSTEM) | 730 | if (new_mem->mem_type == TTM_PL_SYSTEM) |
649 | return ttm_bo_move_memcpy(bo, evict, no_wait, new_mem); | 731 | ret = nouveau_bo_move_flipd(bo, evict, intr, no_wait, new_mem); |
650 | if (nouveau_bo_move_flipd(bo, evict, intr, no_wait, new_mem)) | 732 | else if (old_mem->mem_type == TTM_PL_SYSTEM) |
651 | return ttm_bo_move_memcpy(bo, evict, no_wait, new_mem); | 733 | ret = nouveau_bo_move_flips(bo, evict, intr, no_wait, new_mem); |
652 | } else if (old_mem->mem_type == TTM_PL_SYSTEM) { | 734 | else |
653 | if (nouveau_bo_move_flips(bo, evict, intr, no_wait, new_mem)) | 735 | ret = nouveau_bo_move_m2mf(bo, evict, intr, no_wait, new_mem); |
654 | return ttm_bo_move_memcpy(bo, evict, no_wait, new_mem); | ||
655 | } else { | ||
656 | if (nouveau_bo_move_m2mf(bo, evict, no_wait, old_mem, new_mem)) | ||
657 | return ttm_bo_move_memcpy(bo, evict, no_wait, new_mem); | ||
658 | } | ||
659 | 736 | ||
660 | return 0; | 737 | if (!ret) |
738 | goto out; | ||
739 | |||
740 | /* Fallback to software copy. */ | ||
741 | ret = ttm_bo_move_memcpy(bo, evict, no_wait, new_mem); | ||
742 | |||
743 | out: | ||
744 | if (ret) | ||
745 | nouveau_bo_vm_cleanup(bo, NULL, &new_tile); | ||
746 | else | ||
747 | nouveau_bo_vm_cleanup(bo, new_tile, &nvbo->tile); | ||
748 | |||
749 | return ret; | ||
661 | } | 750 | } |
662 | 751 | ||
663 | static int | 752 | static int |
diff --git a/drivers/gpu/drm/nouveau/nouveau_channel.c b/drivers/gpu/drm/nouveau/nouveau_channel.c index 9aaa972f8822..343d718a9667 100644 --- a/drivers/gpu/drm/nouveau/nouveau_channel.c +++ b/drivers/gpu/drm/nouveau/nouveau_channel.c | |||
@@ -158,6 +158,8 @@ nouveau_channel_alloc(struct drm_device *dev, struct nouveau_channel **chan_ret, | |||
158 | return ret; | 158 | return ret; |
159 | } | 159 | } |
160 | 160 | ||
161 | nouveau_dma_pre_init(chan); | ||
162 | |||
161 | /* Locate channel's user control regs */ | 163 | /* Locate channel's user control regs */ |
162 | if (dev_priv->card_type < NV_40) | 164 | if (dev_priv->card_type < NV_40) |
163 | user = NV03_USER(channel); | 165 | user = NV03_USER(channel); |
@@ -235,47 +237,6 @@ nouveau_channel_alloc(struct drm_device *dev, struct nouveau_channel **chan_ret, | |||
235 | return 0; | 237 | return 0; |
236 | } | 238 | } |
237 | 239 | ||
238 | int | ||
239 | nouveau_channel_idle(struct nouveau_channel *chan) | ||
240 | { | ||
241 | struct drm_device *dev = chan->dev; | ||
242 | struct drm_nouveau_private *dev_priv = dev->dev_private; | ||
243 | struct nouveau_engine *engine = &dev_priv->engine; | ||
244 | uint32_t caches; | ||
245 | int idle; | ||
246 | |||
247 | if (!chan) { | ||
248 | NV_ERROR(dev, "no channel...\n"); | ||
249 | return 1; | ||
250 | } | ||
251 | |||
252 | caches = nv_rd32(dev, NV03_PFIFO_CACHES); | ||
253 | nv_wr32(dev, NV03_PFIFO_CACHES, caches & ~1); | ||
254 | |||
255 | if (engine->fifo.channel_id(dev) != chan->id) { | ||
256 | struct nouveau_gpuobj *ramfc = | ||
257 | chan->ramfc ? chan->ramfc->gpuobj : NULL; | ||
258 | |||
259 | if (!ramfc) { | ||
260 | NV_ERROR(dev, "No RAMFC for channel %d\n", chan->id); | ||
261 | return 1; | ||
262 | } | ||
263 | |||
264 | engine->instmem.prepare_access(dev, false); | ||
265 | if (nv_ro32(dev, ramfc, 0) != nv_ro32(dev, ramfc, 1)) | ||
266 | idle = 0; | ||
267 | else | ||
268 | idle = 1; | ||
269 | engine->instmem.finish_access(dev); | ||
270 | } else { | ||
271 | idle = (nv_rd32(dev, NV04_PFIFO_CACHE1_DMA_GET) == | ||
272 | nv_rd32(dev, NV04_PFIFO_CACHE1_DMA_PUT)); | ||
273 | } | ||
274 | |||
275 | nv_wr32(dev, NV03_PFIFO_CACHES, caches); | ||
276 | return idle; | ||
277 | } | ||
278 | |||
279 | /* stops a fifo */ | 240 | /* stops a fifo */ |
280 | void | 241 | void |
281 | nouveau_channel_free(struct nouveau_channel *chan) | 242 | nouveau_channel_free(struct nouveau_channel *chan) |
@@ -414,7 +375,9 @@ nouveau_ioctl_fifo_alloc(struct drm_device *dev, void *data, | |||
414 | init->subchan[0].grclass = 0x0039; | 375 | init->subchan[0].grclass = 0x0039; |
415 | else | 376 | else |
416 | init->subchan[0].grclass = 0x5039; | 377 | init->subchan[0].grclass = 0x5039; |
417 | init->nr_subchan = 1; | 378 | init->subchan[1].handle = NvSw; |
379 | init->subchan[1].grclass = NV_SW; | ||
380 | init->nr_subchan = 2; | ||
418 | 381 | ||
419 | /* Named memory object area */ | 382 | /* Named memory object area */ |
420 | ret = drm_gem_handle_create(file_priv, chan->notifier_bo->gem, | 383 | ret = drm_gem_handle_create(file_priv, chan->notifier_bo->gem, |
diff --git a/drivers/gpu/drm/nouveau/nouveau_dma.c b/drivers/gpu/drm/nouveau/nouveau_dma.c index 703553687b20..7afbe8b40d51 100644 --- a/drivers/gpu/drm/nouveau/nouveau_dma.c +++ b/drivers/gpu/drm/nouveau/nouveau_dma.c | |||
@@ -29,12 +29,22 @@ | |||
29 | #include "nouveau_drv.h" | 29 | #include "nouveau_drv.h" |
30 | #include "nouveau_dma.h" | 30 | #include "nouveau_dma.h" |
31 | 31 | ||
32 | void | ||
33 | nouveau_dma_pre_init(struct nouveau_channel *chan) | ||
34 | { | ||
35 | chan->dma.max = (chan->pushbuf_bo->bo.mem.size >> 2) - 2; | ||
36 | chan->dma.put = 0; | ||
37 | chan->dma.cur = chan->dma.put; | ||
38 | chan->dma.free = chan->dma.max - chan->dma.cur; | ||
39 | } | ||
40 | |||
32 | int | 41 | int |
33 | nouveau_dma_init(struct nouveau_channel *chan) | 42 | nouveau_dma_init(struct nouveau_channel *chan) |
34 | { | 43 | { |
35 | struct drm_device *dev = chan->dev; | 44 | struct drm_device *dev = chan->dev; |
36 | struct drm_nouveau_private *dev_priv = dev->dev_private; | 45 | struct drm_nouveau_private *dev_priv = dev->dev_private; |
37 | struct nouveau_gpuobj *m2mf = NULL; | 46 | struct nouveau_gpuobj *m2mf = NULL; |
47 | struct nouveau_gpuobj *nvsw = NULL; | ||
38 | int ret, i; | 48 | int ret, i; |
39 | 49 | ||
40 | /* Create NV_MEMORY_TO_MEMORY_FORMAT for buffer moves */ | 50 | /* Create NV_MEMORY_TO_MEMORY_FORMAT for buffer moves */ |
@@ -47,6 +57,15 @@ nouveau_dma_init(struct nouveau_channel *chan) | |||
47 | if (ret) | 57 | if (ret) |
48 | return ret; | 58 | return ret; |
49 | 59 | ||
60 | /* Create an NV_SW object for various sync purposes */ | ||
61 | ret = nouveau_gpuobj_sw_new(chan, NV_SW, &nvsw); | ||
62 | if (ret) | ||
63 | return ret; | ||
64 | |||
65 | ret = nouveau_gpuobj_ref_add(dev, chan, NvSw, nvsw, NULL); | ||
66 | if (ret) | ||
67 | return ret; | ||
68 | |||
50 | /* NV_MEMORY_TO_MEMORY_FORMAT requires a notifier object */ | 69 | /* NV_MEMORY_TO_MEMORY_FORMAT requires a notifier object */ |
51 | ret = nouveau_notifier_alloc(chan, NvNotify0, 32, &chan->m2mf_ntfy); | 70 | ret = nouveau_notifier_alloc(chan, NvNotify0, 32, &chan->m2mf_ntfy); |
52 | if (ret) | 71 | if (ret) |
@@ -64,12 +83,6 @@ nouveau_dma_init(struct nouveau_channel *chan) | |||
64 | return ret; | 83 | return ret; |
65 | } | 84 | } |
66 | 85 | ||
67 | /* Initialise DMA vars */ | ||
68 | chan->dma.max = (chan->pushbuf_bo->bo.mem.size >> 2) - 2; | ||
69 | chan->dma.put = 0; | ||
70 | chan->dma.cur = chan->dma.put; | ||
71 | chan->dma.free = chan->dma.max - chan->dma.cur; | ||
72 | |||
73 | /* Insert NOPS for NOUVEAU_DMA_SKIPS */ | 86 | /* Insert NOPS for NOUVEAU_DMA_SKIPS */ |
74 | ret = RING_SPACE(chan, NOUVEAU_DMA_SKIPS); | 87 | ret = RING_SPACE(chan, NOUVEAU_DMA_SKIPS); |
75 | if (ret) | 88 | if (ret) |
@@ -87,6 +100,13 @@ nouveau_dma_init(struct nouveau_channel *chan) | |||
87 | BEGIN_RING(chan, NvSubM2MF, NV_MEMORY_TO_MEMORY_FORMAT_DMA_NOTIFY, 1); | 100 | BEGIN_RING(chan, NvSubM2MF, NV_MEMORY_TO_MEMORY_FORMAT_DMA_NOTIFY, 1); |
88 | OUT_RING(chan, NvNotify0); | 101 | OUT_RING(chan, NvNotify0); |
89 | 102 | ||
103 | /* Initialise NV_SW */ | ||
104 | ret = RING_SPACE(chan, 2); | ||
105 | if (ret) | ||
106 | return ret; | ||
107 | BEGIN_RING(chan, NvSubSw, 0, 1); | ||
108 | OUT_RING(chan, NvSw); | ||
109 | |||
90 | /* Sit back and pray the channel works.. */ | 110 | /* Sit back and pray the channel works.. */ |
91 | FIRE_RING(chan); | 111 | FIRE_RING(chan); |
92 | 112 | ||
@@ -113,7 +133,7 @@ READ_GET(struct nouveau_channel *chan, uint32_t *get) | |||
113 | 133 | ||
114 | val = nvchan_rd32(chan, chan->user_get); | 134 | val = nvchan_rd32(chan, chan->user_get); |
115 | if (val < chan->pushbuf_base || | 135 | if (val < chan->pushbuf_base || |
116 | val >= chan->pushbuf_base + chan->pushbuf_bo->bo.mem.size) { | 136 | val > chan->pushbuf_base + (chan->dma.max << 2)) { |
117 | /* meaningless to dma_wait() except to know whether the | 137 | /* meaningless to dma_wait() except to know whether the |
118 | * GPU has stalled or not | 138 | * GPU has stalled or not |
119 | */ | 139 | */ |
diff --git a/drivers/gpu/drm/nouveau/nouveau_dma.h b/drivers/gpu/drm/nouveau/nouveau_dma.h index 04e85d8f757e..dabfd655f93e 100644 --- a/drivers/gpu/drm/nouveau/nouveau_dma.h +++ b/drivers/gpu/drm/nouveau/nouveau_dma.h | |||
@@ -46,10 +46,11 @@ | |||
46 | /* Hardcoded object assignments to subchannels (subchannel id). */ | 46 | /* Hardcoded object assignments to subchannels (subchannel id). */ |
47 | enum { | 47 | enum { |
48 | NvSubM2MF = 0, | 48 | NvSubM2MF = 0, |
49 | NvSub2D = 1, | 49 | NvSubSw = 1, |
50 | NvSubCtxSurf2D = 1, | 50 | NvSub2D = 2, |
51 | NvSubGdiRect = 2, | 51 | NvSubCtxSurf2D = 2, |
52 | NvSubImageBlit = 3 | 52 | NvSubGdiRect = 3, |
53 | NvSubImageBlit = 4 | ||
53 | }; | 54 | }; |
54 | 55 | ||
55 | /* Object handles. */ | 56 | /* Object handles. */ |
@@ -67,6 +68,7 @@ enum { | |||
67 | NvClipRect = 0x8000000b, | 68 | NvClipRect = 0x8000000b, |
68 | NvGdiRect = 0x8000000c, | 69 | NvGdiRect = 0x8000000c, |
69 | NvImageBlit = 0x8000000d, | 70 | NvImageBlit = 0x8000000d, |
71 | NvSw = 0x8000000e, | ||
70 | 72 | ||
71 | /* G80+ display objects */ | 73 | /* G80+ display objects */ |
72 | NvEvoVRAM = 0x01000000, | 74 | NvEvoVRAM = 0x01000000, |
diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h index 5f8cbb79c499..026419fe8791 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drv.h +++ b/drivers/gpu/drm/nouveau/nouveau_drv.h | |||
@@ -59,11 +59,19 @@ struct nouveau_grctx; | |||
59 | #define MAX_NUM_DCB_ENTRIES 16 | 59 | #define MAX_NUM_DCB_ENTRIES 16 |
60 | 60 | ||
61 | #define NOUVEAU_MAX_CHANNEL_NR 128 | 61 | #define NOUVEAU_MAX_CHANNEL_NR 128 |
62 | #define NOUVEAU_MAX_TILE_NR 15 | ||
62 | 63 | ||
63 | #define NV50_VM_MAX_VRAM (2*1024*1024*1024ULL) | 64 | #define NV50_VM_MAX_VRAM (2*1024*1024*1024ULL) |
64 | #define NV50_VM_BLOCK (512*1024*1024ULL) | 65 | #define NV50_VM_BLOCK (512*1024*1024ULL) |
65 | #define NV50_VM_VRAM_NR (NV50_VM_MAX_VRAM / NV50_VM_BLOCK) | 66 | #define NV50_VM_VRAM_NR (NV50_VM_MAX_VRAM / NV50_VM_BLOCK) |
66 | 67 | ||
68 | struct nouveau_tile_reg { | ||
69 | struct nouveau_fence *fence; | ||
70 | uint32_t addr; | ||
71 | uint32_t size; | ||
72 | bool used; | ||
73 | }; | ||
74 | |||
67 | struct nouveau_bo { | 75 | struct nouveau_bo { |
68 | struct ttm_buffer_object bo; | 76 | struct ttm_buffer_object bo; |
69 | struct ttm_placement placement; | 77 | struct ttm_placement placement; |
@@ -83,6 +91,7 @@ struct nouveau_bo { | |||
83 | 91 | ||
84 | uint32_t tile_mode; | 92 | uint32_t tile_mode; |
85 | uint32_t tile_flags; | 93 | uint32_t tile_flags; |
94 | struct nouveau_tile_reg *tile; | ||
86 | 95 | ||
87 | struct drm_gem_object *gem; | 96 | struct drm_gem_object *gem; |
88 | struct drm_file *cpu_filp; | 97 | struct drm_file *cpu_filp; |
@@ -277,8 +286,13 @@ struct nouveau_timer_engine { | |||
277 | }; | 286 | }; |
278 | 287 | ||
279 | struct nouveau_fb_engine { | 288 | struct nouveau_fb_engine { |
289 | int num_tiles; | ||
290 | |||
280 | int (*init)(struct drm_device *dev); | 291 | int (*init)(struct drm_device *dev); |
281 | void (*takedown)(struct drm_device *dev); | 292 | void (*takedown)(struct drm_device *dev); |
293 | |||
294 | void (*set_region_tiling)(struct drm_device *dev, int i, uint32_t addr, | ||
295 | uint32_t size, uint32_t pitch); | ||
282 | }; | 296 | }; |
283 | 297 | ||
284 | struct nouveau_fifo_engine { | 298 | struct nouveau_fifo_engine { |
@@ -292,6 +306,8 @@ struct nouveau_fifo_engine { | |||
292 | void (*disable)(struct drm_device *); | 306 | void (*disable)(struct drm_device *); |
293 | void (*enable)(struct drm_device *); | 307 | void (*enable)(struct drm_device *); |
294 | bool (*reassign)(struct drm_device *, bool enable); | 308 | bool (*reassign)(struct drm_device *, bool enable); |
309 | bool (*cache_flush)(struct drm_device *dev); | ||
310 | bool (*cache_pull)(struct drm_device *dev, bool enable); | ||
295 | 311 | ||
296 | int (*channel_id)(struct drm_device *); | 312 | int (*channel_id)(struct drm_device *); |
297 | 313 | ||
@@ -330,6 +346,9 @@ struct nouveau_pgraph_engine { | |||
330 | void (*destroy_context)(struct nouveau_channel *); | 346 | void (*destroy_context)(struct nouveau_channel *); |
331 | int (*load_context)(struct nouveau_channel *); | 347 | int (*load_context)(struct nouveau_channel *); |
332 | int (*unload_context)(struct drm_device *); | 348 | int (*unload_context)(struct drm_device *); |
349 | |||
350 | void (*set_region_tiling)(struct drm_device *dev, int i, uint32_t addr, | ||
351 | uint32_t size, uint32_t pitch); | ||
333 | }; | 352 | }; |
334 | 353 | ||
335 | struct nouveau_engine { | 354 | struct nouveau_engine { |
@@ -548,6 +567,12 @@ struct drm_nouveau_private { | |||
548 | unsigned long sg_handle; | 567 | unsigned long sg_handle; |
549 | } gart_info; | 568 | } gart_info; |
550 | 569 | ||
570 | /* nv10-nv40 tiling regions */ | ||
571 | struct { | ||
572 | struct nouveau_tile_reg reg[NOUVEAU_MAX_TILE_NR]; | ||
573 | spinlock_t lock; | ||
574 | } tile; | ||
575 | |||
551 | /* G8x/G9x virtual address space */ | 576 | /* G8x/G9x virtual address space */ |
552 | uint64_t vm_gart_base; | 577 | uint64_t vm_gart_base; |
553 | uint64_t vm_gart_size; | 578 | uint64_t vm_gart_size; |
@@ -685,6 +710,13 @@ extern void nouveau_mem_release(struct drm_file *, struct mem_block *heap); | |||
685 | extern int nouveau_mem_init(struct drm_device *); | 710 | extern int nouveau_mem_init(struct drm_device *); |
686 | extern int nouveau_mem_init_agp(struct drm_device *); | 711 | extern int nouveau_mem_init_agp(struct drm_device *); |
687 | extern void nouveau_mem_close(struct drm_device *); | 712 | extern void nouveau_mem_close(struct drm_device *); |
713 | extern struct nouveau_tile_reg *nv10_mem_set_tiling(struct drm_device *dev, | ||
714 | uint32_t addr, | ||
715 | uint32_t size, | ||
716 | uint32_t pitch); | ||
717 | extern void nv10_mem_expire_tiling(struct drm_device *dev, | ||
718 | struct nouveau_tile_reg *tile, | ||
719 | struct nouveau_fence *fence); | ||
688 | extern int nv50_mem_vm_bind_linear(struct drm_device *, uint64_t virt, | 720 | extern int nv50_mem_vm_bind_linear(struct drm_device *, uint64_t virt, |
689 | uint32_t size, uint32_t flags, | 721 | uint32_t size, uint32_t flags, |
690 | uint64_t phys); | 722 | uint64_t phys); |
@@ -713,7 +745,6 @@ extern int nouveau_channel_alloc(struct drm_device *dev, | |||
713 | struct drm_file *file_priv, | 745 | struct drm_file *file_priv, |
714 | uint32_t fb_ctxdma, uint32_t tt_ctxdma); | 746 | uint32_t fb_ctxdma, uint32_t tt_ctxdma); |
715 | extern void nouveau_channel_free(struct nouveau_channel *); | 747 | extern void nouveau_channel_free(struct nouveau_channel *); |
716 | extern int nouveau_channel_idle(struct nouveau_channel *chan); | ||
717 | 748 | ||
718 | /* nouveau_object.c */ | 749 | /* nouveau_object.c */ |
719 | extern int nouveau_gpuobj_early_init(struct drm_device *); | 750 | extern int nouveau_gpuobj_early_init(struct drm_device *); |
@@ -756,6 +787,8 @@ extern int nouveau_gpuobj_gart_dma_new(struct nouveau_channel *, | |||
756 | uint32_t *o_ret); | 787 | uint32_t *o_ret); |
757 | extern int nouveau_gpuobj_gr_new(struct nouveau_channel *, int class, | 788 | extern int nouveau_gpuobj_gr_new(struct nouveau_channel *, int class, |
758 | struct nouveau_gpuobj **); | 789 | struct nouveau_gpuobj **); |
790 | extern int nouveau_gpuobj_sw_new(struct nouveau_channel *, int class, | ||
791 | struct nouveau_gpuobj **); | ||
759 | extern int nouveau_ioctl_grobj_alloc(struct drm_device *, void *data, | 792 | extern int nouveau_ioctl_grobj_alloc(struct drm_device *, void *data, |
760 | struct drm_file *); | 793 | struct drm_file *); |
761 | extern int nouveau_ioctl_gpuobj_free(struct drm_device *, void *data, | 794 | extern int nouveau_ioctl_gpuobj_free(struct drm_device *, void *data, |
@@ -804,6 +837,7 @@ nouveau_debugfs_channel_fini(struct nouveau_channel *chan) | |||
804 | #endif | 837 | #endif |
805 | 838 | ||
806 | /* nouveau_dma.c */ | 839 | /* nouveau_dma.c */ |
840 | extern void nouveau_dma_pre_init(struct nouveau_channel *); | ||
807 | extern int nouveau_dma_init(struct nouveau_channel *); | 841 | extern int nouveau_dma_init(struct nouveau_channel *); |
808 | extern int nouveau_dma_wait(struct nouveau_channel *, int size); | 842 | extern int nouveau_dma_wait(struct nouveau_channel *, int size); |
809 | 843 | ||
@@ -879,16 +913,22 @@ extern void nv04_fb_takedown(struct drm_device *); | |||
879 | /* nv10_fb.c */ | 913 | /* nv10_fb.c */ |
880 | extern int nv10_fb_init(struct drm_device *); | 914 | extern int nv10_fb_init(struct drm_device *); |
881 | extern void nv10_fb_takedown(struct drm_device *); | 915 | extern void nv10_fb_takedown(struct drm_device *); |
916 | extern void nv10_fb_set_region_tiling(struct drm_device *, int, uint32_t, | ||
917 | uint32_t, uint32_t); | ||
882 | 918 | ||
883 | /* nv40_fb.c */ | 919 | /* nv40_fb.c */ |
884 | extern int nv40_fb_init(struct drm_device *); | 920 | extern int nv40_fb_init(struct drm_device *); |
885 | extern void nv40_fb_takedown(struct drm_device *); | 921 | extern void nv40_fb_takedown(struct drm_device *); |
922 | extern void nv40_fb_set_region_tiling(struct drm_device *, int, uint32_t, | ||
923 | uint32_t, uint32_t); | ||
886 | 924 | ||
887 | /* nv04_fifo.c */ | 925 | /* nv04_fifo.c */ |
888 | extern int nv04_fifo_init(struct drm_device *); | 926 | extern int nv04_fifo_init(struct drm_device *); |
889 | extern void nv04_fifo_disable(struct drm_device *); | 927 | extern void nv04_fifo_disable(struct drm_device *); |
890 | extern void nv04_fifo_enable(struct drm_device *); | 928 | extern void nv04_fifo_enable(struct drm_device *); |
891 | extern bool nv04_fifo_reassign(struct drm_device *, bool); | 929 | extern bool nv04_fifo_reassign(struct drm_device *, bool); |
930 | extern bool nv04_fifo_cache_flush(struct drm_device *); | ||
931 | extern bool nv04_fifo_cache_pull(struct drm_device *, bool); | ||
892 | extern int nv04_fifo_channel_id(struct drm_device *); | 932 | extern int nv04_fifo_channel_id(struct drm_device *); |
893 | extern int nv04_fifo_create_context(struct nouveau_channel *); | 933 | extern int nv04_fifo_create_context(struct nouveau_channel *); |
894 | extern void nv04_fifo_destroy_context(struct nouveau_channel *); | 934 | extern void nv04_fifo_destroy_context(struct nouveau_channel *); |
@@ -941,6 +981,8 @@ extern void nv10_graph_destroy_context(struct nouveau_channel *); | |||
941 | extern int nv10_graph_load_context(struct nouveau_channel *); | 981 | extern int nv10_graph_load_context(struct nouveau_channel *); |
942 | extern int nv10_graph_unload_context(struct drm_device *); | 982 | extern int nv10_graph_unload_context(struct drm_device *); |
943 | extern void nv10_graph_context_switch(struct drm_device *); | 983 | extern void nv10_graph_context_switch(struct drm_device *); |
984 | extern void nv10_graph_set_region_tiling(struct drm_device *, int, uint32_t, | ||
985 | uint32_t, uint32_t); | ||
944 | 986 | ||
945 | /* nv20_graph.c */ | 987 | /* nv20_graph.c */ |
946 | extern struct nouveau_pgraph_object_class nv20_graph_grclass[]; | 988 | extern struct nouveau_pgraph_object_class nv20_graph_grclass[]; |
@@ -952,6 +994,8 @@ extern int nv20_graph_unload_context(struct drm_device *); | |||
952 | extern int nv20_graph_init(struct drm_device *); | 994 | extern int nv20_graph_init(struct drm_device *); |
953 | extern void nv20_graph_takedown(struct drm_device *); | 995 | extern void nv20_graph_takedown(struct drm_device *); |
954 | extern int nv30_graph_init(struct drm_device *); | 996 | extern int nv30_graph_init(struct drm_device *); |
997 | extern void nv20_graph_set_region_tiling(struct drm_device *, int, uint32_t, | ||
998 | uint32_t, uint32_t); | ||
955 | 999 | ||
956 | /* nv40_graph.c */ | 1000 | /* nv40_graph.c */ |
957 | extern struct nouveau_pgraph_object_class nv40_graph_grclass[]; | 1001 | extern struct nouveau_pgraph_object_class nv40_graph_grclass[]; |
@@ -963,6 +1007,8 @@ extern void nv40_graph_destroy_context(struct nouveau_channel *); | |||
963 | extern int nv40_graph_load_context(struct nouveau_channel *); | 1007 | extern int nv40_graph_load_context(struct nouveau_channel *); |
964 | extern int nv40_graph_unload_context(struct drm_device *); | 1008 | extern int nv40_graph_unload_context(struct drm_device *); |
965 | extern void nv40_grctx_init(struct nouveau_grctx *); | 1009 | extern void nv40_grctx_init(struct nouveau_grctx *); |
1010 | extern void nv40_graph_set_region_tiling(struct drm_device *, int, uint32_t, | ||
1011 | uint32_t, uint32_t); | ||
966 | 1012 | ||
967 | /* nv50_graph.c */ | 1013 | /* nv50_graph.c */ |
968 | extern struct nouveau_pgraph_object_class nv50_graph_grclass[]; | 1014 | extern struct nouveau_pgraph_object_class nv50_graph_grclass[]; |
@@ -1030,8 +1076,7 @@ extern long nouveau_compat_ioctl(struct file *file, unsigned int cmd, | |||
1030 | 1076 | ||
1031 | /* nv04_dac.c */ | 1077 | /* nv04_dac.c */ |
1032 | extern int nv04_dac_create(struct drm_device *dev, struct dcb_entry *entry); | 1078 | extern int nv04_dac_create(struct drm_device *dev, struct dcb_entry *entry); |
1033 | extern enum drm_connector_status nv17_dac_detect(struct drm_encoder *encoder, | 1079 | extern uint32_t nv17_dac_sample_load(struct drm_encoder *encoder); |
1034 | struct drm_connector *connector); | ||
1035 | extern int nv04_dac_output_offset(struct drm_encoder *encoder); | 1080 | extern int nv04_dac_output_offset(struct drm_encoder *encoder); |
1036 | extern void nv04_dac_update_dacclk(struct drm_encoder *encoder, bool enable); | 1081 | extern void nv04_dac_update_dacclk(struct drm_encoder *encoder, bool enable); |
1037 | 1082 | ||
@@ -1049,9 +1094,6 @@ extern int nv04_tv_create(struct drm_device *dev, struct dcb_entry *entry); | |||
1049 | 1094 | ||
1050 | /* nv17_tv.c */ | 1095 | /* nv17_tv.c */ |
1051 | extern int nv17_tv_create(struct drm_device *dev, struct dcb_entry *entry); | 1096 | extern int nv17_tv_create(struct drm_device *dev, struct dcb_entry *entry); |
1052 | extern enum drm_connector_status nv17_tv_detect(struct drm_encoder *encoder, | ||
1053 | struct drm_connector *connector, | ||
1054 | uint32_t pin_mask); | ||
1055 | 1097 | ||
1056 | /* nv04_display.c */ | 1098 | /* nv04_display.c */ |
1057 | extern int nv04_display_create(struct drm_device *); | 1099 | extern int nv04_display_create(struct drm_device *); |
@@ -1290,14 +1332,14 @@ nv_two_reg_pll(struct drm_device *dev) | |||
1290 | return false; | 1332 | return false; |
1291 | } | 1333 | } |
1292 | 1334 | ||
1293 | #define NV50_NVSW 0x0000506e | 1335 | #define NV_SW 0x0000506e |
1294 | #define NV50_NVSW_DMA_SEMAPHORE 0x00000060 | 1336 | #define NV_SW_DMA_SEMAPHORE 0x00000060 |
1295 | #define NV50_NVSW_SEMAPHORE_OFFSET 0x00000064 | 1337 | #define NV_SW_SEMAPHORE_OFFSET 0x00000064 |
1296 | #define NV50_NVSW_SEMAPHORE_ACQUIRE 0x00000068 | 1338 | #define NV_SW_SEMAPHORE_ACQUIRE 0x00000068 |
1297 | #define NV50_NVSW_SEMAPHORE_RELEASE 0x0000006c | 1339 | #define NV_SW_SEMAPHORE_RELEASE 0x0000006c |
1298 | #define NV50_NVSW_DMA_VBLSEM 0x0000018c | 1340 | #define NV_SW_DMA_VBLSEM 0x0000018c |
1299 | #define NV50_NVSW_VBLSEM_OFFSET 0x00000400 | 1341 | #define NV_SW_VBLSEM_OFFSET 0x00000400 |
1300 | #define NV50_NVSW_VBLSEM_RELEASE_VALUE 0x00000404 | 1342 | #define NV_SW_VBLSEM_RELEASE_VALUE 0x00000404 |
1301 | #define NV50_NVSW_VBLSEM_RELEASE 0x00000408 | 1343 | #define NV_SW_VBLSEM_RELEASE 0x00000408 |
1302 | 1344 | ||
1303 | #endif /* __NOUVEAU_DRV_H__ */ | 1345 | #endif /* __NOUVEAU_DRV_H__ */ |
diff --git a/drivers/gpu/drm/nouveau/nouveau_fbcon.c b/drivers/gpu/drm/nouveau/nouveau_fbcon.c index 84af25c238b6..0b05c869e0e7 100644 --- a/drivers/gpu/drm/nouveau/nouveau_fbcon.c +++ b/drivers/gpu/drm/nouveau/nouveau_fbcon.c | |||
@@ -64,8 +64,7 @@ nouveau_fbcon_sync(struct fb_info *info) | |||
64 | return 0; | 64 | return 0; |
65 | 65 | ||
66 | if (RING_SPACE(chan, 4)) { | 66 | if (RING_SPACE(chan, 4)) { |
67 | NV_ERROR(dev, "GPU lockup - switching to software fbcon\n"); | 67 | nouveau_fbcon_gpu_lockup(info); |
68 | info->flags |= FBINFO_HWACCEL_DISABLED; | ||
69 | return 0; | 68 | return 0; |
70 | } | 69 | } |
71 | 70 | ||
@@ -86,8 +85,7 @@ nouveau_fbcon_sync(struct fb_info *info) | |||
86 | } | 85 | } |
87 | 86 | ||
88 | if (ret) { | 87 | if (ret) { |
89 | NV_ERROR(dev, "GPU lockup - switching to software fbcon\n"); | 88 | nouveau_fbcon_gpu_lockup(info); |
90 | info->flags |= FBINFO_HWACCEL_DISABLED; | ||
91 | return 0; | 89 | return 0; |
92 | } | 90 | } |
93 | 91 | ||
@@ -212,11 +210,11 @@ nouveau_fbcon_create(struct drm_device *dev, uint32_t fb_width, | |||
212 | 210 | ||
213 | mode_cmd.bpp = surface_bpp; | 211 | mode_cmd.bpp = surface_bpp; |
214 | mode_cmd.pitch = mode_cmd.width * (mode_cmd.bpp >> 3); | 212 | mode_cmd.pitch = mode_cmd.width * (mode_cmd.bpp >> 3); |
215 | mode_cmd.pitch = ALIGN(mode_cmd.pitch, 256); | 213 | mode_cmd.pitch = roundup(mode_cmd.pitch, 256); |
216 | mode_cmd.depth = surface_depth; | 214 | mode_cmd.depth = surface_depth; |
217 | 215 | ||
218 | size = mode_cmd.pitch * mode_cmd.height; | 216 | size = mode_cmd.pitch * mode_cmd.height; |
219 | size = ALIGN(size, PAGE_SIZE); | 217 | size = roundup(size, PAGE_SIZE); |
220 | 218 | ||
221 | ret = nouveau_gem_new(dev, dev_priv->channel, size, 0, TTM_PL_FLAG_VRAM, | 219 | ret = nouveau_gem_new(dev, dev_priv->channel, size, 0, TTM_PL_FLAG_VRAM, |
222 | 0, 0x0000, false, true, &nvbo); | 220 | 0, 0x0000, false, true, &nvbo); |
@@ -380,3 +378,12 @@ nouveau_fbcon_remove(struct drm_device *dev, struct drm_framebuffer *fb) | |||
380 | 378 | ||
381 | return 0; | 379 | return 0; |
382 | } | 380 | } |
381 | |||
382 | void nouveau_fbcon_gpu_lockup(struct fb_info *info) | ||
383 | { | ||
384 | struct nouveau_fbcon_par *par = info->par; | ||
385 | struct drm_device *dev = par->dev; | ||
386 | |||
387 | NV_ERROR(dev, "GPU lockup - switching to software fbcon\n"); | ||
388 | info->flags |= FBINFO_HWACCEL_DISABLED; | ||
389 | } | ||
diff --git a/drivers/gpu/drm/nouveau/nouveau_fbcon.h b/drivers/gpu/drm/nouveau/nouveau_fbcon.h index 8531140fedbc..462e0b87b4bd 100644 --- a/drivers/gpu/drm/nouveau/nouveau_fbcon.h +++ b/drivers/gpu/drm/nouveau/nouveau_fbcon.h | |||
@@ -43,5 +43,6 @@ void nouveau_fbcon_zfill(struct drm_device *dev); | |||
43 | int nv04_fbcon_accel_init(struct fb_info *info); | 43 | int nv04_fbcon_accel_init(struct fb_info *info); |
44 | int nv50_fbcon_accel_init(struct fb_info *info); | 44 | int nv50_fbcon_accel_init(struct fb_info *info); |
45 | 45 | ||
46 | void nouveau_fbcon_gpu_lockup(struct fb_info *info); | ||
46 | #endif /* __NV50_FBCON_H__ */ | 47 | #endif /* __NV50_FBCON_H__ */ |
47 | 48 | ||
diff --git a/drivers/gpu/drm/nouveau/nouveau_fence.c b/drivers/gpu/drm/nouveau/nouveau_fence.c index dacac9a0842a..faddf53ff9ed 100644 --- a/drivers/gpu/drm/nouveau/nouveau_fence.c +++ b/drivers/gpu/drm/nouveau/nouveau_fence.c | |||
@@ -142,7 +142,7 @@ nouveau_fence_emit(struct nouveau_fence *fence) | |||
142 | list_add_tail(&fence->entry, &chan->fence.pending); | 142 | list_add_tail(&fence->entry, &chan->fence.pending); |
143 | spin_unlock_irqrestore(&chan->fence.lock, flags); | 143 | spin_unlock_irqrestore(&chan->fence.lock, flags); |
144 | 144 | ||
145 | BEGIN_RING(chan, NvSubM2MF, USE_REFCNT ? 0x0050 : 0x0150, 1); | 145 | BEGIN_RING(chan, NvSubSw, USE_REFCNT ? 0x0050 : 0x0150, 1); |
146 | OUT_RING(chan, fence->sequence); | 146 | OUT_RING(chan, fence->sequence); |
147 | FIRE_RING(chan); | 147 | FIRE_RING(chan); |
148 | 148 | ||
diff --git a/drivers/gpu/drm/nouveau/nouveau_gem.c b/drivers/gpu/drm/nouveau/nouveau_gem.c index 18fd8ac9fca7..2009db2426c3 100644 --- a/drivers/gpu/drm/nouveau/nouveau_gem.c +++ b/drivers/gpu/drm/nouveau/nouveau_gem.c | |||
@@ -220,7 +220,6 @@ nouveau_gem_set_domain(struct drm_gem_object *gem, uint32_t read_domains, | |||
220 | } | 220 | } |
221 | 221 | ||
222 | struct validate_op { | 222 | struct validate_op { |
223 | struct nouveau_fence *fence; | ||
224 | struct list_head vram_list; | 223 | struct list_head vram_list; |
225 | struct list_head gart_list; | 224 | struct list_head gart_list; |
226 | struct list_head both_list; | 225 | struct list_head both_list; |
@@ -252,17 +251,11 @@ validate_fini_list(struct list_head *list, struct nouveau_fence *fence) | |||
252 | } | 251 | } |
253 | 252 | ||
254 | static void | 253 | static void |
255 | validate_fini(struct validate_op *op, bool success) | 254 | validate_fini(struct validate_op *op, struct nouveau_fence* fence) |
256 | { | 255 | { |
257 | struct nouveau_fence *fence = op->fence; | 256 | validate_fini_list(&op->vram_list, fence); |
258 | 257 | validate_fini_list(&op->gart_list, fence); | |
259 | if (unlikely(!success)) | 258 | validate_fini_list(&op->both_list, fence); |
260 | op->fence = NULL; | ||
261 | |||
262 | validate_fini_list(&op->vram_list, op->fence); | ||
263 | validate_fini_list(&op->gart_list, op->fence); | ||
264 | validate_fini_list(&op->both_list, op->fence); | ||
265 | nouveau_fence_unref((void *)&fence); | ||
266 | } | 259 | } |
267 | 260 | ||
268 | static int | 261 | static int |
@@ -420,10 +413,6 @@ nouveau_gem_pushbuf_validate(struct nouveau_channel *chan, | |||
420 | INIT_LIST_HEAD(&op->gart_list); | 413 | INIT_LIST_HEAD(&op->gart_list); |
421 | INIT_LIST_HEAD(&op->both_list); | 414 | INIT_LIST_HEAD(&op->both_list); |
422 | 415 | ||
423 | ret = nouveau_fence_new(chan, &op->fence, false); | ||
424 | if (ret) | ||
425 | return ret; | ||
426 | |||
427 | if (nr_buffers == 0) | 416 | if (nr_buffers == 0) |
428 | return 0; | 417 | return 0; |
429 | 418 | ||
@@ -541,6 +530,7 @@ nouveau_gem_ioctl_pushbuf(struct drm_device *dev, void *data, | |||
541 | struct drm_nouveau_gem_pushbuf_bo *bo = NULL; | 530 | struct drm_nouveau_gem_pushbuf_bo *bo = NULL; |
542 | struct nouveau_channel *chan; | 531 | struct nouveau_channel *chan; |
543 | struct validate_op op; | 532 | struct validate_op op; |
533 | struct nouveau_fence* fence = 0; | ||
544 | uint32_t *pushbuf = NULL; | 534 | uint32_t *pushbuf = NULL; |
545 | int ret = 0, do_reloc = 0, i; | 535 | int ret = 0, do_reloc = 0, i; |
546 | 536 | ||
@@ -597,7 +587,7 @@ nouveau_gem_ioctl_pushbuf(struct drm_device *dev, void *data, | |||
597 | 587 | ||
598 | OUT_RINGp(chan, pushbuf, req->nr_dwords); | 588 | OUT_RINGp(chan, pushbuf, req->nr_dwords); |
599 | 589 | ||
600 | ret = nouveau_fence_emit(op.fence); | 590 | ret = nouveau_fence_new(chan, &fence, true); |
601 | if (ret) { | 591 | if (ret) { |
602 | NV_ERROR(dev, "error fencing pushbuf: %d\n", ret); | 592 | NV_ERROR(dev, "error fencing pushbuf: %d\n", ret); |
603 | WIND_RING(chan); | 593 | WIND_RING(chan); |
@@ -605,7 +595,7 @@ nouveau_gem_ioctl_pushbuf(struct drm_device *dev, void *data, | |||
605 | } | 595 | } |
606 | 596 | ||
607 | if (nouveau_gem_pushbuf_sync(chan)) { | 597 | if (nouveau_gem_pushbuf_sync(chan)) { |
608 | ret = nouveau_fence_wait(op.fence, NULL, false, false); | 598 | ret = nouveau_fence_wait(fence, NULL, false, false); |
609 | if (ret) { | 599 | if (ret) { |
610 | for (i = 0; i < req->nr_dwords; i++) | 600 | for (i = 0; i < req->nr_dwords; i++) |
611 | NV_ERROR(dev, "0x%08x\n", pushbuf[i]); | 601 | NV_ERROR(dev, "0x%08x\n", pushbuf[i]); |
@@ -614,7 +604,8 @@ nouveau_gem_ioctl_pushbuf(struct drm_device *dev, void *data, | |||
614 | } | 604 | } |
615 | 605 | ||
616 | out: | 606 | out: |
617 | validate_fini(&op, ret == 0); | 607 | validate_fini(&op, fence); |
608 | nouveau_fence_unref((void**)&fence); | ||
618 | mutex_unlock(&dev->struct_mutex); | 609 | mutex_unlock(&dev->struct_mutex); |
619 | kfree(pushbuf); | 610 | kfree(pushbuf); |
620 | kfree(bo); | 611 | kfree(bo); |
@@ -634,6 +625,7 @@ nouveau_gem_ioctl_pushbuf_call(struct drm_device *dev, void *data, | |||
634 | struct drm_gem_object *gem; | 625 | struct drm_gem_object *gem; |
635 | struct nouveau_bo *pbbo; | 626 | struct nouveau_bo *pbbo; |
636 | struct validate_op op; | 627 | struct validate_op op; |
628 | struct nouveau_fence* fence = 0; | ||
637 | int i, ret = 0, do_reloc = 0; | 629 | int i, ret = 0, do_reloc = 0; |
638 | 630 | ||
639 | NOUVEAU_CHECK_INITIALISED_WITH_RETURN; | 631 | NOUVEAU_CHECK_INITIALISED_WITH_RETURN; |
@@ -772,7 +764,7 @@ nouveau_gem_ioctl_pushbuf_call(struct drm_device *dev, void *data, | |||
772 | OUT_RING(chan, 0); | 764 | OUT_RING(chan, 0); |
773 | } | 765 | } |
774 | 766 | ||
775 | ret = nouveau_fence_emit(op.fence); | 767 | ret = nouveau_fence_new(chan, &fence, true); |
776 | if (ret) { | 768 | if (ret) { |
777 | NV_ERROR(dev, "error fencing pushbuf: %d\n", ret); | 769 | NV_ERROR(dev, "error fencing pushbuf: %d\n", ret); |
778 | WIND_RING(chan); | 770 | WIND_RING(chan); |
@@ -780,7 +772,8 @@ nouveau_gem_ioctl_pushbuf_call(struct drm_device *dev, void *data, | |||
780 | } | 772 | } |
781 | 773 | ||
782 | out: | 774 | out: |
783 | validate_fini(&op, ret == 0); | 775 | validate_fini(&op, fence); |
776 | nouveau_fence_unref((void**)&fence); | ||
784 | mutex_unlock(&dev->struct_mutex); | 777 | mutex_unlock(&dev->struct_mutex); |
785 | kfree(bo); | 778 | kfree(bo); |
786 | 779 | ||
diff --git a/drivers/gpu/drm/nouveau/nouveau_irq.c b/drivers/gpu/drm/nouveau/nouveau_irq.c index 370c72c968d1..919a619ca7fa 100644 --- a/drivers/gpu/drm/nouveau/nouveau_irq.c +++ b/drivers/gpu/drm/nouveau/nouveau_irq.c | |||
@@ -635,6 +635,7 @@ nv50_pgraph_irq_handler(struct drm_device *dev) | |||
635 | 635 | ||
636 | if ((nv_rd32(dev, 0x400500) & isb) != isb) | 636 | if ((nv_rd32(dev, 0x400500) & isb) != isb) |
637 | nv_wr32(dev, 0x400500, nv_rd32(dev, 0x400500) | isb); | 637 | nv_wr32(dev, 0x400500, nv_rd32(dev, 0x400500) | isb); |
638 | nv_wr32(dev, 0x400824, nv_rd32(dev, 0x400824) & ~(1 << 31)); | ||
638 | } | 639 | } |
639 | 640 | ||
640 | nv_wr32(dev, NV03_PMC_INTR_0, NV_PMC_INTR_0_PGRAPH_PENDING); | 641 | nv_wr32(dev, NV03_PMC_INTR_0, NV_PMC_INTR_0_PGRAPH_PENDING); |
diff --git a/drivers/gpu/drm/nouveau/nouveau_mem.c b/drivers/gpu/drm/nouveau/nouveau_mem.c index 5158a12f7844..fb9bdd6edf1f 100644 --- a/drivers/gpu/drm/nouveau/nouveau_mem.c +++ b/drivers/gpu/drm/nouveau/nouveau_mem.c | |||
@@ -192,6 +192,92 @@ void nouveau_mem_release(struct drm_file *file_priv, struct mem_block *heap) | |||
192 | } | 192 | } |
193 | 193 | ||
194 | /* | 194 | /* |
195 | * NV10-NV40 tiling helpers | ||
196 | */ | ||
197 | |||
198 | static void | ||
199 | nv10_mem_set_region_tiling(struct drm_device *dev, int i, uint32_t addr, | ||
200 | uint32_t size, uint32_t pitch) | ||
201 | { | ||
202 | struct drm_nouveau_private *dev_priv = dev->dev_private; | ||
203 | struct nouveau_fifo_engine *pfifo = &dev_priv->engine.fifo; | ||
204 | struct nouveau_fb_engine *pfb = &dev_priv->engine.fb; | ||
205 | struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph; | ||
206 | struct nouveau_tile_reg *tile = &dev_priv->tile.reg[i]; | ||
207 | |||
208 | tile->addr = addr; | ||
209 | tile->size = size; | ||
210 | tile->used = !!pitch; | ||
211 | nouveau_fence_unref((void **)&tile->fence); | ||
212 | |||
213 | if (!pfifo->cache_flush(dev)) | ||
214 | return; | ||
215 | |||
216 | pfifo->reassign(dev, false); | ||
217 | pfifo->cache_flush(dev); | ||
218 | pfifo->cache_pull(dev, false); | ||
219 | |||
220 | nouveau_wait_for_idle(dev); | ||
221 | |||
222 | pgraph->set_region_tiling(dev, i, addr, size, pitch); | ||
223 | pfb->set_region_tiling(dev, i, addr, size, pitch); | ||
224 | |||
225 | pfifo->cache_pull(dev, true); | ||
226 | pfifo->reassign(dev, true); | ||
227 | } | ||
228 | |||
229 | struct nouveau_tile_reg * | ||
230 | nv10_mem_set_tiling(struct drm_device *dev, uint32_t addr, uint32_t size, | ||
231 | uint32_t pitch) | ||
232 | { | ||
233 | struct drm_nouveau_private *dev_priv = dev->dev_private; | ||
234 | struct nouveau_fb_engine *pfb = &dev_priv->engine.fb; | ||
235 | struct nouveau_tile_reg *tile = dev_priv->tile.reg, *found = NULL; | ||
236 | int i; | ||
237 | |||
238 | spin_lock(&dev_priv->tile.lock); | ||
239 | |||
240 | for (i = 0; i < pfb->num_tiles; i++) { | ||
241 | if (tile[i].used) | ||
242 | /* Tile region in use. */ | ||
243 | continue; | ||
244 | |||
245 | if (tile[i].fence && | ||
246 | !nouveau_fence_signalled(tile[i].fence, NULL)) | ||
247 | /* Pending tile region. */ | ||
248 | continue; | ||
249 | |||
250 | if (max(tile[i].addr, addr) < | ||
251 | min(tile[i].addr + tile[i].size, addr + size)) | ||
252 | /* Kill an intersecting tile region. */ | ||
253 | nv10_mem_set_region_tiling(dev, i, 0, 0, 0); | ||
254 | |||
255 | if (pitch && !found) { | ||
256 | /* Free tile region. */ | ||
257 | nv10_mem_set_region_tiling(dev, i, addr, size, pitch); | ||
258 | found = &tile[i]; | ||
259 | } | ||
260 | } | ||
261 | |||
262 | spin_unlock(&dev_priv->tile.lock); | ||
263 | |||
264 | return found; | ||
265 | } | ||
266 | |||
267 | void | ||
268 | nv10_mem_expire_tiling(struct drm_device *dev, struct nouveau_tile_reg *tile, | ||
269 | struct nouveau_fence *fence) | ||
270 | { | ||
271 | if (fence) { | ||
272 | /* Mark it as pending. */ | ||
273 | tile->fence = fence; | ||
274 | nouveau_fence_ref(fence); | ||
275 | } | ||
276 | |||
277 | tile->used = false; | ||
278 | } | ||
279 | |||
280 | /* | ||
195 | * NV50 VM helpers | 281 | * NV50 VM helpers |
196 | */ | 282 | */ |
197 | int | 283 | int |
@@ -513,6 +599,7 @@ nouveau_mem_init(struct drm_device *dev) | |||
513 | 599 | ||
514 | INIT_LIST_HEAD(&dev_priv->ttm.bo_list); | 600 | INIT_LIST_HEAD(&dev_priv->ttm.bo_list); |
515 | spin_lock_init(&dev_priv->ttm.bo_list_lock); | 601 | spin_lock_init(&dev_priv->ttm.bo_list_lock); |
602 | spin_lock_init(&dev_priv->tile.lock); | ||
516 | 603 | ||
517 | dev_priv->fb_available_size = nouveau_mem_fb_amount(dev); | 604 | dev_priv->fb_available_size = nouveau_mem_fb_amount(dev); |
518 | 605 | ||
diff --git a/drivers/gpu/drm/nouveau/nouveau_object.c b/drivers/gpu/drm/nouveau/nouveau_object.c index 93379bb81bea..6c2cf81716df 100644 --- a/drivers/gpu/drm/nouveau/nouveau_object.c +++ b/drivers/gpu/drm/nouveau/nouveau_object.c | |||
@@ -881,7 +881,7 @@ nouveau_gpuobj_gr_new(struct nouveau_channel *chan, int class, | |||
881 | return 0; | 881 | return 0; |
882 | } | 882 | } |
883 | 883 | ||
884 | static int | 884 | int |
885 | nouveau_gpuobj_sw_new(struct nouveau_channel *chan, int class, | 885 | nouveau_gpuobj_sw_new(struct nouveau_channel *chan, int class, |
886 | struct nouveau_gpuobj **gpuobj_ret) | 886 | struct nouveau_gpuobj **gpuobj_ret) |
887 | { | 887 | { |
diff --git a/drivers/gpu/drm/nouveau/nouveau_reg.h b/drivers/gpu/drm/nouveau/nouveau_reg.h index fa1b0e7165b9..251f1b3b38b9 100644 --- a/drivers/gpu/drm/nouveau/nouveau_reg.h +++ b/drivers/gpu/drm/nouveau/nouveau_reg.h | |||
@@ -349,19 +349,19 @@ | |||
349 | #define NV04_PGRAPH_BLEND 0x00400824 | 349 | #define NV04_PGRAPH_BLEND 0x00400824 |
350 | #define NV04_PGRAPH_STORED_FMT 0x00400830 | 350 | #define NV04_PGRAPH_STORED_FMT 0x00400830 |
351 | #define NV04_PGRAPH_PATT_COLORRAM 0x00400900 | 351 | #define NV04_PGRAPH_PATT_COLORRAM 0x00400900 |
352 | #define NV40_PGRAPH_TILE0(i) (0x00400900 + (i*16)) | 352 | #define NV20_PGRAPH_TILE(i) (0x00400900 + (i*16)) |
353 | #define NV40_PGRAPH_TLIMIT0(i) (0x00400904 + (i*16)) | 353 | #define NV20_PGRAPH_TLIMIT(i) (0x00400904 + (i*16)) |
354 | #define NV40_PGRAPH_TSIZE0(i) (0x00400908 + (i*16)) | 354 | #define NV20_PGRAPH_TSIZE(i) (0x00400908 + (i*16)) |
355 | #define NV40_PGRAPH_TSTATUS0(i) (0x0040090C + (i*16)) | 355 | #define NV20_PGRAPH_TSTATUS(i) (0x0040090C + (i*16)) |
356 | #define NV10_PGRAPH_TILE(i) (0x00400B00 + (i*16)) | 356 | #define NV10_PGRAPH_TILE(i) (0x00400B00 + (i*16)) |
357 | #define NV10_PGRAPH_TLIMIT(i) (0x00400B04 + (i*16)) | 357 | #define NV10_PGRAPH_TLIMIT(i) (0x00400B04 + (i*16)) |
358 | #define NV10_PGRAPH_TSIZE(i) (0x00400B08 + (i*16)) | 358 | #define NV10_PGRAPH_TSIZE(i) (0x00400B08 + (i*16)) |
359 | #define NV10_PGRAPH_TSTATUS(i) (0x00400B0C + (i*16)) | 359 | #define NV10_PGRAPH_TSTATUS(i) (0x00400B0C + (i*16)) |
360 | #define NV04_PGRAPH_U_RAM 0x00400D00 | 360 | #define NV04_PGRAPH_U_RAM 0x00400D00 |
361 | #define NV47_PGRAPH_TILE0(i) (0x00400D00 + (i*16)) | 361 | #define NV47_PGRAPH_TILE(i) (0x00400D00 + (i*16)) |
362 | #define NV47_PGRAPH_TLIMIT0(i) (0x00400D04 + (i*16)) | 362 | #define NV47_PGRAPH_TLIMIT(i) (0x00400D04 + (i*16)) |
363 | #define NV47_PGRAPH_TSIZE0(i) (0x00400D08 + (i*16)) | 363 | #define NV47_PGRAPH_TSIZE(i) (0x00400D08 + (i*16)) |
364 | #define NV47_PGRAPH_TSTATUS0(i) (0x00400D0C + (i*16)) | 364 | #define NV47_PGRAPH_TSTATUS(i) (0x00400D0C + (i*16)) |
365 | #define NV04_PGRAPH_V_RAM 0x00400D40 | 365 | #define NV04_PGRAPH_V_RAM 0x00400D40 |
366 | #define NV04_PGRAPH_W_RAM 0x00400D80 | 366 | #define NV04_PGRAPH_W_RAM 0x00400D80 |
367 | #define NV10_PGRAPH_COMBINER0_IN_ALPHA 0x00400E40 | 367 | #define NV10_PGRAPH_COMBINER0_IN_ALPHA 0x00400E40 |
diff --git a/drivers/gpu/drm/nouveau/nouveau_state.c b/drivers/gpu/drm/nouveau/nouveau_state.c index e76ec2d207a9..09b9a46dfc0e 100644 --- a/drivers/gpu/drm/nouveau/nouveau_state.c +++ b/drivers/gpu/drm/nouveau/nouveau_state.c | |||
@@ -76,6 +76,8 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev) | |||
76 | engine->fifo.disable = nv04_fifo_disable; | 76 | engine->fifo.disable = nv04_fifo_disable; |
77 | engine->fifo.enable = nv04_fifo_enable; | 77 | engine->fifo.enable = nv04_fifo_enable; |
78 | engine->fifo.reassign = nv04_fifo_reassign; | 78 | engine->fifo.reassign = nv04_fifo_reassign; |
79 | engine->fifo.cache_flush = nv04_fifo_cache_flush; | ||
80 | engine->fifo.cache_pull = nv04_fifo_cache_pull; | ||
79 | engine->fifo.channel_id = nv04_fifo_channel_id; | 81 | engine->fifo.channel_id = nv04_fifo_channel_id; |
80 | engine->fifo.create_context = nv04_fifo_create_context; | 82 | engine->fifo.create_context = nv04_fifo_create_context; |
81 | engine->fifo.destroy_context = nv04_fifo_destroy_context; | 83 | engine->fifo.destroy_context = nv04_fifo_destroy_context; |
@@ -100,6 +102,7 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev) | |||
100 | engine->timer.takedown = nv04_timer_takedown; | 102 | engine->timer.takedown = nv04_timer_takedown; |
101 | engine->fb.init = nv10_fb_init; | 103 | engine->fb.init = nv10_fb_init; |
102 | engine->fb.takedown = nv10_fb_takedown; | 104 | engine->fb.takedown = nv10_fb_takedown; |
105 | engine->fb.set_region_tiling = nv10_fb_set_region_tiling; | ||
103 | engine->graph.grclass = nv10_graph_grclass; | 106 | engine->graph.grclass = nv10_graph_grclass; |
104 | engine->graph.init = nv10_graph_init; | 107 | engine->graph.init = nv10_graph_init; |
105 | engine->graph.takedown = nv10_graph_takedown; | 108 | engine->graph.takedown = nv10_graph_takedown; |
@@ -109,12 +112,15 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev) | |||
109 | engine->graph.fifo_access = nv04_graph_fifo_access; | 112 | engine->graph.fifo_access = nv04_graph_fifo_access; |
110 | engine->graph.load_context = nv10_graph_load_context; | 113 | engine->graph.load_context = nv10_graph_load_context; |
111 | engine->graph.unload_context = nv10_graph_unload_context; | 114 | engine->graph.unload_context = nv10_graph_unload_context; |
115 | engine->graph.set_region_tiling = nv10_graph_set_region_tiling; | ||
112 | engine->fifo.channels = 32; | 116 | engine->fifo.channels = 32; |
113 | engine->fifo.init = nv10_fifo_init; | 117 | engine->fifo.init = nv10_fifo_init; |
114 | engine->fifo.takedown = nouveau_stub_takedown; | 118 | engine->fifo.takedown = nouveau_stub_takedown; |
115 | engine->fifo.disable = nv04_fifo_disable; | 119 | engine->fifo.disable = nv04_fifo_disable; |
116 | engine->fifo.enable = nv04_fifo_enable; | 120 | engine->fifo.enable = nv04_fifo_enable; |
117 | engine->fifo.reassign = nv04_fifo_reassign; | 121 | engine->fifo.reassign = nv04_fifo_reassign; |
122 | engine->fifo.cache_flush = nv04_fifo_cache_flush; | ||
123 | engine->fifo.cache_pull = nv04_fifo_cache_pull; | ||
118 | engine->fifo.channel_id = nv10_fifo_channel_id; | 124 | engine->fifo.channel_id = nv10_fifo_channel_id; |
119 | engine->fifo.create_context = nv10_fifo_create_context; | 125 | engine->fifo.create_context = nv10_fifo_create_context; |
120 | engine->fifo.destroy_context = nv10_fifo_destroy_context; | 126 | engine->fifo.destroy_context = nv10_fifo_destroy_context; |
@@ -139,6 +145,7 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev) | |||
139 | engine->timer.takedown = nv04_timer_takedown; | 145 | engine->timer.takedown = nv04_timer_takedown; |
140 | engine->fb.init = nv10_fb_init; | 146 | engine->fb.init = nv10_fb_init; |
141 | engine->fb.takedown = nv10_fb_takedown; | 147 | engine->fb.takedown = nv10_fb_takedown; |
148 | engine->fb.set_region_tiling = nv10_fb_set_region_tiling; | ||
142 | engine->graph.grclass = nv20_graph_grclass; | 149 | engine->graph.grclass = nv20_graph_grclass; |
143 | engine->graph.init = nv20_graph_init; | 150 | engine->graph.init = nv20_graph_init; |
144 | engine->graph.takedown = nv20_graph_takedown; | 151 | engine->graph.takedown = nv20_graph_takedown; |
@@ -148,12 +155,15 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev) | |||
148 | engine->graph.fifo_access = nv04_graph_fifo_access; | 155 | engine->graph.fifo_access = nv04_graph_fifo_access; |
149 | engine->graph.load_context = nv20_graph_load_context; | 156 | engine->graph.load_context = nv20_graph_load_context; |
150 | engine->graph.unload_context = nv20_graph_unload_context; | 157 | engine->graph.unload_context = nv20_graph_unload_context; |
158 | engine->graph.set_region_tiling = nv20_graph_set_region_tiling; | ||
151 | engine->fifo.channels = 32; | 159 | engine->fifo.channels = 32; |
152 | engine->fifo.init = nv10_fifo_init; | 160 | engine->fifo.init = nv10_fifo_init; |
153 | engine->fifo.takedown = nouveau_stub_takedown; | 161 | engine->fifo.takedown = nouveau_stub_takedown; |
154 | engine->fifo.disable = nv04_fifo_disable; | 162 | engine->fifo.disable = nv04_fifo_disable; |
155 | engine->fifo.enable = nv04_fifo_enable; | 163 | engine->fifo.enable = nv04_fifo_enable; |
156 | engine->fifo.reassign = nv04_fifo_reassign; | 164 | engine->fifo.reassign = nv04_fifo_reassign; |
165 | engine->fifo.cache_flush = nv04_fifo_cache_flush; | ||
166 | engine->fifo.cache_pull = nv04_fifo_cache_pull; | ||
157 | engine->fifo.channel_id = nv10_fifo_channel_id; | 167 | engine->fifo.channel_id = nv10_fifo_channel_id; |
158 | engine->fifo.create_context = nv10_fifo_create_context; | 168 | engine->fifo.create_context = nv10_fifo_create_context; |
159 | engine->fifo.destroy_context = nv10_fifo_destroy_context; | 169 | engine->fifo.destroy_context = nv10_fifo_destroy_context; |
@@ -178,6 +188,7 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev) | |||
178 | engine->timer.takedown = nv04_timer_takedown; | 188 | engine->timer.takedown = nv04_timer_takedown; |
179 | engine->fb.init = nv10_fb_init; | 189 | engine->fb.init = nv10_fb_init; |
180 | engine->fb.takedown = nv10_fb_takedown; | 190 | engine->fb.takedown = nv10_fb_takedown; |
191 | engine->fb.set_region_tiling = nv10_fb_set_region_tiling; | ||
181 | engine->graph.grclass = nv30_graph_grclass; | 192 | engine->graph.grclass = nv30_graph_grclass; |
182 | engine->graph.init = nv30_graph_init; | 193 | engine->graph.init = nv30_graph_init; |
183 | engine->graph.takedown = nv20_graph_takedown; | 194 | engine->graph.takedown = nv20_graph_takedown; |
@@ -187,12 +198,15 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev) | |||
187 | engine->graph.destroy_context = nv20_graph_destroy_context; | 198 | engine->graph.destroy_context = nv20_graph_destroy_context; |
188 | engine->graph.load_context = nv20_graph_load_context; | 199 | engine->graph.load_context = nv20_graph_load_context; |
189 | engine->graph.unload_context = nv20_graph_unload_context; | 200 | engine->graph.unload_context = nv20_graph_unload_context; |
201 | engine->graph.set_region_tiling = nv20_graph_set_region_tiling; | ||
190 | engine->fifo.channels = 32; | 202 | engine->fifo.channels = 32; |
191 | engine->fifo.init = nv10_fifo_init; | 203 | engine->fifo.init = nv10_fifo_init; |
192 | engine->fifo.takedown = nouveau_stub_takedown; | 204 | engine->fifo.takedown = nouveau_stub_takedown; |
193 | engine->fifo.disable = nv04_fifo_disable; | 205 | engine->fifo.disable = nv04_fifo_disable; |
194 | engine->fifo.enable = nv04_fifo_enable; | 206 | engine->fifo.enable = nv04_fifo_enable; |
195 | engine->fifo.reassign = nv04_fifo_reassign; | 207 | engine->fifo.reassign = nv04_fifo_reassign; |
208 | engine->fifo.cache_flush = nv04_fifo_cache_flush; | ||
209 | engine->fifo.cache_pull = nv04_fifo_cache_pull; | ||
196 | engine->fifo.channel_id = nv10_fifo_channel_id; | 210 | engine->fifo.channel_id = nv10_fifo_channel_id; |
197 | engine->fifo.create_context = nv10_fifo_create_context; | 211 | engine->fifo.create_context = nv10_fifo_create_context; |
198 | engine->fifo.destroy_context = nv10_fifo_destroy_context; | 212 | engine->fifo.destroy_context = nv10_fifo_destroy_context; |
@@ -218,6 +232,7 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev) | |||
218 | engine->timer.takedown = nv04_timer_takedown; | 232 | engine->timer.takedown = nv04_timer_takedown; |
219 | engine->fb.init = nv40_fb_init; | 233 | engine->fb.init = nv40_fb_init; |
220 | engine->fb.takedown = nv40_fb_takedown; | 234 | engine->fb.takedown = nv40_fb_takedown; |
235 | engine->fb.set_region_tiling = nv40_fb_set_region_tiling; | ||
221 | engine->graph.grclass = nv40_graph_grclass; | 236 | engine->graph.grclass = nv40_graph_grclass; |
222 | engine->graph.init = nv40_graph_init; | 237 | engine->graph.init = nv40_graph_init; |
223 | engine->graph.takedown = nv40_graph_takedown; | 238 | engine->graph.takedown = nv40_graph_takedown; |
@@ -227,12 +242,15 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev) | |||
227 | engine->graph.destroy_context = nv40_graph_destroy_context; | 242 | engine->graph.destroy_context = nv40_graph_destroy_context; |
228 | engine->graph.load_context = nv40_graph_load_context; | 243 | engine->graph.load_context = nv40_graph_load_context; |
229 | engine->graph.unload_context = nv40_graph_unload_context; | 244 | engine->graph.unload_context = nv40_graph_unload_context; |
245 | engine->graph.set_region_tiling = nv40_graph_set_region_tiling; | ||
230 | engine->fifo.channels = 32; | 246 | engine->fifo.channels = 32; |
231 | engine->fifo.init = nv40_fifo_init; | 247 | engine->fifo.init = nv40_fifo_init; |
232 | engine->fifo.takedown = nouveau_stub_takedown; | 248 | engine->fifo.takedown = nouveau_stub_takedown; |
233 | engine->fifo.disable = nv04_fifo_disable; | 249 | engine->fifo.disable = nv04_fifo_disable; |
234 | engine->fifo.enable = nv04_fifo_enable; | 250 | engine->fifo.enable = nv04_fifo_enable; |
235 | engine->fifo.reassign = nv04_fifo_reassign; | 251 | engine->fifo.reassign = nv04_fifo_reassign; |
252 | engine->fifo.cache_flush = nv04_fifo_cache_flush; | ||
253 | engine->fifo.cache_pull = nv04_fifo_cache_pull; | ||
236 | engine->fifo.channel_id = nv10_fifo_channel_id; | 254 | engine->fifo.channel_id = nv10_fifo_channel_id; |
237 | engine->fifo.create_context = nv40_fifo_create_context; | 255 | engine->fifo.create_context = nv40_fifo_create_context; |
238 | engine->fifo.destroy_context = nv40_fifo_destroy_context; | 256 | engine->fifo.destroy_context = nv40_fifo_destroy_context; |
@@ -624,7 +642,10 @@ int nouveau_load(struct drm_device *dev, unsigned long flags) | |||
624 | dev_priv->chipset = (reg0 & 0xff00000) >> 20; | 642 | dev_priv->chipset = (reg0 & 0xff00000) >> 20; |
625 | /* NV04 or NV05 */ | 643 | /* NV04 or NV05 */ |
626 | } else if ((reg0 & 0xff00fff0) == 0x20004000) { | 644 | } else if ((reg0 & 0xff00fff0) == 0x20004000) { |
627 | dev_priv->chipset = 0x04; | 645 | if (reg0 & 0x00f00000) |
646 | dev_priv->chipset = 0x05; | ||
647 | else | ||
648 | dev_priv->chipset = 0x04; | ||
628 | } else | 649 | } else |
629 | dev_priv->chipset = 0xff; | 650 | dev_priv->chipset = 0xff; |
630 | 651 | ||
@@ -704,8 +725,8 @@ static void nouveau_close(struct drm_device *dev) | |||
704 | { | 725 | { |
705 | struct drm_nouveau_private *dev_priv = dev->dev_private; | 726 | struct drm_nouveau_private *dev_priv = dev->dev_private; |
706 | 727 | ||
707 | /* In the case of an error dev_priv may not be be allocated yet */ | 728 | /* In the case of an error dev_priv may not be allocated yet */ |
708 | if (dev_priv && dev_priv->card_type) | 729 | if (dev_priv) |
709 | nouveau_card_takedown(dev); | 730 | nouveau_card_takedown(dev); |
710 | } | 731 | } |
711 | 732 | ||
diff --git a/drivers/gpu/drm/nouveau/nouveau_ttm.c b/drivers/gpu/drm/nouveau/nouveau_ttm.c index 187eb84e4da5..c385d50f041b 100644 --- a/drivers/gpu/drm/nouveau/nouveau_ttm.c +++ b/drivers/gpu/drm/nouveau/nouveau_ttm.c | |||
@@ -28,45 +28,17 @@ | |||
28 | 28 | ||
29 | #include "nouveau_drv.h" | 29 | #include "nouveau_drv.h" |
30 | 30 | ||
31 | static struct vm_operations_struct nouveau_ttm_vm_ops; | ||
32 | static const struct vm_operations_struct *ttm_vm_ops; | ||
33 | |||
34 | static int | ||
35 | nouveau_ttm_fault(struct vm_area_struct *vma, struct vm_fault *vmf) | ||
36 | { | ||
37 | struct ttm_buffer_object *bo = vma->vm_private_data; | ||
38 | int ret; | ||
39 | |||
40 | if (unlikely(bo == NULL)) | ||
41 | return VM_FAULT_NOPAGE; | ||
42 | |||
43 | ret = ttm_vm_ops->fault(vma, vmf); | ||
44 | return ret; | ||
45 | } | ||
46 | |||
47 | int | 31 | int |
48 | nouveau_ttm_mmap(struct file *filp, struct vm_area_struct *vma) | 32 | nouveau_ttm_mmap(struct file *filp, struct vm_area_struct *vma) |
49 | { | 33 | { |
50 | struct drm_file *file_priv = filp->private_data; | 34 | struct drm_file *file_priv = filp->private_data; |
51 | struct drm_nouveau_private *dev_priv = | 35 | struct drm_nouveau_private *dev_priv = |
52 | file_priv->minor->dev->dev_private; | 36 | file_priv->minor->dev->dev_private; |
53 | int ret; | ||
54 | 37 | ||
55 | if (unlikely(vma->vm_pgoff < DRM_FILE_PAGE_OFFSET)) | 38 | if (unlikely(vma->vm_pgoff < DRM_FILE_PAGE_OFFSET)) |
56 | return drm_mmap(filp, vma); | 39 | return drm_mmap(filp, vma); |
57 | 40 | ||
58 | ret = ttm_bo_mmap(filp, vma, &dev_priv->ttm.bdev); | 41 | return ttm_bo_mmap(filp, vma, &dev_priv->ttm.bdev); |
59 | if (unlikely(ret != 0)) | ||
60 | return ret; | ||
61 | |||
62 | if (unlikely(ttm_vm_ops == NULL)) { | ||
63 | ttm_vm_ops = vma->vm_ops; | ||
64 | nouveau_ttm_vm_ops = *ttm_vm_ops; | ||
65 | nouveau_ttm_vm_ops.fault = &nouveau_ttm_fault; | ||
66 | } | ||
67 | |||
68 | vma->vm_ops = &nouveau_ttm_vm_ops; | ||
69 | return 0; | ||
70 | } | 42 | } |
71 | 43 | ||
72 | static int | 44 | static int |
diff --git a/drivers/gpu/drm/nouveau/nv04_dac.c b/drivers/gpu/drm/nouveau/nv04_dac.c index d9f32879ba38..d0e038d28948 100644 --- a/drivers/gpu/drm/nouveau/nv04_dac.c +++ b/drivers/gpu/drm/nouveau/nv04_dac.c | |||
@@ -212,16 +212,15 @@ out: | |||
212 | return connector_status_disconnected; | 212 | return connector_status_disconnected; |
213 | } | 213 | } |
214 | 214 | ||
215 | enum drm_connector_status nv17_dac_detect(struct drm_encoder *encoder, | 215 | uint32_t nv17_dac_sample_load(struct drm_encoder *encoder) |
216 | struct drm_connector *connector) | ||
217 | { | 216 | { |
218 | struct drm_device *dev = encoder->dev; | 217 | struct drm_device *dev = encoder->dev; |
219 | struct drm_nouveau_private *dev_priv = dev->dev_private; | 218 | struct drm_nouveau_private *dev_priv = dev->dev_private; |
220 | struct dcb_entry *dcb = nouveau_encoder(encoder)->dcb; | 219 | struct dcb_entry *dcb = nouveau_encoder(encoder)->dcb; |
221 | uint32_t testval, regoffset = nv04_dac_output_offset(encoder); | 220 | uint32_t sample, testval, regoffset = nv04_dac_output_offset(encoder); |
222 | uint32_t saved_powerctrl_2 = 0, saved_powerctrl_4 = 0, saved_routput, | 221 | uint32_t saved_powerctrl_2 = 0, saved_powerctrl_4 = 0, saved_routput, |
223 | saved_rtest_ctrl, saved_gpio0, saved_gpio1, temp, routput; | 222 | saved_rtest_ctrl, saved_gpio0, saved_gpio1, temp, routput; |
224 | int head, present = 0; | 223 | int head; |
225 | 224 | ||
226 | #define RGB_TEST_DATA(r, g, b) (r << 0 | g << 10 | b << 20) | 225 | #define RGB_TEST_DATA(r, g, b) (r << 0 | g << 10 | b << 20) |
227 | if (dcb->type == OUTPUT_TV) { | 226 | if (dcb->type == OUTPUT_TV) { |
@@ -287,13 +286,7 @@ enum drm_connector_status nv17_dac_detect(struct drm_encoder *encoder, | |||
287 | temp | NV_PRAMDAC_TEST_CONTROL_TP_INS_EN_ASSERTED); | 286 | temp | NV_PRAMDAC_TEST_CONTROL_TP_INS_EN_ASSERTED); |
288 | msleep(5); | 287 | msleep(5); |
289 | 288 | ||
290 | temp = NVReadRAMDAC(dev, 0, NV_PRAMDAC_TEST_CONTROL + regoffset); | 289 | sample = NVReadRAMDAC(dev, 0, NV_PRAMDAC_TEST_CONTROL + regoffset); |
291 | |||
292 | if (dcb->type == OUTPUT_TV) | ||
293 | present = (nv17_tv_detect(encoder, connector, temp) | ||
294 | == connector_status_connected); | ||
295 | else | ||
296 | present = temp & NV_PRAMDAC_TEST_CONTROL_SENSEB_ALLHI; | ||
297 | 290 | ||
298 | temp = NVReadRAMDAC(dev, head, NV_PRAMDAC_TEST_CONTROL); | 291 | temp = NVReadRAMDAC(dev, head, NV_PRAMDAC_TEST_CONTROL); |
299 | NVWriteRAMDAC(dev, head, NV_PRAMDAC_TEST_CONTROL, | 292 | NVWriteRAMDAC(dev, head, NV_PRAMDAC_TEST_CONTROL, |
@@ -310,15 +303,25 @@ enum drm_connector_status nv17_dac_detect(struct drm_encoder *encoder, | |||
310 | nv17_gpio_set(dev, DCB_GPIO_TVDAC1, saved_gpio1); | 303 | nv17_gpio_set(dev, DCB_GPIO_TVDAC1, saved_gpio1); |
311 | nv17_gpio_set(dev, DCB_GPIO_TVDAC0, saved_gpio0); | 304 | nv17_gpio_set(dev, DCB_GPIO_TVDAC0, saved_gpio0); |
312 | 305 | ||
313 | if (present) { | 306 | return sample; |
314 | NV_INFO(dev, "Load detected on output %c\n", '@' + ffs(dcb->or)); | 307 | } |
308 | |||
309 | static enum drm_connector_status | ||
310 | nv17_dac_detect(struct drm_encoder *encoder, struct drm_connector *connector) | ||
311 | { | ||
312 | struct drm_device *dev = encoder->dev; | ||
313 | struct dcb_entry *dcb = nouveau_encoder(encoder)->dcb; | ||
314 | uint32_t sample = nv17_dac_sample_load(encoder); | ||
315 | |||
316 | if (sample & NV_PRAMDAC_TEST_CONTROL_SENSEB_ALLHI) { | ||
317 | NV_INFO(dev, "Load detected on output %c\n", | ||
318 | '@' + ffs(dcb->or)); | ||
315 | return connector_status_connected; | 319 | return connector_status_connected; |
320 | } else { | ||
321 | return connector_status_disconnected; | ||
316 | } | 322 | } |
317 | |||
318 | return connector_status_disconnected; | ||
319 | } | 323 | } |
320 | 324 | ||
321 | |||
322 | static bool nv04_dac_mode_fixup(struct drm_encoder *encoder, | 325 | static bool nv04_dac_mode_fixup(struct drm_encoder *encoder, |
323 | struct drm_display_mode *mode, | 326 | struct drm_display_mode *mode, |
324 | struct drm_display_mode *adjusted_mode) | 327 | struct drm_display_mode *adjusted_mode) |
diff --git a/drivers/gpu/drm/nouveau/nv04_fbcon.c b/drivers/gpu/drm/nouveau/nv04_fbcon.c index 09a31071ee58..d910873c1368 100644 --- a/drivers/gpu/drm/nouveau/nv04_fbcon.c +++ b/drivers/gpu/drm/nouveau/nv04_fbcon.c | |||
@@ -39,8 +39,7 @@ nv04_fbcon_copyarea(struct fb_info *info, const struct fb_copyarea *region) | |||
39 | return; | 39 | return; |
40 | 40 | ||
41 | if (!(info->flags & FBINFO_HWACCEL_DISABLED) && RING_SPACE(chan, 4)) { | 41 | if (!(info->flags & FBINFO_HWACCEL_DISABLED) && RING_SPACE(chan, 4)) { |
42 | NV_ERROR(dev, "GPU lockup - switching to software fbcon\n"); | 42 | nouveau_fbcon_gpu_lockup(info); |
43 | info->flags |= FBINFO_HWACCEL_DISABLED; | ||
44 | } | 43 | } |
45 | 44 | ||
46 | if (info->flags & FBINFO_HWACCEL_DISABLED) { | 45 | if (info->flags & FBINFO_HWACCEL_DISABLED) { |
@@ -62,14 +61,12 @@ nv04_fbcon_fillrect(struct fb_info *info, const struct fb_fillrect *rect) | |||
62 | struct drm_device *dev = par->dev; | 61 | struct drm_device *dev = par->dev; |
63 | struct drm_nouveau_private *dev_priv = dev->dev_private; | 62 | struct drm_nouveau_private *dev_priv = dev->dev_private; |
64 | struct nouveau_channel *chan = dev_priv->channel; | 63 | struct nouveau_channel *chan = dev_priv->channel; |
65 | uint32_t color = ((uint32_t *) info->pseudo_palette)[rect->color]; | ||
66 | 64 | ||
67 | if (info->state != FBINFO_STATE_RUNNING) | 65 | if (info->state != FBINFO_STATE_RUNNING) |
68 | return; | 66 | return; |
69 | 67 | ||
70 | if (!(info->flags & FBINFO_HWACCEL_DISABLED) && RING_SPACE(chan, 7)) { | 68 | if (!(info->flags & FBINFO_HWACCEL_DISABLED) && RING_SPACE(chan, 7)) { |
71 | NV_ERROR(dev, "GPU lockup - switching to software fbcon\n"); | 69 | nouveau_fbcon_gpu_lockup(info); |
72 | info->flags |= FBINFO_HWACCEL_DISABLED; | ||
73 | } | 70 | } |
74 | 71 | ||
75 | if (info->flags & FBINFO_HWACCEL_DISABLED) { | 72 | if (info->flags & FBINFO_HWACCEL_DISABLED) { |
@@ -80,7 +77,11 @@ nv04_fbcon_fillrect(struct fb_info *info, const struct fb_fillrect *rect) | |||
80 | BEGIN_RING(chan, NvSubGdiRect, 0x02fc, 1); | 77 | BEGIN_RING(chan, NvSubGdiRect, 0x02fc, 1); |
81 | OUT_RING(chan, (rect->rop != ROP_COPY) ? 1 : 3); | 78 | OUT_RING(chan, (rect->rop != ROP_COPY) ? 1 : 3); |
82 | BEGIN_RING(chan, NvSubGdiRect, 0x03fc, 1); | 79 | BEGIN_RING(chan, NvSubGdiRect, 0x03fc, 1); |
83 | OUT_RING(chan, color); | 80 | if (info->fix.visual == FB_VISUAL_TRUECOLOR || |
81 | info->fix.visual == FB_VISUAL_DIRECTCOLOR) | ||
82 | OUT_RING(chan, ((uint32_t *)info->pseudo_palette)[rect->color]); | ||
83 | else | ||
84 | OUT_RING(chan, rect->color); | ||
84 | BEGIN_RING(chan, NvSubGdiRect, 0x0400, 2); | 85 | BEGIN_RING(chan, NvSubGdiRect, 0x0400, 2); |
85 | OUT_RING(chan, (rect->dx << 16) | rect->dy); | 86 | OUT_RING(chan, (rect->dx << 16) | rect->dy); |
86 | OUT_RING(chan, (rect->width << 16) | rect->height); | 87 | OUT_RING(chan, (rect->width << 16) | rect->height); |
@@ -109,8 +110,7 @@ nv04_fbcon_imageblit(struct fb_info *info, const struct fb_image *image) | |||
109 | } | 110 | } |
110 | 111 | ||
111 | if (!(info->flags & FBINFO_HWACCEL_DISABLED) && RING_SPACE(chan, 8)) { | 112 | if (!(info->flags & FBINFO_HWACCEL_DISABLED) && RING_SPACE(chan, 8)) { |
112 | NV_ERROR(dev, "GPU lockup - switching to software fbcon\n"); | 113 | nouveau_fbcon_gpu_lockup(info); |
113 | info->flags |= FBINFO_HWACCEL_DISABLED; | ||
114 | } | 114 | } |
115 | 115 | ||
116 | if (info->flags & FBINFO_HWACCEL_DISABLED) { | 116 | if (info->flags & FBINFO_HWACCEL_DISABLED) { |
@@ -144,8 +144,7 @@ nv04_fbcon_imageblit(struct fb_info *info, const struct fb_image *image) | |||
144 | int iter_len = dsize > 128 ? 128 : dsize; | 144 | int iter_len = dsize > 128 ? 128 : dsize; |
145 | 145 | ||
146 | if (RING_SPACE(chan, iter_len + 1)) { | 146 | if (RING_SPACE(chan, iter_len + 1)) { |
147 | NV_ERROR(dev, "GPU lockup - switching to software fbcon\n"); | 147 | nouveau_fbcon_gpu_lockup(info); |
148 | info->flags |= FBINFO_HWACCEL_DISABLED; | ||
149 | cfb_imageblit(info, image); | 148 | cfb_imageblit(info, image); |
150 | return; | 149 | return; |
151 | } | 150 | } |
@@ -184,6 +183,7 @@ nv04_fbcon_accel_init(struct fb_info *info) | |||
184 | struct drm_device *dev = par->dev; | 183 | struct drm_device *dev = par->dev; |
185 | struct drm_nouveau_private *dev_priv = dev->dev_private; | 184 | struct drm_nouveau_private *dev_priv = dev->dev_private; |
186 | struct nouveau_channel *chan = dev_priv->channel; | 185 | struct nouveau_channel *chan = dev_priv->channel; |
186 | const int sub = NvSubCtxSurf2D; | ||
187 | int surface_fmt, pattern_fmt, rect_fmt; | 187 | int surface_fmt, pattern_fmt, rect_fmt; |
188 | int ret; | 188 | int ret; |
189 | 189 | ||
@@ -242,30 +242,29 @@ nv04_fbcon_accel_init(struct fb_info *info) | |||
242 | return ret; | 242 | return ret; |
243 | 243 | ||
244 | if (RING_SPACE(chan, 49)) { | 244 | if (RING_SPACE(chan, 49)) { |
245 | NV_ERROR(dev, "GPU lockup - switching to software fbcon\n"); | 245 | nouveau_fbcon_gpu_lockup(info); |
246 | info->flags |= FBINFO_HWACCEL_DISABLED; | ||
247 | return 0; | 246 | return 0; |
248 | } | 247 | } |
249 | 248 | ||
250 | BEGIN_RING(chan, 1, 0x0000, 1); | 249 | BEGIN_RING(chan, sub, 0x0000, 1); |
251 | OUT_RING(chan, NvCtxSurf2D); | 250 | OUT_RING(chan, NvCtxSurf2D); |
252 | BEGIN_RING(chan, 1, 0x0184, 2); | 251 | BEGIN_RING(chan, sub, 0x0184, 2); |
253 | OUT_RING(chan, NvDmaFB); | 252 | OUT_RING(chan, NvDmaFB); |
254 | OUT_RING(chan, NvDmaFB); | 253 | OUT_RING(chan, NvDmaFB); |
255 | BEGIN_RING(chan, 1, 0x0300, 4); | 254 | BEGIN_RING(chan, sub, 0x0300, 4); |
256 | OUT_RING(chan, surface_fmt); | 255 | OUT_RING(chan, surface_fmt); |
257 | OUT_RING(chan, info->fix.line_length | (info->fix.line_length << 16)); | 256 | OUT_RING(chan, info->fix.line_length | (info->fix.line_length << 16)); |
258 | OUT_RING(chan, info->fix.smem_start - dev->mode_config.fb_base); | 257 | OUT_RING(chan, info->fix.smem_start - dev->mode_config.fb_base); |
259 | OUT_RING(chan, info->fix.smem_start - dev->mode_config.fb_base); | 258 | OUT_RING(chan, info->fix.smem_start - dev->mode_config.fb_base); |
260 | 259 | ||
261 | BEGIN_RING(chan, 1, 0x0000, 1); | 260 | BEGIN_RING(chan, sub, 0x0000, 1); |
262 | OUT_RING(chan, NvRop); | 261 | OUT_RING(chan, NvRop); |
263 | BEGIN_RING(chan, 1, 0x0300, 1); | 262 | BEGIN_RING(chan, sub, 0x0300, 1); |
264 | OUT_RING(chan, 0x55); | 263 | OUT_RING(chan, 0x55); |
265 | 264 | ||
266 | BEGIN_RING(chan, 1, 0x0000, 1); | 265 | BEGIN_RING(chan, sub, 0x0000, 1); |
267 | OUT_RING(chan, NvImagePatt); | 266 | OUT_RING(chan, NvImagePatt); |
268 | BEGIN_RING(chan, 1, 0x0300, 8); | 267 | BEGIN_RING(chan, sub, 0x0300, 8); |
269 | OUT_RING(chan, pattern_fmt); | 268 | OUT_RING(chan, pattern_fmt); |
270 | #ifdef __BIG_ENDIAN | 269 | #ifdef __BIG_ENDIAN |
271 | OUT_RING(chan, 2); | 270 | OUT_RING(chan, 2); |
@@ -279,9 +278,9 @@ nv04_fbcon_accel_init(struct fb_info *info) | |||
279 | OUT_RING(chan, ~0); | 278 | OUT_RING(chan, ~0); |
280 | OUT_RING(chan, ~0); | 279 | OUT_RING(chan, ~0); |
281 | 280 | ||
282 | BEGIN_RING(chan, 1, 0x0000, 1); | 281 | BEGIN_RING(chan, sub, 0x0000, 1); |
283 | OUT_RING(chan, NvClipRect); | 282 | OUT_RING(chan, NvClipRect); |
284 | BEGIN_RING(chan, 1, 0x0300, 2); | 283 | BEGIN_RING(chan, sub, 0x0300, 2); |
285 | OUT_RING(chan, 0); | 284 | OUT_RING(chan, 0); |
286 | OUT_RING(chan, (info->var.yres_virtual << 16) | info->var.xres_virtual); | 285 | OUT_RING(chan, (info->var.yres_virtual << 16) | info->var.xres_virtual); |
287 | 286 | ||
diff --git a/drivers/gpu/drm/nouveau/nv04_fifo.c b/drivers/gpu/drm/nouveau/nv04_fifo.c index 0c3cd53c7313..f31347b8c9b0 100644 --- a/drivers/gpu/drm/nouveau/nv04_fifo.c +++ b/drivers/gpu/drm/nouveau/nv04_fifo.c | |||
@@ -71,6 +71,40 @@ nv04_fifo_reassign(struct drm_device *dev, bool enable) | |||
71 | return (reassign == 1); | 71 | return (reassign == 1); |
72 | } | 72 | } |
73 | 73 | ||
74 | bool | ||
75 | nv04_fifo_cache_flush(struct drm_device *dev) | ||
76 | { | ||
77 | struct drm_nouveau_private *dev_priv = dev->dev_private; | ||
78 | struct nouveau_timer_engine *ptimer = &dev_priv->engine.timer; | ||
79 | uint64_t start = ptimer->read(dev); | ||
80 | |||
81 | do { | ||
82 | if (nv_rd32(dev, NV03_PFIFO_CACHE1_GET) == | ||
83 | nv_rd32(dev, NV03_PFIFO_CACHE1_PUT)) | ||
84 | return true; | ||
85 | |||
86 | } while (ptimer->read(dev) - start < 100000000); | ||
87 | |||
88 | NV_ERROR(dev, "Timeout flushing the PFIFO cache.\n"); | ||
89 | |||
90 | return false; | ||
91 | } | ||
92 | |||
93 | bool | ||
94 | nv04_fifo_cache_pull(struct drm_device *dev, bool enable) | ||
95 | { | ||
96 | uint32_t pull = nv_rd32(dev, NV04_PFIFO_CACHE1_PULL0); | ||
97 | |||
98 | if (enable) { | ||
99 | nv_wr32(dev, NV04_PFIFO_CACHE1_PULL0, pull | 1); | ||
100 | } else { | ||
101 | nv_wr32(dev, NV04_PFIFO_CACHE1_PULL0, pull & ~1); | ||
102 | nv_wr32(dev, NV04_PFIFO_CACHE1_HASH, 0); | ||
103 | } | ||
104 | |||
105 | return !!(pull & 1); | ||
106 | } | ||
107 | |||
74 | int | 108 | int |
75 | nv04_fifo_channel_id(struct drm_device *dev) | 109 | nv04_fifo_channel_id(struct drm_device *dev) |
76 | { | 110 | { |
diff --git a/drivers/gpu/drm/nouveau/nv04_graph.c b/drivers/gpu/drm/nouveau/nv04_graph.c index d561d773c0f4..e260986ea65a 100644 --- a/drivers/gpu/drm/nouveau/nv04_graph.c +++ b/drivers/gpu/drm/nouveau/nv04_graph.c | |||
@@ -28,6 +28,10 @@ | |||
28 | #include "nouveau_drv.h" | 28 | #include "nouveau_drv.h" |
29 | 29 | ||
30 | static uint32_t nv04_graph_ctx_regs[] = { | 30 | static uint32_t nv04_graph_ctx_regs[] = { |
31 | 0x0040053c, | ||
32 | 0x00400544, | ||
33 | 0x00400540, | ||
34 | 0x00400548, | ||
31 | NV04_PGRAPH_CTX_SWITCH1, | 35 | NV04_PGRAPH_CTX_SWITCH1, |
32 | NV04_PGRAPH_CTX_SWITCH2, | 36 | NV04_PGRAPH_CTX_SWITCH2, |
33 | NV04_PGRAPH_CTX_SWITCH3, | 37 | NV04_PGRAPH_CTX_SWITCH3, |
@@ -102,69 +106,69 @@ static uint32_t nv04_graph_ctx_regs[] = { | |||
102 | NV04_PGRAPH_PATT_COLOR0, | 106 | NV04_PGRAPH_PATT_COLOR0, |
103 | NV04_PGRAPH_PATT_COLOR1, | 107 | NV04_PGRAPH_PATT_COLOR1, |
104 | NV04_PGRAPH_PATT_COLORRAM+0x00, | 108 | NV04_PGRAPH_PATT_COLORRAM+0x00, |
105 | NV04_PGRAPH_PATT_COLORRAM+0x01, | ||
106 | NV04_PGRAPH_PATT_COLORRAM+0x02, | ||
107 | NV04_PGRAPH_PATT_COLORRAM+0x03, | ||
108 | NV04_PGRAPH_PATT_COLORRAM+0x04, | 109 | NV04_PGRAPH_PATT_COLORRAM+0x04, |
109 | NV04_PGRAPH_PATT_COLORRAM+0x05, | ||
110 | NV04_PGRAPH_PATT_COLORRAM+0x06, | ||
111 | NV04_PGRAPH_PATT_COLORRAM+0x07, | ||
112 | NV04_PGRAPH_PATT_COLORRAM+0x08, | 110 | NV04_PGRAPH_PATT_COLORRAM+0x08, |
113 | NV04_PGRAPH_PATT_COLORRAM+0x09, | 111 | NV04_PGRAPH_PATT_COLORRAM+0x0c, |
114 | NV04_PGRAPH_PATT_COLORRAM+0x0A, | ||
115 | NV04_PGRAPH_PATT_COLORRAM+0x0B, | ||
116 | NV04_PGRAPH_PATT_COLORRAM+0x0C, | ||
117 | NV04_PGRAPH_PATT_COLORRAM+0x0D, | ||
118 | NV04_PGRAPH_PATT_COLORRAM+0x0E, | ||
119 | NV04_PGRAPH_PATT_COLORRAM+0x0F, | ||
120 | NV04_PGRAPH_PATT_COLORRAM+0x10, | 112 | NV04_PGRAPH_PATT_COLORRAM+0x10, |
121 | NV04_PGRAPH_PATT_COLORRAM+0x11, | ||
122 | NV04_PGRAPH_PATT_COLORRAM+0x12, | ||
123 | NV04_PGRAPH_PATT_COLORRAM+0x13, | ||
124 | NV04_PGRAPH_PATT_COLORRAM+0x14, | 113 | NV04_PGRAPH_PATT_COLORRAM+0x14, |
125 | NV04_PGRAPH_PATT_COLORRAM+0x15, | ||
126 | NV04_PGRAPH_PATT_COLORRAM+0x16, | ||
127 | NV04_PGRAPH_PATT_COLORRAM+0x17, | ||
128 | NV04_PGRAPH_PATT_COLORRAM+0x18, | 114 | NV04_PGRAPH_PATT_COLORRAM+0x18, |
129 | NV04_PGRAPH_PATT_COLORRAM+0x19, | 115 | NV04_PGRAPH_PATT_COLORRAM+0x1c, |
130 | NV04_PGRAPH_PATT_COLORRAM+0x1A, | ||
131 | NV04_PGRAPH_PATT_COLORRAM+0x1B, | ||
132 | NV04_PGRAPH_PATT_COLORRAM+0x1C, | ||
133 | NV04_PGRAPH_PATT_COLORRAM+0x1D, | ||
134 | NV04_PGRAPH_PATT_COLORRAM+0x1E, | ||
135 | NV04_PGRAPH_PATT_COLORRAM+0x1F, | ||
136 | NV04_PGRAPH_PATT_COLORRAM+0x20, | 116 | NV04_PGRAPH_PATT_COLORRAM+0x20, |
137 | NV04_PGRAPH_PATT_COLORRAM+0x21, | ||
138 | NV04_PGRAPH_PATT_COLORRAM+0x22, | ||
139 | NV04_PGRAPH_PATT_COLORRAM+0x23, | ||
140 | NV04_PGRAPH_PATT_COLORRAM+0x24, | 117 | NV04_PGRAPH_PATT_COLORRAM+0x24, |
141 | NV04_PGRAPH_PATT_COLORRAM+0x25, | ||
142 | NV04_PGRAPH_PATT_COLORRAM+0x26, | ||
143 | NV04_PGRAPH_PATT_COLORRAM+0x27, | ||
144 | NV04_PGRAPH_PATT_COLORRAM+0x28, | 118 | NV04_PGRAPH_PATT_COLORRAM+0x28, |
145 | NV04_PGRAPH_PATT_COLORRAM+0x29, | 119 | NV04_PGRAPH_PATT_COLORRAM+0x2c, |
146 | NV04_PGRAPH_PATT_COLORRAM+0x2A, | ||
147 | NV04_PGRAPH_PATT_COLORRAM+0x2B, | ||
148 | NV04_PGRAPH_PATT_COLORRAM+0x2C, | ||
149 | NV04_PGRAPH_PATT_COLORRAM+0x2D, | ||
150 | NV04_PGRAPH_PATT_COLORRAM+0x2E, | ||
151 | NV04_PGRAPH_PATT_COLORRAM+0x2F, | ||
152 | NV04_PGRAPH_PATT_COLORRAM+0x30, | 120 | NV04_PGRAPH_PATT_COLORRAM+0x30, |
153 | NV04_PGRAPH_PATT_COLORRAM+0x31, | ||
154 | NV04_PGRAPH_PATT_COLORRAM+0x32, | ||
155 | NV04_PGRAPH_PATT_COLORRAM+0x33, | ||
156 | NV04_PGRAPH_PATT_COLORRAM+0x34, | 121 | NV04_PGRAPH_PATT_COLORRAM+0x34, |
157 | NV04_PGRAPH_PATT_COLORRAM+0x35, | ||
158 | NV04_PGRAPH_PATT_COLORRAM+0x36, | ||
159 | NV04_PGRAPH_PATT_COLORRAM+0x37, | ||
160 | NV04_PGRAPH_PATT_COLORRAM+0x38, | 122 | NV04_PGRAPH_PATT_COLORRAM+0x38, |
161 | NV04_PGRAPH_PATT_COLORRAM+0x39, | 123 | NV04_PGRAPH_PATT_COLORRAM+0x3c, |
162 | NV04_PGRAPH_PATT_COLORRAM+0x3A, | 124 | NV04_PGRAPH_PATT_COLORRAM+0x40, |
163 | NV04_PGRAPH_PATT_COLORRAM+0x3B, | 125 | NV04_PGRAPH_PATT_COLORRAM+0x44, |
164 | NV04_PGRAPH_PATT_COLORRAM+0x3C, | 126 | NV04_PGRAPH_PATT_COLORRAM+0x48, |
165 | NV04_PGRAPH_PATT_COLORRAM+0x3D, | 127 | NV04_PGRAPH_PATT_COLORRAM+0x4c, |
166 | NV04_PGRAPH_PATT_COLORRAM+0x3E, | 128 | NV04_PGRAPH_PATT_COLORRAM+0x50, |
167 | NV04_PGRAPH_PATT_COLORRAM+0x3F, | 129 | NV04_PGRAPH_PATT_COLORRAM+0x54, |
130 | NV04_PGRAPH_PATT_COLORRAM+0x58, | ||
131 | NV04_PGRAPH_PATT_COLORRAM+0x5c, | ||
132 | NV04_PGRAPH_PATT_COLORRAM+0x60, | ||
133 | NV04_PGRAPH_PATT_COLORRAM+0x64, | ||
134 | NV04_PGRAPH_PATT_COLORRAM+0x68, | ||
135 | NV04_PGRAPH_PATT_COLORRAM+0x6c, | ||
136 | NV04_PGRAPH_PATT_COLORRAM+0x70, | ||
137 | NV04_PGRAPH_PATT_COLORRAM+0x74, | ||
138 | NV04_PGRAPH_PATT_COLORRAM+0x78, | ||
139 | NV04_PGRAPH_PATT_COLORRAM+0x7c, | ||
140 | NV04_PGRAPH_PATT_COLORRAM+0x80, | ||
141 | NV04_PGRAPH_PATT_COLORRAM+0x84, | ||
142 | NV04_PGRAPH_PATT_COLORRAM+0x88, | ||
143 | NV04_PGRAPH_PATT_COLORRAM+0x8c, | ||
144 | NV04_PGRAPH_PATT_COLORRAM+0x90, | ||
145 | NV04_PGRAPH_PATT_COLORRAM+0x94, | ||
146 | NV04_PGRAPH_PATT_COLORRAM+0x98, | ||
147 | NV04_PGRAPH_PATT_COLORRAM+0x9c, | ||
148 | NV04_PGRAPH_PATT_COLORRAM+0xa0, | ||
149 | NV04_PGRAPH_PATT_COLORRAM+0xa4, | ||
150 | NV04_PGRAPH_PATT_COLORRAM+0xa8, | ||
151 | NV04_PGRAPH_PATT_COLORRAM+0xac, | ||
152 | NV04_PGRAPH_PATT_COLORRAM+0xb0, | ||
153 | NV04_PGRAPH_PATT_COLORRAM+0xb4, | ||
154 | NV04_PGRAPH_PATT_COLORRAM+0xb8, | ||
155 | NV04_PGRAPH_PATT_COLORRAM+0xbc, | ||
156 | NV04_PGRAPH_PATT_COLORRAM+0xc0, | ||
157 | NV04_PGRAPH_PATT_COLORRAM+0xc4, | ||
158 | NV04_PGRAPH_PATT_COLORRAM+0xc8, | ||
159 | NV04_PGRAPH_PATT_COLORRAM+0xcc, | ||
160 | NV04_PGRAPH_PATT_COLORRAM+0xd0, | ||
161 | NV04_PGRAPH_PATT_COLORRAM+0xd4, | ||
162 | NV04_PGRAPH_PATT_COLORRAM+0xd8, | ||
163 | NV04_PGRAPH_PATT_COLORRAM+0xdc, | ||
164 | NV04_PGRAPH_PATT_COLORRAM+0xe0, | ||
165 | NV04_PGRAPH_PATT_COLORRAM+0xe4, | ||
166 | NV04_PGRAPH_PATT_COLORRAM+0xe8, | ||
167 | NV04_PGRAPH_PATT_COLORRAM+0xec, | ||
168 | NV04_PGRAPH_PATT_COLORRAM+0xf0, | ||
169 | NV04_PGRAPH_PATT_COLORRAM+0xf4, | ||
170 | NV04_PGRAPH_PATT_COLORRAM+0xf8, | ||
171 | NV04_PGRAPH_PATT_COLORRAM+0xfc, | ||
168 | NV04_PGRAPH_PATTERN, | 172 | NV04_PGRAPH_PATTERN, |
169 | 0x0040080c, | 173 | 0x0040080c, |
170 | NV04_PGRAPH_PATTERN_SHAPE, | 174 | NV04_PGRAPH_PATTERN_SHAPE, |
@@ -247,14 +251,6 @@ static uint32_t nv04_graph_ctx_regs[] = { | |||
247 | 0x004004f8, | 251 | 0x004004f8, |
248 | 0x0040047c, | 252 | 0x0040047c, |
249 | 0x004004fc, | 253 | 0x004004fc, |
250 | 0x0040053c, | ||
251 | 0x00400544, | ||
252 | 0x00400540, | ||
253 | 0x00400548, | ||
254 | 0x00400560, | ||
255 | 0x00400568, | ||
256 | 0x00400564, | ||
257 | 0x0040056c, | ||
258 | 0x00400534, | 254 | 0x00400534, |
259 | 0x00400538, | 255 | 0x00400538, |
260 | 0x00400514, | 256 | 0x00400514, |
@@ -341,9 +337,8 @@ static uint32_t nv04_graph_ctx_regs[] = { | |||
341 | 0x00400500, | 337 | 0x00400500, |
342 | 0x00400504, | 338 | 0x00400504, |
343 | NV04_PGRAPH_VALID1, | 339 | NV04_PGRAPH_VALID1, |
344 | NV04_PGRAPH_VALID2 | 340 | NV04_PGRAPH_VALID2, |
345 | 341 | NV04_PGRAPH_DEBUG_3 | |
346 | |||
347 | }; | 342 | }; |
348 | 343 | ||
349 | struct graph_state { | 344 | struct graph_state { |
@@ -388,6 +383,18 @@ nv04_graph_context_switch(struct drm_device *dev) | |||
388 | pgraph->fifo_access(dev, true); | 383 | pgraph->fifo_access(dev, true); |
389 | } | 384 | } |
390 | 385 | ||
386 | static uint32_t *ctx_reg(struct graph_state *ctx, uint32_t reg) | ||
387 | { | ||
388 | int i; | ||
389 | |||
390 | for (i = 0; i < ARRAY_SIZE(nv04_graph_ctx_regs); i++) { | ||
391 | if (nv04_graph_ctx_regs[i] == reg) | ||
392 | return &ctx->nv04[i]; | ||
393 | } | ||
394 | |||
395 | return NULL; | ||
396 | } | ||
397 | |||
391 | int nv04_graph_create_context(struct nouveau_channel *chan) | 398 | int nv04_graph_create_context(struct nouveau_channel *chan) |
392 | { | 399 | { |
393 | struct graph_state *pgraph_ctx; | 400 | struct graph_state *pgraph_ctx; |
@@ -398,15 +405,8 @@ int nv04_graph_create_context(struct nouveau_channel *chan) | |||
398 | if (pgraph_ctx == NULL) | 405 | if (pgraph_ctx == NULL) |
399 | return -ENOMEM; | 406 | return -ENOMEM; |
400 | 407 | ||
401 | /* dev_priv->fifos[channel].pgraph_ctx_user = channel << 24; */ | 408 | *ctx_reg(pgraph_ctx, NV04_PGRAPH_DEBUG_3) = 0xfad4ff31; |
402 | pgraph_ctx->nv04[0] = 0x0001ffff; | 409 | |
403 | /* is it really needed ??? */ | ||
404 | #if 0 | ||
405 | dev_priv->fifos[channel].pgraph_ctx[1] = | ||
406 | nv_rd32(dev, NV_PGRAPH_DEBUG_4); | ||
407 | dev_priv->fifos[channel].pgraph_ctx[2] = | ||
408 | nv_rd32(dev, 0x004006b0); | ||
409 | #endif | ||
410 | return 0; | 410 | return 0; |
411 | } | 411 | } |
412 | 412 | ||
@@ -429,9 +429,13 @@ int nv04_graph_load_context(struct nouveau_channel *chan) | |||
429 | nv_wr32(dev, nv04_graph_ctx_regs[i], pgraph_ctx->nv04[i]); | 429 | nv_wr32(dev, nv04_graph_ctx_regs[i], pgraph_ctx->nv04[i]); |
430 | 430 | ||
431 | nv_wr32(dev, NV04_PGRAPH_CTX_CONTROL, 0x10010100); | 431 | nv_wr32(dev, NV04_PGRAPH_CTX_CONTROL, 0x10010100); |
432 | nv_wr32(dev, NV04_PGRAPH_CTX_USER, chan->id << 24); | 432 | |
433 | tmp = nv_rd32(dev, NV04_PGRAPH_CTX_USER) & 0x00ffffff; | ||
434 | nv_wr32(dev, NV04_PGRAPH_CTX_USER, tmp | chan->id << 24); | ||
435 | |||
433 | tmp = nv_rd32(dev, NV04_PGRAPH_FFINTFC_ST2); | 436 | tmp = nv_rd32(dev, NV04_PGRAPH_FFINTFC_ST2); |
434 | nv_wr32(dev, NV04_PGRAPH_FFINTFC_ST2, tmp & 0x000fffff); | 437 | nv_wr32(dev, NV04_PGRAPH_FFINTFC_ST2, tmp & 0x000fffff); |
438 | |||
435 | return 0; | 439 | return 0; |
436 | } | 440 | } |
437 | 441 | ||
@@ -494,7 +498,7 @@ int nv04_graph_init(struct drm_device *dev) | |||
494 | nv_wr32(dev, NV04_PGRAPH_STATE , 0xFFFFFFFF); | 498 | nv_wr32(dev, NV04_PGRAPH_STATE , 0xFFFFFFFF); |
495 | nv_wr32(dev, NV04_PGRAPH_CTX_CONTROL , 0x10000100); | 499 | nv_wr32(dev, NV04_PGRAPH_CTX_CONTROL , 0x10000100); |
496 | tmp = nv_rd32(dev, NV04_PGRAPH_CTX_USER) & 0x00ffffff; | 500 | tmp = nv_rd32(dev, NV04_PGRAPH_CTX_USER) & 0x00ffffff; |
497 | tmp |= dev_priv->engine.fifo.channels << 24; | 501 | tmp |= (dev_priv->engine.fifo.channels - 1) << 24; |
498 | nv_wr32(dev, NV04_PGRAPH_CTX_USER, tmp); | 502 | nv_wr32(dev, NV04_PGRAPH_CTX_USER, tmp); |
499 | 503 | ||
500 | /* These don't belong here, they're part of a per-channel context */ | 504 | /* These don't belong here, they're part of a per-channel context */ |
@@ -533,7 +537,7 @@ nv04_graph_mthd_set_operation(struct nouveau_channel *chan, int grclass, | |||
533 | int mthd, uint32_t data) | 537 | int mthd, uint32_t data) |
534 | { | 538 | { |
535 | struct drm_device *dev = chan->dev; | 539 | struct drm_device *dev = chan->dev; |
536 | uint32_t instance = nv_rd32(dev, NV04_PGRAPH_CTX_SWITCH4) & 0xffff; | 540 | uint32_t instance = (nv_rd32(dev, NV04_PGRAPH_CTX_SWITCH4) & 0xffff) << 4; |
537 | int subc = (nv_rd32(dev, NV04_PGRAPH_TRAPPED_ADDR) >> 13) & 0x7; | 541 | int subc = (nv_rd32(dev, NV04_PGRAPH_TRAPPED_ADDR) >> 13) & 0x7; |
538 | uint32_t tmp; | 542 | uint32_t tmp; |
539 | 543 | ||
@@ -547,7 +551,7 @@ nv04_graph_mthd_set_operation(struct nouveau_channel *chan, int grclass, | |||
547 | return 0; | 551 | return 0; |
548 | } | 552 | } |
549 | 553 | ||
550 | static struct nouveau_pgraph_object_method nv04_graph_mthds_m2mf[] = { | 554 | static struct nouveau_pgraph_object_method nv04_graph_mthds_sw[] = { |
551 | { 0x0150, nv04_graph_mthd_set_ref }, | 555 | { 0x0150, nv04_graph_mthd_set_ref }, |
552 | {} | 556 | {} |
553 | }; | 557 | }; |
@@ -558,7 +562,7 @@ static struct nouveau_pgraph_object_method nv04_graph_mthds_set_operation[] = { | |||
558 | }; | 562 | }; |
559 | 563 | ||
560 | struct nouveau_pgraph_object_class nv04_graph_grclass[] = { | 564 | struct nouveau_pgraph_object_class nv04_graph_grclass[] = { |
561 | { 0x0039, false, nv04_graph_mthds_m2mf }, | 565 | { 0x0039, false, NULL }, |
562 | { 0x004a, false, nv04_graph_mthds_set_operation }, /* gdirect */ | 566 | { 0x004a, false, nv04_graph_mthds_set_operation }, /* gdirect */ |
563 | { 0x005f, false, nv04_graph_mthds_set_operation }, /* imageblit */ | 567 | { 0x005f, false, nv04_graph_mthds_set_operation }, /* imageblit */ |
564 | { 0x0061, false, nv04_graph_mthds_set_operation }, /* ifc */ | 568 | { 0x0061, false, nv04_graph_mthds_set_operation }, /* ifc */ |
@@ -574,6 +578,7 @@ struct nouveau_pgraph_object_class nv04_graph_grclass[] = { | |||
574 | { 0x0053, false, NULL }, /* surf3d */ | 578 | { 0x0053, false, NULL }, /* surf3d */ |
575 | { 0x0054, false, NULL }, /* tex_tri */ | 579 | { 0x0054, false, NULL }, /* tex_tri */ |
576 | { 0x0055, false, NULL }, /* multitex_tri */ | 580 | { 0x0055, false, NULL }, /* multitex_tri */ |
581 | { 0x506e, true, nv04_graph_mthds_sw }, | ||
577 | {} | 582 | {} |
578 | }; | 583 | }; |
579 | 584 | ||
diff --git a/drivers/gpu/drm/nouveau/nv10_fb.c b/drivers/gpu/drm/nouveau/nv10_fb.c index 79e2d104d70a..cc5cda44e501 100644 --- a/drivers/gpu/drm/nouveau/nv10_fb.c +++ b/drivers/gpu/drm/nouveau/nv10_fb.c | |||
@@ -3,17 +3,37 @@ | |||
3 | #include "nouveau_drv.h" | 3 | #include "nouveau_drv.h" |
4 | #include "nouveau_drm.h" | 4 | #include "nouveau_drm.h" |
5 | 5 | ||
6 | void | ||
7 | nv10_fb_set_region_tiling(struct drm_device *dev, int i, uint32_t addr, | ||
8 | uint32_t size, uint32_t pitch) | ||
9 | { | ||
10 | struct drm_nouveau_private *dev_priv = dev->dev_private; | ||
11 | uint32_t limit = max(1u, addr + size) - 1; | ||
12 | |||
13 | if (pitch) { | ||
14 | if (dev_priv->card_type >= NV_20) | ||
15 | addr |= 1; | ||
16 | else | ||
17 | addr |= 1 << 31; | ||
18 | } | ||
19 | |||
20 | nv_wr32(dev, NV10_PFB_TLIMIT(i), limit); | ||
21 | nv_wr32(dev, NV10_PFB_TSIZE(i), pitch); | ||
22 | nv_wr32(dev, NV10_PFB_TILE(i), addr); | ||
23 | } | ||
24 | |||
6 | int | 25 | int |
7 | nv10_fb_init(struct drm_device *dev) | 26 | nv10_fb_init(struct drm_device *dev) |
8 | { | 27 | { |
9 | uint32_t fb_bar_size; | 28 | struct drm_nouveau_private *dev_priv = dev->dev_private; |
29 | struct nouveau_fb_engine *pfb = &dev_priv->engine.fb; | ||
10 | int i; | 30 | int i; |
11 | 31 | ||
12 | fb_bar_size = drm_get_resource_len(dev, 0) - 1; | 32 | pfb->num_tiles = NV10_PFB_TILE__SIZE; |
13 | for (i = 0; i < NV10_PFB_TILE__SIZE; i++) { | 33 | |
14 | nv_wr32(dev, NV10_PFB_TILE(i), 0); | 34 | /* Turn all the tiling regions off. */ |
15 | nv_wr32(dev, NV10_PFB_TLIMIT(i), fb_bar_size); | 35 | for (i = 0; i < pfb->num_tiles; i++) |
16 | } | 36 | pfb->set_region_tiling(dev, i, 0, 0, 0); |
17 | 37 | ||
18 | return 0; | 38 | return 0; |
19 | } | 39 | } |
diff --git a/drivers/gpu/drm/nouveau/nv10_graph.c b/drivers/gpu/drm/nouveau/nv10_graph.c index 6870e0ee2e7e..fcf2cdd19493 100644 --- a/drivers/gpu/drm/nouveau/nv10_graph.c +++ b/drivers/gpu/drm/nouveau/nv10_graph.c | |||
@@ -807,6 +807,20 @@ void nv10_graph_destroy_context(struct nouveau_channel *chan) | |||
807 | chan->pgraph_ctx = NULL; | 807 | chan->pgraph_ctx = NULL; |
808 | } | 808 | } |
809 | 809 | ||
810 | void | ||
811 | nv10_graph_set_region_tiling(struct drm_device *dev, int i, uint32_t addr, | ||
812 | uint32_t size, uint32_t pitch) | ||
813 | { | ||
814 | uint32_t limit = max(1u, addr + size) - 1; | ||
815 | |||
816 | if (pitch) | ||
817 | addr |= 1 << 31; | ||
818 | |||
819 | nv_wr32(dev, NV10_PGRAPH_TLIMIT(i), limit); | ||
820 | nv_wr32(dev, NV10_PGRAPH_TSIZE(i), pitch); | ||
821 | nv_wr32(dev, NV10_PGRAPH_TILE(i), addr); | ||
822 | } | ||
823 | |||
810 | int nv10_graph_init(struct drm_device *dev) | 824 | int nv10_graph_init(struct drm_device *dev) |
811 | { | 825 | { |
812 | struct drm_nouveau_private *dev_priv = dev->dev_private; | 826 | struct drm_nouveau_private *dev_priv = dev->dev_private; |
@@ -838,17 +852,9 @@ int nv10_graph_init(struct drm_device *dev) | |||
838 | } else | 852 | } else |
839 | nv_wr32(dev, NV10_PGRAPH_DEBUG_4, 0x00000000); | 853 | nv_wr32(dev, NV10_PGRAPH_DEBUG_4, 0x00000000); |
840 | 854 | ||
841 | /* copy tile info from PFB */ | 855 | /* Turn all the tiling regions off. */ |
842 | for (i = 0; i < NV10_PFB_TILE__SIZE; i++) { | 856 | for (i = 0; i < NV10_PFB_TILE__SIZE; i++) |
843 | nv_wr32(dev, NV10_PGRAPH_TILE(i), | 857 | nv10_graph_set_region_tiling(dev, i, 0, 0, 0); |
844 | nv_rd32(dev, NV10_PFB_TILE(i))); | ||
845 | nv_wr32(dev, NV10_PGRAPH_TLIMIT(i), | ||
846 | nv_rd32(dev, NV10_PFB_TLIMIT(i))); | ||
847 | nv_wr32(dev, NV10_PGRAPH_TSIZE(i), | ||
848 | nv_rd32(dev, NV10_PFB_TSIZE(i))); | ||
849 | nv_wr32(dev, NV10_PGRAPH_TSTATUS(i), | ||
850 | nv_rd32(dev, NV10_PFB_TSTATUS(i))); | ||
851 | } | ||
852 | 858 | ||
853 | nv_wr32(dev, NV10_PGRAPH_CTX_SWITCH1, 0x00000000); | 859 | nv_wr32(dev, NV10_PGRAPH_CTX_SWITCH1, 0x00000000); |
854 | nv_wr32(dev, NV10_PGRAPH_CTX_SWITCH2, 0x00000000); | 860 | nv_wr32(dev, NV10_PGRAPH_CTX_SWITCH2, 0x00000000); |
diff --git a/drivers/gpu/drm/nouveau/nv17_tv.c b/drivers/gpu/drm/nouveau/nv17_tv.c index 81c01353a9f9..58b917c3341b 100644 --- a/drivers/gpu/drm/nouveau/nv17_tv.c +++ b/drivers/gpu/drm/nouveau/nv17_tv.c | |||
@@ -33,13 +33,103 @@ | |||
33 | #include "nouveau_hw.h" | 33 | #include "nouveau_hw.h" |
34 | #include "nv17_tv.h" | 34 | #include "nv17_tv.h" |
35 | 35 | ||
36 | enum drm_connector_status nv17_tv_detect(struct drm_encoder *encoder, | 36 | static uint32_t nv42_tv_sample_load(struct drm_encoder *encoder) |
37 | struct drm_connector *connector, | ||
38 | uint32_t pin_mask) | ||
39 | { | 37 | { |
38 | struct drm_device *dev = encoder->dev; | ||
39 | struct drm_nouveau_private *dev_priv = dev->dev_private; | ||
40 | uint32_t testval, regoffset = nv04_dac_output_offset(encoder); | ||
41 | uint32_t gpio0, gpio1, fp_htotal, fp_hsync_start, fp_hsync_end, | ||
42 | fp_control, test_ctrl, dacclk, ctv_14, ctv_1c, ctv_6c; | ||
43 | uint32_t sample = 0; | ||
44 | int head; | ||
45 | |||
46 | #define RGB_TEST_DATA(r, g, b) (r << 0 | g << 10 | b << 20) | ||
47 | testval = RGB_TEST_DATA(0x82, 0xeb, 0x82); | ||
48 | if (dev_priv->vbios->tvdactestval) | ||
49 | testval = dev_priv->vbios->tvdactestval; | ||
50 | |||
51 | dacclk = NVReadRAMDAC(dev, 0, NV_PRAMDAC_DACCLK + regoffset); | ||
52 | head = (dacclk & 0x100) >> 8; | ||
53 | |||
54 | /* Save the previous state. */ | ||
55 | gpio1 = nv17_gpio_get(dev, DCB_GPIO_TVDAC1); | ||
56 | gpio0 = nv17_gpio_get(dev, DCB_GPIO_TVDAC0); | ||
57 | fp_htotal = NVReadRAMDAC(dev, head, NV_PRAMDAC_FP_HTOTAL); | ||
58 | fp_hsync_start = NVReadRAMDAC(dev, head, NV_PRAMDAC_FP_HSYNC_START); | ||
59 | fp_hsync_end = NVReadRAMDAC(dev, head, NV_PRAMDAC_FP_HSYNC_END); | ||
60 | fp_control = NVReadRAMDAC(dev, head, NV_PRAMDAC_FP_TG_CONTROL); | ||
61 | test_ctrl = NVReadRAMDAC(dev, 0, NV_PRAMDAC_TEST_CONTROL + regoffset); | ||
62 | ctv_1c = NVReadRAMDAC(dev, head, 0x680c1c); | ||
63 | ctv_14 = NVReadRAMDAC(dev, head, 0x680c14); | ||
64 | ctv_6c = NVReadRAMDAC(dev, head, 0x680c6c); | ||
65 | |||
66 | /* Prepare the DAC for load detection. */ | ||
67 | nv17_gpio_set(dev, DCB_GPIO_TVDAC1, true); | ||
68 | nv17_gpio_set(dev, DCB_GPIO_TVDAC0, true); | ||
69 | |||
70 | NVWriteRAMDAC(dev, head, NV_PRAMDAC_FP_HTOTAL, 1343); | ||
71 | NVWriteRAMDAC(dev, head, NV_PRAMDAC_FP_HSYNC_START, 1047); | ||
72 | NVWriteRAMDAC(dev, head, NV_PRAMDAC_FP_HSYNC_END, 1183); | ||
73 | NVWriteRAMDAC(dev, head, NV_PRAMDAC_FP_TG_CONTROL, | ||
74 | NV_PRAMDAC_FP_TG_CONTROL_DISPEN_POS | | ||
75 | NV_PRAMDAC_FP_TG_CONTROL_WIDTH_12 | | ||
76 | NV_PRAMDAC_FP_TG_CONTROL_READ_PROG | | ||
77 | NV_PRAMDAC_FP_TG_CONTROL_HSYNC_POS | | ||
78 | NV_PRAMDAC_FP_TG_CONTROL_VSYNC_POS); | ||
79 | |||
80 | NVWriteRAMDAC(dev, 0, NV_PRAMDAC_TEST_CONTROL + regoffset, 0); | ||
81 | |||
82 | NVWriteRAMDAC(dev, 0, NV_PRAMDAC_DACCLK + regoffset, | ||
83 | (dacclk & ~0xff) | 0x22); | ||
84 | msleep(1); | ||
85 | NVWriteRAMDAC(dev, 0, NV_PRAMDAC_DACCLK + regoffset, | ||
86 | (dacclk & ~0xff) | 0x21); | ||
87 | |||
88 | NVWriteRAMDAC(dev, head, 0x680c1c, 1 << 20); | ||
89 | NVWriteRAMDAC(dev, head, 0x680c14, 4 << 16); | ||
90 | |||
91 | /* Sample pin 0x4 (usually S-video luma). */ | ||
92 | NVWriteRAMDAC(dev, head, 0x680c6c, testval >> 10 & 0x3ff); | ||
93 | msleep(20); | ||
94 | sample |= NVReadRAMDAC(dev, 0, NV_PRAMDAC_TEST_CONTROL + regoffset) | ||
95 | & 0x4 << 28; | ||
96 | |||
97 | /* Sample the remaining pins. */ | ||
98 | NVWriteRAMDAC(dev, head, 0x680c6c, testval & 0x3ff); | ||
99 | msleep(20); | ||
100 | sample |= NVReadRAMDAC(dev, 0, NV_PRAMDAC_TEST_CONTROL + regoffset) | ||
101 | & 0xa << 28; | ||
102 | |||
103 | /* Restore the previous state. */ | ||
104 | NVWriteRAMDAC(dev, head, 0x680c1c, ctv_1c); | ||
105 | NVWriteRAMDAC(dev, head, 0x680c14, ctv_14); | ||
106 | NVWriteRAMDAC(dev, head, 0x680c6c, ctv_6c); | ||
107 | NVWriteRAMDAC(dev, 0, NV_PRAMDAC_DACCLK + regoffset, dacclk); | ||
108 | NVWriteRAMDAC(dev, 0, NV_PRAMDAC_TEST_CONTROL + regoffset, test_ctrl); | ||
109 | NVWriteRAMDAC(dev, head, NV_PRAMDAC_FP_TG_CONTROL, fp_control); | ||
110 | NVWriteRAMDAC(dev, head, NV_PRAMDAC_FP_HSYNC_END, fp_hsync_end); | ||
111 | NVWriteRAMDAC(dev, head, NV_PRAMDAC_FP_HSYNC_START, fp_hsync_start); | ||
112 | NVWriteRAMDAC(dev, head, NV_PRAMDAC_FP_HTOTAL, fp_htotal); | ||
113 | nv17_gpio_set(dev, DCB_GPIO_TVDAC1, gpio1); | ||
114 | nv17_gpio_set(dev, DCB_GPIO_TVDAC0, gpio0); | ||
115 | |||
116 | return sample; | ||
117 | } | ||
118 | |||
119 | static enum drm_connector_status | ||
120 | nv17_tv_detect(struct drm_encoder *encoder, struct drm_connector *connector) | ||
121 | { | ||
122 | struct drm_device *dev = encoder->dev; | ||
123 | struct drm_nouveau_private *dev_priv = dev->dev_private; | ||
124 | struct drm_mode_config *conf = &dev->mode_config; | ||
40 | struct nv17_tv_encoder *tv_enc = to_tv_enc(encoder); | 125 | struct nv17_tv_encoder *tv_enc = to_tv_enc(encoder); |
126 | struct dcb_entry *dcb = tv_enc->base.dcb; | ||
41 | 127 | ||
42 | tv_enc->pin_mask = pin_mask >> 28 & 0xe; | 128 | if (dev_priv->chipset == 0x42 || |
129 | dev_priv->chipset == 0x43) | ||
130 | tv_enc->pin_mask = nv42_tv_sample_load(encoder) >> 28 & 0xe; | ||
131 | else | ||
132 | tv_enc->pin_mask = nv17_dac_sample_load(encoder) >> 28 & 0xe; | ||
43 | 133 | ||
44 | switch (tv_enc->pin_mask) { | 134 | switch (tv_enc->pin_mask) { |
45 | case 0x2: | 135 | case 0x2: |
@@ -50,7 +140,7 @@ enum drm_connector_status nv17_tv_detect(struct drm_encoder *encoder, | |||
50 | tv_enc->subconnector = DRM_MODE_SUBCONNECTOR_SVIDEO; | 140 | tv_enc->subconnector = DRM_MODE_SUBCONNECTOR_SVIDEO; |
51 | break; | 141 | break; |
52 | case 0xe: | 142 | case 0xe: |
53 | if (nouveau_encoder(encoder)->dcb->tvconf.has_component_output) | 143 | if (dcb->tvconf.has_component_output) |
54 | tv_enc->subconnector = DRM_MODE_SUBCONNECTOR_Component; | 144 | tv_enc->subconnector = DRM_MODE_SUBCONNECTOR_Component; |
55 | else | 145 | else |
56 | tv_enc->subconnector = DRM_MODE_SUBCONNECTOR_SCART; | 146 | tv_enc->subconnector = DRM_MODE_SUBCONNECTOR_SCART; |
@@ -61,11 +151,16 @@ enum drm_connector_status nv17_tv_detect(struct drm_encoder *encoder, | |||
61 | } | 151 | } |
62 | 152 | ||
63 | drm_connector_property_set_value(connector, | 153 | drm_connector_property_set_value(connector, |
64 | encoder->dev->mode_config.tv_subconnector_property, | 154 | conf->tv_subconnector_property, |
65 | tv_enc->subconnector); | 155 | tv_enc->subconnector); |
66 | 156 | ||
67 | return tv_enc->subconnector ? connector_status_connected : | 157 | if (tv_enc->subconnector) { |
68 | connector_status_disconnected; | 158 | NV_INFO(dev, "Load detected on output %c\n", |
159 | '@' + ffs(dcb->or)); | ||
160 | return connector_status_connected; | ||
161 | } else { | ||
162 | return connector_status_disconnected; | ||
163 | } | ||
69 | } | 164 | } |
70 | 165 | ||
71 | static const struct { | 166 | static const struct { |
@@ -633,7 +728,7 @@ static struct drm_encoder_helper_funcs nv17_tv_helper_funcs = { | |||
633 | .prepare = nv17_tv_prepare, | 728 | .prepare = nv17_tv_prepare, |
634 | .commit = nv17_tv_commit, | 729 | .commit = nv17_tv_commit, |
635 | .mode_set = nv17_tv_mode_set, | 730 | .mode_set = nv17_tv_mode_set, |
636 | .detect = nv17_dac_detect, | 731 | .detect = nv17_tv_detect, |
637 | }; | 732 | }; |
638 | 733 | ||
639 | static struct drm_encoder_slave_funcs nv17_tv_slave_funcs = { | 734 | static struct drm_encoder_slave_funcs nv17_tv_slave_funcs = { |
diff --git a/drivers/gpu/drm/nouveau/nv20_graph.c b/drivers/gpu/drm/nouveau/nv20_graph.c index 18ba74f19703..d6fc0a82f03d 100644 --- a/drivers/gpu/drm/nouveau/nv20_graph.c +++ b/drivers/gpu/drm/nouveau/nv20_graph.c | |||
@@ -514,6 +514,27 @@ nv20_graph_rdi(struct drm_device *dev) | |||
514 | nouveau_wait_for_idle(dev); | 514 | nouveau_wait_for_idle(dev); |
515 | } | 515 | } |
516 | 516 | ||
517 | void | ||
518 | nv20_graph_set_region_tiling(struct drm_device *dev, int i, uint32_t addr, | ||
519 | uint32_t size, uint32_t pitch) | ||
520 | { | ||
521 | uint32_t limit = max(1u, addr + size) - 1; | ||
522 | |||
523 | if (pitch) | ||
524 | addr |= 1; | ||
525 | |||
526 | nv_wr32(dev, NV20_PGRAPH_TLIMIT(i), limit); | ||
527 | nv_wr32(dev, NV20_PGRAPH_TSIZE(i), pitch); | ||
528 | nv_wr32(dev, NV20_PGRAPH_TILE(i), addr); | ||
529 | |||
530 | nv_wr32(dev, NV10_PGRAPH_RDI_INDEX, 0x00EA0030 + 4 * i); | ||
531 | nv_wr32(dev, NV10_PGRAPH_RDI_DATA, limit); | ||
532 | nv_wr32(dev, NV10_PGRAPH_RDI_INDEX, 0x00EA0050 + 4 * i); | ||
533 | nv_wr32(dev, NV10_PGRAPH_RDI_DATA, pitch); | ||
534 | nv_wr32(dev, NV10_PGRAPH_RDI_INDEX, 0x00EA0010 + 4 * i); | ||
535 | nv_wr32(dev, NV10_PGRAPH_RDI_DATA, addr); | ||
536 | } | ||
537 | |||
517 | int | 538 | int |
518 | nv20_graph_init(struct drm_device *dev) | 539 | nv20_graph_init(struct drm_device *dev) |
519 | { | 540 | { |
@@ -572,27 +593,10 @@ nv20_graph_init(struct drm_device *dev) | |||
572 | nv_wr32(dev, NV10_PGRAPH_RDI_DATA , 0x00000030); | 593 | nv_wr32(dev, NV10_PGRAPH_RDI_DATA , 0x00000030); |
573 | } | 594 | } |
574 | 595 | ||
575 | /* copy tile info from PFB */ | 596 | /* Turn all the tiling regions off. */ |
576 | for (i = 0; i < NV10_PFB_TILE__SIZE; i++) { | 597 | for (i = 0; i < NV10_PFB_TILE__SIZE; i++) |
577 | nv_wr32(dev, 0x00400904 + i * 0x10, | 598 | nv20_graph_set_region_tiling(dev, i, 0, 0, 0); |
578 | nv_rd32(dev, NV10_PFB_TLIMIT(i))); | 599 | |
579 | /* which is NV40_PGRAPH_TLIMIT0(i) ?? */ | ||
580 | nv_wr32(dev, NV10_PGRAPH_RDI_INDEX, 0x00EA0030 + i * 4); | ||
581 | nv_wr32(dev, NV10_PGRAPH_RDI_DATA, | ||
582 | nv_rd32(dev, NV10_PFB_TLIMIT(i))); | ||
583 | nv_wr32(dev, 0x00400908 + i * 0x10, | ||
584 | nv_rd32(dev, NV10_PFB_TSIZE(i))); | ||
585 | /* which is NV40_PGRAPH_TSIZE0(i) ?? */ | ||
586 | nv_wr32(dev, NV10_PGRAPH_RDI_INDEX, 0x00EA0050 + i * 4); | ||
587 | nv_wr32(dev, NV10_PGRAPH_RDI_DATA, | ||
588 | nv_rd32(dev, NV10_PFB_TSIZE(i))); | ||
589 | nv_wr32(dev, 0x00400900 + i * 0x10, | ||
590 | nv_rd32(dev, NV10_PFB_TILE(i))); | ||
591 | /* which is NV40_PGRAPH_TILE0(i) ?? */ | ||
592 | nv_wr32(dev, NV10_PGRAPH_RDI_INDEX, 0x00EA0010 + i * 4); | ||
593 | nv_wr32(dev, NV10_PGRAPH_RDI_DATA, | ||
594 | nv_rd32(dev, NV10_PFB_TILE(i))); | ||
595 | } | ||
596 | for (i = 0; i < 8; i++) { | 600 | for (i = 0; i < 8; i++) { |
597 | nv_wr32(dev, 0x400980 + i * 4, nv_rd32(dev, 0x100300 + i * 4)); | 601 | nv_wr32(dev, 0x400980 + i * 4, nv_rd32(dev, 0x100300 + i * 4)); |
598 | nv_wr32(dev, NV10_PGRAPH_RDI_INDEX, 0x00EA0090 + i * 4); | 602 | nv_wr32(dev, NV10_PGRAPH_RDI_INDEX, 0x00EA0090 + i * 4); |
@@ -704,18 +708,9 @@ nv30_graph_init(struct drm_device *dev) | |||
704 | 708 | ||
705 | nv_wr32(dev, 0x4000c0, 0x00000016); | 709 | nv_wr32(dev, 0x4000c0, 0x00000016); |
706 | 710 | ||
707 | /* copy tile info from PFB */ | 711 | /* Turn all the tiling regions off. */ |
708 | for (i = 0; i < NV10_PFB_TILE__SIZE; i++) { | 712 | for (i = 0; i < NV10_PFB_TILE__SIZE; i++) |
709 | nv_wr32(dev, 0x00400904 + i * 0x10, | 713 | nv20_graph_set_region_tiling(dev, i, 0, 0, 0); |
710 | nv_rd32(dev, NV10_PFB_TLIMIT(i))); | ||
711 | /* which is NV40_PGRAPH_TLIMIT0(i) ?? */ | ||
712 | nv_wr32(dev, 0x00400908 + i * 0x10, | ||
713 | nv_rd32(dev, NV10_PFB_TSIZE(i))); | ||
714 | /* which is NV40_PGRAPH_TSIZE0(i) ?? */ | ||
715 | nv_wr32(dev, 0x00400900 + i * 0x10, | ||
716 | nv_rd32(dev, NV10_PFB_TILE(i))); | ||
717 | /* which is NV40_PGRAPH_TILE0(i) ?? */ | ||
718 | } | ||
719 | 714 | ||
720 | nv_wr32(dev, NV10_PGRAPH_CTX_CONTROL, 0x10000100); | 715 | nv_wr32(dev, NV10_PGRAPH_CTX_CONTROL, 0x10000100); |
721 | nv_wr32(dev, NV10_PGRAPH_STATE , 0xFFFFFFFF); | 716 | nv_wr32(dev, NV10_PGRAPH_STATE , 0xFFFFFFFF); |
diff --git a/drivers/gpu/drm/nouveau/nv40_fb.c b/drivers/gpu/drm/nouveau/nv40_fb.c index ca1d27107a8e..3cd07d8d5bd7 100644 --- a/drivers/gpu/drm/nouveau/nv40_fb.c +++ b/drivers/gpu/drm/nouveau/nv40_fb.c | |||
@@ -3,12 +3,37 @@ | |||
3 | #include "nouveau_drv.h" | 3 | #include "nouveau_drv.h" |
4 | #include "nouveau_drm.h" | 4 | #include "nouveau_drm.h" |
5 | 5 | ||
6 | void | ||
7 | nv40_fb_set_region_tiling(struct drm_device *dev, int i, uint32_t addr, | ||
8 | uint32_t size, uint32_t pitch) | ||
9 | { | ||
10 | struct drm_nouveau_private *dev_priv = dev->dev_private; | ||
11 | uint32_t limit = max(1u, addr + size) - 1; | ||
12 | |||
13 | if (pitch) | ||
14 | addr |= 1; | ||
15 | |||
16 | switch (dev_priv->chipset) { | ||
17 | case 0x40: | ||
18 | nv_wr32(dev, NV10_PFB_TLIMIT(i), limit); | ||
19 | nv_wr32(dev, NV10_PFB_TSIZE(i), pitch); | ||
20 | nv_wr32(dev, NV10_PFB_TILE(i), addr); | ||
21 | break; | ||
22 | |||
23 | default: | ||
24 | nv_wr32(dev, NV40_PFB_TLIMIT(i), limit); | ||
25 | nv_wr32(dev, NV40_PFB_TSIZE(i), pitch); | ||
26 | nv_wr32(dev, NV40_PFB_TILE(i), addr); | ||
27 | break; | ||
28 | } | ||
29 | } | ||
30 | |||
6 | int | 31 | int |
7 | nv40_fb_init(struct drm_device *dev) | 32 | nv40_fb_init(struct drm_device *dev) |
8 | { | 33 | { |
9 | struct drm_nouveau_private *dev_priv = dev->dev_private; | 34 | struct drm_nouveau_private *dev_priv = dev->dev_private; |
10 | uint32_t fb_bar_size, tmp; | 35 | struct nouveau_fb_engine *pfb = &dev_priv->engine.fb; |
11 | int num_tiles; | 36 | uint32_t tmp; |
12 | int i; | 37 | int i; |
13 | 38 | ||
14 | /* This is strictly a NV4x register (don't know about NV5x). */ | 39 | /* This is strictly a NV4x register (don't know about NV5x). */ |
@@ -23,35 +48,23 @@ nv40_fb_init(struct drm_device *dev) | |||
23 | case 0x45: | 48 | case 0x45: |
24 | tmp = nv_rd32(dev, NV10_PFB_CLOSE_PAGE2); | 49 | tmp = nv_rd32(dev, NV10_PFB_CLOSE_PAGE2); |
25 | nv_wr32(dev, NV10_PFB_CLOSE_PAGE2, tmp & ~(1 << 15)); | 50 | nv_wr32(dev, NV10_PFB_CLOSE_PAGE2, tmp & ~(1 << 15)); |
26 | num_tiles = NV10_PFB_TILE__SIZE; | 51 | pfb->num_tiles = NV10_PFB_TILE__SIZE; |
27 | break; | 52 | break; |
28 | case 0x46: /* G72 */ | 53 | case 0x46: /* G72 */ |
29 | case 0x47: /* G70 */ | 54 | case 0x47: /* G70 */ |
30 | case 0x49: /* G71 */ | 55 | case 0x49: /* G71 */ |
31 | case 0x4b: /* G73 */ | 56 | case 0x4b: /* G73 */ |
32 | case 0x4c: /* C51 (G7X version) */ | 57 | case 0x4c: /* C51 (G7X version) */ |
33 | num_tiles = NV40_PFB_TILE__SIZE_1; | 58 | pfb->num_tiles = NV40_PFB_TILE__SIZE_1; |
34 | break; | 59 | break; |
35 | default: | 60 | default: |
36 | num_tiles = NV40_PFB_TILE__SIZE_0; | 61 | pfb->num_tiles = NV40_PFB_TILE__SIZE_0; |
37 | break; | 62 | break; |
38 | } | 63 | } |
39 | 64 | ||
40 | fb_bar_size = drm_get_resource_len(dev, 0) - 1; | 65 | /* Turn all the tiling regions off. */ |
41 | switch (dev_priv->chipset) { | 66 | for (i = 0; i < pfb->num_tiles; i++) |
42 | case 0x40: | 67 | pfb->set_region_tiling(dev, i, 0, 0, 0); |
43 | for (i = 0; i < num_tiles; i++) { | ||
44 | nv_wr32(dev, NV10_PFB_TILE(i), 0); | ||
45 | nv_wr32(dev, NV10_PFB_TLIMIT(i), fb_bar_size); | ||
46 | } | ||
47 | break; | ||
48 | default: | ||
49 | for (i = 0; i < num_tiles; i++) { | ||
50 | nv_wr32(dev, NV40_PFB_TILE(i), 0); | ||
51 | nv_wr32(dev, NV40_PFB_TLIMIT(i), fb_bar_size); | ||
52 | } | ||
53 | break; | ||
54 | } | ||
55 | 68 | ||
56 | return 0; | 69 | return 0; |
57 | } | 70 | } |
diff --git a/drivers/gpu/drm/nouveau/nv40_graph.c b/drivers/gpu/drm/nouveau/nv40_graph.c index 2b332bb55acf..53e8afe1dcd1 100644 --- a/drivers/gpu/drm/nouveau/nv40_graph.c +++ b/drivers/gpu/drm/nouveau/nv40_graph.c | |||
@@ -181,6 +181,48 @@ nv40_graph_unload_context(struct drm_device *dev) | |||
181 | return ret; | 181 | return ret; |
182 | } | 182 | } |
183 | 183 | ||
184 | void | ||
185 | nv40_graph_set_region_tiling(struct drm_device *dev, int i, uint32_t addr, | ||
186 | uint32_t size, uint32_t pitch) | ||
187 | { | ||
188 | struct drm_nouveau_private *dev_priv = dev->dev_private; | ||
189 | uint32_t limit = max(1u, addr + size) - 1; | ||
190 | |||
191 | if (pitch) | ||
192 | addr |= 1; | ||
193 | |||
194 | switch (dev_priv->chipset) { | ||
195 | case 0x44: | ||
196 | case 0x4a: | ||
197 | case 0x4e: | ||
198 | nv_wr32(dev, NV20_PGRAPH_TSIZE(i), pitch); | ||
199 | nv_wr32(dev, NV20_PGRAPH_TLIMIT(i), limit); | ||
200 | nv_wr32(dev, NV20_PGRAPH_TILE(i), addr); | ||
201 | break; | ||
202 | |||
203 | case 0x46: | ||
204 | case 0x47: | ||
205 | case 0x49: | ||
206 | case 0x4b: | ||
207 | nv_wr32(dev, NV47_PGRAPH_TSIZE(i), pitch); | ||
208 | nv_wr32(dev, NV47_PGRAPH_TLIMIT(i), limit); | ||
209 | nv_wr32(dev, NV47_PGRAPH_TILE(i), addr); | ||
210 | nv_wr32(dev, NV40_PGRAPH_TSIZE1(i), pitch); | ||
211 | nv_wr32(dev, NV40_PGRAPH_TLIMIT1(i), limit); | ||
212 | nv_wr32(dev, NV40_PGRAPH_TILE1(i), addr); | ||
213 | break; | ||
214 | |||
215 | default: | ||
216 | nv_wr32(dev, NV20_PGRAPH_TSIZE(i), pitch); | ||
217 | nv_wr32(dev, NV20_PGRAPH_TLIMIT(i), limit); | ||
218 | nv_wr32(dev, NV20_PGRAPH_TILE(i), addr); | ||
219 | nv_wr32(dev, NV40_PGRAPH_TSIZE1(i), pitch); | ||
220 | nv_wr32(dev, NV40_PGRAPH_TLIMIT1(i), limit); | ||
221 | nv_wr32(dev, NV40_PGRAPH_TILE1(i), addr); | ||
222 | break; | ||
223 | } | ||
224 | } | ||
225 | |||
184 | /* | 226 | /* |
185 | * G70 0x47 | 227 | * G70 0x47 |
186 | * G71 0x49 | 228 | * G71 0x49 |
@@ -195,7 +237,8 @@ nv40_graph_init(struct drm_device *dev) | |||
195 | { | 237 | { |
196 | struct drm_nouveau_private *dev_priv = | 238 | struct drm_nouveau_private *dev_priv = |
197 | (struct drm_nouveau_private *)dev->dev_private; | 239 | (struct drm_nouveau_private *)dev->dev_private; |
198 | uint32_t vramsz, tmp; | 240 | struct nouveau_fb_engine *pfb = &dev_priv->engine.fb; |
241 | uint32_t vramsz; | ||
199 | int i, j; | 242 | int i, j; |
200 | 243 | ||
201 | nv_wr32(dev, NV03_PMC_ENABLE, nv_rd32(dev, NV03_PMC_ENABLE) & | 244 | nv_wr32(dev, NV03_PMC_ENABLE, nv_rd32(dev, NV03_PMC_ENABLE) & |
@@ -292,74 +335,9 @@ nv40_graph_init(struct drm_device *dev) | |||
292 | nv_wr32(dev, 0x400b38, 0x2ffff800); | 335 | nv_wr32(dev, 0x400b38, 0x2ffff800); |
293 | nv_wr32(dev, 0x400b3c, 0x00006000); | 336 | nv_wr32(dev, 0x400b3c, 0x00006000); |
294 | 337 | ||
295 | /* copy tile info from PFB */ | 338 | /* Turn all the tiling regions off. */ |
296 | switch (dev_priv->chipset) { | 339 | for (i = 0; i < pfb->num_tiles; i++) |
297 | case 0x40: /* vanilla NV40 */ | 340 | nv40_graph_set_region_tiling(dev, i, 0, 0, 0); |
298 | for (i = 0; i < NV10_PFB_TILE__SIZE; i++) { | ||
299 | tmp = nv_rd32(dev, NV10_PFB_TILE(i)); | ||
300 | nv_wr32(dev, NV40_PGRAPH_TILE0(i), tmp); | ||
301 | nv_wr32(dev, NV40_PGRAPH_TILE1(i), tmp); | ||
302 | tmp = nv_rd32(dev, NV10_PFB_TLIMIT(i)); | ||
303 | nv_wr32(dev, NV40_PGRAPH_TLIMIT0(i), tmp); | ||
304 | nv_wr32(dev, NV40_PGRAPH_TLIMIT1(i), tmp); | ||
305 | tmp = nv_rd32(dev, NV10_PFB_TSIZE(i)); | ||
306 | nv_wr32(dev, NV40_PGRAPH_TSIZE0(i), tmp); | ||
307 | nv_wr32(dev, NV40_PGRAPH_TSIZE1(i), tmp); | ||
308 | tmp = nv_rd32(dev, NV10_PFB_TSTATUS(i)); | ||
309 | nv_wr32(dev, NV40_PGRAPH_TSTATUS0(i), tmp); | ||
310 | nv_wr32(dev, NV40_PGRAPH_TSTATUS1(i), tmp); | ||
311 | } | ||
312 | break; | ||
313 | case 0x44: | ||
314 | case 0x4a: | ||
315 | case 0x4e: /* NV44-based cores don't have 0x406900? */ | ||
316 | for (i = 0; i < NV40_PFB_TILE__SIZE_0; i++) { | ||
317 | tmp = nv_rd32(dev, NV40_PFB_TILE(i)); | ||
318 | nv_wr32(dev, NV40_PGRAPH_TILE0(i), tmp); | ||
319 | tmp = nv_rd32(dev, NV40_PFB_TLIMIT(i)); | ||
320 | nv_wr32(dev, NV40_PGRAPH_TLIMIT0(i), tmp); | ||
321 | tmp = nv_rd32(dev, NV40_PFB_TSIZE(i)); | ||
322 | nv_wr32(dev, NV40_PGRAPH_TSIZE0(i), tmp); | ||
323 | tmp = nv_rd32(dev, NV40_PFB_TSTATUS(i)); | ||
324 | nv_wr32(dev, NV40_PGRAPH_TSTATUS0(i), tmp); | ||
325 | } | ||
326 | break; | ||
327 | case 0x46: | ||
328 | case 0x47: | ||
329 | case 0x49: | ||
330 | case 0x4b: /* G7X-based cores */ | ||
331 | for (i = 0; i < NV40_PFB_TILE__SIZE_1; i++) { | ||
332 | tmp = nv_rd32(dev, NV40_PFB_TILE(i)); | ||
333 | nv_wr32(dev, NV47_PGRAPH_TILE0(i), tmp); | ||
334 | nv_wr32(dev, NV40_PGRAPH_TILE1(i), tmp); | ||
335 | tmp = nv_rd32(dev, NV40_PFB_TLIMIT(i)); | ||
336 | nv_wr32(dev, NV47_PGRAPH_TLIMIT0(i), tmp); | ||
337 | nv_wr32(dev, NV40_PGRAPH_TLIMIT1(i), tmp); | ||
338 | tmp = nv_rd32(dev, NV40_PFB_TSIZE(i)); | ||
339 | nv_wr32(dev, NV47_PGRAPH_TSIZE0(i), tmp); | ||
340 | nv_wr32(dev, NV40_PGRAPH_TSIZE1(i), tmp); | ||
341 | tmp = nv_rd32(dev, NV40_PFB_TSTATUS(i)); | ||
342 | nv_wr32(dev, NV47_PGRAPH_TSTATUS0(i), tmp); | ||
343 | nv_wr32(dev, NV40_PGRAPH_TSTATUS1(i), tmp); | ||
344 | } | ||
345 | break; | ||
346 | default: /* everything else */ | ||
347 | for (i = 0; i < NV40_PFB_TILE__SIZE_0; i++) { | ||
348 | tmp = nv_rd32(dev, NV40_PFB_TILE(i)); | ||
349 | nv_wr32(dev, NV40_PGRAPH_TILE0(i), tmp); | ||
350 | nv_wr32(dev, NV40_PGRAPH_TILE1(i), tmp); | ||
351 | tmp = nv_rd32(dev, NV40_PFB_TLIMIT(i)); | ||
352 | nv_wr32(dev, NV40_PGRAPH_TLIMIT0(i), tmp); | ||
353 | nv_wr32(dev, NV40_PGRAPH_TLIMIT1(i), tmp); | ||
354 | tmp = nv_rd32(dev, NV40_PFB_TSIZE(i)); | ||
355 | nv_wr32(dev, NV40_PGRAPH_TSIZE0(i), tmp); | ||
356 | nv_wr32(dev, NV40_PGRAPH_TSIZE1(i), tmp); | ||
357 | tmp = nv_rd32(dev, NV40_PFB_TSTATUS(i)); | ||
358 | nv_wr32(dev, NV40_PGRAPH_TSTATUS0(i), tmp); | ||
359 | nv_wr32(dev, NV40_PGRAPH_TSTATUS1(i), tmp); | ||
360 | } | ||
361 | break; | ||
362 | } | ||
363 | 341 | ||
364 | /* begin RAM config */ | 342 | /* begin RAM config */ |
365 | vramsz = drm_get_resource_len(dev, 0) - 1; | 343 | vramsz = drm_get_resource_len(dev, 0) - 1; |
diff --git a/drivers/gpu/drm/nouveau/nv50_display.c b/drivers/gpu/drm/nouveau/nv50_display.c index a9263d92a231..90f0bf59fbcd 100644 --- a/drivers/gpu/drm/nouveau/nv50_display.c +++ b/drivers/gpu/drm/nouveau/nv50_display.c | |||
@@ -690,9 +690,21 @@ nv50_display_script_select(struct drm_device *dev, struct dcb_entry *dcbent, | |||
690 | int pxclk) | 690 | int pxclk) |
691 | { | 691 | { |
692 | struct drm_nouveau_private *dev_priv = dev->dev_private; | 692 | struct drm_nouveau_private *dev_priv = dev->dev_private; |
693 | struct nouveau_connector *nv_connector = NULL; | ||
694 | struct drm_encoder *encoder; | ||
693 | struct nvbios *bios = &dev_priv->VBIOS; | 695 | struct nvbios *bios = &dev_priv->VBIOS; |
694 | uint32_t mc, script = 0, or; | 696 | uint32_t mc, script = 0, or; |
695 | 697 | ||
698 | list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { | ||
699 | struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); | ||
700 | |||
701 | if (nv_encoder->dcb != dcbent) | ||
702 | continue; | ||
703 | |||
704 | nv_connector = nouveau_encoder_connector_get(nv_encoder); | ||
705 | break; | ||
706 | } | ||
707 | |||
696 | or = ffs(dcbent->or) - 1; | 708 | or = ffs(dcbent->or) - 1; |
697 | mc = nv50_display_mode_ctrl(dev, dcbent->type != OUTPUT_ANALOG, or); | 709 | mc = nv50_display_mode_ctrl(dev, dcbent->type != OUTPUT_ANALOG, or); |
698 | switch (dcbent->type) { | 710 | switch (dcbent->type) { |
@@ -711,6 +723,11 @@ nv50_display_script_select(struct drm_device *dev, struct dcb_entry *dcbent, | |||
711 | } else | 723 | } else |
712 | if (bios->fp.strapless_is_24bit & 1) | 724 | if (bios->fp.strapless_is_24bit & 1) |
713 | script |= 0x0200; | 725 | script |= 0x0200; |
726 | |||
727 | if (nv_connector && nv_connector->edid && | ||
728 | (nv_connector->edid->revision >= 4) && | ||
729 | (nv_connector->edid->input & 0x70) >= 0x20) | ||
730 | script |= 0x0200; | ||
714 | } | 731 | } |
715 | 732 | ||
716 | if (nouveau_uscript_lvds >= 0) { | 733 | if (nouveau_uscript_lvds >= 0) { |
diff --git a/drivers/gpu/drm/nouveau/nv50_fbcon.c b/drivers/gpu/drm/nouveau/nv50_fbcon.c index 6bcc6d39e9b0..e4f279ee61cf 100644 --- a/drivers/gpu/drm/nouveau/nv50_fbcon.c +++ b/drivers/gpu/drm/nouveau/nv50_fbcon.c | |||
@@ -16,9 +16,7 @@ nv50_fbcon_fillrect(struct fb_info *info, const struct fb_fillrect *rect) | |||
16 | 16 | ||
17 | if (!(info->flags & FBINFO_HWACCEL_DISABLED) && | 17 | if (!(info->flags & FBINFO_HWACCEL_DISABLED) && |
18 | RING_SPACE(chan, rect->rop == ROP_COPY ? 7 : 11)) { | 18 | RING_SPACE(chan, rect->rop == ROP_COPY ? 7 : 11)) { |
19 | NV_ERROR(dev, "GPU lockup - switching to software fbcon\n"); | 19 | nouveau_fbcon_gpu_lockup(info); |
20 | |||
21 | info->flags |= FBINFO_HWACCEL_DISABLED; | ||
22 | } | 20 | } |
23 | 21 | ||
24 | if (info->flags & FBINFO_HWACCEL_DISABLED) { | 22 | if (info->flags & FBINFO_HWACCEL_DISABLED) { |
@@ -31,7 +29,11 @@ nv50_fbcon_fillrect(struct fb_info *info, const struct fb_fillrect *rect) | |||
31 | OUT_RING(chan, 1); | 29 | OUT_RING(chan, 1); |
32 | } | 30 | } |
33 | BEGIN_RING(chan, NvSub2D, 0x0588, 1); | 31 | BEGIN_RING(chan, NvSub2D, 0x0588, 1); |
34 | OUT_RING(chan, rect->color); | 32 | if (info->fix.visual == FB_VISUAL_TRUECOLOR || |
33 | info->fix.visual == FB_VISUAL_DIRECTCOLOR) | ||
34 | OUT_RING(chan, ((uint32_t *)info->pseudo_palette)[rect->color]); | ||
35 | else | ||
36 | OUT_RING(chan, rect->color); | ||
35 | BEGIN_RING(chan, NvSub2D, 0x0600, 4); | 37 | BEGIN_RING(chan, NvSub2D, 0x0600, 4); |
36 | OUT_RING(chan, rect->dx); | 38 | OUT_RING(chan, rect->dx); |
37 | OUT_RING(chan, rect->dy); | 39 | OUT_RING(chan, rect->dy); |
@@ -56,9 +58,7 @@ nv50_fbcon_copyarea(struct fb_info *info, const struct fb_copyarea *region) | |||
56 | return; | 58 | return; |
57 | 59 | ||
58 | if (!(info->flags & FBINFO_HWACCEL_DISABLED) && RING_SPACE(chan, 12)) { | 60 | if (!(info->flags & FBINFO_HWACCEL_DISABLED) && RING_SPACE(chan, 12)) { |
59 | NV_ERROR(dev, "GPU lockup - switching to software fbcon\n"); | 61 | nouveau_fbcon_gpu_lockup(info); |
60 | |||
61 | info->flags |= FBINFO_HWACCEL_DISABLED; | ||
62 | } | 62 | } |
63 | 63 | ||
64 | if (info->flags & FBINFO_HWACCEL_DISABLED) { | 64 | if (info->flags & FBINFO_HWACCEL_DISABLED) { |
@@ -101,8 +101,7 @@ nv50_fbcon_imageblit(struct fb_info *info, const struct fb_image *image) | |||
101 | } | 101 | } |
102 | 102 | ||
103 | if (!(info->flags & FBINFO_HWACCEL_DISABLED) && RING_SPACE(chan, 11)) { | 103 | if (!(info->flags & FBINFO_HWACCEL_DISABLED) && RING_SPACE(chan, 11)) { |
104 | NV_ERROR(dev, "GPU lockup - switching to software fbcon\n"); | 104 | nouveau_fbcon_gpu_lockup(info); |
105 | info->flags |= FBINFO_HWACCEL_DISABLED; | ||
106 | } | 105 | } |
107 | 106 | ||
108 | if (info->flags & FBINFO_HWACCEL_DISABLED) { | 107 | if (info->flags & FBINFO_HWACCEL_DISABLED) { |
@@ -135,9 +134,7 @@ nv50_fbcon_imageblit(struct fb_info *info, const struct fb_image *image) | |||
135 | int push = dwords > 2047 ? 2047 : dwords; | 134 | int push = dwords > 2047 ? 2047 : dwords; |
136 | 135 | ||
137 | if (RING_SPACE(chan, push + 1)) { | 136 | if (RING_SPACE(chan, push + 1)) { |
138 | NV_ERROR(dev, | 137 | nouveau_fbcon_gpu_lockup(info); |
139 | "GPU lockup - switching to software fbcon\n"); | ||
140 | info->flags |= FBINFO_HWACCEL_DISABLED; | ||
141 | cfb_imageblit(info, image); | 138 | cfb_imageblit(info, image); |
142 | return; | 139 | return; |
143 | } | 140 | } |
@@ -199,7 +196,7 @@ nv50_fbcon_accel_init(struct fb_info *info) | |||
199 | 196 | ||
200 | ret = RING_SPACE(chan, 59); | 197 | ret = RING_SPACE(chan, 59); |
201 | if (ret) { | 198 | if (ret) { |
202 | NV_ERROR(dev, "GPU lockup - switching to software fbcon\n"); | 199 | nouveau_fbcon_gpu_lockup(info); |
203 | return ret; | 200 | return ret; |
204 | } | 201 | } |
205 | 202 | ||
diff --git a/drivers/gpu/drm/nouveau/nv50_fifo.c b/drivers/gpu/drm/nouveau/nv50_fifo.c index b7282284f080..39caf167587d 100644 --- a/drivers/gpu/drm/nouveau/nv50_fifo.c +++ b/drivers/gpu/drm/nouveau/nv50_fifo.c | |||
@@ -384,8 +384,8 @@ nv50_fifo_load_context(struct nouveau_channel *chan) | |||
384 | nv_wr32(dev, NV40_PFIFO_CACHE1_DATA(ptr), | 384 | nv_wr32(dev, NV40_PFIFO_CACHE1_DATA(ptr), |
385 | nv_ro32(dev, cache, (ptr * 2) + 1)); | 385 | nv_ro32(dev, cache, (ptr * 2) + 1)); |
386 | } | 386 | } |
387 | nv_wr32(dev, 0x3210, cnt << 2); | 387 | nv_wr32(dev, NV03_PFIFO_CACHE1_PUT, cnt << 2); |
388 | nv_wr32(dev, 0x3270, 0); | 388 | nv_wr32(dev, NV03_PFIFO_CACHE1_GET, 0); |
389 | 389 | ||
390 | /* guessing that all the 0x34xx regs aren't on NV50 */ | 390 | /* guessing that all the 0x34xx regs aren't on NV50 */ |
391 | if (!IS_G80) { | 391 | if (!IS_G80) { |
@@ -398,8 +398,6 @@ nv50_fifo_load_context(struct nouveau_channel *chan) | |||
398 | 398 | ||
399 | dev_priv->engine.instmem.finish_access(dev); | 399 | dev_priv->engine.instmem.finish_access(dev); |
400 | 400 | ||
401 | nv_wr32(dev, NV03_PFIFO_CACHE1_GET, 0); | ||
402 | nv_wr32(dev, NV03_PFIFO_CACHE1_PUT, 0); | ||
403 | nv_wr32(dev, NV03_PFIFO_CACHE1_PUSH1, chan->id | (1<<16)); | 401 | nv_wr32(dev, NV03_PFIFO_CACHE1_PUSH1, chan->id | (1<<16)); |
404 | return 0; | 402 | return 0; |
405 | } | 403 | } |
diff --git a/drivers/gpu/drm/radeon/Makefile b/drivers/gpu/drm/radeon/Makefile index b5f5fe75e6af..1cc7b937b1ea 100644 --- a/drivers/gpu/drm/radeon/Makefile +++ b/drivers/gpu/drm/radeon/Makefile | |||
@@ -24,6 +24,9 @@ $(obj)/rv515_reg_safe.h: $(src)/reg_srcs/rv515 $(obj)/mkregtable | |||
24 | $(obj)/r300_reg_safe.h: $(src)/reg_srcs/r300 $(obj)/mkregtable | 24 | $(obj)/r300_reg_safe.h: $(src)/reg_srcs/r300 $(obj)/mkregtable |
25 | $(call if_changed,mkregtable) | 25 | $(call if_changed,mkregtable) |
26 | 26 | ||
27 | $(obj)/r420_reg_safe.h: $(src)/reg_srcs/r420 $(obj)/mkregtable | ||
28 | $(call if_changed,mkregtable) | ||
29 | |||
27 | $(obj)/rs600_reg_safe.h: $(src)/reg_srcs/rs600 $(obj)/mkregtable | 30 | $(obj)/rs600_reg_safe.h: $(src)/reg_srcs/rs600 $(obj)/mkregtable |
28 | $(call if_changed,mkregtable) | 31 | $(call if_changed,mkregtable) |
29 | 32 | ||
@@ -35,6 +38,8 @@ $(obj)/rv515.o: $(obj)/rv515_reg_safe.h | |||
35 | 38 | ||
36 | $(obj)/r300.o: $(obj)/r300_reg_safe.h | 39 | $(obj)/r300.o: $(obj)/r300_reg_safe.h |
37 | 40 | ||
41 | $(obj)/r420.o: $(obj)/r420_reg_safe.h | ||
42 | |||
38 | $(obj)/rs600.o: $(obj)/rs600_reg_safe.h | 43 | $(obj)/rs600.o: $(obj)/rs600_reg_safe.h |
39 | 44 | ||
40 | radeon-y := radeon_drv.o radeon_cp.o radeon_state.o radeon_mem.o \ | 45 | radeon-y := radeon_drv.o radeon_cp.o radeon_state.o radeon_mem.o \ |
diff --git a/drivers/gpu/drm/radeon/ObjectID.h b/drivers/gpu/drm/radeon/ObjectID.h index 6d0183c61d3b..c714179d1bfa 100644 --- a/drivers/gpu/drm/radeon/ObjectID.h +++ b/drivers/gpu/drm/radeon/ObjectID.h | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright 2006-2007 Advanced Micro Devices, Inc. | 2 | * Copyright 2006-2007 Advanced Micro Devices, Inc. |
3 | * | 3 | * |
4 | * Permission is hereby granted, free of charge, to any person obtaining a | 4 | * Permission is hereby granted, free of charge, to any person obtaining a |
5 | * copy of this software and associated documentation files (the "Software"), | 5 | * copy of this software and associated documentation files (the "Software"), |
@@ -41,14 +41,14 @@ | |||
41 | /****************************************************/ | 41 | /****************************************************/ |
42 | /* Encoder Object ID Definition */ | 42 | /* Encoder Object ID Definition */ |
43 | /****************************************************/ | 43 | /****************************************************/ |
44 | #define ENCODER_OBJECT_ID_NONE 0x00 | 44 | #define ENCODER_OBJECT_ID_NONE 0x00 |
45 | 45 | ||
46 | /* Radeon Class Display Hardware */ | 46 | /* Radeon Class Display Hardware */ |
47 | #define ENCODER_OBJECT_ID_INTERNAL_LVDS 0x01 | 47 | #define ENCODER_OBJECT_ID_INTERNAL_LVDS 0x01 |
48 | #define ENCODER_OBJECT_ID_INTERNAL_TMDS1 0x02 | 48 | #define ENCODER_OBJECT_ID_INTERNAL_TMDS1 0x02 |
49 | #define ENCODER_OBJECT_ID_INTERNAL_TMDS2 0x03 | 49 | #define ENCODER_OBJECT_ID_INTERNAL_TMDS2 0x03 |
50 | #define ENCODER_OBJECT_ID_INTERNAL_DAC1 0x04 | 50 | #define ENCODER_OBJECT_ID_INTERNAL_DAC1 0x04 |
51 | #define ENCODER_OBJECT_ID_INTERNAL_DAC2 0x05 /* TV/CV DAC */ | 51 | #define ENCODER_OBJECT_ID_INTERNAL_DAC2 0x05 /* TV/CV DAC */ |
52 | #define ENCODER_OBJECT_ID_INTERNAL_SDVOA 0x06 | 52 | #define ENCODER_OBJECT_ID_INTERNAL_SDVOA 0x06 |
53 | #define ENCODER_OBJECT_ID_INTERNAL_SDVOB 0x07 | 53 | #define ENCODER_OBJECT_ID_INTERNAL_SDVOB 0x07 |
54 | 54 | ||
@@ -56,11 +56,11 @@ | |||
56 | #define ENCODER_OBJECT_ID_SI170B 0x08 | 56 | #define ENCODER_OBJECT_ID_SI170B 0x08 |
57 | #define ENCODER_OBJECT_ID_CH7303 0x09 | 57 | #define ENCODER_OBJECT_ID_CH7303 0x09 |
58 | #define ENCODER_OBJECT_ID_CH7301 0x0A | 58 | #define ENCODER_OBJECT_ID_CH7301 0x0A |
59 | #define ENCODER_OBJECT_ID_INTERNAL_DVO1 0x0B /* This belongs to Radeon Class Display Hardware */ | 59 | #define ENCODER_OBJECT_ID_INTERNAL_DVO1 0x0B /* This belongs to Radeon Class Display Hardware */ |
60 | #define ENCODER_OBJECT_ID_EXTERNAL_SDVOA 0x0C | 60 | #define ENCODER_OBJECT_ID_EXTERNAL_SDVOA 0x0C |
61 | #define ENCODER_OBJECT_ID_EXTERNAL_SDVOB 0x0D | 61 | #define ENCODER_OBJECT_ID_EXTERNAL_SDVOB 0x0D |
62 | #define ENCODER_OBJECT_ID_TITFP513 0x0E | 62 | #define ENCODER_OBJECT_ID_TITFP513 0x0E |
63 | #define ENCODER_OBJECT_ID_INTERNAL_LVTM1 0x0F /* not used for Radeon */ | 63 | #define ENCODER_OBJECT_ID_INTERNAL_LVTM1 0x0F /* not used for Radeon */ |
64 | #define ENCODER_OBJECT_ID_VT1623 0x10 | 64 | #define ENCODER_OBJECT_ID_VT1623 0x10 |
65 | #define ENCODER_OBJECT_ID_HDMI_SI1930 0x11 | 65 | #define ENCODER_OBJECT_ID_HDMI_SI1930 0x11 |
66 | #define ENCODER_OBJECT_ID_HDMI_INTERNAL 0x12 | 66 | #define ENCODER_OBJECT_ID_HDMI_INTERNAL 0x12 |
@@ -68,9 +68,9 @@ | |||
68 | #define ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1 0x13 | 68 | #define ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1 0x13 |
69 | #define ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1 0x14 | 69 | #define ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1 0x14 |
70 | #define ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1 0x15 | 70 | #define ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1 0x15 |
71 | #define ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2 0x16 /* Shared with CV/TV and CRT */ | 71 | #define ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2 0x16 /* Shared with CV/TV and CRT */ |
72 | #define ENCODER_OBJECT_ID_SI178 0X17 /* External TMDS (dual link, no HDCP.) */ | 72 | #define ENCODER_OBJECT_ID_SI178 0X17 /* External TMDS (dual link, no HDCP.) */ |
73 | #define ENCODER_OBJECT_ID_MVPU_FPGA 0x18 /* MVPU FPGA chip */ | 73 | #define ENCODER_OBJECT_ID_MVPU_FPGA 0x18 /* MVPU FPGA chip */ |
74 | #define ENCODER_OBJECT_ID_INTERNAL_DDI 0x19 | 74 | #define ENCODER_OBJECT_ID_INTERNAL_DDI 0x19 |
75 | #define ENCODER_OBJECT_ID_VT1625 0x1A | 75 | #define ENCODER_OBJECT_ID_VT1625 0x1A |
76 | #define ENCODER_OBJECT_ID_HDMI_SI1932 0x1B | 76 | #define ENCODER_OBJECT_ID_HDMI_SI1932 0x1B |
@@ -86,7 +86,7 @@ | |||
86 | /****************************************************/ | 86 | /****************************************************/ |
87 | /* Connector Object ID Definition */ | 87 | /* Connector Object ID Definition */ |
88 | /****************************************************/ | 88 | /****************************************************/ |
89 | #define CONNECTOR_OBJECT_ID_NONE 0x00 | 89 | #define CONNECTOR_OBJECT_ID_NONE 0x00 |
90 | #define CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I 0x01 | 90 | #define CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I 0x01 |
91 | #define CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_I 0x02 | 91 | #define CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_I 0x02 |
92 | #define CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_D 0x03 | 92 | #define CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_D 0x03 |
@@ -96,7 +96,7 @@ | |||
96 | #define CONNECTOR_OBJECT_ID_SVIDEO 0x07 | 96 | #define CONNECTOR_OBJECT_ID_SVIDEO 0x07 |
97 | #define CONNECTOR_OBJECT_ID_YPbPr 0x08 | 97 | #define CONNECTOR_OBJECT_ID_YPbPr 0x08 |
98 | #define CONNECTOR_OBJECT_ID_D_CONNECTOR 0x09 | 98 | #define CONNECTOR_OBJECT_ID_D_CONNECTOR 0x09 |
99 | #define CONNECTOR_OBJECT_ID_9PIN_DIN 0x0A /* Supports both CV & TV */ | 99 | #define CONNECTOR_OBJECT_ID_9PIN_DIN 0x0A /* Supports both CV & TV */ |
100 | #define CONNECTOR_OBJECT_ID_SCART 0x0B | 100 | #define CONNECTOR_OBJECT_ID_SCART 0x0B |
101 | #define CONNECTOR_OBJECT_ID_HDMI_TYPE_A 0x0C | 101 | #define CONNECTOR_OBJECT_ID_HDMI_TYPE_A 0x0C |
102 | #define CONNECTOR_OBJECT_ID_HDMI_TYPE_B 0x0D | 102 | #define CONNECTOR_OBJECT_ID_HDMI_TYPE_B 0x0D |
@@ -106,6 +106,8 @@ | |||
106 | #define CONNECTOR_OBJECT_ID_CROSSFIRE 0x11 | 106 | #define CONNECTOR_OBJECT_ID_CROSSFIRE 0x11 |
107 | #define CONNECTOR_OBJECT_ID_HARDCODE_DVI 0x12 | 107 | #define CONNECTOR_OBJECT_ID_HARDCODE_DVI 0x12 |
108 | #define CONNECTOR_OBJECT_ID_DISPLAYPORT 0x13 | 108 | #define CONNECTOR_OBJECT_ID_DISPLAYPORT 0x13 |
109 | #define CONNECTOR_OBJECT_ID_eDP 0x14 | ||
110 | #define CONNECTOR_OBJECT_ID_MXM 0x15 | ||
109 | 111 | ||
110 | /* deleted */ | 112 | /* deleted */ |
111 | 113 | ||
@@ -116,6 +118,14 @@ | |||
116 | #define ROUTER_OBJECT_ID_I2C_EXTENDER_CNTL 0x01 | 118 | #define ROUTER_OBJECT_ID_I2C_EXTENDER_CNTL 0x01 |
117 | 119 | ||
118 | /****************************************************/ | 120 | /****************************************************/ |
121 | /* Generic Object ID Definition */ | ||
122 | /****************************************************/ | ||
123 | #define GENERIC_OBJECT_ID_NONE 0x00 | ||
124 | #define GENERIC_OBJECT_ID_GLSYNC 0x01 | ||
125 | #define GENERIC_OBJECT_ID_PX2_NON_DRIVABLE 0x02 | ||
126 | #define GENERIC_OBJECT_ID_MXM_OPM 0x03 | ||
127 | |||
128 | /****************************************************/ | ||
119 | /* Graphics Object ENUM ID Definition */ | 129 | /* Graphics Object ENUM ID Definition */ |
120 | /****************************************************/ | 130 | /****************************************************/ |
121 | #define GRAPH_OBJECT_ENUM_ID1 0x01 | 131 | #define GRAPH_OBJECT_ENUM_ID1 0x01 |
@@ -124,6 +134,7 @@ | |||
124 | #define GRAPH_OBJECT_ENUM_ID4 0x04 | 134 | #define GRAPH_OBJECT_ENUM_ID4 0x04 |
125 | #define GRAPH_OBJECT_ENUM_ID5 0x05 | 135 | #define GRAPH_OBJECT_ENUM_ID5 0x05 |
126 | #define GRAPH_OBJECT_ENUM_ID6 0x06 | 136 | #define GRAPH_OBJECT_ENUM_ID6 0x06 |
137 | #define GRAPH_OBJECT_ENUM_ID7 0x07 | ||
127 | 138 | ||
128 | /****************************************************/ | 139 | /****************************************************/ |
129 | /* Graphics Object ID Bit definition */ | 140 | /* Graphics Object ID Bit definition */ |
@@ -133,35 +144,35 @@ | |||
133 | #define RESERVED1_ID_MASK 0x0800 | 144 | #define RESERVED1_ID_MASK 0x0800 |
134 | #define OBJECT_TYPE_MASK 0x7000 | 145 | #define OBJECT_TYPE_MASK 0x7000 |
135 | #define RESERVED2_ID_MASK 0x8000 | 146 | #define RESERVED2_ID_MASK 0x8000 |
136 | 147 | ||
137 | #define OBJECT_ID_SHIFT 0x00 | 148 | #define OBJECT_ID_SHIFT 0x00 |
138 | #define ENUM_ID_SHIFT 0x08 | 149 | #define ENUM_ID_SHIFT 0x08 |
139 | #define OBJECT_TYPE_SHIFT 0x0C | 150 | #define OBJECT_TYPE_SHIFT 0x0C |
140 | 151 | ||
152 | |||
141 | /****************************************************/ | 153 | /****************************************************/ |
142 | /* Graphics Object family definition */ | 154 | /* Graphics Object family definition */ |
143 | /****************************************************/ | 155 | /****************************************************/ |
144 | #define CONSTRUCTOBJECTFAMILYID(GRAPHICS_OBJECT_TYPE, GRAPHICS_OBJECT_ID) \ | 156 | #define CONSTRUCTOBJECTFAMILYID(GRAPHICS_OBJECT_TYPE, GRAPHICS_OBJECT_ID) (GRAPHICS_OBJECT_TYPE << OBJECT_TYPE_SHIFT | \ |
145 | (GRAPHICS_OBJECT_TYPE << OBJECT_TYPE_SHIFT | \ | 157 | GRAPHICS_OBJECT_ID << OBJECT_ID_SHIFT) |
146 | GRAPHICS_OBJECT_ID << OBJECT_ID_SHIFT) | ||
147 | /****************************************************/ | 158 | /****************************************************/ |
148 | /* GPU Object ID definition - Shared with BIOS */ | 159 | /* GPU Object ID definition - Shared with BIOS */ |
149 | /****************************************************/ | 160 | /****************************************************/ |
150 | #define GPU_ENUM_ID1 (GRAPH_OBJECT_TYPE_GPU << OBJECT_TYPE_SHIFT |\ | 161 | #define GPU_ENUM_ID1 ( GRAPH_OBJECT_TYPE_GPU << OBJECT_TYPE_SHIFT |\ |
151 | GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT) | 162 | GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT) |
152 | 163 | ||
153 | /****************************************************/ | 164 | /****************************************************/ |
154 | /* Encoder Object ID definition - Shared with BIOS */ | 165 | /* Encoder Object ID definition - Shared with BIOS */ |
155 | /****************************************************/ | 166 | /****************************************************/ |
156 | /* | 167 | /* |
157 | #define ENCODER_INTERNAL_LVDS_ENUM_ID1 0x2101 | 168 | #define ENCODER_INTERNAL_LVDS_ENUM_ID1 0x2101 |
158 | #define ENCODER_INTERNAL_TMDS1_ENUM_ID1 0x2102 | 169 | #define ENCODER_INTERNAL_TMDS1_ENUM_ID1 0x2102 |
159 | #define ENCODER_INTERNAL_TMDS2_ENUM_ID1 0x2103 | 170 | #define ENCODER_INTERNAL_TMDS2_ENUM_ID1 0x2103 |
160 | #define ENCODER_INTERNAL_DAC1_ENUM_ID1 0x2104 | 171 | #define ENCODER_INTERNAL_DAC1_ENUM_ID1 0x2104 |
161 | #define ENCODER_INTERNAL_DAC2_ENUM_ID1 0x2105 | 172 | #define ENCODER_INTERNAL_DAC2_ENUM_ID1 0x2105 |
162 | #define ENCODER_INTERNAL_SDVOA_ENUM_ID1 0x2106 | 173 | #define ENCODER_INTERNAL_SDVOA_ENUM_ID1 0x2106 |
163 | #define ENCODER_INTERNAL_SDVOB_ENUM_ID1 0x2107 | 174 | #define ENCODER_INTERNAL_SDVOB_ENUM_ID1 0x2107 |
164 | #define ENCODER_SIL170B_ENUM_ID1 0x2108 | 175 | #define ENCODER_SIL170B_ENUM_ID1 0x2108 |
165 | #define ENCODER_CH7303_ENUM_ID1 0x2109 | 176 | #define ENCODER_CH7303_ENUM_ID1 0x2109 |
166 | #define ENCODER_CH7301_ENUM_ID1 0x210A | 177 | #define ENCODER_CH7301_ENUM_ID1 0x210A |
167 | #define ENCODER_INTERNAL_DVO1_ENUM_ID1 0x210B | 178 | #define ENCODER_INTERNAL_DVO1_ENUM_ID1 0x210B |
@@ -175,8 +186,8 @@ | |||
175 | #define ENCODER_INTERNAL_KLDSCP_TMDS1_ENUM_ID1 0x2113 | 186 | #define ENCODER_INTERNAL_KLDSCP_TMDS1_ENUM_ID1 0x2113 |
176 | #define ENCODER_INTERNAL_KLDSCP_DVO1_ENUM_ID1 0x2114 | 187 | #define ENCODER_INTERNAL_KLDSCP_DVO1_ENUM_ID1 0x2114 |
177 | #define ENCODER_INTERNAL_KLDSCP_DAC1_ENUM_ID1 0x2115 | 188 | #define ENCODER_INTERNAL_KLDSCP_DAC1_ENUM_ID1 0x2115 |
178 | #define ENCODER_INTERNAL_KLDSCP_DAC2_ENUM_ID1 0x2116 | 189 | #define ENCODER_INTERNAL_KLDSCP_DAC2_ENUM_ID1 0x2116 |
179 | #define ENCODER_SI178_ENUM_ID1 0x2117 | 190 | #define ENCODER_SI178_ENUM_ID1 0x2117 |
180 | #define ENCODER_MVPU_FPGA_ENUM_ID1 0x2118 | 191 | #define ENCODER_MVPU_FPGA_ENUM_ID1 0x2118 |
181 | #define ENCODER_INTERNAL_DDI_ENUM_ID1 0x2119 | 192 | #define ENCODER_INTERNAL_DDI_ENUM_ID1 0x2119 |
182 | #define ENCODER_VT1625_ENUM_ID1 0x211A | 193 | #define ENCODER_VT1625_ENUM_ID1 0x211A |
@@ -185,205 +196,169 @@ | |||
185 | #define ENCODER_DP_DP501_ENUM_ID1 0x211D | 196 | #define ENCODER_DP_DP501_ENUM_ID1 0x211D |
186 | #define ENCODER_INTERNAL_UNIPHY_ENUM_ID1 0x211E | 197 | #define ENCODER_INTERNAL_UNIPHY_ENUM_ID1 0x211E |
187 | */ | 198 | */ |
188 | #define ENCODER_INTERNAL_LVDS_ENUM_ID1 \ | 199 | #define ENCODER_INTERNAL_LVDS_ENUM_ID1 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ |
189 | (GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ | 200 | GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ |
190 | GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ | 201 | ENCODER_OBJECT_ID_INTERNAL_LVDS << OBJECT_ID_SHIFT) |
191 | ENCODER_OBJECT_ID_INTERNAL_LVDS << OBJECT_ID_SHIFT) | 202 | |
192 | 203 | #define ENCODER_INTERNAL_TMDS1_ENUM_ID1 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ | |
193 | #define ENCODER_INTERNAL_TMDS1_ENUM_ID1 \ | 204 | GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ |
194 | (GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ | 205 | ENCODER_OBJECT_ID_INTERNAL_TMDS1 << OBJECT_ID_SHIFT) |
195 | GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ | 206 | |
196 | ENCODER_OBJECT_ID_INTERNAL_TMDS1 << OBJECT_ID_SHIFT) | 207 | #define ENCODER_INTERNAL_TMDS2_ENUM_ID1 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ |
197 | 208 | GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ | |
198 | #define ENCODER_INTERNAL_TMDS2_ENUM_ID1 \ | 209 | ENCODER_OBJECT_ID_INTERNAL_TMDS2 << OBJECT_ID_SHIFT) |
199 | (GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ | 210 | |
200 | GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ | 211 | #define ENCODER_INTERNAL_DAC1_ENUM_ID1 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ |
201 | ENCODER_OBJECT_ID_INTERNAL_TMDS2 << OBJECT_ID_SHIFT) | 212 | GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ |
202 | 213 | ENCODER_OBJECT_ID_INTERNAL_DAC1 << OBJECT_ID_SHIFT) | |
203 | #define ENCODER_INTERNAL_DAC1_ENUM_ID1 \ | 214 | |
204 | (GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ | 215 | #define ENCODER_INTERNAL_DAC2_ENUM_ID1 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ |
205 | GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ | 216 | GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ |
206 | ENCODER_OBJECT_ID_INTERNAL_DAC1 << OBJECT_ID_SHIFT) | 217 | ENCODER_OBJECT_ID_INTERNAL_DAC2 << OBJECT_ID_SHIFT) |
207 | 218 | ||
208 | #define ENCODER_INTERNAL_DAC2_ENUM_ID1 \ | 219 | #define ENCODER_INTERNAL_SDVOA_ENUM_ID1 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ |
209 | (GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ | 220 | GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ |
210 | GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ | 221 | ENCODER_OBJECT_ID_INTERNAL_SDVOA << OBJECT_ID_SHIFT) |
211 | ENCODER_OBJECT_ID_INTERNAL_DAC2 << OBJECT_ID_SHIFT) | 222 | |
212 | 223 | #define ENCODER_INTERNAL_SDVOA_ENUM_ID2 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ | |
213 | #define ENCODER_INTERNAL_SDVOA_ENUM_ID1 \ | 224 | GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\ |
214 | (GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ | 225 | ENCODER_OBJECT_ID_INTERNAL_SDVOA << OBJECT_ID_SHIFT) |
215 | GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ | 226 | |
216 | ENCODER_OBJECT_ID_INTERNAL_SDVOA << OBJECT_ID_SHIFT) | 227 | #define ENCODER_INTERNAL_SDVOB_ENUM_ID1 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ |
217 | 228 | GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ | |
218 | #define ENCODER_INTERNAL_SDVOA_ENUM_ID2 \ | 229 | ENCODER_OBJECT_ID_INTERNAL_SDVOB << OBJECT_ID_SHIFT) |
219 | (GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ | 230 | |
220 | GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\ | 231 | #define ENCODER_SIL170B_ENUM_ID1 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ |
221 | ENCODER_OBJECT_ID_INTERNAL_SDVOA << OBJECT_ID_SHIFT) | 232 | GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ |
222 | 233 | ENCODER_OBJECT_ID_SI170B << OBJECT_ID_SHIFT) | |
223 | #define ENCODER_INTERNAL_SDVOB_ENUM_ID1 \ | 234 | |
224 | (GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ | 235 | #define ENCODER_CH7303_ENUM_ID1 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ |
225 | GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ | 236 | GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ |
226 | ENCODER_OBJECT_ID_INTERNAL_SDVOB << OBJECT_ID_SHIFT) | 237 | ENCODER_OBJECT_ID_CH7303 << OBJECT_ID_SHIFT) |
227 | 238 | ||
228 | #define ENCODER_SIL170B_ENUM_ID1 \ | 239 | #define ENCODER_CH7301_ENUM_ID1 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ |
229 | (GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ | 240 | GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ |
230 | GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ | 241 | ENCODER_OBJECT_ID_CH7301 << OBJECT_ID_SHIFT) |
231 | ENCODER_OBJECT_ID_SI170B << OBJECT_ID_SHIFT) | 242 | |
232 | 243 | #define ENCODER_INTERNAL_DVO1_ENUM_ID1 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ | |
233 | #define ENCODER_CH7303_ENUM_ID1 \ | 244 | GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ |
234 | (GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ | 245 | ENCODER_OBJECT_ID_INTERNAL_DVO1 << OBJECT_ID_SHIFT) |
235 | GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ | 246 | |
236 | ENCODER_OBJECT_ID_CH7303 << OBJECT_ID_SHIFT) | 247 | #define ENCODER_EXTERNAL_SDVOA_ENUM_ID1 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ |
237 | 248 | GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ | |
238 | #define ENCODER_CH7301_ENUM_ID1 \ | 249 | ENCODER_OBJECT_ID_EXTERNAL_SDVOA << OBJECT_ID_SHIFT) |
239 | (GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ | 250 | |
240 | GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ | 251 | #define ENCODER_EXTERNAL_SDVOA_ENUM_ID2 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ |
241 | ENCODER_OBJECT_ID_CH7301 << OBJECT_ID_SHIFT) | 252 | GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\ |
242 | 253 | ENCODER_OBJECT_ID_EXTERNAL_SDVOA << OBJECT_ID_SHIFT) | |
243 | #define ENCODER_INTERNAL_DVO1_ENUM_ID1 \ | 254 | |
244 | (GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ | 255 | |
245 | GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ | 256 | #define ENCODER_EXTERNAL_SDVOB_ENUM_ID1 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ |
246 | ENCODER_OBJECT_ID_INTERNAL_DVO1 << OBJECT_ID_SHIFT) | 257 | GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ |
247 | 258 | ENCODER_OBJECT_ID_EXTERNAL_SDVOB << OBJECT_ID_SHIFT) | |
248 | #define ENCODER_EXTERNAL_SDVOA_ENUM_ID1 \ | 259 | |
249 | (GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ | 260 | |
250 | GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ | 261 | #define ENCODER_TITFP513_ENUM_ID1 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ |
251 | ENCODER_OBJECT_ID_EXTERNAL_SDVOA << OBJECT_ID_SHIFT) | 262 | GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ |
252 | 263 | ENCODER_OBJECT_ID_TITFP513 << OBJECT_ID_SHIFT) | |
253 | #define ENCODER_EXTERNAL_SDVOA_ENUM_ID2 \ | 264 | |
254 | (GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ | 265 | #define ENCODER_INTERNAL_LVTM1_ENUM_ID1 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ |
255 | GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\ | 266 | GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ |
256 | ENCODER_OBJECT_ID_EXTERNAL_SDVOA << OBJECT_ID_SHIFT) | 267 | ENCODER_OBJECT_ID_INTERNAL_LVTM1 << OBJECT_ID_SHIFT) |
257 | 268 | ||
258 | #define ENCODER_EXTERNAL_SDVOB_ENUM_ID1 \ | 269 | #define ENCODER_VT1623_ENUM_ID1 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ |
259 | (GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ | 270 | GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ |
260 | GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ | 271 | ENCODER_OBJECT_ID_VT1623 << OBJECT_ID_SHIFT) |
261 | ENCODER_OBJECT_ID_EXTERNAL_SDVOB << OBJECT_ID_SHIFT) | 272 | |
262 | 273 | #define ENCODER_HDMI_SI1930_ENUM_ID1 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ | |
263 | #define ENCODER_TITFP513_ENUM_ID1 \ | 274 | GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ |
264 | (GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ | 275 | ENCODER_OBJECT_ID_HDMI_SI1930 << OBJECT_ID_SHIFT) |
265 | GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ | 276 | |
266 | ENCODER_OBJECT_ID_TITFP513 << OBJECT_ID_SHIFT) | 277 | #define ENCODER_HDMI_INTERNAL_ENUM_ID1 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ |
267 | 278 | GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ | |
268 | #define ENCODER_INTERNAL_LVTM1_ENUM_ID1 \ | 279 | ENCODER_OBJECT_ID_HDMI_INTERNAL << OBJECT_ID_SHIFT) |
269 | (GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ | 280 | |
270 | GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ | 281 | #define ENCODER_INTERNAL_KLDSCP_TMDS1_ENUM_ID1 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ |
271 | ENCODER_OBJECT_ID_INTERNAL_LVTM1 << OBJECT_ID_SHIFT) | 282 | GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ |
272 | 283 | ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1 << OBJECT_ID_SHIFT) | |
273 | #define ENCODER_VT1623_ENUM_ID1 \ | 284 | |
274 | (GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ | 285 | |
275 | GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ | 286 | #define ENCODER_INTERNAL_KLDSCP_TMDS1_ENUM_ID2 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ |
276 | ENCODER_OBJECT_ID_VT1623 << OBJECT_ID_SHIFT) | 287 | GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\ |
277 | 288 | ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1 << OBJECT_ID_SHIFT) | |
278 | #define ENCODER_HDMI_SI1930_ENUM_ID1 \ | 289 | |
279 | (GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ | 290 | |
280 | GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ | 291 | #define ENCODER_INTERNAL_KLDSCP_DVO1_ENUM_ID1 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ |
281 | ENCODER_OBJECT_ID_HDMI_SI1930 << OBJECT_ID_SHIFT) | 292 | GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ |
282 | 293 | ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1 << OBJECT_ID_SHIFT) | |
283 | #define ENCODER_HDMI_INTERNAL_ENUM_ID1 \ | 294 | |
284 | (GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ | 295 | #define ENCODER_INTERNAL_KLDSCP_DAC1_ENUM_ID1 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ |
285 | GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ | 296 | GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ |
286 | ENCODER_OBJECT_ID_HDMI_INTERNAL << OBJECT_ID_SHIFT) | 297 | ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1 << OBJECT_ID_SHIFT) |
287 | 298 | ||
288 | #define ENCODER_INTERNAL_KLDSCP_TMDS1_ENUM_ID1 \ | 299 | #define ENCODER_INTERNAL_KLDSCP_DAC2_ENUM_ID1 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ |
289 | (GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ | 300 | GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ |
290 | GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ | 301 | ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2 << OBJECT_ID_SHIFT) // Shared with CV/TV and CRT |
291 | ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1 << OBJECT_ID_SHIFT) | 302 | |
292 | 303 | #define ENCODER_SI178_ENUM_ID1 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ | |
293 | #define ENCODER_INTERNAL_KLDSCP_TMDS1_ENUM_ID2 \ | 304 | GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ |
294 | (GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ | 305 | ENCODER_OBJECT_ID_SI178 << OBJECT_ID_SHIFT) |
295 | GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\ | 306 | |
296 | ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1 << OBJECT_ID_SHIFT) | 307 | #define ENCODER_MVPU_FPGA_ENUM_ID1 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ |
297 | 308 | GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ | |
298 | #define ENCODER_INTERNAL_KLDSCP_DVO1_ENUM_ID1 \ | 309 | ENCODER_OBJECT_ID_MVPU_FPGA << OBJECT_ID_SHIFT) |
299 | (GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ | 310 | |
300 | GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ | 311 | #define ENCODER_INTERNAL_DDI_ENUM_ID1 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ |
301 | ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1 << OBJECT_ID_SHIFT) | 312 | GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ |
302 | 313 | ENCODER_OBJECT_ID_INTERNAL_DDI << OBJECT_ID_SHIFT) | |
303 | #define ENCODER_INTERNAL_KLDSCP_DAC1_ENUM_ID1 \ | 314 | |
304 | (GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ | 315 | #define ENCODER_VT1625_ENUM_ID1 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ |
305 | GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ | 316 | GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ |
306 | ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1 << OBJECT_ID_SHIFT) | 317 | ENCODER_OBJECT_ID_VT1625 << OBJECT_ID_SHIFT) |
307 | 318 | ||
308 | #define ENCODER_INTERNAL_KLDSCP_DAC2_ENUM_ID1 \ | 319 | #define ENCODER_HDMI_SI1932_ENUM_ID1 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ |
309 | (GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ | 320 | GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ |
310 | GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ | 321 | ENCODER_OBJECT_ID_HDMI_SI1932 << OBJECT_ID_SHIFT) |
311 | ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2 << OBJECT_ID_SHIFT) /* Shared with CV/TV and CRT */ | 322 | |
312 | 323 | #define ENCODER_DP_DP501_ENUM_ID1 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ | |
313 | #define ENCODER_SI178_ENUM_ID1 \ | 324 | GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ |
314 | (GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ | 325 | ENCODER_OBJECT_ID_DP_DP501 << OBJECT_ID_SHIFT) |
315 | GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ | 326 | |
316 | ENCODER_OBJECT_ID_SI178 << OBJECT_ID_SHIFT) | 327 | #define ENCODER_DP_AN9801_ENUM_ID1 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ |
317 | 328 | GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ | |
318 | #define ENCODER_MVPU_FPGA_ENUM_ID1 \ | 329 | ENCODER_OBJECT_ID_DP_AN9801 << OBJECT_ID_SHIFT) |
319 | (GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ | 330 | |
320 | GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ | 331 | #define ENCODER_INTERNAL_UNIPHY_ENUM_ID1 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ |
321 | ENCODER_OBJECT_ID_MVPU_FPGA << OBJECT_ID_SHIFT) | 332 | GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ |
322 | 333 | ENCODER_OBJECT_ID_INTERNAL_UNIPHY << OBJECT_ID_SHIFT) | |
323 | #define ENCODER_INTERNAL_DDI_ENUM_ID1 \ | 334 | |
324 | (GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ | 335 | #define ENCODER_INTERNAL_UNIPHY_ENUM_ID2 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ |
325 | GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ | 336 | GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\ |
326 | ENCODER_OBJECT_ID_INTERNAL_DDI << OBJECT_ID_SHIFT) | 337 | ENCODER_OBJECT_ID_INTERNAL_UNIPHY << OBJECT_ID_SHIFT) |
327 | 338 | ||
328 | #define ENCODER_VT1625_ENUM_ID1 \ | 339 | #define ENCODER_INTERNAL_KLDSCP_LVTMA_ENUM_ID1 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ |
329 | (GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ | 340 | GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ |
330 | GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ | 341 | ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA << OBJECT_ID_SHIFT) |
331 | ENCODER_OBJECT_ID_VT1625 << OBJECT_ID_SHIFT) | 342 | |
332 | 343 | #define ENCODER_INTERNAL_UNIPHY1_ENUM_ID1 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ | |
333 | #define ENCODER_HDMI_SI1932_ENUM_ID1 \ | 344 | GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ |
334 | (GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ | 345 | ENCODER_OBJECT_ID_INTERNAL_UNIPHY1 << OBJECT_ID_SHIFT) |
335 | GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ | 346 | |
336 | ENCODER_OBJECT_ID_HDMI_SI1932 << OBJECT_ID_SHIFT) | 347 | #define ENCODER_INTERNAL_UNIPHY1_ENUM_ID2 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ |
337 | 348 | GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\ | |
338 | #define ENCODER_DP_DP501_ENUM_ID1 \ | 349 | ENCODER_OBJECT_ID_INTERNAL_UNIPHY1 << OBJECT_ID_SHIFT) |
339 | (GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ | 350 | |
340 | GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ | 351 | #define ENCODER_INTERNAL_UNIPHY2_ENUM_ID1 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ |
341 | ENCODER_OBJECT_ID_DP_DP501 << OBJECT_ID_SHIFT) | 352 | GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ |
342 | 353 | ENCODER_OBJECT_ID_INTERNAL_UNIPHY2 << OBJECT_ID_SHIFT) | |
343 | #define ENCODER_DP_AN9801_ENUM_ID1 \ | 354 | |
344 | (GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ | 355 | #define ENCODER_INTERNAL_UNIPHY2_ENUM_ID2 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ |
345 | GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ | 356 | GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\ |
346 | ENCODER_OBJECT_ID_DP_AN9801 << OBJECT_ID_SHIFT) | 357 | ENCODER_OBJECT_ID_INTERNAL_UNIPHY2 << OBJECT_ID_SHIFT) |
347 | 358 | ||
348 | #define ENCODER_INTERNAL_UNIPHY_ENUM_ID1 \ | 359 | #define ENCODER_GENERAL_EXTERNAL_DVO_ENUM_ID1 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ |
349 | (GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ | 360 | GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ |
350 | GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ | 361 | ENCODER_OBJECT_ID_GENERAL_EXTERNAL_DVO << OBJECT_ID_SHIFT) |
351 | ENCODER_OBJECT_ID_INTERNAL_UNIPHY << OBJECT_ID_SHIFT) | ||
352 | |||
353 | #define ENCODER_INTERNAL_UNIPHY_ENUM_ID2 \ | ||
354 | (GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ | ||
355 | GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\ | ||
356 | ENCODER_OBJECT_ID_INTERNAL_UNIPHY << OBJECT_ID_SHIFT) | ||
357 | |||
358 | #define ENCODER_INTERNAL_KLDSCP_LVTMA_ENUM_ID1 \ | ||
359 | (GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ | ||
360 | GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ | ||
361 | ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA << OBJECT_ID_SHIFT) | ||
362 | |||
363 | #define ENCODER_INTERNAL_UNIPHY1_ENUM_ID1 \ | ||
364 | (GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ | ||
365 | GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ | ||
366 | ENCODER_OBJECT_ID_INTERNAL_UNIPHY1 << OBJECT_ID_SHIFT) | ||
367 | |||
368 | #define ENCODER_INTERNAL_UNIPHY1_ENUM_ID2 \ | ||
369 | (GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ | ||
370 | GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\ | ||
371 | ENCODER_OBJECT_ID_INTERNAL_UNIPHY1 << OBJECT_ID_SHIFT) | ||
372 | |||
373 | #define ENCODER_INTERNAL_UNIPHY2_ENUM_ID1 \ | ||
374 | (GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ | ||
375 | GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ | ||
376 | ENCODER_OBJECT_ID_INTERNAL_UNIPHY2 << OBJECT_ID_SHIFT) | ||
377 | |||
378 | #define ENCODER_INTERNAL_UNIPHY2_ENUM_ID2 \ | ||
379 | (GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ | ||
380 | GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\ | ||
381 | ENCODER_OBJECT_ID_INTERNAL_UNIPHY2 << OBJECT_ID_SHIFT) | ||
382 | |||
383 | #define ENCODER_GENERAL_EXTERNAL_DVO_ENUM_ID1 \ | ||
384 | (GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ | ||
385 | GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ | ||
386 | ENCODER_OBJECT_ID_GENERAL_EXTERNAL_DVO << OBJECT_ID_SHIFT) | ||
387 | 362 | ||
388 | /****************************************************/ | 363 | /****************************************************/ |
389 | /* Connector Object ID definition - Shared with BIOS */ | 364 | /* Connector Object ID definition - Shared with BIOS */ |
@@ -406,167 +381,253 @@ | |||
406 | #define CONNECTOR_7PIN_DIN_ENUM_ID1 0x310F | 381 | #define CONNECTOR_7PIN_DIN_ENUM_ID1 0x310F |
407 | #define CONNECTOR_PCIE_CONNECTOR_ENUM_ID1 0x3110 | 382 | #define CONNECTOR_PCIE_CONNECTOR_ENUM_ID1 0x3110 |
408 | */ | 383 | */ |
409 | #define CONNECTOR_LVDS_ENUM_ID1 \ | 384 | #define CONNECTOR_LVDS_ENUM_ID1 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ |
410 | (GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ | 385 | GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ |
411 | GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ | 386 | CONNECTOR_OBJECT_ID_LVDS << OBJECT_ID_SHIFT) |
412 | CONNECTOR_OBJECT_ID_LVDS << OBJECT_ID_SHIFT) | 387 | |
413 | 388 | #define CONNECTOR_LVDS_ENUM_ID2 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ | |
414 | #define CONNECTOR_SINGLE_LINK_DVI_I_ENUM_ID1 \ | 389 | GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\ |
415 | (GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ | 390 | CONNECTOR_OBJECT_ID_LVDS << OBJECT_ID_SHIFT) |
416 | GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ | 391 | |
417 | CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I << OBJECT_ID_SHIFT) | 392 | #define CONNECTOR_eDP_ENUM_ID1 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ |
418 | 393 | GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ | |
419 | #define CONNECTOR_SINGLE_LINK_DVI_I_ENUM_ID2 \ | 394 | CONNECTOR_OBJECT_ID_eDP << OBJECT_ID_SHIFT) |
420 | (GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ | 395 | |
421 | GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\ | 396 | #define CONNECTOR_eDP_ENUM_ID2 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ |
422 | CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I << OBJECT_ID_SHIFT) | 397 | GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\ |
423 | 398 | CONNECTOR_OBJECT_ID_eDP << OBJECT_ID_SHIFT) | |
424 | #define CONNECTOR_DUAL_LINK_DVI_I_ENUM_ID1 \ | 399 | |
425 | (GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ | 400 | #define CONNECTOR_SINGLE_LINK_DVI_I_ENUM_ID1 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ |
426 | GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ | 401 | GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ |
427 | CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_I << OBJECT_ID_SHIFT) | 402 | CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I << OBJECT_ID_SHIFT) |
428 | 403 | ||
429 | #define CONNECTOR_DUAL_LINK_DVI_I_ENUM_ID2 \ | 404 | #define CONNECTOR_SINGLE_LINK_DVI_I_ENUM_ID2 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ |
430 | (GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ | 405 | GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\ |
431 | GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\ | 406 | CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I << OBJECT_ID_SHIFT) |
432 | CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_I << OBJECT_ID_SHIFT) | 407 | |
433 | 408 | #define CONNECTOR_DUAL_LINK_DVI_I_ENUM_ID1 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ | |
434 | #define CONNECTOR_SINGLE_LINK_DVI_D_ENUM_ID1 \ | 409 | GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ |
435 | (GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ | 410 | CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_I << OBJECT_ID_SHIFT) |
436 | GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ | 411 | |
437 | CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_D << OBJECT_ID_SHIFT) | 412 | #define CONNECTOR_DUAL_LINK_DVI_I_ENUM_ID2 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ |
438 | 413 | GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\ | |
439 | #define CONNECTOR_SINGLE_LINK_DVI_D_ENUM_ID2 \ | 414 | CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_I << OBJECT_ID_SHIFT) |
440 | (GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ | 415 | |
441 | GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\ | 416 | #define CONNECTOR_SINGLE_LINK_DVI_D_ENUM_ID1 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ |
442 | CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_D << OBJECT_ID_SHIFT) | 417 | GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ |
443 | 418 | CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_D << OBJECT_ID_SHIFT) | |
444 | #define CONNECTOR_DUAL_LINK_DVI_D_ENUM_ID1 \ | 419 | |
445 | (GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ | 420 | #define CONNECTOR_SINGLE_LINK_DVI_D_ENUM_ID2 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ |
446 | GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ | 421 | GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\ |
447 | CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_D << OBJECT_ID_SHIFT) | 422 | CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_D << OBJECT_ID_SHIFT) |
448 | 423 | ||
449 | #define CONNECTOR_VGA_ENUM_ID1 \ | 424 | #define CONNECTOR_DUAL_LINK_DVI_D_ENUM_ID1 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ |
450 | (GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ | 425 | GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ |
451 | GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ | 426 | CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_D << OBJECT_ID_SHIFT) |
452 | CONNECTOR_OBJECT_ID_VGA << OBJECT_ID_SHIFT) | 427 | |
453 | 428 | #define CONNECTOR_DUAL_LINK_DVI_D_ENUM_ID2 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ | |
454 | #define CONNECTOR_VGA_ENUM_ID2 \ | 429 | GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\ |
455 | (GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ | 430 | CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_D << OBJECT_ID_SHIFT) |
456 | GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\ | 431 | |
457 | CONNECTOR_OBJECT_ID_VGA << OBJECT_ID_SHIFT) | 432 | #define CONNECTOR_DUAL_LINK_DVI_D_ENUM_ID3 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ |
458 | 433 | GRAPH_OBJECT_ENUM_ID3 << ENUM_ID_SHIFT |\ | |
459 | #define CONNECTOR_COMPOSITE_ENUM_ID1 \ | 434 | CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_D << OBJECT_ID_SHIFT) |
460 | (GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ | 435 | |
461 | GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ | 436 | #define CONNECTOR_VGA_ENUM_ID1 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ |
462 | CONNECTOR_OBJECT_ID_COMPOSITE << OBJECT_ID_SHIFT) | 437 | GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ |
463 | 438 | CONNECTOR_OBJECT_ID_VGA << OBJECT_ID_SHIFT) | |
464 | #define CONNECTOR_SVIDEO_ENUM_ID1 \ | 439 | |
465 | (GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ | 440 | #define CONNECTOR_VGA_ENUM_ID2 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ |
466 | GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ | 441 | GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\ |
467 | CONNECTOR_OBJECT_ID_SVIDEO << OBJECT_ID_SHIFT) | 442 | CONNECTOR_OBJECT_ID_VGA << OBJECT_ID_SHIFT) |
468 | 443 | ||
469 | #define CONNECTOR_YPbPr_ENUM_ID1 \ | 444 | #define CONNECTOR_COMPOSITE_ENUM_ID1 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ |
470 | (GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ | 445 | GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ |
471 | GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ | 446 | CONNECTOR_OBJECT_ID_COMPOSITE << OBJECT_ID_SHIFT) |
472 | CONNECTOR_OBJECT_ID_YPbPr << OBJECT_ID_SHIFT) | 447 | |
473 | 448 | #define CONNECTOR_COMPOSITE_ENUM_ID2 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ | |
474 | #define CONNECTOR_D_CONNECTOR_ENUM_ID1 \ | 449 | GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\ |
475 | (GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ | 450 | CONNECTOR_OBJECT_ID_COMPOSITE << OBJECT_ID_SHIFT) |
476 | GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ | 451 | |
477 | CONNECTOR_OBJECT_ID_D_CONNECTOR << OBJECT_ID_SHIFT) | 452 | #define CONNECTOR_SVIDEO_ENUM_ID1 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ |
478 | 453 | GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ | |
479 | #define CONNECTOR_9PIN_DIN_ENUM_ID1 \ | 454 | CONNECTOR_OBJECT_ID_SVIDEO << OBJECT_ID_SHIFT) |
480 | (GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ | 455 | |
481 | GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ | 456 | #define CONNECTOR_SVIDEO_ENUM_ID2 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ |
482 | CONNECTOR_OBJECT_ID_9PIN_DIN << OBJECT_ID_SHIFT) | 457 | GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\ |
483 | 458 | CONNECTOR_OBJECT_ID_SVIDEO << OBJECT_ID_SHIFT) | |
484 | #define CONNECTOR_SCART_ENUM_ID1 \ | 459 | |
485 | (GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ | 460 | #define CONNECTOR_YPbPr_ENUM_ID1 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ |
486 | GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ | 461 | GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ |
487 | CONNECTOR_OBJECT_ID_SCART << OBJECT_ID_SHIFT) | 462 | CONNECTOR_OBJECT_ID_YPbPr << OBJECT_ID_SHIFT) |
488 | 463 | ||
489 | #define CONNECTOR_HDMI_TYPE_A_ENUM_ID1 \ | 464 | #define CONNECTOR_YPbPr_ENUM_ID2 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ |
490 | (GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ | 465 | GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\ |
491 | GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ | 466 | CONNECTOR_OBJECT_ID_YPbPr << OBJECT_ID_SHIFT) |
492 | CONNECTOR_OBJECT_ID_HDMI_TYPE_A << OBJECT_ID_SHIFT) | 467 | |
493 | 468 | #define CONNECTOR_D_CONNECTOR_ENUM_ID1 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ | |
494 | #define CONNECTOR_HDMI_TYPE_B_ENUM_ID1 \ | 469 | GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ |
495 | (GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ | 470 | CONNECTOR_OBJECT_ID_D_CONNECTOR << OBJECT_ID_SHIFT) |
496 | GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ | 471 | |
497 | CONNECTOR_OBJECT_ID_HDMI_TYPE_B << OBJECT_ID_SHIFT) | 472 | #define CONNECTOR_D_CONNECTOR_ENUM_ID2 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ |
498 | 473 | GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\ | |
499 | #define CONNECTOR_7PIN_DIN_ENUM_ID1 \ | 474 | CONNECTOR_OBJECT_ID_D_CONNECTOR << OBJECT_ID_SHIFT) |
500 | (GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ | 475 | |
501 | GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ | 476 | #define CONNECTOR_9PIN_DIN_ENUM_ID1 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ |
502 | CONNECTOR_OBJECT_ID_7PIN_DIN << OBJECT_ID_SHIFT) | 477 | GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ |
503 | 478 | CONNECTOR_OBJECT_ID_9PIN_DIN << OBJECT_ID_SHIFT) | |
504 | #define CONNECTOR_PCIE_CONNECTOR_ENUM_ID1 \ | 479 | |
505 | (GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ | 480 | #define CONNECTOR_9PIN_DIN_ENUM_ID2 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ |
506 | GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ | 481 | GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\ |
507 | CONNECTOR_OBJECT_ID_PCIE_CONNECTOR << OBJECT_ID_SHIFT) | 482 | CONNECTOR_OBJECT_ID_9PIN_DIN << OBJECT_ID_SHIFT) |
508 | 483 | ||
509 | #define CONNECTOR_PCIE_CONNECTOR_ENUM_ID2 \ | 484 | #define CONNECTOR_SCART_ENUM_ID1 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ |
510 | (GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ | 485 | GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ |
511 | GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\ | 486 | CONNECTOR_OBJECT_ID_SCART << OBJECT_ID_SHIFT) |
512 | CONNECTOR_OBJECT_ID_PCIE_CONNECTOR << OBJECT_ID_SHIFT) | 487 | |
513 | 488 | #define CONNECTOR_SCART_ENUM_ID2 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ | |
514 | #define CONNECTOR_CROSSFIRE_ENUM_ID1 \ | 489 | GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\ |
515 | (GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ | 490 | CONNECTOR_OBJECT_ID_SCART << OBJECT_ID_SHIFT) |
516 | GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ | 491 | |
517 | CONNECTOR_OBJECT_ID_CROSSFIRE << OBJECT_ID_SHIFT) | 492 | #define CONNECTOR_HDMI_TYPE_A_ENUM_ID1 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ |
518 | 493 | GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ | |
519 | #define CONNECTOR_CROSSFIRE_ENUM_ID2 \ | 494 | CONNECTOR_OBJECT_ID_HDMI_TYPE_A << OBJECT_ID_SHIFT) |
520 | (GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ | 495 | |
521 | GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\ | 496 | #define CONNECTOR_HDMI_TYPE_A_ENUM_ID2 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ |
522 | CONNECTOR_OBJECT_ID_CROSSFIRE << OBJECT_ID_SHIFT) | 497 | GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\ |
523 | 498 | CONNECTOR_OBJECT_ID_HDMI_TYPE_A << OBJECT_ID_SHIFT) | |
524 | #define CONNECTOR_HARDCODE_DVI_ENUM_ID1 \ | 499 | |
525 | (GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ | 500 | #define CONNECTOR_HDMI_TYPE_A_ENUM_ID3 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ |
526 | GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ | 501 | GRAPH_OBJECT_ENUM_ID3 << ENUM_ID_SHIFT |\ |
527 | CONNECTOR_OBJECT_ID_HARDCODE_DVI << OBJECT_ID_SHIFT) | 502 | CONNECTOR_OBJECT_ID_HDMI_TYPE_A << OBJECT_ID_SHIFT) |
528 | 503 | ||
529 | #define CONNECTOR_HARDCODE_DVI_ENUM_ID2 \ | 504 | #define CONNECTOR_HDMI_TYPE_B_ENUM_ID1 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ |
530 | (GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ | 505 | GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ |
531 | GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\ | 506 | CONNECTOR_OBJECT_ID_HDMI_TYPE_B << OBJECT_ID_SHIFT) |
532 | CONNECTOR_OBJECT_ID_HARDCODE_DVI << OBJECT_ID_SHIFT) | 507 | |
533 | 508 | #define CONNECTOR_HDMI_TYPE_B_ENUM_ID2 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ | |
534 | #define CONNECTOR_DISPLAYPORT_ENUM_ID1 \ | 509 | GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\ |
535 | (GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ | 510 | CONNECTOR_OBJECT_ID_HDMI_TYPE_B << OBJECT_ID_SHIFT) |
536 | GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ | 511 | |
537 | CONNECTOR_OBJECT_ID_DISPLAYPORT << OBJECT_ID_SHIFT) | 512 | #define CONNECTOR_7PIN_DIN_ENUM_ID1 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ |
538 | 513 | GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ | |
539 | #define CONNECTOR_DISPLAYPORT_ENUM_ID2 \ | 514 | CONNECTOR_OBJECT_ID_7PIN_DIN << OBJECT_ID_SHIFT) |
540 | (GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ | 515 | #define CONNECTOR_7PIN_DIN_ENUM_ID2 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ |
541 | GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\ | 516 | GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\ |
542 | CONNECTOR_OBJECT_ID_DISPLAYPORT << OBJECT_ID_SHIFT) | 517 | CONNECTOR_OBJECT_ID_7PIN_DIN << OBJECT_ID_SHIFT) |
543 | 518 | ||
544 | #define CONNECTOR_DISPLAYPORT_ENUM_ID3 \ | 519 | #define CONNECTOR_PCIE_CONNECTOR_ENUM_ID1 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ |
545 | (GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ | 520 | GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ |
546 | GRAPH_OBJECT_ENUM_ID3 << ENUM_ID_SHIFT |\ | 521 | CONNECTOR_OBJECT_ID_PCIE_CONNECTOR << OBJECT_ID_SHIFT) |
547 | CONNECTOR_OBJECT_ID_DISPLAYPORT << OBJECT_ID_SHIFT) | 522 | |
548 | 523 | #define CONNECTOR_PCIE_CONNECTOR_ENUM_ID2 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ | |
549 | #define CONNECTOR_DISPLAYPORT_ENUM_ID4 \ | 524 | GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\ |
550 | (GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ | 525 | CONNECTOR_OBJECT_ID_PCIE_CONNECTOR << OBJECT_ID_SHIFT) |
551 | GRAPH_OBJECT_ENUM_ID4 << ENUM_ID_SHIFT |\ | 526 | |
552 | CONNECTOR_OBJECT_ID_DISPLAYPORT << OBJECT_ID_SHIFT) | 527 | #define CONNECTOR_CROSSFIRE_ENUM_ID1 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ |
528 | GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ | ||
529 | CONNECTOR_OBJECT_ID_CROSSFIRE << OBJECT_ID_SHIFT) | ||
530 | |||
531 | #define CONNECTOR_CROSSFIRE_ENUM_ID2 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ | ||
532 | GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\ | ||
533 | CONNECTOR_OBJECT_ID_CROSSFIRE << OBJECT_ID_SHIFT) | ||
534 | |||
535 | |||
536 | #define CONNECTOR_HARDCODE_DVI_ENUM_ID1 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ | ||
537 | GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ | ||
538 | CONNECTOR_OBJECT_ID_HARDCODE_DVI << OBJECT_ID_SHIFT) | ||
539 | |||
540 | #define CONNECTOR_HARDCODE_DVI_ENUM_ID2 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ | ||
541 | GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\ | ||
542 | CONNECTOR_OBJECT_ID_HARDCODE_DVI << OBJECT_ID_SHIFT) | ||
543 | |||
544 | #define CONNECTOR_DISPLAYPORT_ENUM_ID1 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ | ||
545 | GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ | ||
546 | CONNECTOR_OBJECT_ID_DISPLAYPORT << OBJECT_ID_SHIFT) | ||
547 | |||
548 | #define CONNECTOR_DISPLAYPORT_ENUM_ID2 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ | ||
549 | GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\ | ||
550 | CONNECTOR_OBJECT_ID_DISPLAYPORT << OBJECT_ID_SHIFT) | ||
551 | |||
552 | #define CONNECTOR_DISPLAYPORT_ENUM_ID3 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ | ||
553 | GRAPH_OBJECT_ENUM_ID3 << ENUM_ID_SHIFT |\ | ||
554 | CONNECTOR_OBJECT_ID_DISPLAYPORT << OBJECT_ID_SHIFT) | ||
555 | |||
556 | #define CONNECTOR_DISPLAYPORT_ENUM_ID4 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ | ||
557 | GRAPH_OBJECT_ENUM_ID4 << ENUM_ID_SHIFT |\ | ||
558 | CONNECTOR_OBJECT_ID_DISPLAYPORT << OBJECT_ID_SHIFT) | ||
559 | |||
560 | #define CONNECTOR_DISPLAYPORT_ENUM_ID5 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ | ||
561 | GRAPH_OBJECT_ENUM_ID5 << ENUM_ID_SHIFT |\ | ||
562 | CONNECTOR_OBJECT_ID_DISPLAYPORT << OBJECT_ID_SHIFT) | ||
563 | |||
564 | #define CONNECTOR_DISPLAYPORT_ENUM_ID6 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ | ||
565 | GRAPH_OBJECT_ENUM_ID6 << ENUM_ID_SHIFT |\ | ||
566 | CONNECTOR_OBJECT_ID_DISPLAYPORT << OBJECT_ID_SHIFT) | ||
567 | |||
568 | #define CONNECTOR_MXM_ENUM_ID1 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ | ||
569 | GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ | ||
570 | CONNECTOR_OBJECT_ID_MXM << OBJECT_ID_SHIFT) //Mapping to MXM_DP_A | ||
571 | |||
572 | #define CONNECTOR_MXM_ENUM_ID2 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ | ||
573 | GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\ | ||
574 | CONNECTOR_OBJECT_ID_MXM << OBJECT_ID_SHIFT) //Mapping to MXM_DP_B | ||
575 | |||
576 | #define CONNECTOR_MXM_ENUM_ID3 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ | ||
577 | GRAPH_OBJECT_ENUM_ID3 << ENUM_ID_SHIFT |\ | ||
578 | CONNECTOR_OBJECT_ID_MXM << OBJECT_ID_SHIFT) //Mapping to MXM_DP_C | ||
579 | |||
580 | #define CONNECTOR_MXM_ENUM_ID4 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ | ||
581 | GRAPH_OBJECT_ENUM_ID4 << ENUM_ID_SHIFT |\ | ||
582 | CONNECTOR_OBJECT_ID_MXM << OBJECT_ID_SHIFT) //Mapping to MXM_DP_D | ||
583 | |||
584 | #define CONNECTOR_MXM_ENUM_ID5 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ | ||
585 | GRAPH_OBJECT_ENUM_ID5 << ENUM_ID_SHIFT |\ | ||
586 | CONNECTOR_OBJECT_ID_MXM << OBJECT_ID_SHIFT) //Mapping to MXM_LVDS_TXxx | ||
587 | |||
588 | #define CONNECTOR_MXM_ENUM_ID6 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ | ||
589 | GRAPH_OBJECT_ENUM_ID6 << ENUM_ID_SHIFT |\ | ||
590 | CONNECTOR_OBJECT_ID_MXM << OBJECT_ID_SHIFT) //Mapping to MXM_LVDS_UXxx | ||
591 | |||
592 | #define CONNECTOR_MXM_ENUM_ID7 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ | ||
593 | GRAPH_OBJECT_ENUM_ID7 << ENUM_ID_SHIFT |\ | ||
594 | CONNECTOR_OBJECT_ID_MXM << OBJECT_ID_SHIFT) //Mapping to MXM_DAC | ||
553 | 595 | ||
554 | /****************************************************/ | 596 | /****************************************************/ |
555 | /* Router Object ID definition - Shared with BIOS */ | 597 | /* Router Object ID definition - Shared with BIOS */ |
556 | /****************************************************/ | 598 | /****************************************************/ |
557 | #define ROUTER_I2C_EXTENDER_CNTL_ENUM_ID1 \ | 599 | #define ROUTER_I2C_EXTENDER_CNTL_ENUM_ID1 ( GRAPH_OBJECT_TYPE_ROUTER << OBJECT_TYPE_SHIFT |\ |
558 | (GRAPH_OBJECT_TYPE_ROUTER << OBJECT_TYPE_SHIFT |\ | 600 | GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ |
559 | GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ | 601 | ROUTER_OBJECT_ID_I2C_EXTENDER_CNTL << OBJECT_ID_SHIFT) |
560 | ROUTER_OBJECT_ID_I2C_EXTENDER_CNTL << OBJECT_ID_SHIFT) | ||
561 | 602 | ||
562 | /* deleted */ | 603 | /* deleted */ |
563 | 604 | ||
564 | /****************************************************/ | 605 | /****************************************************/ |
606 | /* Generic Object ID definition - Shared with BIOS */ | ||
607 | /****************************************************/ | ||
608 | #define GENERICOBJECT_GLSYNC_ENUM_ID1 (GRAPH_OBJECT_TYPE_GENERIC << OBJECT_TYPE_SHIFT |\ | ||
609 | GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ | ||
610 | GENERIC_OBJECT_ID_GLSYNC << OBJECT_ID_SHIFT) | ||
611 | |||
612 | #define GENERICOBJECT_PX2_NON_DRIVABLE_ID1 (GRAPH_OBJECT_TYPE_GENERIC << OBJECT_TYPE_SHIFT |\ | ||
613 | GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ | ||
614 | GENERIC_OBJECT_ID_PX2_NON_DRIVABLE<< OBJECT_ID_SHIFT) | ||
615 | |||
616 | #define GENERICOBJECT_PX2_NON_DRIVABLE_ID2 (GRAPH_OBJECT_TYPE_GENERIC << OBJECT_TYPE_SHIFT |\ | ||
617 | GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\ | ||
618 | GENERIC_OBJECT_ID_PX2_NON_DRIVABLE<< OBJECT_ID_SHIFT) | ||
619 | |||
620 | #define GENERICOBJECT_MXM_OPM_ENUM_ID1 (GRAPH_OBJECT_TYPE_GENERIC << OBJECT_TYPE_SHIFT |\ | ||
621 | GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ | ||
622 | GENERIC_OBJECT_ID_MXM_OPM << OBJECT_ID_SHIFT) | ||
623 | |||
624 | /****************************************************/ | ||
565 | /* Object Cap definition - Shared with BIOS */ | 625 | /* Object Cap definition - Shared with BIOS */ |
566 | /****************************************************/ | 626 | /****************************************************/ |
567 | #define GRAPHICS_OBJECT_CAP_I2C 0x00000001L | 627 | #define GRAPHICS_OBJECT_CAP_I2C 0x00000001L |
568 | #define GRAPHICS_OBJECT_CAP_TABLE_ID 0x00000002L | 628 | #define GRAPHICS_OBJECT_CAP_TABLE_ID 0x00000002L |
569 | 629 | ||
630 | |||
570 | #define GRAPHICS_OBJECT_I2CCOMMAND_TABLE_ID 0x01 | 631 | #define GRAPHICS_OBJECT_I2CCOMMAND_TABLE_ID 0x01 |
571 | #define GRAPHICS_OBJECT_HOTPLUGDETECTIONINTERUPT_TABLE_ID 0x02 | 632 | #define GRAPHICS_OBJECT_HOTPLUGDETECTIONINTERUPT_TABLE_ID 0x02 |
572 | #define GRAPHICS_OBJECT_ENCODER_OUTPUT_PROTECTION_TABLE_ID 0x03 | 633 | #define GRAPHICS_OBJECT_ENCODER_OUTPUT_PROTECTION_TABLE_ID 0x03 |
@@ -575,4 +636,8 @@ | |||
575 | #pragma pack() | 636 | #pragma pack() |
576 | #endif | 637 | #endif |
577 | 638 | ||
578 | #endif /*GRAPHICTYPE */ | 639 | #endif /*GRAPHICTYPE */ |
640 | |||
641 | |||
642 | |||
643 | |||
diff --git a/drivers/gpu/drm/radeon/atombios_dp.c b/drivers/gpu/drm/radeon/atombios_dp.c index 0d63c4436e7c..3eb0ca5b3d73 100644 --- a/drivers/gpu/drm/radeon/atombios_dp.c +++ b/drivers/gpu/drm/radeon/atombios_dp.c | |||
@@ -468,7 +468,8 @@ void radeon_dp_set_link_config(struct drm_connector *connector, | |||
468 | struct radeon_connector *radeon_connector; | 468 | struct radeon_connector *radeon_connector; |
469 | struct radeon_connector_atom_dig *dig_connector; | 469 | struct radeon_connector_atom_dig *dig_connector; |
470 | 470 | ||
471 | if (connector->connector_type != DRM_MODE_CONNECTOR_DisplayPort) | 471 | if ((connector->connector_type != DRM_MODE_CONNECTOR_DisplayPort) || |
472 | (connector->connector_type != DRM_MODE_CONNECTOR_eDP)) | ||
472 | return; | 473 | return; |
473 | 474 | ||
474 | radeon_connector = to_radeon_connector(connector); | 475 | radeon_connector = to_radeon_connector(connector); |
@@ -582,7 +583,8 @@ void dp_link_train(struct drm_encoder *encoder, | |||
582 | u8 train_set[4]; | 583 | u8 train_set[4]; |
583 | int i; | 584 | int i; |
584 | 585 | ||
585 | if (connector->connector_type != DRM_MODE_CONNECTOR_DisplayPort) | 586 | if ((connector->connector_type != DRM_MODE_CONNECTOR_DisplayPort) || |
587 | (connector->connector_type != DRM_MODE_CONNECTOR_eDP)) | ||
586 | return; | 588 | return; |
587 | 589 | ||
588 | if (!radeon_encoder->enc_priv) | 590 | if (!radeon_encoder->enc_priv) |
diff --git a/drivers/gpu/drm/radeon/mkregtable.c b/drivers/gpu/drm/radeon/mkregtable.c index 0d79577c1576..607241c6a8a9 100644 --- a/drivers/gpu/drm/radeon/mkregtable.c +++ b/drivers/gpu/drm/radeon/mkregtable.c | |||
@@ -661,8 +661,10 @@ static int parser_auth(struct table *t, const char *filename) | |||
661 | fseek(file, 0, SEEK_SET); | 661 | fseek(file, 0, SEEK_SET); |
662 | 662 | ||
663 | /* get header */ | 663 | /* get header */ |
664 | if (fgets(buf, 1024, file) == NULL) | 664 | if (fgets(buf, 1024, file) == NULL) { |
665 | fclose(file); | ||
665 | return -1; | 666 | return -1; |
667 | } | ||
666 | 668 | ||
667 | /* first line will contain the last register | 669 | /* first line will contain the last register |
668 | * and gpu name */ | 670 | * and gpu name */ |
diff --git a/drivers/gpu/drm/radeon/r100.c b/drivers/gpu/drm/radeon/r100.c index 71727460968f..8760d66e058a 100644 --- a/drivers/gpu/drm/radeon/r100.c +++ b/drivers/gpu/drm/radeon/r100.c | |||
@@ -131,7 +131,8 @@ void r100_hpd_init(struct radeon_device *rdev) | |||
131 | break; | 131 | break; |
132 | } | 132 | } |
133 | } | 133 | } |
134 | r100_irq_set(rdev); | 134 | if (rdev->irq.installed) |
135 | r100_irq_set(rdev); | ||
135 | } | 136 | } |
136 | 137 | ||
137 | void r100_hpd_fini(struct radeon_device *rdev) | 138 | void r100_hpd_fini(struct radeon_device *rdev) |
@@ -243,6 +244,11 @@ int r100_irq_set(struct radeon_device *rdev) | |||
243 | { | 244 | { |
244 | uint32_t tmp = 0; | 245 | uint32_t tmp = 0; |
245 | 246 | ||
247 | if (!rdev->irq.installed) { | ||
248 | WARN(1, "Can't enable IRQ/MSI because no handler is installed.\n"); | ||
249 | WREG32(R_000040_GEN_INT_CNTL, 0); | ||
250 | return -EINVAL; | ||
251 | } | ||
246 | if (rdev->irq.sw_int) { | 252 | if (rdev->irq.sw_int) { |
247 | tmp |= RADEON_SW_INT_ENABLE; | 253 | tmp |= RADEON_SW_INT_ENABLE; |
248 | } | 254 | } |
@@ -356,6 +362,11 @@ void r100_fence_ring_emit(struct radeon_device *rdev, | |||
356 | /* Wait until IDLE & CLEAN */ | 362 | /* Wait until IDLE & CLEAN */ |
357 | radeon_ring_write(rdev, PACKET0(0x1720, 0)); | 363 | radeon_ring_write(rdev, PACKET0(0x1720, 0)); |
358 | radeon_ring_write(rdev, (1 << 16) | (1 << 17)); | 364 | radeon_ring_write(rdev, (1 << 16) | (1 << 17)); |
365 | radeon_ring_write(rdev, PACKET0(RADEON_HOST_PATH_CNTL, 0)); | ||
366 | radeon_ring_write(rdev, rdev->config.r100.hdp_cntl | | ||
367 | RADEON_HDP_READ_BUFFER_INVALIDATE); | ||
368 | radeon_ring_write(rdev, PACKET0(RADEON_HOST_PATH_CNTL, 0)); | ||
369 | radeon_ring_write(rdev, rdev->config.r100.hdp_cntl); | ||
359 | /* Emit fence sequence & fire IRQ */ | 370 | /* Emit fence sequence & fire IRQ */ |
360 | radeon_ring_write(rdev, PACKET0(rdev->fence_drv.scratch_reg, 0)); | 371 | radeon_ring_write(rdev, PACKET0(rdev->fence_drv.scratch_reg, 0)); |
361 | radeon_ring_write(rdev, fence->seq); | 372 | radeon_ring_write(rdev, fence->seq); |
@@ -1713,14 +1724,6 @@ void r100_gpu_init(struct radeon_device *rdev) | |||
1713 | r100_hdp_reset(rdev); | 1724 | r100_hdp_reset(rdev); |
1714 | } | 1725 | } |
1715 | 1726 | ||
1716 | void r100_hdp_flush(struct radeon_device *rdev) | ||
1717 | { | ||
1718 | u32 tmp; | ||
1719 | tmp = RREG32(RADEON_HOST_PATH_CNTL); | ||
1720 | tmp |= RADEON_HDP_READ_BUFFER_INVALIDATE; | ||
1721 | WREG32(RADEON_HOST_PATH_CNTL, tmp); | ||
1722 | } | ||
1723 | |||
1724 | void r100_hdp_reset(struct radeon_device *rdev) | 1727 | void r100_hdp_reset(struct radeon_device *rdev) |
1725 | { | 1728 | { |
1726 | uint32_t tmp; | 1729 | uint32_t tmp; |
@@ -3313,6 +3316,7 @@ static int r100_startup(struct radeon_device *rdev) | |||
3313 | } | 3316 | } |
3314 | /* Enable IRQ */ | 3317 | /* Enable IRQ */ |
3315 | r100_irq_set(rdev); | 3318 | r100_irq_set(rdev); |
3319 | rdev->config.r100.hdp_cntl = RREG32(RADEON_HOST_PATH_CNTL); | ||
3316 | /* 1M ring buffer */ | 3320 | /* 1M ring buffer */ |
3317 | r = r100_cp_init(rdev, 1024 * 1024); | 3321 | r = r100_cp_init(rdev, 1024 * 1024); |
3318 | if (r) { | 3322 | if (r) { |
@@ -3371,6 +3375,7 @@ void r100_fini(struct radeon_device *rdev) | |||
3371 | radeon_gem_fini(rdev); | 3375 | radeon_gem_fini(rdev); |
3372 | if (rdev->flags & RADEON_IS_PCI) | 3376 | if (rdev->flags & RADEON_IS_PCI) |
3373 | r100_pci_gart_fini(rdev); | 3377 | r100_pci_gart_fini(rdev); |
3378 | radeon_agp_fini(rdev); | ||
3374 | radeon_irq_kms_fini(rdev); | 3379 | radeon_irq_kms_fini(rdev); |
3375 | radeon_fence_driver_fini(rdev); | 3380 | radeon_fence_driver_fini(rdev); |
3376 | radeon_bo_fini(rdev); | 3381 | radeon_bo_fini(rdev); |
diff --git a/drivers/gpu/drm/radeon/r300.c b/drivers/gpu/drm/radeon/r300.c index 3f2cc9e2e8d9..0051d11b907c 100644 --- a/drivers/gpu/drm/radeon/r300.c +++ b/drivers/gpu/drm/radeon/r300.c | |||
@@ -36,7 +36,15 @@ | |||
36 | #include "rv350d.h" | 36 | #include "rv350d.h" |
37 | #include "r300_reg_safe.h" | 37 | #include "r300_reg_safe.h" |
38 | 38 | ||
39 | /* This files gather functions specifics to: r300,r350,rv350,rv370,rv380 */ | 39 | /* This files gather functions specifics to: r300,r350,rv350,rv370,rv380 |
40 | * | ||
41 | * GPU Errata: | ||
42 | * - HOST_PATH_CNTL: r300 family seems to dislike write to HOST_PATH_CNTL | ||
43 | * using MMIO to flush host path read cache, this lead to HARDLOCKUP. | ||
44 | * However, scheduling such write to the ring seems harmless, i suspect | ||
45 | * the CP read collide with the flush somehow, or maybe the MC, hard to | ||
46 | * tell. (Jerome Glisse) | ||
47 | */ | ||
40 | 48 | ||
41 | /* | 49 | /* |
42 | * rv370,rv380 PCIE GART | 50 | * rv370,rv380 PCIE GART |
@@ -178,6 +186,11 @@ void r300_fence_ring_emit(struct radeon_device *rdev, | |||
178 | /* Wait until IDLE & CLEAN */ | 186 | /* Wait until IDLE & CLEAN */ |
179 | radeon_ring_write(rdev, PACKET0(0x1720, 0)); | 187 | radeon_ring_write(rdev, PACKET0(0x1720, 0)); |
180 | radeon_ring_write(rdev, (1 << 17) | (1 << 16) | (1 << 9)); | 188 | radeon_ring_write(rdev, (1 << 17) | (1 << 16) | (1 << 9)); |
189 | radeon_ring_write(rdev, PACKET0(RADEON_HOST_PATH_CNTL, 0)); | ||
190 | radeon_ring_write(rdev, rdev->config.r300.hdp_cntl | | ||
191 | RADEON_HDP_READ_BUFFER_INVALIDATE); | ||
192 | radeon_ring_write(rdev, PACKET0(RADEON_HOST_PATH_CNTL, 0)); | ||
193 | radeon_ring_write(rdev, rdev->config.r300.hdp_cntl); | ||
181 | /* Emit fence sequence & fire IRQ */ | 194 | /* Emit fence sequence & fire IRQ */ |
182 | radeon_ring_write(rdev, PACKET0(rdev->fence_drv.scratch_reg, 0)); | 195 | radeon_ring_write(rdev, PACKET0(rdev->fence_drv.scratch_reg, 0)); |
183 | radeon_ring_write(rdev, fence->seq); | 196 | radeon_ring_write(rdev, fence->seq); |
@@ -1258,6 +1271,7 @@ static int r300_startup(struct radeon_device *rdev) | |||
1258 | } | 1271 | } |
1259 | /* Enable IRQ */ | 1272 | /* Enable IRQ */ |
1260 | r100_irq_set(rdev); | 1273 | r100_irq_set(rdev); |
1274 | rdev->config.r300.hdp_cntl = RREG32(RADEON_HOST_PATH_CNTL); | ||
1261 | /* 1M ring buffer */ | 1275 | /* 1M ring buffer */ |
1262 | r = r100_cp_init(rdev, 1024 * 1024); | 1276 | r = r100_cp_init(rdev, 1024 * 1024); |
1263 | if (r) { | 1277 | if (r) { |
@@ -1322,6 +1336,7 @@ void r300_fini(struct radeon_device *rdev) | |||
1322 | rv370_pcie_gart_fini(rdev); | 1336 | rv370_pcie_gart_fini(rdev); |
1323 | if (rdev->flags & RADEON_IS_PCI) | 1337 | if (rdev->flags & RADEON_IS_PCI) |
1324 | r100_pci_gart_fini(rdev); | 1338 | r100_pci_gart_fini(rdev); |
1339 | radeon_agp_fini(rdev); | ||
1325 | radeon_irq_kms_fini(rdev); | 1340 | radeon_irq_kms_fini(rdev); |
1326 | radeon_fence_driver_fini(rdev); | 1341 | radeon_fence_driver_fini(rdev); |
1327 | radeon_bo_fini(rdev); | 1342 | radeon_bo_fini(rdev); |
diff --git a/drivers/gpu/drm/radeon/r420.c b/drivers/gpu/drm/radeon/r420.c index c05a7270cf0c..053404e71a9d 100644 --- a/drivers/gpu/drm/radeon/r420.c +++ b/drivers/gpu/drm/radeon/r420.c | |||
@@ -30,7 +30,15 @@ | |||
30 | #include "radeon_reg.h" | 30 | #include "radeon_reg.h" |
31 | #include "radeon.h" | 31 | #include "radeon.h" |
32 | #include "atom.h" | 32 | #include "atom.h" |
33 | #include "r100d.h" | ||
33 | #include "r420d.h" | 34 | #include "r420d.h" |
35 | #include "r420_reg_safe.h" | ||
36 | |||
37 | static void r420_set_reg_safe(struct radeon_device *rdev) | ||
38 | { | ||
39 | rdev->config.r300.reg_safe_bm = r420_reg_safe_bm; | ||
40 | rdev->config.r300.reg_safe_bm_size = ARRAY_SIZE(r420_reg_safe_bm); | ||
41 | } | ||
34 | 42 | ||
35 | int r420_mc_init(struct radeon_device *rdev) | 43 | int r420_mc_init(struct radeon_device *rdev) |
36 | { | 44 | { |
@@ -165,6 +173,34 @@ static void r420_clock_resume(struct radeon_device *rdev) | |||
165 | WREG32_PLL(R_00000D_SCLK_CNTL, sclk_cntl); | 173 | WREG32_PLL(R_00000D_SCLK_CNTL, sclk_cntl); |
166 | } | 174 | } |
167 | 175 | ||
176 | static void r420_cp_errata_init(struct radeon_device *rdev) | ||
177 | { | ||
178 | /* RV410 and R420 can lock up if CP DMA to host memory happens | ||
179 | * while the 2D engine is busy. | ||
180 | * | ||
181 | * The proper workaround is to queue a RESYNC at the beginning | ||
182 | * of the CP init, apparently. | ||
183 | */ | ||
184 | radeon_scratch_get(rdev, &rdev->config.r300.resync_scratch); | ||
185 | radeon_ring_lock(rdev, 8); | ||
186 | radeon_ring_write(rdev, PACKET0(R300_CP_RESYNC_ADDR, 1)); | ||
187 | radeon_ring_write(rdev, rdev->config.r300.resync_scratch); | ||
188 | radeon_ring_write(rdev, 0xDEADBEEF); | ||
189 | radeon_ring_unlock_commit(rdev); | ||
190 | } | ||
191 | |||
192 | static void r420_cp_errata_fini(struct radeon_device *rdev) | ||
193 | { | ||
194 | /* Catch the RESYNC we dispatched all the way back, | ||
195 | * at the very beginning of the CP init. | ||
196 | */ | ||
197 | radeon_ring_lock(rdev, 8); | ||
198 | radeon_ring_write(rdev, PACKET0(R300_RB3D_DSTCACHE_CTLSTAT, 0)); | ||
199 | radeon_ring_write(rdev, R300_RB3D_DC_FINISH); | ||
200 | radeon_ring_unlock_commit(rdev); | ||
201 | radeon_scratch_free(rdev, rdev->config.r300.resync_scratch); | ||
202 | } | ||
203 | |||
168 | static int r420_startup(struct radeon_device *rdev) | 204 | static int r420_startup(struct radeon_device *rdev) |
169 | { | 205 | { |
170 | int r; | 206 | int r; |
@@ -190,12 +226,14 @@ static int r420_startup(struct radeon_device *rdev) | |||
190 | r420_pipes_init(rdev); | 226 | r420_pipes_init(rdev); |
191 | /* Enable IRQ */ | 227 | /* Enable IRQ */ |
192 | r100_irq_set(rdev); | 228 | r100_irq_set(rdev); |
229 | rdev->config.r300.hdp_cntl = RREG32(RADEON_HOST_PATH_CNTL); | ||
193 | /* 1M ring buffer */ | 230 | /* 1M ring buffer */ |
194 | r = r100_cp_init(rdev, 1024 * 1024); | 231 | r = r100_cp_init(rdev, 1024 * 1024); |
195 | if (r) { | 232 | if (r) { |
196 | dev_err(rdev->dev, "failled initializing CP (%d).\n", r); | 233 | dev_err(rdev->dev, "failled initializing CP (%d).\n", r); |
197 | return r; | 234 | return r; |
198 | } | 235 | } |
236 | r420_cp_errata_init(rdev); | ||
199 | r = r100_wb_init(rdev); | 237 | r = r100_wb_init(rdev); |
200 | if (r) { | 238 | if (r) { |
201 | dev_err(rdev->dev, "failled initializing WB (%d).\n", r); | 239 | dev_err(rdev->dev, "failled initializing WB (%d).\n", r); |
@@ -238,6 +276,7 @@ int r420_resume(struct radeon_device *rdev) | |||
238 | 276 | ||
239 | int r420_suspend(struct radeon_device *rdev) | 277 | int r420_suspend(struct radeon_device *rdev) |
240 | { | 278 | { |
279 | r420_cp_errata_fini(rdev); | ||
241 | r100_cp_disable(rdev); | 280 | r100_cp_disable(rdev); |
242 | r100_wb_disable(rdev); | 281 | r100_wb_disable(rdev); |
243 | r100_irq_disable(rdev); | 282 | r100_irq_disable(rdev); |
@@ -346,7 +385,7 @@ int r420_init(struct radeon_device *rdev) | |||
346 | if (r) | 385 | if (r) |
347 | return r; | 386 | return r; |
348 | } | 387 | } |
349 | r300_set_reg_safe(rdev); | 388 | r420_set_reg_safe(rdev); |
350 | rdev->accel_working = true; | 389 | rdev->accel_working = true; |
351 | r = r420_startup(rdev); | 390 | r = r420_startup(rdev); |
352 | if (r) { | 391 | if (r) { |
diff --git a/drivers/gpu/drm/radeon/r520.c b/drivers/gpu/drm/radeon/r520.c index 0f3843b6dac7..9a189072f2b9 100644 --- a/drivers/gpu/drm/radeon/r520.c +++ b/drivers/gpu/drm/radeon/r520.c | |||
@@ -186,6 +186,7 @@ static int r520_startup(struct radeon_device *rdev) | |||
186 | } | 186 | } |
187 | /* Enable IRQ */ | 187 | /* Enable IRQ */ |
188 | rs600_irq_set(rdev); | 188 | rs600_irq_set(rdev); |
189 | rdev->config.r300.hdp_cntl = RREG32(RADEON_HOST_PATH_CNTL); | ||
189 | /* 1M ring buffer */ | 190 | /* 1M ring buffer */ |
190 | r = r100_cp_init(rdev, 1024 * 1024); | 191 | r = r100_cp_init(rdev, 1024 * 1024); |
191 | if (r) { | 192 | if (r) { |
diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c index a0ac3c134b1b..f5ff3490929f 100644 --- a/drivers/gpu/drm/radeon/r600.c +++ b/drivers/gpu/drm/radeon/r600.c | |||
@@ -285,7 +285,8 @@ void r600_hpd_init(struct radeon_device *rdev) | |||
285 | } | 285 | } |
286 | } | 286 | } |
287 | } | 287 | } |
288 | r600_irq_set(rdev); | 288 | if (rdev->irq.installed) |
289 | r600_irq_set(rdev); | ||
289 | } | 290 | } |
290 | 291 | ||
291 | void r600_hpd_fini(struct radeon_device *rdev) | 292 | void r600_hpd_fini(struct radeon_device *rdev) |
@@ -726,6 +727,10 @@ int r600_mc_init(struct radeon_device *rdev) | |||
726 | a.full = rfixed_const(100); | 727 | a.full = rfixed_const(100); |
727 | rdev->pm.sclk.full = rfixed_const(rdev->clock.default_sclk); | 728 | rdev->pm.sclk.full = rfixed_const(rdev->clock.default_sclk); |
728 | rdev->pm.sclk.full = rfixed_div(rdev->pm.sclk, a); | 729 | rdev->pm.sclk.full = rfixed_div(rdev->pm.sclk, a); |
730 | |||
731 | if (rdev->flags & RADEON_IS_IGP) | ||
732 | rdev->mc.igp_sideport_enabled = radeon_atombios_sideport_present(rdev); | ||
733 | |||
729 | return 0; | 734 | return 0; |
730 | } | 735 | } |
731 | 736 | ||
@@ -1384,11 +1389,6 @@ void r600_pciep_wreg(struct radeon_device *rdev, u32 reg, u32 v) | |||
1384 | (void)RREG32(PCIE_PORT_DATA); | 1389 | (void)RREG32(PCIE_PORT_DATA); |
1385 | } | 1390 | } |
1386 | 1391 | ||
1387 | void r600_hdp_flush(struct radeon_device *rdev) | ||
1388 | { | ||
1389 | WREG32(R_005480_HDP_MEM_COHERENCY_FLUSH_CNTL, 0x1); | ||
1390 | } | ||
1391 | |||
1392 | /* | 1392 | /* |
1393 | * CP & Ring | 1393 | * CP & Ring |
1394 | */ | 1394 | */ |
@@ -1785,6 +1785,8 @@ void r600_fence_ring_emit(struct radeon_device *rdev, | |||
1785 | radeon_ring_write(rdev, PACKET3(PACKET3_SET_CONFIG_REG, 1)); | 1785 | radeon_ring_write(rdev, PACKET3(PACKET3_SET_CONFIG_REG, 1)); |
1786 | radeon_ring_write(rdev, ((rdev->fence_drv.scratch_reg - PACKET3_SET_CONFIG_REG_OFFSET) >> 2)); | 1786 | radeon_ring_write(rdev, ((rdev->fence_drv.scratch_reg - PACKET3_SET_CONFIG_REG_OFFSET) >> 2)); |
1787 | radeon_ring_write(rdev, fence->seq); | 1787 | radeon_ring_write(rdev, fence->seq); |
1788 | radeon_ring_write(rdev, PACKET0(R_005480_HDP_MEM_COHERENCY_FLUSH_CNTL, 0)); | ||
1789 | radeon_ring_write(rdev, 1); | ||
1788 | /* CP_INTERRUPT packet 3 no longer exists, use packet 0 */ | 1790 | /* CP_INTERRUPT packet 3 no longer exists, use packet 0 */ |
1789 | radeon_ring_write(rdev, PACKET0(CP_INT_STATUS, 0)); | 1791 | radeon_ring_write(rdev, PACKET0(CP_INT_STATUS, 0)); |
1790 | radeon_ring_write(rdev, RB_INT_STAT); | 1792 | radeon_ring_write(rdev, RB_INT_STAT); |
@@ -2089,8 +2091,7 @@ void r600_fini(struct radeon_device *rdev) | |||
2089 | radeon_gem_fini(rdev); | 2091 | radeon_gem_fini(rdev); |
2090 | radeon_fence_driver_fini(rdev); | 2092 | radeon_fence_driver_fini(rdev); |
2091 | radeon_clocks_fini(rdev); | 2093 | radeon_clocks_fini(rdev); |
2092 | if (rdev->flags & RADEON_IS_AGP) | 2094 | radeon_agp_fini(rdev); |
2093 | radeon_agp_fini(rdev); | ||
2094 | radeon_bo_fini(rdev); | 2095 | radeon_bo_fini(rdev); |
2095 | radeon_atombios_fini(rdev); | 2096 | radeon_atombios_fini(rdev); |
2096 | kfree(rdev->bios); | 2097 | kfree(rdev->bios); |
@@ -2461,6 +2462,10 @@ int r600_irq_set(struct radeon_device *rdev) | |||
2461 | u32 mode_int = 0; | 2462 | u32 mode_int = 0; |
2462 | u32 hpd1, hpd2, hpd3, hpd4 = 0, hpd5 = 0, hpd6 = 0; | 2463 | u32 hpd1, hpd2, hpd3, hpd4 = 0, hpd5 = 0, hpd6 = 0; |
2463 | 2464 | ||
2465 | if (!rdev->irq.installed) { | ||
2466 | WARN(1, "Can't enable IRQ/MSI because no handler is installed.\n"); | ||
2467 | return -EINVAL; | ||
2468 | } | ||
2464 | /* don't enable anything if the ih is disabled */ | 2469 | /* don't enable anything if the ih is disabled */ |
2465 | if (!rdev->ih.enabled) | 2470 | if (!rdev->ih.enabled) |
2466 | return 0; | 2471 | return 0; |
@@ -2724,7 +2729,7 @@ restart_ih: | |||
2724 | } | 2729 | } |
2725 | break; | 2730 | break; |
2726 | default: | 2731 | default: |
2727 | DRM_ERROR("Unhandled interrupt: %d %d\n", src_id, src_data); | 2732 | DRM_DEBUG("Unhandled interrupt: %d %d\n", src_id, src_data); |
2728 | break; | 2733 | break; |
2729 | } | 2734 | } |
2730 | break; | 2735 | break; |
@@ -2744,7 +2749,7 @@ restart_ih: | |||
2744 | } | 2749 | } |
2745 | break; | 2750 | break; |
2746 | default: | 2751 | default: |
2747 | DRM_ERROR("Unhandled interrupt: %d %d\n", src_id, src_data); | 2752 | DRM_DEBUG("Unhandled interrupt: %d %d\n", src_id, src_data); |
2748 | break; | 2753 | break; |
2749 | } | 2754 | } |
2750 | break; | 2755 | break; |
@@ -2793,7 +2798,7 @@ restart_ih: | |||
2793 | } | 2798 | } |
2794 | break; | 2799 | break; |
2795 | default: | 2800 | default: |
2796 | DRM_ERROR("Unhandled interrupt: %d %d\n", src_id, src_data); | 2801 | DRM_DEBUG("Unhandled interrupt: %d %d\n", src_id, src_data); |
2797 | break; | 2802 | break; |
2798 | } | 2803 | } |
2799 | break; | 2804 | break; |
@@ -2807,7 +2812,7 @@ restart_ih: | |||
2807 | DRM_DEBUG("IH: CP EOP\n"); | 2812 | DRM_DEBUG("IH: CP EOP\n"); |
2808 | break; | 2813 | break; |
2809 | default: | 2814 | default: |
2810 | DRM_ERROR("Unhandled interrupt: %d %d\n", src_id, src_data); | 2815 | DRM_DEBUG("Unhandled interrupt: %d %d\n", src_id, src_data); |
2811 | break; | 2816 | break; |
2812 | } | 2817 | } |
2813 | 2818 | ||
diff --git a/drivers/gpu/drm/radeon/r600_blit_kms.c b/drivers/gpu/drm/radeon/r600_blit_kms.c index 9aecafb51b66..8787ea89dc6e 100644 --- a/drivers/gpu/drm/radeon/r600_blit_kms.c +++ b/drivers/gpu/drm/radeon/r600_blit_kms.c | |||
@@ -577,9 +577,9 @@ int r600_blit_prepare_copy(struct radeon_device *rdev, int size_bytes) | |||
577 | ring_size = num_loops * dwords_per_loop; | 577 | ring_size = num_loops * dwords_per_loop; |
578 | /* set default + shaders */ | 578 | /* set default + shaders */ |
579 | ring_size += 40; /* shaders + def state */ | 579 | ring_size += 40; /* shaders + def state */ |
580 | ring_size += 5; /* fence emit for VB IB */ | 580 | ring_size += 7; /* fence emit for VB IB */ |
581 | ring_size += 5; /* done copy */ | 581 | ring_size += 5; /* done copy */ |
582 | ring_size += 5; /* fence emit for done copy */ | 582 | ring_size += 7; /* fence emit for done copy */ |
583 | r = radeon_ring_lock(rdev, ring_size); | 583 | r = radeon_ring_lock(rdev, ring_size); |
584 | WARN_ON(r); | 584 | WARN_ON(r); |
585 | 585 | ||
diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h index 53b55608102b..eb5f99b9469d 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h | |||
@@ -319,10 +319,12 @@ struct radeon_mc { | |||
319 | u64 real_vram_size; | 319 | u64 real_vram_size; |
320 | int vram_mtrr; | 320 | int vram_mtrr; |
321 | bool vram_is_ddr; | 321 | bool vram_is_ddr; |
322 | bool igp_sideport_enabled; | ||
322 | }; | 323 | }; |
323 | 324 | ||
324 | int radeon_mc_setup(struct radeon_device *rdev); | 325 | int radeon_mc_setup(struct radeon_device *rdev); |
325 | 326 | bool radeon_combios_sideport_present(struct radeon_device *rdev); | |
327 | bool radeon_atombios_sideport_present(struct radeon_device *rdev); | ||
326 | 328 | ||
327 | /* | 329 | /* |
328 | * GPU scratch registers structures, functions & helpers | 330 | * GPU scratch registers structures, functions & helpers |
@@ -654,7 +656,6 @@ struct radeon_asic { | |||
654 | uint32_t offset, uint32_t obj_size); | 656 | uint32_t offset, uint32_t obj_size); |
655 | int (*clear_surface_reg)(struct radeon_device *rdev, int reg); | 657 | int (*clear_surface_reg)(struct radeon_device *rdev, int reg); |
656 | void (*bandwidth_update)(struct radeon_device *rdev); | 658 | void (*bandwidth_update)(struct radeon_device *rdev); |
657 | void (*hdp_flush)(struct radeon_device *rdev); | ||
658 | void (*hpd_init)(struct radeon_device *rdev); | 659 | void (*hpd_init)(struct radeon_device *rdev); |
659 | void (*hpd_fini)(struct radeon_device *rdev); | 660 | void (*hpd_fini)(struct radeon_device *rdev); |
660 | bool (*hpd_sense)(struct radeon_device *rdev, enum radeon_hpd_id hpd); | 661 | bool (*hpd_sense)(struct radeon_device *rdev, enum radeon_hpd_id hpd); |
@@ -667,11 +668,14 @@ struct radeon_asic { | |||
667 | struct r100_asic { | 668 | struct r100_asic { |
668 | const unsigned *reg_safe_bm; | 669 | const unsigned *reg_safe_bm; |
669 | unsigned reg_safe_bm_size; | 670 | unsigned reg_safe_bm_size; |
671 | u32 hdp_cntl; | ||
670 | }; | 672 | }; |
671 | 673 | ||
672 | struct r300_asic { | 674 | struct r300_asic { |
673 | const unsigned *reg_safe_bm; | 675 | const unsigned *reg_safe_bm; |
674 | unsigned reg_safe_bm_size; | 676 | unsigned reg_safe_bm_size; |
677 | u32 resync_scratch; | ||
678 | u32 hdp_cntl; | ||
675 | }; | 679 | }; |
676 | 680 | ||
677 | struct r600_asic { | 681 | struct r600_asic { |
@@ -1007,7 +1011,6 @@ static inline void radeon_ring_write(struct radeon_device *rdev, uint32_t v) | |||
1007 | #define radeon_set_surface_reg(rdev, r, f, p, o, s) ((rdev)->asic->set_surface_reg((rdev), (r), (f), (p), (o), (s))) | 1011 | #define radeon_set_surface_reg(rdev, r, f, p, o, s) ((rdev)->asic->set_surface_reg((rdev), (r), (f), (p), (o), (s))) |
1008 | #define radeon_clear_surface_reg(rdev, r) ((rdev)->asic->clear_surface_reg((rdev), (r))) | 1012 | #define radeon_clear_surface_reg(rdev, r) ((rdev)->asic->clear_surface_reg((rdev), (r))) |
1009 | #define radeon_bandwidth_update(rdev) (rdev)->asic->bandwidth_update((rdev)) | 1013 | #define radeon_bandwidth_update(rdev) (rdev)->asic->bandwidth_update((rdev)) |
1010 | #define radeon_hdp_flush(rdev) (rdev)->asic->hdp_flush((rdev)) | ||
1011 | #define radeon_hpd_init(rdev) (rdev)->asic->hpd_init((rdev)) | 1014 | #define radeon_hpd_init(rdev) (rdev)->asic->hpd_init((rdev)) |
1012 | #define radeon_hpd_fini(rdev) (rdev)->asic->hpd_fini((rdev)) | 1015 | #define radeon_hpd_fini(rdev) (rdev)->asic->hpd_fini((rdev)) |
1013 | #define radeon_hpd_sense(rdev, hpd) (rdev)->asic->hpd_sense((rdev), (hpd)) | 1016 | #define radeon_hpd_sense(rdev, hpd) (rdev)->asic->hpd_sense((rdev), (hpd)) |
diff --git a/drivers/gpu/drm/radeon/radeon_agp.c b/drivers/gpu/drm/radeon/radeon_agp.c index 54bf49a6d676..220f454ea9fa 100644 --- a/drivers/gpu/drm/radeon/radeon_agp.c +++ b/drivers/gpu/drm/radeon/radeon_agp.c | |||
@@ -252,10 +252,8 @@ void radeon_agp_resume(struct radeon_device *rdev) | |||
252 | void radeon_agp_fini(struct radeon_device *rdev) | 252 | void radeon_agp_fini(struct radeon_device *rdev) |
253 | { | 253 | { |
254 | #if __OS_HAS_AGP | 254 | #if __OS_HAS_AGP |
255 | if (rdev->flags & RADEON_IS_AGP) { | 255 | if (rdev->ddev->agp && rdev->ddev->agp->acquired) { |
256 | if (rdev->ddev->agp && rdev->ddev->agp->acquired) { | 256 | drm_agp_release(rdev->ddev); |
257 | drm_agp_release(rdev->ddev); | ||
258 | } | ||
259 | } | 257 | } |
260 | #endif | 258 | #endif |
261 | } | 259 | } |
diff --git a/drivers/gpu/drm/radeon/radeon_asic.h b/drivers/gpu/drm/radeon/radeon_asic.h index eb29217bbf1d..f2fbd2e4e9df 100644 --- a/drivers/gpu/drm/radeon/radeon_asic.h +++ b/drivers/gpu/drm/radeon/radeon_asic.h | |||
@@ -77,7 +77,6 @@ int r100_clear_surface_reg(struct radeon_device *rdev, int reg); | |||
77 | void r100_bandwidth_update(struct radeon_device *rdev); | 77 | void r100_bandwidth_update(struct radeon_device *rdev); |
78 | void r100_ring_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib); | 78 | void r100_ring_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib); |
79 | int r100_ring_test(struct radeon_device *rdev); | 79 | int r100_ring_test(struct radeon_device *rdev); |
80 | void r100_hdp_flush(struct radeon_device *rdev); | ||
81 | void r100_hpd_init(struct radeon_device *rdev); | 80 | void r100_hpd_init(struct radeon_device *rdev); |
82 | void r100_hpd_fini(struct radeon_device *rdev); | 81 | void r100_hpd_fini(struct radeon_device *rdev); |
83 | bool r100_hpd_sense(struct radeon_device *rdev, enum radeon_hpd_id hpd); | 82 | bool r100_hpd_sense(struct radeon_device *rdev, enum radeon_hpd_id hpd); |
@@ -114,7 +113,6 @@ static struct radeon_asic r100_asic = { | |||
114 | .set_surface_reg = r100_set_surface_reg, | 113 | .set_surface_reg = r100_set_surface_reg, |
115 | .clear_surface_reg = r100_clear_surface_reg, | 114 | .clear_surface_reg = r100_clear_surface_reg, |
116 | .bandwidth_update = &r100_bandwidth_update, | 115 | .bandwidth_update = &r100_bandwidth_update, |
117 | .hdp_flush = &r100_hdp_flush, | ||
118 | .hpd_init = &r100_hpd_init, | 116 | .hpd_init = &r100_hpd_init, |
119 | .hpd_fini = &r100_hpd_fini, | 117 | .hpd_fini = &r100_hpd_fini, |
120 | .hpd_sense = &r100_hpd_sense, | 118 | .hpd_sense = &r100_hpd_sense, |
@@ -174,7 +172,6 @@ static struct radeon_asic r300_asic = { | |||
174 | .set_surface_reg = r100_set_surface_reg, | 172 | .set_surface_reg = r100_set_surface_reg, |
175 | .clear_surface_reg = r100_clear_surface_reg, | 173 | .clear_surface_reg = r100_clear_surface_reg, |
176 | .bandwidth_update = &r100_bandwidth_update, | 174 | .bandwidth_update = &r100_bandwidth_update, |
177 | .hdp_flush = &r100_hdp_flush, | ||
178 | .hpd_init = &r100_hpd_init, | 175 | .hpd_init = &r100_hpd_init, |
179 | .hpd_fini = &r100_hpd_fini, | 176 | .hpd_fini = &r100_hpd_fini, |
180 | .hpd_sense = &r100_hpd_sense, | 177 | .hpd_sense = &r100_hpd_sense, |
@@ -218,7 +215,6 @@ static struct radeon_asic r420_asic = { | |||
218 | .set_surface_reg = r100_set_surface_reg, | 215 | .set_surface_reg = r100_set_surface_reg, |
219 | .clear_surface_reg = r100_clear_surface_reg, | 216 | .clear_surface_reg = r100_clear_surface_reg, |
220 | .bandwidth_update = &r100_bandwidth_update, | 217 | .bandwidth_update = &r100_bandwidth_update, |
221 | .hdp_flush = &r100_hdp_flush, | ||
222 | .hpd_init = &r100_hpd_init, | 218 | .hpd_init = &r100_hpd_init, |
223 | .hpd_fini = &r100_hpd_fini, | 219 | .hpd_fini = &r100_hpd_fini, |
224 | .hpd_sense = &r100_hpd_sense, | 220 | .hpd_sense = &r100_hpd_sense, |
@@ -267,7 +263,6 @@ static struct radeon_asic rs400_asic = { | |||
267 | .set_surface_reg = r100_set_surface_reg, | 263 | .set_surface_reg = r100_set_surface_reg, |
268 | .clear_surface_reg = r100_clear_surface_reg, | 264 | .clear_surface_reg = r100_clear_surface_reg, |
269 | .bandwidth_update = &r100_bandwidth_update, | 265 | .bandwidth_update = &r100_bandwidth_update, |
270 | .hdp_flush = &r100_hdp_flush, | ||
271 | .hpd_init = &r100_hpd_init, | 266 | .hpd_init = &r100_hpd_init, |
272 | .hpd_fini = &r100_hpd_fini, | 267 | .hpd_fini = &r100_hpd_fini, |
273 | .hpd_sense = &r100_hpd_sense, | 268 | .hpd_sense = &r100_hpd_sense, |
@@ -324,7 +319,6 @@ static struct radeon_asic rs600_asic = { | |||
324 | .set_pcie_lanes = NULL, | 319 | .set_pcie_lanes = NULL, |
325 | .set_clock_gating = &radeon_atom_set_clock_gating, | 320 | .set_clock_gating = &radeon_atom_set_clock_gating, |
326 | .bandwidth_update = &rs600_bandwidth_update, | 321 | .bandwidth_update = &rs600_bandwidth_update, |
327 | .hdp_flush = &r100_hdp_flush, | ||
328 | .hpd_init = &rs600_hpd_init, | 322 | .hpd_init = &rs600_hpd_init, |
329 | .hpd_fini = &rs600_hpd_fini, | 323 | .hpd_fini = &rs600_hpd_fini, |
330 | .hpd_sense = &rs600_hpd_sense, | 324 | .hpd_sense = &rs600_hpd_sense, |
@@ -372,7 +366,6 @@ static struct radeon_asic rs690_asic = { | |||
372 | .set_surface_reg = r100_set_surface_reg, | 366 | .set_surface_reg = r100_set_surface_reg, |
373 | .clear_surface_reg = r100_clear_surface_reg, | 367 | .clear_surface_reg = r100_clear_surface_reg, |
374 | .bandwidth_update = &rs690_bandwidth_update, | 368 | .bandwidth_update = &rs690_bandwidth_update, |
375 | .hdp_flush = &r100_hdp_flush, | ||
376 | .hpd_init = &rs600_hpd_init, | 369 | .hpd_init = &rs600_hpd_init, |
377 | .hpd_fini = &rs600_hpd_fini, | 370 | .hpd_fini = &rs600_hpd_fini, |
378 | .hpd_sense = &rs600_hpd_sense, | 371 | .hpd_sense = &rs600_hpd_sense, |
@@ -424,7 +417,6 @@ static struct radeon_asic rv515_asic = { | |||
424 | .set_surface_reg = r100_set_surface_reg, | 417 | .set_surface_reg = r100_set_surface_reg, |
425 | .clear_surface_reg = r100_clear_surface_reg, | 418 | .clear_surface_reg = r100_clear_surface_reg, |
426 | .bandwidth_update = &rv515_bandwidth_update, | 419 | .bandwidth_update = &rv515_bandwidth_update, |
427 | .hdp_flush = &r100_hdp_flush, | ||
428 | .hpd_init = &rs600_hpd_init, | 420 | .hpd_init = &rs600_hpd_init, |
429 | .hpd_fini = &rs600_hpd_fini, | 421 | .hpd_fini = &rs600_hpd_fini, |
430 | .hpd_sense = &rs600_hpd_sense, | 422 | .hpd_sense = &rs600_hpd_sense, |
@@ -467,7 +459,6 @@ static struct radeon_asic r520_asic = { | |||
467 | .set_surface_reg = r100_set_surface_reg, | 459 | .set_surface_reg = r100_set_surface_reg, |
468 | .clear_surface_reg = r100_clear_surface_reg, | 460 | .clear_surface_reg = r100_clear_surface_reg, |
469 | .bandwidth_update = &rv515_bandwidth_update, | 461 | .bandwidth_update = &rv515_bandwidth_update, |
470 | .hdp_flush = &r100_hdp_flush, | ||
471 | .hpd_init = &rs600_hpd_init, | 462 | .hpd_init = &rs600_hpd_init, |
472 | .hpd_fini = &rs600_hpd_fini, | 463 | .hpd_fini = &rs600_hpd_fini, |
473 | .hpd_sense = &rs600_hpd_sense, | 464 | .hpd_sense = &rs600_hpd_sense, |
@@ -508,7 +499,6 @@ int r600_ring_test(struct radeon_device *rdev); | |||
508 | int r600_copy_blit(struct radeon_device *rdev, | 499 | int r600_copy_blit(struct radeon_device *rdev, |
509 | uint64_t src_offset, uint64_t dst_offset, | 500 | uint64_t src_offset, uint64_t dst_offset, |
510 | unsigned num_pages, struct radeon_fence *fence); | 501 | unsigned num_pages, struct radeon_fence *fence); |
511 | void r600_hdp_flush(struct radeon_device *rdev); | ||
512 | void r600_hpd_init(struct radeon_device *rdev); | 502 | void r600_hpd_init(struct radeon_device *rdev); |
513 | void r600_hpd_fini(struct radeon_device *rdev); | 503 | void r600_hpd_fini(struct radeon_device *rdev); |
514 | bool r600_hpd_sense(struct radeon_device *rdev, enum radeon_hpd_id hpd); | 504 | bool r600_hpd_sense(struct radeon_device *rdev, enum radeon_hpd_id hpd); |
@@ -544,7 +534,6 @@ static struct radeon_asic r600_asic = { | |||
544 | .set_surface_reg = r600_set_surface_reg, | 534 | .set_surface_reg = r600_set_surface_reg, |
545 | .clear_surface_reg = r600_clear_surface_reg, | 535 | .clear_surface_reg = r600_clear_surface_reg, |
546 | .bandwidth_update = &rv515_bandwidth_update, | 536 | .bandwidth_update = &rv515_bandwidth_update, |
547 | .hdp_flush = &r600_hdp_flush, | ||
548 | .hpd_init = &r600_hpd_init, | 537 | .hpd_init = &r600_hpd_init, |
549 | .hpd_fini = &r600_hpd_fini, | 538 | .hpd_fini = &r600_hpd_fini, |
550 | .hpd_sense = &r600_hpd_sense, | 539 | .hpd_sense = &r600_hpd_sense, |
@@ -589,7 +578,6 @@ static struct radeon_asic rv770_asic = { | |||
589 | .set_surface_reg = r600_set_surface_reg, | 578 | .set_surface_reg = r600_set_surface_reg, |
590 | .clear_surface_reg = r600_clear_surface_reg, | 579 | .clear_surface_reg = r600_clear_surface_reg, |
591 | .bandwidth_update = &rv515_bandwidth_update, | 580 | .bandwidth_update = &rv515_bandwidth_update, |
592 | .hdp_flush = &r600_hdp_flush, | ||
593 | .hpd_init = &r600_hpd_init, | 581 | .hpd_init = &r600_hpd_init, |
594 | .hpd_fini = &r600_hpd_fini, | 582 | .hpd_fini = &r600_hpd_fini, |
595 | .hpd_sense = &r600_hpd_sense, | 583 | .hpd_sense = &r600_hpd_sense, |
diff --git a/drivers/gpu/drm/radeon/radeon_atombios.c b/drivers/gpu/drm/radeon/radeon_atombios.c index 321044bef71c..fa82ca74324e 100644 --- a/drivers/gpu/drm/radeon/radeon_atombios.c +++ b/drivers/gpu/drm/radeon/radeon_atombios.c | |||
@@ -114,6 +114,7 @@ static inline struct radeon_i2c_bus_rec radeon_lookup_i2c_gpio(struct radeon_dev | |||
114 | i2c.i2c_id = gpio->sucI2cId.ucAccess; | 114 | i2c.i2c_id = gpio->sucI2cId.ucAccess; |
115 | 115 | ||
116 | i2c.valid = true; | 116 | i2c.valid = true; |
117 | break; | ||
117 | } | 118 | } |
118 | } | 119 | } |
119 | 120 | ||
@@ -345,7 +346,9 @@ const int object_connector_convert[] = { | |||
345 | DRM_MODE_CONNECTOR_Unknown, | 346 | DRM_MODE_CONNECTOR_Unknown, |
346 | DRM_MODE_CONNECTOR_Unknown, | 347 | DRM_MODE_CONNECTOR_Unknown, |
347 | DRM_MODE_CONNECTOR_Unknown, | 348 | DRM_MODE_CONNECTOR_Unknown, |
348 | DRM_MODE_CONNECTOR_DisplayPort | 349 | DRM_MODE_CONNECTOR_DisplayPort, |
350 | DRM_MODE_CONNECTOR_eDP, | ||
351 | DRM_MODE_CONNECTOR_Unknown | ||
349 | }; | 352 | }; |
350 | 353 | ||
351 | bool radeon_get_atom_connector_info_from_object_table(struct drm_device *dev) | 354 | bool radeon_get_atom_connector_info_from_object_table(struct drm_device *dev) |
@@ -935,6 +938,43 @@ bool radeon_atom_get_clock_info(struct drm_device *dev) | |||
935 | return false; | 938 | return false; |
936 | } | 939 | } |
937 | 940 | ||
941 | union igp_info { | ||
942 | struct _ATOM_INTEGRATED_SYSTEM_INFO info; | ||
943 | struct _ATOM_INTEGRATED_SYSTEM_INFO_V2 info_2; | ||
944 | }; | ||
945 | |||
946 | bool radeon_atombios_sideport_present(struct radeon_device *rdev) | ||
947 | { | ||
948 | struct radeon_mode_info *mode_info = &rdev->mode_info; | ||
949 | int index = GetIndexIntoMasterTable(DATA, IntegratedSystemInfo); | ||
950 | union igp_info *igp_info; | ||
951 | u8 frev, crev; | ||
952 | u16 data_offset; | ||
953 | |||
954 | atom_parse_data_header(mode_info->atom_context, index, NULL, &frev, | ||
955 | &crev, &data_offset); | ||
956 | |||
957 | igp_info = (union igp_info *)(mode_info->atom_context->bios + | ||
958 | data_offset); | ||
959 | |||
960 | if (igp_info) { | ||
961 | switch (crev) { | ||
962 | case 1: | ||
963 | if (igp_info->info.ucMemoryType & 0xf0) | ||
964 | return true; | ||
965 | break; | ||
966 | case 2: | ||
967 | if (igp_info->info_2.ucMemoryType & 0x0f) | ||
968 | return true; | ||
969 | break; | ||
970 | default: | ||
971 | DRM_ERROR("Unsupported IGP table: %d %d\n", frev, crev); | ||
972 | break; | ||
973 | } | ||
974 | } | ||
975 | return false; | ||
976 | } | ||
977 | |||
938 | bool radeon_atombios_get_tmds_info(struct radeon_encoder *encoder, | 978 | bool radeon_atombios_get_tmds_info(struct radeon_encoder *encoder, |
939 | struct radeon_encoder_int_tmds *tmds) | 979 | struct radeon_encoder_int_tmds *tmds) |
940 | { | 980 | { |
@@ -1026,6 +1066,7 @@ static struct radeon_atom_ss *radeon_atombios_get_ss_info(struct | |||
1026 | ss->delay = ss_info->asSS_Info[i].ucSS_Delay; | 1066 | ss->delay = ss_info->asSS_Info[i].ucSS_Delay; |
1027 | ss->range = ss_info->asSS_Info[i].ucSS_Range; | 1067 | ss->range = ss_info->asSS_Info[i].ucSS_Range; |
1028 | ss->refdiv = ss_info->asSS_Info[i].ucRecommendedRef_Div; | 1068 | ss->refdiv = ss_info->asSS_Info[i].ucRecommendedRef_Div; |
1069 | break; | ||
1029 | } | 1070 | } |
1030 | } | 1071 | } |
1031 | } | 1072 | } |
diff --git a/drivers/gpu/drm/radeon/radeon_combios.c b/drivers/gpu/drm/radeon/radeon_combios.c index fd94dbca33ac..579c8920e081 100644 --- a/drivers/gpu/drm/radeon/radeon_combios.c +++ b/drivers/gpu/drm/radeon/radeon_combios.c | |||
@@ -595,6 +595,48 @@ bool radeon_combios_get_clock_info(struct drm_device *dev) | |||
595 | return false; | 595 | return false; |
596 | } | 596 | } |
597 | 597 | ||
598 | bool radeon_combios_sideport_present(struct radeon_device *rdev) | ||
599 | { | ||
600 | struct drm_device *dev = rdev->ddev; | ||
601 | u16 igp_info; | ||
602 | |||
603 | igp_info = combios_get_table_offset(dev, COMBIOS_INTEGRATED_SYSTEM_INFO_TABLE); | ||
604 | |||
605 | if (igp_info) { | ||
606 | if (RBIOS16(igp_info + 0x4)) | ||
607 | return true; | ||
608 | } | ||
609 | return false; | ||
610 | } | ||
611 | |||
612 | static const uint32_t default_primarydac_adj[CHIP_LAST] = { | ||
613 | 0x00000808, /* r100 */ | ||
614 | 0x00000808, /* rv100 */ | ||
615 | 0x00000808, /* rs100 */ | ||
616 | 0x00000808, /* rv200 */ | ||
617 | 0x00000808, /* rs200 */ | ||
618 | 0x00000808, /* r200 */ | ||
619 | 0x00000808, /* rv250 */ | ||
620 | 0x00000000, /* rs300 */ | ||
621 | 0x00000808, /* rv280 */ | ||
622 | 0x00000808, /* r300 */ | ||
623 | 0x00000808, /* r350 */ | ||
624 | 0x00000808, /* rv350 */ | ||
625 | 0x00000808, /* rv380 */ | ||
626 | 0x00000808, /* r420 */ | ||
627 | 0x00000808, /* r423 */ | ||
628 | 0x00000808, /* rv410 */ | ||
629 | 0x00000000, /* rs400 */ | ||
630 | 0x00000000, /* rs480 */ | ||
631 | }; | ||
632 | |||
633 | static void radeon_legacy_get_primary_dac_info_from_table(struct radeon_device *rdev, | ||
634 | struct radeon_encoder_primary_dac *p_dac) | ||
635 | { | ||
636 | p_dac->ps2_pdac_adj = default_primarydac_adj[rdev->family]; | ||
637 | return; | ||
638 | } | ||
639 | |||
598 | struct radeon_encoder_primary_dac *radeon_combios_get_primary_dac_info(struct | 640 | struct radeon_encoder_primary_dac *radeon_combios_get_primary_dac_info(struct |
599 | radeon_encoder | 641 | radeon_encoder |
600 | *encoder) | 642 | *encoder) |
@@ -604,20 +646,20 @@ struct radeon_encoder_primary_dac *radeon_combios_get_primary_dac_info(struct | |||
604 | uint16_t dac_info; | 646 | uint16_t dac_info; |
605 | uint8_t rev, bg, dac; | 647 | uint8_t rev, bg, dac; |
606 | struct radeon_encoder_primary_dac *p_dac = NULL; | 648 | struct radeon_encoder_primary_dac *p_dac = NULL; |
649 | int found = 0; | ||
607 | 650 | ||
608 | if (rdev->bios == NULL) | 651 | p_dac = kzalloc(sizeof(struct radeon_encoder_primary_dac), |
652 | GFP_KERNEL); | ||
653 | |||
654 | if (!p_dac) | ||
609 | return NULL; | 655 | return NULL; |
610 | 656 | ||
657 | if (rdev->bios == NULL) | ||
658 | goto out; | ||
659 | |||
611 | /* check CRT table */ | 660 | /* check CRT table */ |
612 | dac_info = combios_get_table_offset(dev, COMBIOS_CRT_INFO_TABLE); | 661 | dac_info = combios_get_table_offset(dev, COMBIOS_CRT_INFO_TABLE); |
613 | if (dac_info) { | 662 | if (dac_info) { |
614 | p_dac = | ||
615 | kzalloc(sizeof(struct radeon_encoder_primary_dac), | ||
616 | GFP_KERNEL); | ||
617 | |||
618 | if (!p_dac) | ||
619 | return NULL; | ||
620 | |||
621 | rev = RBIOS8(dac_info) & 0x3; | 663 | rev = RBIOS8(dac_info) & 0x3; |
622 | if (rev < 2) { | 664 | if (rev < 2) { |
623 | bg = RBIOS8(dac_info + 0x2) & 0xf; | 665 | bg = RBIOS8(dac_info + 0x2) & 0xf; |
@@ -628,9 +670,13 @@ struct radeon_encoder_primary_dac *radeon_combios_get_primary_dac_info(struct | |||
628 | dac = RBIOS8(dac_info + 0x3) & 0xf; | 670 | dac = RBIOS8(dac_info + 0x3) & 0xf; |
629 | p_dac->ps2_pdac_adj = (bg << 8) | (dac); | 671 | p_dac->ps2_pdac_adj = (bg << 8) | (dac); |
630 | } | 672 | } |
631 | 673 | found = 1; | |
632 | } | 674 | } |
633 | 675 | ||
676 | out: | ||
677 | if (!found) /* fallback to defaults */ | ||
678 | radeon_legacy_get_primary_dac_info_from_table(rdev, p_dac); | ||
679 | |||
634 | return p_dac; | 680 | return p_dac; |
635 | } | 681 | } |
636 | 682 | ||
@@ -641,6 +687,9 @@ radeon_combios_get_tv_info(struct radeon_device *rdev) | |||
641 | uint16_t tv_info; | 687 | uint16_t tv_info; |
642 | enum radeon_tv_std tv_std = TV_STD_NTSC; | 688 | enum radeon_tv_std tv_std = TV_STD_NTSC; |
643 | 689 | ||
690 | if (rdev->bios == NULL) | ||
691 | return tv_std; | ||
692 | |||
644 | tv_info = combios_get_table_offset(dev, COMBIOS_TV_INFO_TABLE); | 693 | tv_info = combios_get_table_offset(dev, COMBIOS_TV_INFO_TABLE); |
645 | if (tv_info) { | 694 | if (tv_info) { |
646 | if (RBIOS8(tv_info + 6) == 'T') { | 695 | if (RBIOS8(tv_info + 6) == 'T') { |
diff --git a/drivers/gpu/drm/radeon/radeon_connectors.c b/drivers/gpu/drm/radeon/radeon_connectors.c index 20161567dbff..55266416fa47 100644 --- a/drivers/gpu/drm/radeon/radeon_connectors.c +++ b/drivers/gpu/drm/radeon/radeon_connectors.c | |||
@@ -49,8 +49,10 @@ void radeon_connector_hotplug(struct drm_connector *connector) | |||
49 | if (radeon_connector->hpd.hpd != RADEON_HPD_NONE) | 49 | if (radeon_connector->hpd.hpd != RADEON_HPD_NONE) |
50 | radeon_hpd_set_polarity(rdev, radeon_connector->hpd.hpd); | 50 | radeon_hpd_set_polarity(rdev, radeon_connector->hpd.hpd); |
51 | 51 | ||
52 | if (connector->connector_type == DRM_MODE_CONNECTOR_DisplayPort) { | 52 | if ((connector->connector_type == DRM_MODE_CONNECTOR_DisplayPort) || |
53 | if (radeon_dp_getsinktype(radeon_connector) == CONNECTOR_OBJECT_ID_DISPLAYPORT) { | 53 | (connector->connector_type == DRM_MODE_CONNECTOR_eDP)) { |
54 | if ((radeon_dp_getsinktype(radeon_connector) == CONNECTOR_OBJECT_ID_DISPLAYPORT) || | ||
55 | (radeon_dp_getsinktype(radeon_connector) == CONNECTOR_OBJECT_ID_eDP)) { | ||
54 | if (radeon_dp_needs_link_train(radeon_connector)) { | 56 | if (radeon_dp_needs_link_train(radeon_connector)) { |
55 | if (connector->encoder) | 57 | if (connector->encoder) |
56 | dp_link_train(connector->encoder, connector); | 58 | dp_link_train(connector->encoder, connector); |
@@ -615,7 +617,7 @@ static enum drm_connector_status radeon_vga_detect(struct drm_connector *connect | |||
615 | ret = connector_status_connected; | 617 | ret = connector_status_connected; |
616 | } | 618 | } |
617 | } else { | 619 | } else { |
618 | if (radeon_connector->dac_load_detect) { | 620 | if (radeon_connector->dac_load_detect && encoder) { |
619 | encoder_funcs = encoder->helper_private; | 621 | encoder_funcs = encoder->helper_private; |
620 | ret = encoder_funcs->detect(encoder, connector); | 622 | ret = encoder_funcs->detect(encoder, connector); |
621 | } | 623 | } |
@@ -898,10 +900,18 @@ static void radeon_dvi_force(struct drm_connector *connector) | |||
898 | static int radeon_dvi_mode_valid(struct drm_connector *connector, | 900 | static int radeon_dvi_mode_valid(struct drm_connector *connector, |
899 | struct drm_display_mode *mode) | 901 | struct drm_display_mode *mode) |
900 | { | 902 | { |
903 | struct drm_device *dev = connector->dev; | ||
904 | struct radeon_device *rdev = dev->dev_private; | ||
901 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); | 905 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); |
902 | 906 | ||
903 | /* XXX check mode bandwidth */ | 907 | /* XXX check mode bandwidth */ |
904 | 908 | ||
909 | /* clocks over 135 MHz have heat issues with DVI on RV100 */ | ||
910 | if (radeon_connector->use_digital && | ||
911 | (rdev->family == CHIP_RV100) && | ||
912 | (mode->clock > 135000)) | ||
913 | return MODE_CLOCK_HIGH; | ||
914 | |||
905 | if (radeon_connector->use_digital && (mode->clock > 165000)) { | 915 | if (radeon_connector->use_digital && (mode->clock > 165000)) { |
906 | if ((radeon_connector->connector_object_id == CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_I) || | 916 | if ((radeon_connector->connector_object_id == CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_I) || |
907 | (radeon_connector->connector_object_id == CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_D) || | 917 | (radeon_connector->connector_object_id == CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_D) || |
@@ -967,7 +977,8 @@ static enum drm_connector_status radeon_dp_detect(struct drm_connector *connecto | |||
967 | } | 977 | } |
968 | 978 | ||
969 | sink_type = radeon_dp_getsinktype(radeon_connector); | 979 | sink_type = radeon_dp_getsinktype(radeon_connector); |
970 | if (sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT) { | 980 | if ((sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT) || |
981 | (sink_type == CONNECTOR_OBJECT_ID_eDP)) { | ||
971 | if (radeon_dp_getdpcd(radeon_connector)) { | 982 | if (radeon_dp_getdpcd(radeon_connector)) { |
972 | radeon_dig_connector->dp_sink_type = sink_type; | 983 | radeon_dig_connector->dp_sink_type = sink_type; |
973 | ret = connector_status_connected; | 984 | ret = connector_status_connected; |
@@ -992,7 +1003,8 @@ static int radeon_dp_mode_valid(struct drm_connector *connector, | |||
992 | 1003 | ||
993 | /* XXX check mode bandwidth */ | 1004 | /* XXX check mode bandwidth */ |
994 | 1005 | ||
995 | if (radeon_dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT) | 1006 | if ((radeon_dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT) || |
1007 | (radeon_dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_eDP)) | ||
996 | return radeon_dp_mode_valid_helper(radeon_connector, mode); | 1008 | return radeon_dp_mode_valid_helper(radeon_connector, mode); |
997 | else | 1009 | else |
998 | return MODE_OK; | 1010 | return MODE_OK; |
@@ -1145,6 +1157,7 @@ radeon_add_atom_connector(struct drm_device *dev, | |||
1145 | subpixel_order = SubPixelHorizontalRGB; | 1157 | subpixel_order = SubPixelHorizontalRGB; |
1146 | break; | 1158 | break; |
1147 | case DRM_MODE_CONNECTOR_DisplayPort: | 1159 | case DRM_MODE_CONNECTOR_DisplayPort: |
1160 | case DRM_MODE_CONNECTOR_eDP: | ||
1148 | radeon_dig_connector = kzalloc(sizeof(struct radeon_connector_atom_dig), GFP_KERNEL); | 1161 | radeon_dig_connector = kzalloc(sizeof(struct radeon_connector_atom_dig), GFP_KERNEL); |
1149 | if (!radeon_dig_connector) | 1162 | if (!radeon_dig_connector) |
1150 | goto failed; | 1163 | goto failed; |
@@ -1157,10 +1170,16 @@ radeon_add_atom_connector(struct drm_device *dev, | |||
1157 | goto failed; | 1170 | goto failed; |
1158 | if (i2c_bus->valid) { | 1171 | if (i2c_bus->valid) { |
1159 | /* add DP i2c bus */ | 1172 | /* add DP i2c bus */ |
1160 | radeon_dig_connector->dp_i2c_bus = radeon_i2c_create_dp(dev, i2c_bus, "DP-auxch"); | 1173 | if (connector_type == DRM_MODE_CONNECTOR_eDP) |
1174 | radeon_dig_connector->dp_i2c_bus = radeon_i2c_create_dp(dev, i2c_bus, "eDP-auxch"); | ||
1175 | else | ||
1176 | radeon_dig_connector->dp_i2c_bus = radeon_i2c_create_dp(dev, i2c_bus, "DP-auxch"); | ||
1161 | if (!radeon_dig_connector->dp_i2c_bus) | 1177 | if (!radeon_dig_connector->dp_i2c_bus) |
1162 | goto failed; | 1178 | goto failed; |
1163 | radeon_connector->ddc_bus = radeon_i2c_create(dev, i2c_bus, "DP"); | 1179 | if (connector_type == DRM_MODE_CONNECTOR_eDP) |
1180 | radeon_connector->ddc_bus = radeon_i2c_create(dev, i2c_bus, "eDP"); | ||
1181 | else | ||
1182 | radeon_connector->ddc_bus = radeon_i2c_create(dev, i2c_bus, "DP"); | ||
1164 | if (!radeon_connector->ddc_bus) | 1183 | if (!radeon_connector->ddc_bus) |
1165 | goto failed; | 1184 | goto failed; |
1166 | } | 1185 | } |
diff --git a/drivers/gpu/drm/radeon/radeon_cp.c b/drivers/gpu/drm/radeon/radeon_cp.c index 0b2f9c2ad2c1..06123ba31d31 100644 --- a/drivers/gpu/drm/radeon/radeon_cp.c +++ b/drivers/gpu/drm/radeon/radeon_cp.c | |||
@@ -2145,6 +2145,7 @@ int radeon_master_create(struct drm_device *dev, struct drm_master *master) | |||
2145 | &master_priv->sarea); | 2145 | &master_priv->sarea); |
2146 | if (ret) { | 2146 | if (ret) { |
2147 | DRM_ERROR("SAREA setup failed\n"); | 2147 | DRM_ERROR("SAREA setup failed\n"); |
2148 | kfree(master_priv); | ||
2148 | return ret; | 2149 | return ret; |
2149 | } | 2150 | } |
2150 | master_priv->sarea_priv = master_priv->sarea->handle + sizeof(struct drm_sarea); | 2151 | master_priv->sarea_priv = master_priv->sarea->handle + sizeof(struct drm_sarea); |
diff --git a/drivers/gpu/drm/radeon/radeon_device.c b/drivers/gpu/drm/radeon/radeon_device.c index 7c6848096bcd..0c51f8e46613 100644 --- a/drivers/gpu/drm/radeon/radeon_device.c +++ b/drivers/gpu/drm/radeon/radeon_device.c | |||
@@ -733,16 +733,18 @@ void radeon_device_fini(struct radeon_device *rdev) | |||
733 | */ | 733 | */ |
734 | int radeon_suspend_kms(struct drm_device *dev, pm_message_t state) | 734 | int radeon_suspend_kms(struct drm_device *dev, pm_message_t state) |
735 | { | 735 | { |
736 | struct radeon_device *rdev = dev->dev_private; | 736 | struct radeon_device *rdev; |
737 | struct drm_crtc *crtc; | 737 | struct drm_crtc *crtc; |
738 | int r; | 738 | int r; |
739 | 739 | ||
740 | if (dev == NULL || rdev == NULL) { | 740 | if (dev == NULL || dev->dev_private == NULL) { |
741 | return -ENODEV; | 741 | return -ENODEV; |
742 | } | 742 | } |
743 | if (state.event == PM_EVENT_PRETHAW) { | 743 | if (state.event == PM_EVENT_PRETHAW) { |
744 | return 0; | 744 | return 0; |
745 | } | 745 | } |
746 | rdev = dev->dev_private; | ||
747 | |||
746 | /* unpin the front buffers */ | 748 | /* unpin the front buffers */ |
747 | list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { | 749 | list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { |
748 | struct radeon_framebuffer *rfb = to_radeon_framebuffer(crtc->fb); | 750 | struct radeon_framebuffer *rfb = to_radeon_framebuffer(crtc->fb); |
diff --git a/drivers/gpu/drm/radeon/radeon_display.c b/drivers/gpu/drm/radeon/radeon_display.c index 91d72b70abc9..0ec491ead2ff 100644 --- a/drivers/gpu/drm/radeon/radeon_display.c +++ b/drivers/gpu/drm/radeon/radeon_display.c | |||
@@ -234,7 +234,7 @@ static const char *encoder_names[34] = { | |||
234 | "INTERNAL_UNIPHY2", | 234 | "INTERNAL_UNIPHY2", |
235 | }; | 235 | }; |
236 | 236 | ||
237 | static const char *connector_names[13] = { | 237 | static const char *connector_names[15] = { |
238 | "Unknown", | 238 | "Unknown", |
239 | "VGA", | 239 | "VGA", |
240 | "DVI-I", | 240 | "DVI-I", |
@@ -248,6 +248,8 @@ static const char *connector_names[13] = { | |||
248 | "DisplayPort", | 248 | "DisplayPort", |
249 | "HDMI-A", | 249 | "HDMI-A", |
250 | "HDMI-B", | 250 | "HDMI-B", |
251 | "TV", | ||
252 | "eDP", | ||
251 | }; | 253 | }; |
252 | 254 | ||
253 | static const char *hpd_names[7] = { | 255 | static const char *hpd_names[7] = { |
@@ -329,8 +331,11 @@ static bool radeon_setup_enc_conn(struct drm_device *dev) | |||
329 | ret = radeon_get_atom_connector_info_from_object_table(dev); | 331 | ret = radeon_get_atom_connector_info_from_object_table(dev); |
330 | else | 332 | else |
331 | ret = radeon_get_atom_connector_info_from_supported_devices_table(dev); | 333 | ret = radeon_get_atom_connector_info_from_supported_devices_table(dev); |
332 | } else | 334 | } else { |
333 | ret = radeon_get_legacy_connector_info_from_bios(dev); | 335 | ret = radeon_get_legacy_connector_info_from_bios(dev); |
336 | if (ret == false) | ||
337 | ret = radeon_get_legacy_connector_info_from_table(dev); | ||
338 | } | ||
334 | } else { | 339 | } else { |
335 | if (!ASIC_IS_AVIVO(rdev)) | 340 | if (!ASIC_IS_AVIVO(rdev)) |
336 | ret = radeon_get_legacy_connector_info_from_table(dev); | 341 | ret = radeon_get_legacy_connector_info_from_table(dev); |
@@ -349,7 +354,8 @@ int radeon_ddc_get_modes(struct radeon_connector *radeon_connector) | |||
349 | { | 354 | { |
350 | int ret = 0; | 355 | int ret = 0; |
351 | 356 | ||
352 | if (radeon_connector->base.connector_type == DRM_MODE_CONNECTOR_DisplayPort) { | 357 | if ((radeon_connector->base.connector_type == DRM_MODE_CONNECTOR_DisplayPort) || |
358 | (radeon_connector->base.connector_type == DRM_MODE_CONNECTOR_eDP)) { | ||
353 | struct radeon_connector_atom_dig *dig = radeon_connector->con_priv; | 359 | struct radeon_connector_atom_dig *dig = radeon_connector->con_priv; |
354 | if (dig->dp_i2c_bus) | 360 | if (dig->dp_i2c_bus) |
355 | radeon_connector->edid = drm_get_edid(&radeon_connector->base, &dig->dp_i2c_bus->adapter); | 361 | radeon_connector->edid = drm_get_edid(&radeon_connector->base, &dig->dp_i2c_bus->adapter); |
diff --git a/drivers/gpu/drm/radeon/radeon_encoders.c b/drivers/gpu/drm/radeon/radeon_encoders.c index ccba95f83d11..82eb551970b9 100644 --- a/drivers/gpu/drm/radeon/radeon_encoders.c +++ b/drivers/gpu/drm/radeon/radeon_encoders.c | |||
@@ -596,21 +596,23 @@ atombios_get_encoder_mode(struct drm_encoder *encoder) | |||
596 | return ATOM_ENCODER_MODE_LVDS; | 596 | return ATOM_ENCODER_MODE_LVDS; |
597 | break; | 597 | break; |
598 | case DRM_MODE_CONNECTOR_DisplayPort: | 598 | case DRM_MODE_CONNECTOR_DisplayPort: |
599 | case DRM_MODE_CONNECTOR_eDP: | ||
599 | radeon_dig_connector = radeon_connector->con_priv; | 600 | radeon_dig_connector = radeon_connector->con_priv; |
600 | if (radeon_dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT) | 601 | if ((radeon_dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT) || |
602 | (radeon_dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_eDP)) | ||
601 | return ATOM_ENCODER_MODE_DP; | 603 | return ATOM_ENCODER_MODE_DP; |
602 | else if (drm_detect_hdmi_monitor(radeon_connector->edid)) | 604 | else if (drm_detect_hdmi_monitor(radeon_connector->edid)) |
603 | return ATOM_ENCODER_MODE_HDMI; | 605 | return ATOM_ENCODER_MODE_HDMI; |
604 | else | 606 | else |
605 | return ATOM_ENCODER_MODE_DVI; | 607 | return ATOM_ENCODER_MODE_DVI; |
606 | break; | 608 | break; |
607 | case CONNECTOR_DVI_A: | 609 | case DRM_MODE_CONNECTOR_DVIA: |
608 | case CONNECTOR_VGA: | 610 | case DRM_MODE_CONNECTOR_VGA: |
609 | return ATOM_ENCODER_MODE_CRT; | 611 | return ATOM_ENCODER_MODE_CRT; |
610 | break; | 612 | break; |
611 | case CONNECTOR_STV: | 613 | case DRM_MODE_CONNECTOR_Composite: |
612 | case CONNECTOR_CTV: | 614 | case DRM_MODE_CONNECTOR_SVIDEO: |
613 | case CONNECTOR_DIN: | 615 | case DRM_MODE_CONNECTOR_9PinDIN: |
614 | /* fix me */ | 616 | /* fix me */ |
615 | return ATOM_ENCODER_MODE_TV; | 617 | return ATOM_ENCODER_MODE_TV; |
616 | /*return ATOM_ENCODER_MODE_CV;*/ | 618 | /*return ATOM_ENCODER_MODE_CV;*/ |
diff --git a/drivers/gpu/drm/radeon/radeon_fence.c b/drivers/gpu/drm/radeon/radeon_fence.c index 4cdd8b4f7549..8495d4e32e18 100644 --- a/drivers/gpu/drm/radeon/radeon_fence.c +++ b/drivers/gpu/drm/radeon/radeon_fence.c | |||
@@ -140,16 +140,15 @@ int radeon_fence_create(struct radeon_device *rdev, struct radeon_fence **fence) | |||
140 | 140 | ||
141 | bool radeon_fence_signaled(struct radeon_fence *fence) | 141 | bool radeon_fence_signaled(struct radeon_fence *fence) |
142 | { | 142 | { |
143 | struct radeon_device *rdev = fence->rdev; | ||
144 | unsigned long irq_flags; | 143 | unsigned long irq_flags; |
145 | bool signaled = false; | 144 | bool signaled = false; |
146 | 145 | ||
147 | if (rdev->gpu_lockup) { | 146 | if (!fence) |
148 | return true; | 147 | return true; |
149 | } | 148 | |
150 | if (fence == NULL) { | 149 | if (fence->rdev->gpu_lockup) |
151 | return true; | 150 | return true; |
152 | } | 151 | |
153 | write_lock_irqsave(&fence->rdev->fence_drv.lock, irq_flags); | 152 | write_lock_irqsave(&fence->rdev->fence_drv.lock, irq_flags); |
154 | signaled = fence->signaled; | 153 | signaled = fence->signaled; |
155 | /* if we are shuting down report all fence as signaled */ | 154 | /* if we are shuting down report all fence as signaled */ |
diff --git a/drivers/gpu/drm/radeon/radeon_gem.c b/drivers/gpu/drm/radeon/radeon_gem.c index 60df2d7e7e4c..0e1325e18534 100644 --- a/drivers/gpu/drm/radeon/radeon_gem.c +++ b/drivers/gpu/drm/radeon/radeon_gem.c | |||
@@ -131,7 +131,6 @@ int radeon_gem_set_domain(struct drm_gem_object *gobj, | |||
131 | printk(KERN_ERR "Failed to wait for object !\n"); | 131 | printk(KERN_ERR "Failed to wait for object !\n"); |
132 | return r; | 132 | return r; |
133 | } | 133 | } |
134 | radeon_hdp_flush(robj->rdev); | ||
135 | } | 134 | } |
136 | return 0; | 135 | return 0; |
137 | } | 136 | } |
@@ -312,7 +311,6 @@ int radeon_gem_wait_idle_ioctl(struct drm_device *dev, void *data, | |||
312 | mutex_lock(&dev->struct_mutex); | 311 | mutex_lock(&dev->struct_mutex); |
313 | drm_gem_object_unreference(gobj); | 312 | drm_gem_object_unreference(gobj); |
314 | mutex_unlock(&dev->struct_mutex); | 313 | mutex_unlock(&dev->struct_mutex); |
315 | radeon_hdp_flush(robj->rdev); | ||
316 | return r; | 314 | return r; |
317 | } | 315 | } |
318 | 316 | ||
diff --git a/drivers/gpu/drm/radeon/radeon_irq.c b/drivers/gpu/drm/radeon/radeon_irq.c index b79ecc4a7cc4..2f349a300195 100644 --- a/drivers/gpu/drm/radeon/radeon_irq.c +++ b/drivers/gpu/drm/radeon/radeon_irq.c | |||
@@ -289,16 +289,16 @@ int radeon_irq_emit(struct drm_device *dev, void *data, struct drm_file *file_pr | |||
289 | drm_radeon_irq_emit_t *emit = data; | 289 | drm_radeon_irq_emit_t *emit = data; |
290 | int result; | 290 | int result; |
291 | 291 | ||
292 | if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) | ||
293 | return -EINVAL; | ||
294 | |||
295 | LOCK_TEST_WITH_RETURN(dev, file_priv); | ||
296 | |||
297 | if (!dev_priv) { | 292 | if (!dev_priv) { |
298 | DRM_ERROR("called with no initialization\n"); | 293 | DRM_ERROR("called with no initialization\n"); |
299 | return -EINVAL; | 294 | return -EINVAL; |
300 | } | 295 | } |
301 | 296 | ||
297 | if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) | ||
298 | return -EINVAL; | ||
299 | |||
300 | LOCK_TEST_WITH_RETURN(dev, file_priv); | ||
301 | |||
302 | result = radeon_emit_irq(dev); | 302 | result = radeon_emit_irq(dev); |
303 | 303 | ||
304 | if (DRM_COPY_TO_USER(emit->irq_seq, &result, sizeof(int))) { | 304 | if (DRM_COPY_TO_USER(emit->irq_seq, &result, sizeof(int))) { |
diff --git a/drivers/gpu/drm/radeon/radeon_irq_kms.c b/drivers/gpu/drm/radeon/radeon_irq_kms.c index 9223296fe37b..3cfd60fd0083 100644 --- a/drivers/gpu/drm/radeon/radeon_irq_kms.c +++ b/drivers/gpu/drm/radeon/radeon_irq_kms.c | |||
@@ -97,6 +97,7 @@ void radeon_driver_irq_uninstall_kms(struct drm_device *dev) | |||
97 | rdev->irq.sw_int = false; | 97 | rdev->irq.sw_int = false; |
98 | for (i = 0; i < 2; i++) { | 98 | for (i = 0; i < 2; i++) { |
99 | rdev->irq.crtc_vblank_int[i] = false; | 99 | rdev->irq.crtc_vblank_int[i] = false; |
100 | rdev->irq.hpd[i] = false; | ||
100 | } | 101 | } |
101 | radeon_irq_set(rdev); | 102 | radeon_irq_set(rdev); |
102 | } | 103 | } |
@@ -128,17 +129,22 @@ int radeon_irq_kms_init(struct radeon_device *rdev) | |||
128 | DRM_INFO("radeon: using MSI.\n"); | 129 | DRM_INFO("radeon: using MSI.\n"); |
129 | } | 130 | } |
130 | } | 131 | } |
131 | drm_irq_install(rdev->ddev); | ||
132 | rdev->irq.installed = true; | 132 | rdev->irq.installed = true; |
133 | r = drm_irq_install(rdev->ddev); | ||
134 | if (r) { | ||
135 | rdev->irq.installed = false; | ||
136 | return r; | ||
137 | } | ||
133 | DRM_INFO("radeon: irq initialized.\n"); | 138 | DRM_INFO("radeon: irq initialized.\n"); |
134 | return 0; | 139 | return 0; |
135 | } | 140 | } |
136 | 141 | ||
137 | void radeon_irq_kms_fini(struct radeon_device *rdev) | 142 | void radeon_irq_kms_fini(struct radeon_device *rdev) |
138 | { | 143 | { |
144 | drm_vblank_cleanup(rdev->ddev); | ||
139 | if (rdev->irq.installed) { | 145 | if (rdev->irq.installed) { |
140 | rdev->irq.installed = false; | ||
141 | drm_irq_uninstall(rdev->ddev); | 146 | drm_irq_uninstall(rdev->ddev); |
147 | rdev->irq.installed = false; | ||
142 | if (rdev->msi_enabled) | 148 | if (rdev->msi_enabled) |
143 | pci_disable_msi(rdev->pdev); | 149 | pci_disable_msi(rdev->pdev); |
144 | } | 150 | } |
diff --git a/drivers/gpu/drm/radeon/radeon_legacy_encoders.c b/drivers/gpu/drm/radeon/radeon_legacy_encoders.c index 981508ff7037..38e45e231ef5 100644 --- a/drivers/gpu/drm/radeon/radeon_legacy_encoders.c +++ b/drivers/gpu/drm/radeon/radeon_legacy_encoders.c | |||
@@ -46,6 +46,7 @@ static void radeon_legacy_lvds_dpms(struct drm_encoder *encoder, int mode) | |||
46 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | 46 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); |
47 | uint32_t lvds_gen_cntl, lvds_pll_cntl, pixclks_cntl, disp_pwr_man; | 47 | uint32_t lvds_gen_cntl, lvds_pll_cntl, pixclks_cntl, disp_pwr_man; |
48 | int panel_pwr_delay = 2000; | 48 | int panel_pwr_delay = 2000; |
49 | bool is_mac = false; | ||
49 | DRM_DEBUG("\n"); | 50 | DRM_DEBUG("\n"); |
50 | 51 | ||
51 | if (radeon_encoder->enc_priv) { | 52 | if (radeon_encoder->enc_priv) { |
@@ -58,6 +59,15 @@ static void radeon_legacy_lvds_dpms(struct drm_encoder *encoder, int mode) | |||
58 | } | 59 | } |
59 | } | 60 | } |
60 | 61 | ||
62 | /* macs (and possibly some x86 oem systems?) wire up LVDS strangely | ||
63 | * Taken from radeonfb. | ||
64 | */ | ||
65 | if ((rdev->mode_info.connector_table == CT_IBOOK) || | ||
66 | (rdev->mode_info.connector_table == CT_POWERBOOK_EXTERNAL) || | ||
67 | (rdev->mode_info.connector_table == CT_POWERBOOK_INTERNAL) || | ||
68 | (rdev->mode_info.connector_table == CT_POWERBOOK_VGA)) | ||
69 | is_mac = true; | ||
70 | |||
61 | switch (mode) { | 71 | switch (mode) { |
62 | case DRM_MODE_DPMS_ON: | 72 | case DRM_MODE_DPMS_ON: |
63 | disp_pwr_man = RREG32(RADEON_DISP_PWR_MAN); | 73 | disp_pwr_man = RREG32(RADEON_DISP_PWR_MAN); |
@@ -74,6 +84,8 @@ static void radeon_legacy_lvds_dpms(struct drm_encoder *encoder, int mode) | |||
74 | 84 | ||
75 | lvds_gen_cntl = RREG32(RADEON_LVDS_GEN_CNTL); | 85 | lvds_gen_cntl = RREG32(RADEON_LVDS_GEN_CNTL); |
76 | lvds_gen_cntl |= (RADEON_LVDS_ON | RADEON_LVDS_EN | RADEON_LVDS_DIGON | RADEON_LVDS_BLON); | 86 | lvds_gen_cntl |= (RADEON_LVDS_ON | RADEON_LVDS_EN | RADEON_LVDS_DIGON | RADEON_LVDS_BLON); |
87 | if (is_mac) | ||
88 | lvds_gen_cntl |= RADEON_LVDS_BL_MOD_EN; | ||
77 | lvds_gen_cntl &= ~(RADEON_LVDS_DISPLAY_DIS); | 89 | lvds_gen_cntl &= ~(RADEON_LVDS_DISPLAY_DIS); |
78 | udelay(panel_pwr_delay * 1000); | 90 | udelay(panel_pwr_delay * 1000); |
79 | WREG32(RADEON_LVDS_GEN_CNTL, lvds_gen_cntl); | 91 | WREG32(RADEON_LVDS_GEN_CNTL, lvds_gen_cntl); |
@@ -85,7 +97,14 @@ static void radeon_legacy_lvds_dpms(struct drm_encoder *encoder, int mode) | |||
85 | WREG32_PLL_P(RADEON_PIXCLKS_CNTL, 0, ~RADEON_PIXCLK_LVDS_ALWAYS_ONb); | 97 | WREG32_PLL_P(RADEON_PIXCLKS_CNTL, 0, ~RADEON_PIXCLK_LVDS_ALWAYS_ONb); |
86 | lvds_gen_cntl = RREG32(RADEON_LVDS_GEN_CNTL); | 98 | lvds_gen_cntl = RREG32(RADEON_LVDS_GEN_CNTL); |
87 | lvds_gen_cntl |= RADEON_LVDS_DISPLAY_DIS; | 99 | lvds_gen_cntl |= RADEON_LVDS_DISPLAY_DIS; |
88 | lvds_gen_cntl &= ~(RADEON_LVDS_ON | RADEON_LVDS_BLON | RADEON_LVDS_EN | RADEON_LVDS_DIGON); | 100 | if (is_mac) { |
101 | lvds_gen_cntl &= ~RADEON_LVDS_BL_MOD_EN; | ||
102 | WREG32(RADEON_LVDS_GEN_CNTL, lvds_gen_cntl); | ||
103 | lvds_gen_cntl &= ~(RADEON_LVDS_ON | RADEON_LVDS_EN); | ||
104 | } else { | ||
105 | WREG32(RADEON_LVDS_GEN_CNTL, lvds_gen_cntl); | ||
106 | lvds_gen_cntl &= ~(RADEON_LVDS_ON | RADEON_LVDS_BLON | RADEON_LVDS_EN | RADEON_LVDS_DIGON); | ||
107 | } | ||
89 | udelay(panel_pwr_delay * 1000); | 108 | udelay(panel_pwr_delay * 1000); |
90 | WREG32(RADEON_LVDS_GEN_CNTL, lvds_gen_cntl); | 109 | WREG32(RADEON_LVDS_GEN_CNTL, lvds_gen_cntl); |
91 | WREG32_PLL(RADEON_PIXCLKS_CNTL, pixclks_cntl); | 110 | WREG32_PLL(RADEON_PIXCLKS_CNTL, pixclks_cntl); |
diff --git a/drivers/gpu/drm/radeon/radeon_legacy_tv.c b/drivers/gpu/drm/radeon/radeon_legacy_tv.c index 3a12bb0c0563..417684daef4c 100644 --- a/drivers/gpu/drm/radeon/radeon_legacy_tv.c +++ b/drivers/gpu/drm/radeon/radeon_legacy_tv.c | |||
@@ -77,7 +77,7 @@ struct radeon_tv_mode_constants { | |||
77 | unsigned pix_to_tv; | 77 | unsigned pix_to_tv; |
78 | }; | 78 | }; |
79 | 79 | ||
80 | static const uint16_t hor_timing_NTSC[] = { | 80 | static const uint16_t hor_timing_NTSC[MAX_H_CODE_TIMING_LEN] = { |
81 | 0x0007, | 81 | 0x0007, |
82 | 0x003f, | 82 | 0x003f, |
83 | 0x0263, | 83 | 0x0263, |
@@ -98,7 +98,7 @@ static const uint16_t hor_timing_NTSC[] = { | |||
98 | 0 | 98 | 0 |
99 | }; | 99 | }; |
100 | 100 | ||
101 | static const uint16_t vert_timing_NTSC[] = { | 101 | static const uint16_t vert_timing_NTSC[MAX_V_CODE_TIMING_LEN] = { |
102 | 0x2001, | 102 | 0x2001, |
103 | 0x200d, | 103 | 0x200d, |
104 | 0x1006, | 104 | 0x1006, |
@@ -115,7 +115,7 @@ static const uint16_t vert_timing_NTSC[] = { | |||
115 | 0 | 115 | 0 |
116 | }; | 116 | }; |
117 | 117 | ||
118 | static const uint16_t hor_timing_PAL[] = { | 118 | static const uint16_t hor_timing_PAL[MAX_H_CODE_TIMING_LEN] = { |
119 | 0x0007, | 119 | 0x0007, |
120 | 0x0058, | 120 | 0x0058, |
121 | 0x027c, | 121 | 0x027c, |
@@ -136,7 +136,7 @@ static const uint16_t hor_timing_PAL[] = { | |||
136 | 0 | 136 | 0 |
137 | }; | 137 | }; |
138 | 138 | ||
139 | static const uint16_t vert_timing_PAL[] = { | 139 | static const uint16_t vert_timing_PAL[MAX_V_CODE_TIMING_LEN] = { |
140 | 0x2001, | 140 | 0x2001, |
141 | 0x200c, | 141 | 0x200c, |
142 | 0x1005, | 142 | 0x1005, |
@@ -623,9 +623,9 @@ void radeon_legacy_tv_mode_set(struct drm_encoder *encoder, | |||
623 | } | 623 | } |
624 | flicker_removal = (tmp + 500) / 1000; | 624 | flicker_removal = (tmp + 500) / 1000; |
625 | 625 | ||
626 | if (flicker_removal < 3) | 626 | if (flicker_removal < 2) |
627 | flicker_removal = 3; | 627 | flicker_removal = 2; |
628 | for (i = 0; i < 6; ++i) { | 628 | for (i = 0; i < ARRAY_SIZE(SLOPE_limit); ++i) { |
629 | if (flicker_removal == SLOPE_limit[i]) | 629 | if (flicker_removal == SLOPE_limit[i]) |
630 | break; | 630 | break; |
631 | } | 631 | } |
diff --git a/drivers/gpu/drm/radeon/radeon_mode.h b/drivers/gpu/drm/radeon/radeon_mode.h index 402369db5ba0..91cb041cb40d 100644 --- a/drivers/gpu/drm/radeon/radeon_mode.h +++ b/drivers/gpu/drm/radeon/radeon_mode.h | |||
@@ -46,32 +46,6 @@ struct radeon_device; | |||
46 | #define to_radeon_encoder(x) container_of(x, struct radeon_encoder, base) | 46 | #define to_radeon_encoder(x) container_of(x, struct radeon_encoder, base) |
47 | #define to_radeon_framebuffer(x) container_of(x, struct radeon_framebuffer, base) | 47 | #define to_radeon_framebuffer(x) container_of(x, struct radeon_framebuffer, base) |
48 | 48 | ||
49 | enum radeon_connector_type { | ||
50 | CONNECTOR_NONE, | ||
51 | CONNECTOR_VGA, | ||
52 | CONNECTOR_DVI_I, | ||
53 | CONNECTOR_DVI_D, | ||
54 | CONNECTOR_DVI_A, | ||
55 | CONNECTOR_STV, | ||
56 | CONNECTOR_CTV, | ||
57 | CONNECTOR_LVDS, | ||
58 | CONNECTOR_DIGITAL, | ||
59 | CONNECTOR_SCART, | ||
60 | CONNECTOR_HDMI_TYPE_A, | ||
61 | CONNECTOR_HDMI_TYPE_B, | ||
62 | CONNECTOR_0XC, | ||
63 | CONNECTOR_0XD, | ||
64 | CONNECTOR_DIN, | ||
65 | CONNECTOR_DISPLAY_PORT, | ||
66 | CONNECTOR_UNSUPPORTED | ||
67 | }; | ||
68 | |||
69 | enum radeon_dvi_type { | ||
70 | DVI_AUTO, | ||
71 | DVI_DIGITAL, | ||
72 | DVI_ANALOG | ||
73 | }; | ||
74 | |||
75 | enum radeon_rmx_type { | 49 | enum radeon_rmx_type { |
76 | RMX_OFF, | 50 | RMX_OFF, |
77 | RMX_FULL, | 51 | RMX_FULL, |
diff --git a/drivers/gpu/drm/radeon/radeon_object.c b/drivers/gpu/drm/radeon/radeon_object.c index d9ffe1f56e8f..4e636de877b2 100644 --- a/drivers/gpu/drm/radeon/radeon_object.c +++ b/drivers/gpu/drm/radeon/radeon_object.c | |||
@@ -221,8 +221,9 @@ int radeon_bo_unpin(struct radeon_bo *bo) | |||
221 | int radeon_bo_evict_vram(struct radeon_device *rdev) | 221 | int radeon_bo_evict_vram(struct radeon_device *rdev) |
222 | { | 222 | { |
223 | if (rdev->flags & RADEON_IS_IGP) { | 223 | if (rdev->flags & RADEON_IS_IGP) { |
224 | /* Useless to evict on IGP chips */ | 224 | if (rdev->mc.igp_sideport_enabled == false) |
225 | return 0; | 225 | /* Useless to evict on IGP chips */ |
226 | return 0; | ||
226 | } | 227 | } |
227 | return ttm_bo_evict_mm(&rdev->mman.bdev, TTM_PL_VRAM); | 228 | return ttm_bo_evict_mm(&rdev->mman.bdev, TTM_PL_VRAM); |
228 | } | 229 | } |
diff --git a/drivers/gpu/drm/radeon/radeon_ttm.c b/drivers/gpu/drm/radeon/radeon_ttm.c index 3b0c07b444a2..58b5adf974ca 100644 --- a/drivers/gpu/drm/radeon/radeon_ttm.c +++ b/drivers/gpu/drm/radeon/radeon_ttm.c | |||
@@ -215,7 +215,10 @@ static void radeon_evict_flags(struct ttm_buffer_object *bo, | |||
215 | rbo = container_of(bo, struct radeon_bo, tbo); | 215 | rbo = container_of(bo, struct radeon_bo, tbo); |
216 | switch (bo->mem.mem_type) { | 216 | switch (bo->mem.mem_type) { |
217 | case TTM_PL_VRAM: | 217 | case TTM_PL_VRAM: |
218 | radeon_ttm_placement_from_domain(rbo, RADEON_GEM_DOMAIN_GTT); | 218 | if (rbo->rdev->cp.ready == false) |
219 | radeon_ttm_placement_from_domain(rbo, RADEON_GEM_DOMAIN_CPU); | ||
220 | else | ||
221 | radeon_ttm_placement_from_domain(rbo, RADEON_GEM_DOMAIN_GTT); | ||
219 | break; | 222 | break; |
220 | case TTM_PL_TT: | 223 | case TTM_PL_TT: |
221 | default: | 224 | default: |
diff --git a/drivers/gpu/drm/radeon/reg_srcs/r420 b/drivers/gpu/drm/radeon/reg_srcs/r420 new file mode 100644 index 000000000000..989f7a020832 --- /dev/null +++ b/drivers/gpu/drm/radeon/reg_srcs/r420 | |||
@@ -0,0 +1,795 @@ | |||
1 | r420 0x4f60 | ||
2 | 0x1434 SRC_Y_X | ||
3 | 0x1438 DST_Y_X | ||
4 | 0x143C DST_HEIGHT_WIDTH | ||
5 | 0x146C DP_GUI_MASTER_CNTL | ||
6 | 0x1474 BRUSH_Y_X | ||
7 | 0x1478 DP_BRUSH_BKGD_CLR | ||
8 | 0x147C DP_BRUSH_FRGD_CLR | ||
9 | 0x1480 BRUSH_DATA0 | ||
10 | 0x1484 BRUSH_DATA1 | ||
11 | 0x1598 DST_WIDTH_HEIGHT | ||
12 | 0x15C0 CLR_CMP_CNTL | ||
13 | 0x15C4 CLR_CMP_CLR_SRC | ||
14 | 0x15C8 CLR_CMP_CLR_DST | ||
15 | 0x15CC CLR_CMP_MSK | ||
16 | 0x15D8 DP_SRC_FRGD_CLR | ||
17 | 0x15DC DP_SRC_BKGD_CLR | ||
18 | 0x1600 DST_LINE_START | ||
19 | 0x1604 DST_LINE_END | ||
20 | 0x1608 DST_LINE_PATCOUNT | ||
21 | 0x16C0 DP_CNTL | ||
22 | 0x16CC DP_WRITE_MSK | ||
23 | 0x16D0 DP_CNTL_XDIR_YDIR_YMAJOR | ||
24 | 0x16E8 DEFAULT_SC_BOTTOM_RIGHT | ||
25 | 0x16EC SC_TOP_LEFT | ||
26 | 0x16F0 SC_BOTTOM_RIGHT | ||
27 | 0x16F4 SRC_SC_BOTTOM_RIGHT | ||
28 | 0x1714 DSTCACHE_CTLSTAT | ||
29 | 0x1720 WAIT_UNTIL | ||
30 | 0x172C RBBM_GUICNTL | ||
31 | 0x1D98 VAP_VPORT_XSCALE | ||
32 | 0x1D9C VAP_VPORT_XOFFSET | ||
33 | 0x1DA0 VAP_VPORT_YSCALE | ||
34 | 0x1DA4 VAP_VPORT_YOFFSET | ||
35 | 0x1DA8 VAP_VPORT_ZSCALE | ||
36 | 0x1DAC VAP_VPORT_ZOFFSET | ||
37 | 0x2080 VAP_CNTL | ||
38 | 0x2090 VAP_OUT_VTX_FMT_0 | ||
39 | 0x2094 VAP_OUT_VTX_FMT_1 | ||
40 | 0x20B0 VAP_VTE_CNTL | ||
41 | 0x2138 VAP_VF_MIN_VTX_INDX | ||
42 | 0x2140 VAP_CNTL_STATUS | ||
43 | 0x2150 VAP_PROG_STREAM_CNTL_0 | ||
44 | 0x2154 VAP_PROG_STREAM_CNTL_1 | ||
45 | 0x2158 VAP_PROG_STREAM_CNTL_2 | ||
46 | 0x215C VAP_PROG_STREAM_CNTL_3 | ||
47 | 0x2160 VAP_PROG_STREAM_CNTL_4 | ||
48 | 0x2164 VAP_PROG_STREAM_CNTL_5 | ||
49 | 0x2168 VAP_PROG_STREAM_CNTL_6 | ||
50 | 0x216C VAP_PROG_STREAM_CNTL_7 | ||
51 | 0x2180 VAP_VTX_STATE_CNTL | ||
52 | 0x2184 VAP_VSM_VTX_ASSM | ||
53 | 0x2188 VAP_VTX_STATE_IND_REG_0 | ||
54 | 0x218C VAP_VTX_STATE_IND_REG_1 | ||
55 | 0x2190 VAP_VTX_STATE_IND_REG_2 | ||
56 | 0x2194 VAP_VTX_STATE_IND_REG_3 | ||
57 | 0x2198 VAP_VTX_STATE_IND_REG_4 | ||
58 | 0x219C VAP_VTX_STATE_IND_REG_5 | ||
59 | 0x21A0 VAP_VTX_STATE_IND_REG_6 | ||
60 | 0x21A4 VAP_VTX_STATE_IND_REG_7 | ||
61 | 0x21A8 VAP_VTX_STATE_IND_REG_8 | ||
62 | 0x21AC VAP_VTX_STATE_IND_REG_9 | ||
63 | 0x21B0 VAP_VTX_STATE_IND_REG_10 | ||
64 | 0x21B4 VAP_VTX_STATE_IND_REG_11 | ||
65 | 0x21B8 VAP_VTX_STATE_IND_REG_12 | ||
66 | 0x21BC VAP_VTX_STATE_IND_REG_13 | ||
67 | 0x21C0 VAP_VTX_STATE_IND_REG_14 | ||
68 | 0x21C4 VAP_VTX_STATE_IND_REG_15 | ||
69 | 0x21DC VAP_PSC_SGN_NORM_CNTL | ||
70 | 0x21E0 VAP_PROG_STREAM_CNTL_EXT_0 | ||
71 | 0x21E4 VAP_PROG_STREAM_CNTL_EXT_1 | ||
72 | 0x21E8 VAP_PROG_STREAM_CNTL_EXT_2 | ||
73 | 0x21EC VAP_PROG_STREAM_CNTL_EXT_3 | ||
74 | 0x21F0 VAP_PROG_STREAM_CNTL_EXT_4 | ||
75 | 0x21F4 VAP_PROG_STREAM_CNTL_EXT_5 | ||
76 | 0x21F8 VAP_PROG_STREAM_CNTL_EXT_6 | ||
77 | 0x21FC VAP_PROG_STREAM_CNTL_EXT_7 | ||
78 | 0x2200 VAP_PVS_VECTOR_INDX_REG | ||
79 | 0x2204 VAP_PVS_VECTOR_DATA_REG | ||
80 | 0x2208 VAP_PVS_VECTOR_DATA_REG_128 | ||
81 | 0x221C VAP_CLIP_CNTL | ||
82 | 0x2220 VAP_GB_VERT_CLIP_ADJ | ||
83 | 0x2224 VAP_GB_VERT_DISC_ADJ | ||
84 | 0x2228 VAP_GB_HORZ_CLIP_ADJ | ||
85 | 0x222C VAP_GB_HORZ_DISC_ADJ | ||
86 | 0x2230 VAP_PVS_FLOW_CNTL_ADDRS_0 | ||
87 | 0x2234 VAP_PVS_FLOW_CNTL_ADDRS_1 | ||
88 | 0x2238 VAP_PVS_FLOW_CNTL_ADDRS_2 | ||
89 | 0x223C VAP_PVS_FLOW_CNTL_ADDRS_3 | ||
90 | 0x2240 VAP_PVS_FLOW_CNTL_ADDRS_4 | ||
91 | 0x2244 VAP_PVS_FLOW_CNTL_ADDRS_5 | ||
92 | 0x2248 VAP_PVS_FLOW_CNTL_ADDRS_6 | ||
93 | 0x224C VAP_PVS_FLOW_CNTL_ADDRS_7 | ||
94 | 0x2250 VAP_PVS_FLOW_CNTL_ADDRS_8 | ||
95 | 0x2254 VAP_PVS_FLOW_CNTL_ADDRS_9 | ||
96 | 0x2258 VAP_PVS_FLOW_CNTL_ADDRS_10 | ||
97 | 0x225C VAP_PVS_FLOW_CNTL_ADDRS_11 | ||
98 | 0x2260 VAP_PVS_FLOW_CNTL_ADDRS_12 | ||
99 | 0x2264 VAP_PVS_FLOW_CNTL_ADDRS_13 | ||
100 | 0x2268 VAP_PVS_FLOW_CNTL_ADDRS_14 | ||
101 | 0x226C VAP_PVS_FLOW_CNTL_ADDRS_15 | ||
102 | 0x2284 VAP_PVS_STATE_FLUSH_REG | ||
103 | 0x2288 VAP_PVS_VTX_TIMEOUT_REG | ||
104 | 0x2290 VAP_PVS_FLOW_CNTL_LOOP_INDEX_0 | ||
105 | 0x2294 VAP_PVS_FLOW_CNTL_LOOP_INDEX_1 | ||
106 | 0x2298 VAP_PVS_FLOW_CNTL_LOOP_INDEX_2 | ||
107 | 0x229C VAP_PVS_FLOW_CNTL_LOOP_INDEX_3 | ||
108 | 0x22A0 VAP_PVS_FLOW_CNTL_LOOP_INDEX_4 | ||
109 | 0x22A4 VAP_PVS_FLOW_CNTL_LOOP_INDEX_5 | ||
110 | 0x22A8 VAP_PVS_FLOW_CNTL_LOOP_INDEX_6 | ||
111 | 0x22AC VAP_PVS_FLOW_CNTL_LOOP_INDEX_7 | ||
112 | 0x22B0 VAP_PVS_FLOW_CNTL_LOOP_INDEX_8 | ||
113 | 0x22B4 VAP_PVS_FLOW_CNTL_LOOP_INDEX_9 | ||
114 | 0x22B8 VAP_PVS_FLOW_CNTL_LOOP_INDEX_10 | ||
115 | 0x22BC VAP_PVS_FLOW_CNTL_LOOP_INDEX_11 | ||
116 | 0x22C0 VAP_PVS_FLOW_CNTL_LOOP_INDEX_12 | ||
117 | 0x22C4 VAP_PVS_FLOW_CNTL_LOOP_INDEX_13 | ||
118 | 0x22C8 VAP_PVS_FLOW_CNTL_LOOP_INDEX_14 | ||
119 | 0x22CC VAP_PVS_FLOW_CNTL_LOOP_INDEX_15 | ||
120 | 0x22D0 VAP_PVS_CODE_CNTL_0 | ||
121 | 0x22D4 VAP_PVS_CONST_CNTL | ||
122 | 0x22D8 VAP_PVS_CODE_CNTL_1 | ||
123 | 0x22DC VAP_PVS_FLOW_CNTL_OPC | ||
124 | 0x342C RB2D_DSTCACHE_CTLSTAT | ||
125 | 0x4000 GB_VAP_RASTER_VTX_FMT_0 | ||
126 | 0x4004 GB_VAP_RASTER_VTX_FMT_1 | ||
127 | 0x4008 GB_ENABLE | ||
128 | 0x401C GB_SELECT | ||
129 | 0x4020 GB_AA_CONFIG | ||
130 | 0x4024 GB_FIFO_SIZE | ||
131 | 0x4100 TX_INVALTAGS | ||
132 | 0x4200 GA_POINT_S0 | ||
133 | 0x4204 GA_POINT_T0 | ||
134 | 0x4208 GA_POINT_S1 | ||
135 | 0x420C GA_POINT_T1 | ||
136 | 0x4214 GA_TRIANGLE_STIPPLE | ||
137 | 0x421C GA_POINT_SIZE | ||
138 | 0x4230 GA_POINT_MINMAX | ||
139 | 0x4234 GA_LINE_CNTL | ||
140 | 0x4238 GA_LINE_STIPPLE_CONFIG | ||
141 | 0x4260 GA_LINE_STIPPLE_VALUE | ||
142 | 0x4264 GA_LINE_S0 | ||
143 | 0x4268 GA_LINE_S1 | ||
144 | 0x4278 GA_COLOR_CONTROL | ||
145 | 0x427C GA_SOLID_RG | ||
146 | 0x4280 GA_SOLID_BA | ||
147 | 0x4288 GA_POLY_MODE | ||
148 | 0x428C GA_ROUND_MODE | ||
149 | 0x4290 GA_OFFSET | ||
150 | 0x4294 GA_FOG_SCALE | ||
151 | 0x4298 GA_FOG_OFFSET | ||
152 | 0x42A0 SU_TEX_WRAP | ||
153 | 0x42A4 SU_POLY_OFFSET_FRONT_SCALE | ||
154 | 0x42A8 SU_POLY_OFFSET_FRONT_OFFSET | ||
155 | 0x42AC SU_POLY_OFFSET_BACK_SCALE | ||
156 | 0x42B0 SU_POLY_OFFSET_BACK_OFFSET | ||
157 | 0x42B4 SU_POLY_OFFSET_ENABLE | ||
158 | 0x42B8 SU_CULL_MODE | ||
159 | 0x42C0 SU_DEPTH_SCALE | ||
160 | 0x42C4 SU_DEPTH_OFFSET | ||
161 | 0x42C8 SU_REG_DEST | ||
162 | 0x4300 RS_COUNT | ||
163 | 0x4304 RS_INST_COUNT | ||
164 | 0x4310 RS_IP_0 | ||
165 | 0x4314 RS_IP_1 | ||
166 | 0x4318 RS_IP_2 | ||
167 | 0x431C RS_IP_3 | ||
168 | 0x4320 RS_IP_4 | ||
169 | 0x4324 RS_IP_5 | ||
170 | 0x4328 RS_IP_6 | ||
171 | 0x432C RS_IP_7 | ||
172 | 0x4330 RS_INST_0 | ||
173 | 0x4334 RS_INST_1 | ||
174 | 0x4338 RS_INST_2 | ||
175 | 0x433C RS_INST_3 | ||
176 | 0x4340 RS_INST_4 | ||
177 | 0x4344 RS_INST_5 | ||
178 | 0x4348 RS_INST_6 | ||
179 | 0x434C RS_INST_7 | ||
180 | 0x4350 RS_INST_8 | ||
181 | 0x4354 RS_INST_9 | ||
182 | 0x4358 RS_INST_10 | ||
183 | 0x435C RS_INST_11 | ||
184 | 0x4360 RS_INST_12 | ||
185 | 0x4364 RS_INST_13 | ||
186 | 0x4368 RS_INST_14 | ||
187 | 0x436C RS_INST_15 | ||
188 | 0x43A4 SC_HYPERZ_EN | ||
189 | 0x43A8 SC_EDGERULE | ||
190 | 0x43B0 SC_CLIP_0_A | ||
191 | 0x43B4 SC_CLIP_0_B | ||
192 | 0x43B8 SC_CLIP_1_A | ||
193 | 0x43BC SC_CLIP_1_B | ||
194 | 0x43C0 SC_CLIP_2_A | ||
195 | 0x43C4 SC_CLIP_2_B | ||
196 | 0x43C8 SC_CLIP_3_A | ||
197 | 0x43CC SC_CLIP_3_B | ||
198 | 0x43D0 SC_CLIP_RULE | ||
199 | 0x43E0 SC_SCISSOR0 | ||
200 | 0x43E8 SC_SCREENDOOR | ||
201 | 0x4440 TX_FILTER1_0 | ||
202 | 0x4444 TX_FILTER1_1 | ||
203 | 0x4448 TX_FILTER1_2 | ||
204 | 0x444C TX_FILTER1_3 | ||
205 | 0x4450 TX_FILTER1_4 | ||
206 | 0x4454 TX_FILTER1_5 | ||
207 | 0x4458 TX_FILTER1_6 | ||
208 | 0x445C TX_FILTER1_7 | ||
209 | 0x4460 TX_FILTER1_8 | ||
210 | 0x4464 TX_FILTER1_9 | ||
211 | 0x4468 TX_FILTER1_10 | ||
212 | 0x446C TX_FILTER1_11 | ||
213 | 0x4470 TX_FILTER1_12 | ||
214 | 0x4474 TX_FILTER1_13 | ||
215 | 0x4478 TX_FILTER1_14 | ||
216 | 0x447C TX_FILTER1_15 | ||
217 | 0x4580 TX_CHROMA_KEY_0 | ||
218 | 0x4584 TX_CHROMA_KEY_1 | ||
219 | 0x4588 TX_CHROMA_KEY_2 | ||
220 | 0x458C TX_CHROMA_KEY_3 | ||
221 | 0x4590 TX_CHROMA_KEY_4 | ||
222 | 0x4594 TX_CHROMA_KEY_5 | ||
223 | 0x4598 TX_CHROMA_KEY_6 | ||
224 | 0x459C TX_CHROMA_KEY_7 | ||
225 | 0x45A0 TX_CHROMA_KEY_8 | ||
226 | 0x45A4 TX_CHROMA_KEY_9 | ||
227 | 0x45A8 TX_CHROMA_KEY_10 | ||
228 | 0x45AC TX_CHROMA_KEY_11 | ||
229 | 0x45B0 TX_CHROMA_KEY_12 | ||
230 | 0x45B4 TX_CHROMA_KEY_13 | ||
231 | 0x45B8 TX_CHROMA_KEY_14 | ||
232 | 0x45BC TX_CHROMA_KEY_15 | ||
233 | 0x45C0 TX_BORDER_COLOR_0 | ||
234 | 0x45C4 TX_BORDER_COLOR_1 | ||
235 | 0x45C8 TX_BORDER_COLOR_2 | ||
236 | 0x45CC TX_BORDER_COLOR_3 | ||
237 | 0x45D0 TX_BORDER_COLOR_4 | ||
238 | 0x45D4 TX_BORDER_COLOR_5 | ||
239 | 0x45D8 TX_BORDER_COLOR_6 | ||
240 | 0x45DC TX_BORDER_COLOR_7 | ||
241 | 0x45E0 TX_BORDER_COLOR_8 | ||
242 | 0x45E4 TX_BORDER_COLOR_9 | ||
243 | 0x45E8 TX_BORDER_COLOR_10 | ||
244 | 0x45EC TX_BORDER_COLOR_11 | ||
245 | 0x45F0 TX_BORDER_COLOR_12 | ||
246 | 0x45F4 TX_BORDER_COLOR_13 | ||
247 | 0x45F8 TX_BORDER_COLOR_14 | ||
248 | 0x45FC TX_BORDER_COLOR_15 | ||
249 | 0x4600 US_CONFIG | ||
250 | 0x4604 US_PIXSIZE | ||
251 | 0x4608 US_CODE_OFFSET | ||
252 | 0x460C US_RESET | ||
253 | 0x4610 US_CODE_ADDR_0 | ||
254 | 0x4614 US_CODE_ADDR_1 | ||
255 | 0x4618 US_CODE_ADDR_2 | ||
256 | 0x461C US_CODE_ADDR_3 | ||
257 | 0x4620 US_TEX_INST_0 | ||
258 | 0x4624 US_TEX_INST_1 | ||
259 | 0x4628 US_TEX_INST_2 | ||
260 | 0x462C US_TEX_INST_3 | ||
261 | 0x4630 US_TEX_INST_4 | ||
262 | 0x4634 US_TEX_INST_5 | ||
263 | 0x4638 US_TEX_INST_6 | ||
264 | 0x463C US_TEX_INST_7 | ||
265 | 0x4640 US_TEX_INST_8 | ||
266 | 0x4644 US_TEX_INST_9 | ||
267 | 0x4648 US_TEX_INST_10 | ||
268 | 0x464C US_TEX_INST_11 | ||
269 | 0x4650 US_TEX_INST_12 | ||
270 | 0x4654 US_TEX_INST_13 | ||
271 | 0x4658 US_TEX_INST_14 | ||
272 | 0x465C US_TEX_INST_15 | ||
273 | 0x4660 US_TEX_INST_16 | ||
274 | 0x4664 US_TEX_INST_17 | ||
275 | 0x4668 US_TEX_INST_18 | ||
276 | 0x466C US_TEX_INST_19 | ||
277 | 0x4670 US_TEX_INST_20 | ||
278 | 0x4674 US_TEX_INST_21 | ||
279 | 0x4678 US_TEX_INST_22 | ||
280 | 0x467C US_TEX_INST_23 | ||
281 | 0x4680 US_TEX_INST_24 | ||
282 | 0x4684 US_TEX_INST_25 | ||
283 | 0x4688 US_TEX_INST_26 | ||
284 | 0x468C US_TEX_INST_27 | ||
285 | 0x4690 US_TEX_INST_28 | ||
286 | 0x4694 US_TEX_INST_29 | ||
287 | 0x4698 US_TEX_INST_30 | ||
288 | 0x469C US_TEX_INST_31 | ||
289 | 0x46A4 US_OUT_FMT_0 | ||
290 | 0x46A8 US_OUT_FMT_1 | ||
291 | 0x46AC US_OUT_FMT_2 | ||
292 | 0x46B0 US_OUT_FMT_3 | ||
293 | 0x46B4 US_W_FMT | ||
294 | 0x46B8 US_CODE_BANK | ||
295 | 0x46BC US_CODE_EXT | ||
296 | 0x46C0 US_ALU_RGB_ADDR_0 | ||
297 | 0x46C4 US_ALU_RGB_ADDR_1 | ||
298 | 0x46C8 US_ALU_RGB_ADDR_2 | ||
299 | 0x46CC US_ALU_RGB_ADDR_3 | ||
300 | 0x46D0 US_ALU_RGB_ADDR_4 | ||
301 | 0x46D4 US_ALU_RGB_ADDR_5 | ||
302 | 0x46D8 US_ALU_RGB_ADDR_6 | ||
303 | 0x46DC US_ALU_RGB_ADDR_7 | ||
304 | 0x46E0 US_ALU_RGB_ADDR_8 | ||
305 | 0x46E4 US_ALU_RGB_ADDR_9 | ||
306 | 0x46E8 US_ALU_RGB_ADDR_10 | ||
307 | 0x46EC US_ALU_RGB_ADDR_11 | ||
308 | 0x46F0 US_ALU_RGB_ADDR_12 | ||
309 | 0x46F4 US_ALU_RGB_ADDR_13 | ||
310 | 0x46F8 US_ALU_RGB_ADDR_14 | ||
311 | 0x46FC US_ALU_RGB_ADDR_15 | ||
312 | 0x4700 US_ALU_RGB_ADDR_16 | ||
313 | 0x4704 US_ALU_RGB_ADDR_17 | ||
314 | 0x4708 US_ALU_RGB_ADDR_18 | ||
315 | 0x470C US_ALU_RGB_ADDR_19 | ||
316 | 0x4710 US_ALU_RGB_ADDR_20 | ||
317 | 0x4714 US_ALU_RGB_ADDR_21 | ||
318 | 0x4718 US_ALU_RGB_ADDR_22 | ||
319 | 0x471C US_ALU_RGB_ADDR_23 | ||
320 | 0x4720 US_ALU_RGB_ADDR_24 | ||
321 | 0x4724 US_ALU_RGB_ADDR_25 | ||
322 | 0x4728 US_ALU_RGB_ADDR_26 | ||
323 | 0x472C US_ALU_RGB_ADDR_27 | ||
324 | 0x4730 US_ALU_RGB_ADDR_28 | ||
325 | 0x4734 US_ALU_RGB_ADDR_29 | ||
326 | 0x4738 US_ALU_RGB_ADDR_30 | ||
327 | 0x473C US_ALU_RGB_ADDR_31 | ||
328 | 0x4740 US_ALU_RGB_ADDR_32 | ||
329 | 0x4744 US_ALU_RGB_ADDR_33 | ||
330 | 0x4748 US_ALU_RGB_ADDR_34 | ||
331 | 0x474C US_ALU_RGB_ADDR_35 | ||
332 | 0x4750 US_ALU_RGB_ADDR_36 | ||
333 | 0x4754 US_ALU_RGB_ADDR_37 | ||
334 | 0x4758 US_ALU_RGB_ADDR_38 | ||
335 | 0x475C US_ALU_RGB_ADDR_39 | ||
336 | 0x4760 US_ALU_RGB_ADDR_40 | ||
337 | 0x4764 US_ALU_RGB_ADDR_41 | ||
338 | 0x4768 US_ALU_RGB_ADDR_42 | ||
339 | 0x476C US_ALU_RGB_ADDR_43 | ||
340 | 0x4770 US_ALU_RGB_ADDR_44 | ||
341 | 0x4774 US_ALU_RGB_ADDR_45 | ||
342 | 0x4778 US_ALU_RGB_ADDR_46 | ||
343 | 0x477C US_ALU_RGB_ADDR_47 | ||
344 | 0x4780 US_ALU_RGB_ADDR_48 | ||
345 | 0x4784 US_ALU_RGB_ADDR_49 | ||
346 | 0x4788 US_ALU_RGB_ADDR_50 | ||
347 | 0x478C US_ALU_RGB_ADDR_51 | ||
348 | 0x4790 US_ALU_RGB_ADDR_52 | ||
349 | 0x4794 US_ALU_RGB_ADDR_53 | ||
350 | 0x4798 US_ALU_RGB_ADDR_54 | ||
351 | 0x479C US_ALU_RGB_ADDR_55 | ||
352 | 0x47A0 US_ALU_RGB_ADDR_56 | ||
353 | 0x47A4 US_ALU_RGB_ADDR_57 | ||
354 | 0x47A8 US_ALU_RGB_ADDR_58 | ||
355 | 0x47AC US_ALU_RGB_ADDR_59 | ||
356 | 0x47B0 US_ALU_RGB_ADDR_60 | ||
357 | 0x47B4 US_ALU_RGB_ADDR_61 | ||
358 | 0x47B8 US_ALU_RGB_ADDR_62 | ||
359 | 0x47BC US_ALU_RGB_ADDR_63 | ||
360 | 0x47C0 US_ALU_ALPHA_ADDR_0 | ||
361 | 0x47C4 US_ALU_ALPHA_ADDR_1 | ||
362 | 0x47C8 US_ALU_ALPHA_ADDR_2 | ||
363 | 0x47CC US_ALU_ALPHA_ADDR_3 | ||
364 | 0x47D0 US_ALU_ALPHA_ADDR_4 | ||
365 | 0x47D4 US_ALU_ALPHA_ADDR_5 | ||
366 | 0x47D8 US_ALU_ALPHA_ADDR_6 | ||
367 | 0x47DC US_ALU_ALPHA_ADDR_7 | ||
368 | 0x47E0 US_ALU_ALPHA_ADDR_8 | ||
369 | 0x47E4 US_ALU_ALPHA_ADDR_9 | ||
370 | 0x47E8 US_ALU_ALPHA_ADDR_10 | ||
371 | 0x47EC US_ALU_ALPHA_ADDR_11 | ||
372 | 0x47F0 US_ALU_ALPHA_ADDR_12 | ||
373 | 0x47F4 US_ALU_ALPHA_ADDR_13 | ||
374 | 0x47F8 US_ALU_ALPHA_ADDR_14 | ||
375 | 0x47FC US_ALU_ALPHA_ADDR_15 | ||
376 | 0x4800 US_ALU_ALPHA_ADDR_16 | ||
377 | 0x4804 US_ALU_ALPHA_ADDR_17 | ||
378 | 0x4808 US_ALU_ALPHA_ADDR_18 | ||
379 | 0x480C US_ALU_ALPHA_ADDR_19 | ||
380 | 0x4810 US_ALU_ALPHA_ADDR_20 | ||
381 | 0x4814 US_ALU_ALPHA_ADDR_21 | ||
382 | 0x4818 US_ALU_ALPHA_ADDR_22 | ||
383 | 0x481C US_ALU_ALPHA_ADDR_23 | ||
384 | 0x4820 US_ALU_ALPHA_ADDR_24 | ||
385 | 0x4824 US_ALU_ALPHA_ADDR_25 | ||
386 | 0x4828 US_ALU_ALPHA_ADDR_26 | ||
387 | 0x482C US_ALU_ALPHA_ADDR_27 | ||
388 | 0x4830 US_ALU_ALPHA_ADDR_28 | ||
389 | 0x4834 US_ALU_ALPHA_ADDR_29 | ||
390 | 0x4838 US_ALU_ALPHA_ADDR_30 | ||
391 | 0x483C US_ALU_ALPHA_ADDR_31 | ||
392 | 0x4840 US_ALU_ALPHA_ADDR_32 | ||
393 | 0x4844 US_ALU_ALPHA_ADDR_33 | ||
394 | 0x4848 US_ALU_ALPHA_ADDR_34 | ||
395 | 0x484C US_ALU_ALPHA_ADDR_35 | ||
396 | 0x4850 US_ALU_ALPHA_ADDR_36 | ||
397 | 0x4854 US_ALU_ALPHA_ADDR_37 | ||
398 | 0x4858 US_ALU_ALPHA_ADDR_38 | ||
399 | 0x485C US_ALU_ALPHA_ADDR_39 | ||
400 | 0x4860 US_ALU_ALPHA_ADDR_40 | ||
401 | 0x4864 US_ALU_ALPHA_ADDR_41 | ||
402 | 0x4868 US_ALU_ALPHA_ADDR_42 | ||
403 | 0x486C US_ALU_ALPHA_ADDR_43 | ||
404 | 0x4870 US_ALU_ALPHA_ADDR_44 | ||
405 | 0x4874 US_ALU_ALPHA_ADDR_45 | ||
406 | 0x4878 US_ALU_ALPHA_ADDR_46 | ||
407 | 0x487C US_ALU_ALPHA_ADDR_47 | ||
408 | 0x4880 US_ALU_ALPHA_ADDR_48 | ||
409 | 0x4884 US_ALU_ALPHA_ADDR_49 | ||
410 | 0x4888 US_ALU_ALPHA_ADDR_50 | ||
411 | 0x488C US_ALU_ALPHA_ADDR_51 | ||
412 | 0x4890 US_ALU_ALPHA_ADDR_52 | ||
413 | 0x4894 US_ALU_ALPHA_ADDR_53 | ||
414 | 0x4898 US_ALU_ALPHA_ADDR_54 | ||
415 | 0x489C US_ALU_ALPHA_ADDR_55 | ||
416 | 0x48A0 US_ALU_ALPHA_ADDR_56 | ||
417 | 0x48A4 US_ALU_ALPHA_ADDR_57 | ||
418 | 0x48A8 US_ALU_ALPHA_ADDR_58 | ||
419 | 0x48AC US_ALU_ALPHA_ADDR_59 | ||
420 | 0x48B0 US_ALU_ALPHA_ADDR_60 | ||
421 | 0x48B4 US_ALU_ALPHA_ADDR_61 | ||
422 | 0x48B8 US_ALU_ALPHA_ADDR_62 | ||
423 | 0x48BC US_ALU_ALPHA_ADDR_63 | ||
424 | 0x48C0 US_ALU_RGB_INST_0 | ||
425 | 0x48C4 US_ALU_RGB_INST_1 | ||
426 | 0x48C8 US_ALU_RGB_INST_2 | ||
427 | 0x48CC US_ALU_RGB_INST_3 | ||
428 | 0x48D0 US_ALU_RGB_INST_4 | ||
429 | 0x48D4 US_ALU_RGB_INST_5 | ||
430 | 0x48D8 US_ALU_RGB_INST_6 | ||
431 | 0x48DC US_ALU_RGB_INST_7 | ||
432 | 0x48E0 US_ALU_RGB_INST_8 | ||
433 | 0x48E4 US_ALU_RGB_INST_9 | ||
434 | 0x48E8 US_ALU_RGB_INST_10 | ||
435 | 0x48EC US_ALU_RGB_INST_11 | ||
436 | 0x48F0 US_ALU_RGB_INST_12 | ||
437 | 0x48F4 US_ALU_RGB_INST_13 | ||
438 | 0x48F8 US_ALU_RGB_INST_14 | ||
439 | 0x48FC US_ALU_RGB_INST_15 | ||
440 | 0x4900 US_ALU_RGB_INST_16 | ||
441 | 0x4904 US_ALU_RGB_INST_17 | ||
442 | 0x4908 US_ALU_RGB_INST_18 | ||
443 | 0x490C US_ALU_RGB_INST_19 | ||
444 | 0x4910 US_ALU_RGB_INST_20 | ||
445 | 0x4914 US_ALU_RGB_INST_21 | ||
446 | 0x4918 US_ALU_RGB_INST_22 | ||
447 | 0x491C US_ALU_RGB_INST_23 | ||
448 | 0x4920 US_ALU_RGB_INST_24 | ||
449 | 0x4924 US_ALU_RGB_INST_25 | ||
450 | 0x4928 US_ALU_RGB_INST_26 | ||
451 | 0x492C US_ALU_RGB_INST_27 | ||
452 | 0x4930 US_ALU_RGB_INST_28 | ||
453 | 0x4934 US_ALU_RGB_INST_29 | ||
454 | 0x4938 US_ALU_RGB_INST_30 | ||
455 | 0x493C US_ALU_RGB_INST_31 | ||
456 | 0x4940 US_ALU_RGB_INST_32 | ||
457 | 0x4944 US_ALU_RGB_INST_33 | ||
458 | 0x4948 US_ALU_RGB_INST_34 | ||
459 | 0x494C US_ALU_RGB_INST_35 | ||
460 | 0x4950 US_ALU_RGB_INST_36 | ||
461 | 0x4954 US_ALU_RGB_INST_37 | ||
462 | 0x4958 US_ALU_RGB_INST_38 | ||
463 | 0x495C US_ALU_RGB_INST_39 | ||
464 | 0x4960 US_ALU_RGB_INST_40 | ||
465 | 0x4964 US_ALU_RGB_INST_41 | ||
466 | 0x4968 US_ALU_RGB_INST_42 | ||
467 | 0x496C US_ALU_RGB_INST_43 | ||
468 | 0x4970 US_ALU_RGB_INST_44 | ||
469 | 0x4974 US_ALU_RGB_INST_45 | ||
470 | 0x4978 US_ALU_RGB_INST_46 | ||
471 | 0x497C US_ALU_RGB_INST_47 | ||
472 | 0x4980 US_ALU_RGB_INST_48 | ||
473 | 0x4984 US_ALU_RGB_INST_49 | ||
474 | 0x4988 US_ALU_RGB_INST_50 | ||
475 | 0x498C US_ALU_RGB_INST_51 | ||
476 | 0x4990 US_ALU_RGB_INST_52 | ||
477 | 0x4994 US_ALU_RGB_INST_53 | ||
478 | 0x4998 US_ALU_RGB_INST_54 | ||
479 | 0x499C US_ALU_RGB_INST_55 | ||
480 | 0x49A0 US_ALU_RGB_INST_56 | ||
481 | 0x49A4 US_ALU_RGB_INST_57 | ||
482 | 0x49A8 US_ALU_RGB_INST_58 | ||
483 | 0x49AC US_ALU_RGB_INST_59 | ||
484 | 0x49B0 US_ALU_RGB_INST_60 | ||
485 | 0x49B4 US_ALU_RGB_INST_61 | ||
486 | 0x49B8 US_ALU_RGB_INST_62 | ||
487 | 0x49BC US_ALU_RGB_INST_63 | ||
488 | 0x49C0 US_ALU_ALPHA_INST_0 | ||
489 | 0x49C4 US_ALU_ALPHA_INST_1 | ||
490 | 0x49C8 US_ALU_ALPHA_INST_2 | ||
491 | 0x49CC US_ALU_ALPHA_INST_3 | ||
492 | 0x49D0 US_ALU_ALPHA_INST_4 | ||
493 | 0x49D4 US_ALU_ALPHA_INST_5 | ||
494 | 0x49D8 US_ALU_ALPHA_INST_6 | ||
495 | 0x49DC US_ALU_ALPHA_INST_7 | ||
496 | 0x49E0 US_ALU_ALPHA_INST_8 | ||
497 | 0x49E4 US_ALU_ALPHA_INST_9 | ||
498 | 0x49E8 US_ALU_ALPHA_INST_10 | ||
499 | 0x49EC US_ALU_ALPHA_INST_11 | ||
500 | 0x49F0 US_ALU_ALPHA_INST_12 | ||
501 | 0x49F4 US_ALU_ALPHA_INST_13 | ||
502 | 0x49F8 US_ALU_ALPHA_INST_14 | ||
503 | 0x49FC US_ALU_ALPHA_INST_15 | ||
504 | 0x4A00 US_ALU_ALPHA_INST_16 | ||
505 | 0x4A04 US_ALU_ALPHA_INST_17 | ||
506 | 0x4A08 US_ALU_ALPHA_INST_18 | ||
507 | 0x4A0C US_ALU_ALPHA_INST_19 | ||
508 | 0x4A10 US_ALU_ALPHA_INST_20 | ||
509 | 0x4A14 US_ALU_ALPHA_INST_21 | ||
510 | 0x4A18 US_ALU_ALPHA_INST_22 | ||
511 | 0x4A1C US_ALU_ALPHA_INST_23 | ||
512 | 0x4A20 US_ALU_ALPHA_INST_24 | ||
513 | 0x4A24 US_ALU_ALPHA_INST_25 | ||
514 | 0x4A28 US_ALU_ALPHA_INST_26 | ||
515 | 0x4A2C US_ALU_ALPHA_INST_27 | ||
516 | 0x4A30 US_ALU_ALPHA_INST_28 | ||
517 | 0x4A34 US_ALU_ALPHA_INST_29 | ||
518 | 0x4A38 US_ALU_ALPHA_INST_30 | ||
519 | 0x4A3C US_ALU_ALPHA_INST_31 | ||
520 | 0x4A40 US_ALU_ALPHA_INST_32 | ||
521 | 0x4A44 US_ALU_ALPHA_INST_33 | ||
522 | 0x4A48 US_ALU_ALPHA_INST_34 | ||
523 | 0x4A4C US_ALU_ALPHA_INST_35 | ||
524 | 0x4A50 US_ALU_ALPHA_INST_36 | ||
525 | 0x4A54 US_ALU_ALPHA_INST_37 | ||
526 | 0x4A58 US_ALU_ALPHA_INST_38 | ||
527 | 0x4A5C US_ALU_ALPHA_INST_39 | ||
528 | 0x4A60 US_ALU_ALPHA_INST_40 | ||
529 | 0x4A64 US_ALU_ALPHA_INST_41 | ||
530 | 0x4A68 US_ALU_ALPHA_INST_42 | ||
531 | 0x4A6C US_ALU_ALPHA_INST_43 | ||
532 | 0x4A70 US_ALU_ALPHA_INST_44 | ||
533 | 0x4A74 US_ALU_ALPHA_INST_45 | ||
534 | 0x4A78 US_ALU_ALPHA_INST_46 | ||
535 | 0x4A7C US_ALU_ALPHA_INST_47 | ||
536 | 0x4A80 US_ALU_ALPHA_INST_48 | ||
537 | 0x4A84 US_ALU_ALPHA_INST_49 | ||
538 | 0x4A88 US_ALU_ALPHA_INST_50 | ||
539 | 0x4A8C US_ALU_ALPHA_INST_51 | ||
540 | 0x4A90 US_ALU_ALPHA_INST_52 | ||
541 | 0x4A94 US_ALU_ALPHA_INST_53 | ||
542 | 0x4A98 US_ALU_ALPHA_INST_54 | ||
543 | 0x4A9C US_ALU_ALPHA_INST_55 | ||
544 | 0x4AA0 US_ALU_ALPHA_INST_56 | ||
545 | 0x4AA4 US_ALU_ALPHA_INST_57 | ||
546 | 0x4AA8 US_ALU_ALPHA_INST_58 | ||
547 | 0x4AAC US_ALU_ALPHA_INST_59 | ||
548 | 0x4AB0 US_ALU_ALPHA_INST_60 | ||
549 | 0x4AB4 US_ALU_ALPHA_INST_61 | ||
550 | 0x4AB8 US_ALU_ALPHA_INST_62 | ||
551 | 0x4ABC US_ALU_ALPHA_INST_63 | ||
552 | 0x4AC0 US_ALU_EXT_ADDR_0 | ||
553 | 0x4AC4 US_ALU_EXT_ADDR_1 | ||
554 | 0x4AC8 US_ALU_EXT_ADDR_2 | ||
555 | 0x4ACC US_ALU_EXT_ADDR_3 | ||
556 | 0x4AD0 US_ALU_EXT_ADDR_4 | ||
557 | 0x4AD4 US_ALU_EXT_ADDR_5 | ||
558 | 0x4AD8 US_ALU_EXT_ADDR_6 | ||
559 | 0x4ADC US_ALU_EXT_ADDR_7 | ||
560 | 0x4AE0 US_ALU_EXT_ADDR_8 | ||
561 | 0x4AE4 US_ALU_EXT_ADDR_9 | ||
562 | 0x4AE8 US_ALU_EXT_ADDR_10 | ||
563 | 0x4AEC US_ALU_EXT_ADDR_11 | ||
564 | 0x4AF0 US_ALU_EXT_ADDR_12 | ||
565 | 0x4AF4 US_ALU_EXT_ADDR_13 | ||
566 | 0x4AF8 US_ALU_EXT_ADDR_14 | ||
567 | 0x4AFC US_ALU_EXT_ADDR_15 | ||
568 | 0x4B00 US_ALU_EXT_ADDR_16 | ||
569 | 0x4B04 US_ALU_EXT_ADDR_17 | ||
570 | 0x4B08 US_ALU_EXT_ADDR_18 | ||
571 | 0x4B0C US_ALU_EXT_ADDR_19 | ||
572 | 0x4B10 US_ALU_EXT_ADDR_20 | ||
573 | 0x4B14 US_ALU_EXT_ADDR_21 | ||
574 | 0x4B18 US_ALU_EXT_ADDR_22 | ||
575 | 0x4B1C US_ALU_EXT_ADDR_23 | ||
576 | 0x4B20 US_ALU_EXT_ADDR_24 | ||
577 | 0x4B24 US_ALU_EXT_ADDR_25 | ||
578 | 0x4B28 US_ALU_EXT_ADDR_26 | ||
579 | 0x4B2C US_ALU_EXT_ADDR_27 | ||
580 | 0x4B30 US_ALU_EXT_ADDR_28 | ||
581 | 0x4B34 US_ALU_EXT_ADDR_29 | ||
582 | 0x4B38 US_ALU_EXT_ADDR_30 | ||
583 | 0x4B3C US_ALU_EXT_ADDR_31 | ||
584 | 0x4B40 US_ALU_EXT_ADDR_32 | ||
585 | 0x4B44 US_ALU_EXT_ADDR_33 | ||
586 | 0x4B48 US_ALU_EXT_ADDR_34 | ||
587 | 0x4B4C US_ALU_EXT_ADDR_35 | ||
588 | 0x4B50 US_ALU_EXT_ADDR_36 | ||
589 | 0x4B54 US_ALU_EXT_ADDR_37 | ||
590 | 0x4B58 US_ALU_EXT_ADDR_38 | ||
591 | 0x4B5C US_ALU_EXT_ADDR_39 | ||
592 | 0x4B60 US_ALU_EXT_ADDR_40 | ||
593 | 0x4B64 US_ALU_EXT_ADDR_41 | ||
594 | 0x4B68 US_ALU_EXT_ADDR_42 | ||
595 | 0x4B6C US_ALU_EXT_ADDR_43 | ||
596 | 0x4B70 US_ALU_EXT_ADDR_44 | ||
597 | 0x4B74 US_ALU_EXT_ADDR_45 | ||
598 | 0x4B78 US_ALU_EXT_ADDR_46 | ||
599 | 0x4B7C US_ALU_EXT_ADDR_47 | ||
600 | 0x4B80 US_ALU_EXT_ADDR_48 | ||
601 | 0x4B84 US_ALU_EXT_ADDR_49 | ||
602 | 0x4B88 US_ALU_EXT_ADDR_50 | ||
603 | 0x4B8C US_ALU_EXT_ADDR_51 | ||
604 | 0x4B90 US_ALU_EXT_ADDR_52 | ||
605 | 0x4B94 US_ALU_EXT_ADDR_53 | ||
606 | 0x4B98 US_ALU_EXT_ADDR_54 | ||
607 | 0x4B9C US_ALU_EXT_ADDR_55 | ||
608 | 0x4BA0 US_ALU_EXT_ADDR_56 | ||
609 | 0x4BA4 US_ALU_EXT_ADDR_57 | ||
610 | 0x4BA8 US_ALU_EXT_ADDR_58 | ||
611 | 0x4BAC US_ALU_EXT_ADDR_59 | ||
612 | 0x4BB0 US_ALU_EXT_ADDR_60 | ||
613 | 0x4BB4 US_ALU_EXT_ADDR_61 | ||
614 | 0x4BB8 US_ALU_EXT_ADDR_62 | ||
615 | 0x4BBC US_ALU_EXT_ADDR_63 | ||
616 | 0x4BC0 FG_FOG_BLEND | ||
617 | 0x4BC4 FG_FOG_FACTOR | ||
618 | 0x4BC8 FG_FOG_COLOR_R | ||
619 | 0x4BCC FG_FOG_COLOR_G | ||
620 | 0x4BD0 FG_FOG_COLOR_B | ||
621 | 0x4BD4 FG_ALPHA_FUNC | ||
622 | 0x4BD8 FG_DEPTH_SRC | ||
623 | 0x4C00 US_ALU_CONST_R_0 | ||
624 | 0x4C04 US_ALU_CONST_G_0 | ||
625 | 0x4C08 US_ALU_CONST_B_0 | ||
626 | 0x4C0C US_ALU_CONST_A_0 | ||
627 | 0x4C10 US_ALU_CONST_R_1 | ||
628 | 0x4C14 US_ALU_CONST_G_1 | ||
629 | 0x4C18 US_ALU_CONST_B_1 | ||
630 | 0x4C1C US_ALU_CONST_A_1 | ||
631 | 0x4C20 US_ALU_CONST_R_2 | ||
632 | 0x4C24 US_ALU_CONST_G_2 | ||
633 | 0x4C28 US_ALU_CONST_B_2 | ||
634 | 0x4C2C US_ALU_CONST_A_2 | ||
635 | 0x4C30 US_ALU_CONST_R_3 | ||
636 | 0x4C34 US_ALU_CONST_G_3 | ||
637 | 0x4C38 US_ALU_CONST_B_3 | ||
638 | 0x4C3C US_ALU_CONST_A_3 | ||
639 | 0x4C40 US_ALU_CONST_R_4 | ||
640 | 0x4C44 US_ALU_CONST_G_4 | ||
641 | 0x4C48 US_ALU_CONST_B_4 | ||
642 | 0x4C4C US_ALU_CONST_A_4 | ||
643 | 0x4C50 US_ALU_CONST_R_5 | ||
644 | 0x4C54 US_ALU_CONST_G_5 | ||
645 | 0x4C58 US_ALU_CONST_B_5 | ||
646 | 0x4C5C US_ALU_CONST_A_5 | ||
647 | 0x4C60 US_ALU_CONST_R_6 | ||
648 | 0x4C64 US_ALU_CONST_G_6 | ||
649 | 0x4C68 US_ALU_CONST_B_6 | ||
650 | 0x4C6C US_ALU_CONST_A_6 | ||
651 | 0x4C70 US_ALU_CONST_R_7 | ||
652 | 0x4C74 US_ALU_CONST_G_7 | ||
653 | 0x4C78 US_ALU_CONST_B_7 | ||
654 | 0x4C7C US_ALU_CONST_A_7 | ||
655 | 0x4C80 US_ALU_CONST_R_8 | ||
656 | 0x4C84 US_ALU_CONST_G_8 | ||
657 | 0x4C88 US_ALU_CONST_B_8 | ||
658 | 0x4C8C US_ALU_CONST_A_8 | ||
659 | 0x4C90 US_ALU_CONST_R_9 | ||
660 | 0x4C94 US_ALU_CONST_G_9 | ||
661 | 0x4C98 US_ALU_CONST_B_9 | ||
662 | 0x4C9C US_ALU_CONST_A_9 | ||
663 | 0x4CA0 US_ALU_CONST_R_10 | ||
664 | 0x4CA4 US_ALU_CONST_G_10 | ||
665 | 0x4CA8 US_ALU_CONST_B_10 | ||
666 | 0x4CAC US_ALU_CONST_A_10 | ||
667 | 0x4CB0 US_ALU_CONST_R_11 | ||
668 | 0x4CB4 US_ALU_CONST_G_11 | ||
669 | 0x4CB8 US_ALU_CONST_B_11 | ||
670 | 0x4CBC US_ALU_CONST_A_11 | ||
671 | 0x4CC0 US_ALU_CONST_R_12 | ||
672 | 0x4CC4 US_ALU_CONST_G_12 | ||
673 | 0x4CC8 US_ALU_CONST_B_12 | ||
674 | 0x4CCC US_ALU_CONST_A_12 | ||
675 | 0x4CD0 US_ALU_CONST_R_13 | ||
676 | 0x4CD4 US_ALU_CONST_G_13 | ||
677 | 0x4CD8 US_ALU_CONST_B_13 | ||
678 | 0x4CDC US_ALU_CONST_A_13 | ||
679 | 0x4CE0 US_ALU_CONST_R_14 | ||
680 | 0x4CE4 US_ALU_CONST_G_14 | ||
681 | 0x4CE8 US_ALU_CONST_B_14 | ||
682 | 0x4CEC US_ALU_CONST_A_14 | ||
683 | 0x4CF0 US_ALU_CONST_R_15 | ||
684 | 0x4CF4 US_ALU_CONST_G_15 | ||
685 | 0x4CF8 US_ALU_CONST_B_15 | ||
686 | 0x4CFC US_ALU_CONST_A_15 | ||
687 | 0x4D00 US_ALU_CONST_R_16 | ||
688 | 0x4D04 US_ALU_CONST_G_16 | ||
689 | 0x4D08 US_ALU_CONST_B_16 | ||
690 | 0x4D0C US_ALU_CONST_A_16 | ||
691 | 0x4D10 US_ALU_CONST_R_17 | ||
692 | 0x4D14 US_ALU_CONST_G_17 | ||
693 | 0x4D18 US_ALU_CONST_B_17 | ||
694 | 0x4D1C US_ALU_CONST_A_17 | ||
695 | 0x4D20 US_ALU_CONST_R_18 | ||
696 | 0x4D24 US_ALU_CONST_G_18 | ||
697 | 0x4D28 US_ALU_CONST_B_18 | ||
698 | 0x4D2C US_ALU_CONST_A_18 | ||
699 | 0x4D30 US_ALU_CONST_R_19 | ||
700 | 0x4D34 US_ALU_CONST_G_19 | ||
701 | 0x4D38 US_ALU_CONST_B_19 | ||
702 | 0x4D3C US_ALU_CONST_A_19 | ||
703 | 0x4D40 US_ALU_CONST_R_20 | ||
704 | 0x4D44 US_ALU_CONST_G_20 | ||
705 | 0x4D48 US_ALU_CONST_B_20 | ||
706 | 0x4D4C US_ALU_CONST_A_20 | ||
707 | 0x4D50 US_ALU_CONST_R_21 | ||
708 | 0x4D54 US_ALU_CONST_G_21 | ||
709 | 0x4D58 US_ALU_CONST_B_21 | ||
710 | 0x4D5C US_ALU_CONST_A_21 | ||
711 | 0x4D60 US_ALU_CONST_R_22 | ||
712 | 0x4D64 US_ALU_CONST_G_22 | ||
713 | 0x4D68 US_ALU_CONST_B_22 | ||
714 | 0x4D6C US_ALU_CONST_A_22 | ||
715 | 0x4D70 US_ALU_CONST_R_23 | ||
716 | 0x4D74 US_ALU_CONST_G_23 | ||
717 | 0x4D78 US_ALU_CONST_B_23 | ||
718 | 0x4D7C US_ALU_CONST_A_23 | ||
719 | 0x4D80 US_ALU_CONST_R_24 | ||
720 | 0x4D84 US_ALU_CONST_G_24 | ||
721 | 0x4D88 US_ALU_CONST_B_24 | ||
722 | 0x4D8C US_ALU_CONST_A_24 | ||
723 | 0x4D90 US_ALU_CONST_R_25 | ||
724 | 0x4D94 US_ALU_CONST_G_25 | ||
725 | 0x4D98 US_ALU_CONST_B_25 | ||
726 | 0x4D9C US_ALU_CONST_A_25 | ||
727 | 0x4DA0 US_ALU_CONST_R_26 | ||
728 | 0x4DA4 US_ALU_CONST_G_26 | ||
729 | 0x4DA8 US_ALU_CONST_B_26 | ||
730 | 0x4DAC US_ALU_CONST_A_26 | ||
731 | 0x4DB0 US_ALU_CONST_R_27 | ||
732 | 0x4DB4 US_ALU_CONST_G_27 | ||
733 | 0x4DB8 US_ALU_CONST_B_27 | ||
734 | 0x4DBC US_ALU_CONST_A_27 | ||
735 | 0x4DC0 US_ALU_CONST_R_28 | ||
736 | 0x4DC4 US_ALU_CONST_G_28 | ||
737 | 0x4DC8 US_ALU_CONST_B_28 | ||
738 | 0x4DCC US_ALU_CONST_A_28 | ||
739 | 0x4DD0 US_ALU_CONST_R_29 | ||
740 | 0x4DD4 US_ALU_CONST_G_29 | ||
741 | 0x4DD8 US_ALU_CONST_B_29 | ||
742 | 0x4DDC US_ALU_CONST_A_29 | ||
743 | 0x4DE0 US_ALU_CONST_R_30 | ||
744 | 0x4DE4 US_ALU_CONST_G_30 | ||
745 | 0x4DE8 US_ALU_CONST_B_30 | ||
746 | 0x4DEC US_ALU_CONST_A_30 | ||
747 | 0x4DF0 US_ALU_CONST_R_31 | ||
748 | 0x4DF4 US_ALU_CONST_G_31 | ||
749 | 0x4DF8 US_ALU_CONST_B_31 | ||
750 | 0x4DFC US_ALU_CONST_A_31 | ||
751 | 0x4E04 RB3D_BLENDCNTL_R3 | ||
752 | 0x4E08 RB3D_ABLENDCNTL_R3 | ||
753 | 0x4E0C RB3D_COLOR_CHANNEL_MASK | ||
754 | 0x4E10 RB3D_CONSTANT_COLOR | ||
755 | 0x4E14 RB3D_COLOR_CLEAR_VALUE | ||
756 | 0x4E18 RB3D_ROPCNTL_R3 | ||
757 | 0x4E1C RB3D_CLRCMP_FLIPE_R3 | ||
758 | 0x4E20 RB3D_CLRCMP_CLR_R3 | ||
759 | 0x4E24 RB3D_CLRCMP_MSK_R3 | ||
760 | 0x4E48 RB3D_DEBUG_CTL | ||
761 | 0x4E4C RB3D_DSTCACHE_CTLSTAT_R3 | ||
762 | 0x4E50 RB3D_DITHER_CTL | ||
763 | 0x4E54 RB3D_CMASK_OFFSET0 | ||
764 | 0x4E58 RB3D_CMASK_OFFSET1 | ||
765 | 0x4E5C RB3D_CMASK_OFFSET2 | ||
766 | 0x4E60 RB3D_CMASK_OFFSET3 | ||
767 | 0x4E64 RB3D_CMASK_PITCH0 | ||
768 | 0x4E68 RB3D_CMASK_PITCH1 | ||
769 | 0x4E6C RB3D_CMASK_PITCH2 | ||
770 | 0x4E70 RB3D_CMASK_PITCH3 | ||
771 | 0x4E74 RB3D_CMASK_WRINDEX | ||
772 | 0x4E78 RB3D_CMASK_DWORD | ||
773 | 0x4E7C RB3D_CMASK_RDINDEX | ||
774 | 0x4E80 RB3D_AARESOLVE_OFFSET | ||
775 | 0x4E84 RB3D_AARESOLVE_PITCH | ||
776 | 0x4E88 RB3D_AARESOLVE_CTL | ||
777 | 0x4EA0 RB3D_DISCARD_SRC_PIXEL_LTE_THRESHOLD | ||
778 | 0x4EA4 RB3D_DISCARD_SRC_PIXEL_GTE_THRESHOLD | ||
779 | 0x4F04 ZB_ZSTENCILCNTL | ||
780 | 0x4F08 ZB_STENCILREFMASK | ||
781 | 0x4F14 ZB_ZTOP | ||
782 | 0x4F18 ZB_ZCACHE_CTLSTAT | ||
783 | 0x4F1C ZB_BW_CNTL | ||
784 | 0x4F28 ZB_DEPTHCLEARVALUE | ||
785 | 0x4F30 ZB_ZMASK_OFFSET | ||
786 | 0x4F34 ZB_ZMASK_PITCH | ||
787 | 0x4F38 ZB_ZMASK_WRINDEX | ||
788 | 0x4F3C ZB_ZMASK_DWORD | ||
789 | 0x4F40 ZB_ZMASK_RDINDEX | ||
790 | 0x4F44 ZB_HIZ_OFFSET | ||
791 | 0x4F48 ZB_HIZ_WRINDEX | ||
792 | 0x4F4C ZB_HIZ_DWORD | ||
793 | 0x4F50 ZB_HIZ_RDINDEX | ||
794 | 0x4F54 ZB_HIZ_PITCH | ||
795 | 0x4F58 ZB_ZPASS_DATA | ||
diff --git a/drivers/gpu/drm/radeon/reg_srcs/rs600 b/drivers/gpu/drm/radeon/reg_srcs/rs600 index 8e3c0b807add..6801b865d1c4 100644 --- a/drivers/gpu/drm/radeon/reg_srcs/rs600 +++ b/drivers/gpu/drm/radeon/reg_srcs/rs600 | |||
@@ -153,7 +153,7 @@ rs600 0x6d40 | |||
153 | 0x42A4 SU_POLY_OFFSET_FRONT_SCALE | 153 | 0x42A4 SU_POLY_OFFSET_FRONT_SCALE |
154 | 0x42A8 SU_POLY_OFFSET_FRONT_OFFSET | 154 | 0x42A8 SU_POLY_OFFSET_FRONT_OFFSET |
155 | 0x42AC SU_POLY_OFFSET_BACK_SCALE | 155 | 0x42AC SU_POLY_OFFSET_BACK_SCALE |
156 | 0x42B0 SU_POLY_OFFSET_BACK_OFFSET | 156 | 0x42B0 SU_POLY_OFFSET_BACK_OFFSET |
157 | 0x42B4 SU_POLY_OFFSET_ENABLE | 157 | 0x42B4 SU_POLY_OFFSET_ENABLE |
158 | 0x42B8 SU_CULL_MODE | 158 | 0x42B8 SU_CULL_MODE |
159 | 0x42C0 SU_DEPTH_SCALE | 159 | 0x42C0 SU_DEPTH_SCALE |
@@ -291,6 +291,8 @@ rs600 0x6d40 | |||
291 | 0x46AC US_OUT_FMT_2 | 291 | 0x46AC US_OUT_FMT_2 |
292 | 0x46B0 US_OUT_FMT_3 | 292 | 0x46B0 US_OUT_FMT_3 |
293 | 0x46B4 US_W_FMT | 293 | 0x46B4 US_W_FMT |
294 | 0x46B8 US_CODE_BANK | ||
295 | 0x46BC US_CODE_EXT | ||
294 | 0x46C0 US_ALU_RGB_ADDR_0 | 296 | 0x46C0 US_ALU_RGB_ADDR_0 |
295 | 0x46C4 US_ALU_RGB_ADDR_1 | 297 | 0x46C4 US_ALU_RGB_ADDR_1 |
296 | 0x46C8 US_ALU_RGB_ADDR_2 | 298 | 0x46C8 US_ALU_RGB_ADDR_2 |
@@ -547,6 +549,70 @@ rs600 0x6d40 | |||
547 | 0x4AB4 US_ALU_ALPHA_INST_61 | 549 | 0x4AB4 US_ALU_ALPHA_INST_61 |
548 | 0x4AB8 US_ALU_ALPHA_INST_62 | 550 | 0x4AB8 US_ALU_ALPHA_INST_62 |
549 | 0x4ABC US_ALU_ALPHA_INST_63 | 551 | 0x4ABC US_ALU_ALPHA_INST_63 |
552 | 0x4AC0 US_ALU_EXT_ADDR_0 | ||
553 | 0x4AC4 US_ALU_EXT_ADDR_1 | ||
554 | 0x4AC8 US_ALU_EXT_ADDR_2 | ||
555 | 0x4ACC US_ALU_EXT_ADDR_3 | ||
556 | 0x4AD0 US_ALU_EXT_ADDR_4 | ||
557 | 0x4AD4 US_ALU_EXT_ADDR_5 | ||
558 | 0x4AD8 US_ALU_EXT_ADDR_6 | ||
559 | 0x4ADC US_ALU_EXT_ADDR_7 | ||
560 | 0x4AE0 US_ALU_EXT_ADDR_8 | ||
561 | 0x4AE4 US_ALU_EXT_ADDR_9 | ||
562 | 0x4AE8 US_ALU_EXT_ADDR_10 | ||
563 | 0x4AEC US_ALU_EXT_ADDR_11 | ||
564 | 0x4AF0 US_ALU_EXT_ADDR_12 | ||
565 | 0x4AF4 US_ALU_EXT_ADDR_13 | ||
566 | 0x4AF8 US_ALU_EXT_ADDR_14 | ||
567 | 0x4AFC US_ALU_EXT_ADDR_15 | ||
568 | 0x4B00 US_ALU_EXT_ADDR_16 | ||
569 | 0x4B04 US_ALU_EXT_ADDR_17 | ||
570 | 0x4B08 US_ALU_EXT_ADDR_18 | ||
571 | 0x4B0C US_ALU_EXT_ADDR_19 | ||
572 | 0x4B10 US_ALU_EXT_ADDR_20 | ||
573 | 0x4B14 US_ALU_EXT_ADDR_21 | ||
574 | 0x4B18 US_ALU_EXT_ADDR_22 | ||
575 | 0x4B1C US_ALU_EXT_ADDR_23 | ||
576 | 0x4B20 US_ALU_EXT_ADDR_24 | ||
577 | 0x4B24 US_ALU_EXT_ADDR_25 | ||
578 | 0x4B28 US_ALU_EXT_ADDR_26 | ||
579 | 0x4B2C US_ALU_EXT_ADDR_27 | ||
580 | 0x4B30 US_ALU_EXT_ADDR_28 | ||
581 | 0x4B34 US_ALU_EXT_ADDR_29 | ||
582 | 0x4B38 US_ALU_EXT_ADDR_30 | ||
583 | 0x4B3C US_ALU_EXT_ADDR_31 | ||
584 | 0x4B40 US_ALU_EXT_ADDR_32 | ||
585 | 0x4B44 US_ALU_EXT_ADDR_33 | ||
586 | 0x4B48 US_ALU_EXT_ADDR_34 | ||
587 | 0x4B4C US_ALU_EXT_ADDR_35 | ||
588 | 0x4B50 US_ALU_EXT_ADDR_36 | ||
589 | 0x4B54 US_ALU_EXT_ADDR_37 | ||
590 | 0x4B58 US_ALU_EXT_ADDR_38 | ||
591 | 0x4B5C US_ALU_EXT_ADDR_39 | ||
592 | 0x4B60 US_ALU_EXT_ADDR_40 | ||
593 | 0x4B64 US_ALU_EXT_ADDR_41 | ||
594 | 0x4B68 US_ALU_EXT_ADDR_42 | ||
595 | 0x4B6C US_ALU_EXT_ADDR_43 | ||
596 | 0x4B70 US_ALU_EXT_ADDR_44 | ||
597 | 0x4B74 US_ALU_EXT_ADDR_45 | ||
598 | 0x4B78 US_ALU_EXT_ADDR_46 | ||
599 | 0x4B7C US_ALU_EXT_ADDR_47 | ||
600 | 0x4B80 US_ALU_EXT_ADDR_48 | ||
601 | 0x4B84 US_ALU_EXT_ADDR_49 | ||
602 | 0x4B88 US_ALU_EXT_ADDR_50 | ||
603 | 0x4B8C US_ALU_EXT_ADDR_51 | ||
604 | 0x4B90 US_ALU_EXT_ADDR_52 | ||
605 | 0x4B94 US_ALU_EXT_ADDR_53 | ||
606 | 0x4B98 US_ALU_EXT_ADDR_54 | ||
607 | 0x4B9C US_ALU_EXT_ADDR_55 | ||
608 | 0x4BA0 US_ALU_EXT_ADDR_56 | ||
609 | 0x4BA4 US_ALU_EXT_ADDR_57 | ||
610 | 0x4BA8 US_ALU_EXT_ADDR_58 | ||
611 | 0x4BAC US_ALU_EXT_ADDR_59 | ||
612 | 0x4BB0 US_ALU_EXT_ADDR_60 | ||
613 | 0x4BB4 US_ALU_EXT_ADDR_61 | ||
614 | 0x4BB8 US_ALU_EXT_ADDR_62 | ||
615 | 0x4BBC US_ALU_EXT_ADDR_63 | ||
550 | 0x4BC0 FG_FOG_BLEND | 616 | 0x4BC0 FG_FOG_BLEND |
551 | 0x4BC4 FG_FOG_FACTOR | 617 | 0x4BC4 FG_FOG_FACTOR |
552 | 0x4BC8 FG_FOG_COLOR_R | 618 | 0x4BC8 FG_FOG_COLOR_R |
diff --git a/drivers/gpu/drm/radeon/reg_srcs/rv515 b/drivers/gpu/drm/radeon/reg_srcs/rv515 index 0102a0d5735c..38abf63bf2cd 100644 --- a/drivers/gpu/drm/radeon/reg_srcs/rv515 +++ b/drivers/gpu/drm/radeon/reg_srcs/rv515 | |||
@@ -161,7 +161,12 @@ rv515 0x6d40 | |||
161 | 0x401C GB_SELECT | 161 | 0x401C GB_SELECT |
162 | 0x4020 GB_AA_CONFIG | 162 | 0x4020 GB_AA_CONFIG |
163 | 0x4024 GB_FIFO_SIZE | 163 | 0x4024 GB_FIFO_SIZE |
164 | 0x4028 GB_Z_PEQ_CONFIG | ||
164 | 0x4100 TX_INVALTAGS | 165 | 0x4100 TX_INVALTAGS |
166 | 0x4114 SU_TEX_WRAP_PS3 | ||
167 | 0x4118 PS3_ENABLE | ||
168 | 0x411c PS3_VTX_FMT | ||
169 | 0x4120 PS3_TEX_SOURCE | ||
165 | 0x4200 GA_POINT_S0 | 170 | 0x4200 GA_POINT_S0 |
166 | 0x4204 GA_POINT_T0 | 171 | 0x4204 GA_POINT_T0 |
167 | 0x4208 GA_POINT_S1 | 172 | 0x4208 GA_POINT_S1 |
@@ -171,6 +176,7 @@ rv515 0x6d40 | |||
171 | 0x4230 GA_POINT_MINMAX | 176 | 0x4230 GA_POINT_MINMAX |
172 | 0x4234 GA_LINE_CNTL | 177 | 0x4234 GA_LINE_CNTL |
173 | 0x4238 GA_LINE_STIPPLE_CONFIG | 178 | 0x4238 GA_LINE_STIPPLE_CONFIG |
179 | 0x4258 GA_COLOR_CONTROL_PS3 | ||
174 | 0x4260 GA_LINE_STIPPLE_VALUE | 180 | 0x4260 GA_LINE_STIPPLE_VALUE |
175 | 0x4264 GA_LINE_S0 | 181 | 0x4264 GA_LINE_S0 |
176 | 0x4268 GA_LINE_S1 | 182 | 0x4268 GA_LINE_S1 |
diff --git a/drivers/gpu/drm/radeon/rs400.c b/drivers/gpu/drm/radeon/rs400.c index 368415df5f3a..9f5418983e2a 100644 --- a/drivers/gpu/drm/radeon/rs400.c +++ b/drivers/gpu/drm/radeon/rs400.c | |||
@@ -356,6 +356,7 @@ static int rs400_mc_init(struct radeon_device *rdev) | |||
356 | rdev->mc.vram_location = G_00015C_MC_FB_START(tmp) << 16; | 356 | rdev->mc.vram_location = G_00015C_MC_FB_START(tmp) << 16; |
357 | rdev->mc.gtt_location = 0xFFFFFFFFUL; | 357 | rdev->mc.gtt_location = 0xFFFFFFFFUL; |
358 | r = radeon_mc_setup(rdev); | 358 | r = radeon_mc_setup(rdev); |
359 | rdev->mc.igp_sideport_enabled = radeon_combios_sideport_present(rdev); | ||
359 | if (r) | 360 | if (r) |
360 | return r; | 361 | return r; |
361 | return 0; | 362 | return 0; |
@@ -395,6 +396,7 @@ static int rs400_startup(struct radeon_device *rdev) | |||
395 | return r; | 396 | return r; |
396 | /* Enable IRQ */ | 397 | /* Enable IRQ */ |
397 | r100_irq_set(rdev); | 398 | r100_irq_set(rdev); |
399 | rdev->config.r300.hdp_cntl = RREG32(RADEON_HOST_PATH_CNTL); | ||
398 | /* 1M ring buffer */ | 400 | /* 1M ring buffer */ |
399 | r = r100_cp_init(rdev, 1024 * 1024); | 401 | r = r100_cp_init(rdev, 1024 * 1024); |
400 | if (r) { | 402 | if (r) { |
diff --git a/drivers/gpu/drm/radeon/rs600.c b/drivers/gpu/drm/radeon/rs600.c index 4f8ea4260572..d5255751e7b3 100644 --- a/drivers/gpu/drm/radeon/rs600.c +++ b/drivers/gpu/drm/radeon/rs600.c | |||
@@ -56,6 +56,7 @@ int rs600_mc_init(struct radeon_device *rdev) | |||
56 | rdev->mc.vram_location = G_000004_MC_FB_START(tmp) << 16; | 56 | rdev->mc.vram_location = G_000004_MC_FB_START(tmp) << 16; |
57 | rdev->mc.gtt_location = 0xffffffffUL; | 57 | rdev->mc.gtt_location = 0xffffffffUL; |
58 | r = radeon_mc_setup(rdev); | 58 | r = radeon_mc_setup(rdev); |
59 | rdev->mc.igp_sideport_enabled = radeon_atombios_sideport_present(rdev); | ||
59 | if (r) | 60 | if (r) |
60 | return r; | 61 | return r; |
61 | return 0; | 62 | return 0; |
@@ -134,7 +135,8 @@ void rs600_hpd_init(struct radeon_device *rdev) | |||
134 | break; | 135 | break; |
135 | } | 136 | } |
136 | } | 137 | } |
137 | rs600_irq_set(rdev); | 138 | if (rdev->irq.installed) |
139 | rs600_irq_set(rdev); | ||
138 | } | 140 | } |
139 | 141 | ||
140 | void rs600_hpd_fini(struct radeon_device *rdev) | 142 | void rs600_hpd_fini(struct radeon_device *rdev) |
@@ -315,6 +317,11 @@ int rs600_irq_set(struct radeon_device *rdev) | |||
315 | u32 hpd2 = RREG32(R_007D18_DC_HOT_PLUG_DETECT2_INT_CONTROL) & | 317 | u32 hpd2 = RREG32(R_007D18_DC_HOT_PLUG_DETECT2_INT_CONTROL) & |
316 | ~S_007D18_DC_HOT_PLUG_DETECT2_INT_EN(1); | 318 | ~S_007D18_DC_HOT_PLUG_DETECT2_INT_EN(1); |
317 | 319 | ||
320 | if (!rdev->irq.installed) { | ||
321 | WARN(1, "Can't enable IRQ/MSI because no handler is installed.\n"); | ||
322 | WREG32(R_000040_GEN_INT_CNTL, 0); | ||
323 | return -EINVAL; | ||
324 | } | ||
318 | if (rdev->irq.sw_int) { | 325 | if (rdev->irq.sw_int) { |
319 | tmp |= S_000040_SW_INT_EN(1); | 326 | tmp |= S_000040_SW_INT_EN(1); |
320 | } | 327 | } |
@@ -396,7 +403,7 @@ int rs600_irq_process(struct radeon_device *rdev) | |||
396 | } | 403 | } |
397 | while (status || r500_disp_int) { | 404 | while (status || r500_disp_int) { |
398 | /* SW interrupt */ | 405 | /* SW interrupt */ |
399 | if (G_000040_SW_INT_EN(status)) | 406 | if (G_000044_SW_INT(status)) |
400 | radeon_fence_process(rdev); | 407 | radeon_fence_process(rdev); |
401 | /* Vertical blank interrupts */ | 408 | /* Vertical blank interrupts */ |
402 | if (G_007EDC_LB_D1_VBLANK_INTERRUPT(r500_disp_int)) | 409 | if (G_007EDC_LB_D1_VBLANK_INTERRUPT(r500_disp_int)) |
@@ -553,6 +560,7 @@ static int rs600_startup(struct radeon_device *rdev) | |||
553 | return r; | 560 | return r; |
554 | /* Enable IRQ */ | 561 | /* Enable IRQ */ |
555 | rs600_irq_set(rdev); | 562 | rs600_irq_set(rdev); |
563 | rdev->config.r300.hdp_cntl = RREG32(RADEON_HOST_PATH_CNTL); | ||
556 | /* 1M ring buffer */ | 564 | /* 1M ring buffer */ |
557 | r = r100_cp_init(rdev, 1024 * 1024); | 565 | r = r100_cp_init(rdev, 1024 * 1024); |
558 | if (r) { | 566 | if (r) { |
diff --git a/drivers/gpu/drm/radeon/rs690.c b/drivers/gpu/drm/radeon/rs690.c index 1e22f52d6039..cd31da913771 100644 --- a/drivers/gpu/drm/radeon/rs690.c +++ b/drivers/gpu/drm/radeon/rs690.c | |||
@@ -172,6 +172,7 @@ static int rs690_mc_init(struct radeon_device *rdev) | |||
172 | rdev->mc.vram_location = G_000100_MC_FB_START(tmp) << 16; | 172 | rdev->mc.vram_location = G_000100_MC_FB_START(tmp) << 16; |
173 | rdev->mc.gtt_location = 0xFFFFFFFFUL; | 173 | rdev->mc.gtt_location = 0xFFFFFFFFUL; |
174 | r = radeon_mc_setup(rdev); | 174 | r = radeon_mc_setup(rdev); |
175 | rdev->mc.igp_sideport_enabled = radeon_atombios_sideport_present(rdev); | ||
175 | if (r) | 176 | if (r) |
176 | return r; | 177 | return r; |
177 | return 0; | 178 | return 0; |
@@ -625,6 +626,7 @@ static int rs690_startup(struct radeon_device *rdev) | |||
625 | return r; | 626 | return r; |
626 | /* Enable IRQ */ | 627 | /* Enable IRQ */ |
627 | rs600_irq_set(rdev); | 628 | rs600_irq_set(rdev); |
629 | rdev->config.r300.hdp_cntl = RREG32(RADEON_HOST_PATH_CNTL); | ||
628 | /* 1M ring buffer */ | 630 | /* 1M ring buffer */ |
629 | r = r100_cp_init(rdev, 1024 * 1024); | 631 | r = r100_cp_init(rdev, 1024 * 1024); |
630 | if (r) { | 632 | if (r) { |
diff --git a/drivers/gpu/drm/radeon/rv515.c b/drivers/gpu/drm/radeon/rv515.c index 59632a506b46..62756717b044 100644 --- a/drivers/gpu/drm/radeon/rv515.c +++ b/drivers/gpu/drm/radeon/rv515.c | |||
@@ -479,6 +479,7 @@ static int rv515_startup(struct radeon_device *rdev) | |||
479 | } | 479 | } |
480 | /* Enable IRQ */ | 480 | /* Enable IRQ */ |
481 | rs600_irq_set(rdev); | 481 | rs600_irq_set(rdev); |
482 | rdev->config.r300.hdp_cntl = RREG32(RADEON_HOST_PATH_CNTL); | ||
482 | /* 1M ring buffer */ | 483 | /* 1M ring buffer */ |
483 | r = r100_cp_init(rdev, 1024 * 1024); | 484 | r = r100_cp_init(rdev, 1024 * 1024); |
484 | if (r) { | 485 | if (r) { |
diff --git a/drivers/gpu/drm/radeon/rv770.c b/drivers/gpu/drm/radeon/rv770.c index 3bcb66e52786..59c71245fb91 100644 --- a/drivers/gpu/drm/radeon/rv770.c +++ b/drivers/gpu/drm/radeon/rv770.c | |||
@@ -1096,8 +1096,7 @@ void rv770_fini(struct radeon_device *rdev) | |||
1096 | radeon_gem_fini(rdev); | 1096 | radeon_gem_fini(rdev); |
1097 | radeon_fence_driver_fini(rdev); | 1097 | radeon_fence_driver_fini(rdev); |
1098 | radeon_clocks_fini(rdev); | 1098 | radeon_clocks_fini(rdev); |
1099 | if (rdev->flags & RADEON_IS_AGP) | 1099 | radeon_agp_fini(rdev); |
1100 | radeon_agp_fini(rdev); | ||
1101 | radeon_bo_fini(rdev); | 1100 | radeon_bo_fini(rdev); |
1102 | radeon_atombios_fini(rdev); | 1101 | radeon_atombios_fini(rdev); |
1103 | kfree(rdev->bios); | 1102 | kfree(rdev->bios); |
diff --git a/drivers/hid/hid-apple.c b/drivers/hid/hid-apple.c index 4b96e7a898cf..5b4d66dc1a05 100644 --- a/drivers/hid/hid-apple.c +++ b/drivers/hid/hid-apple.c | |||
@@ -431,6 +431,13 @@ static const struct hid_device_id apple_devices[] = { | |||
431 | .driver_data = APPLE_HAS_FN | APPLE_ISO_KEYBOARD }, | 431 | .driver_data = APPLE_HAS_FN | APPLE_ISO_KEYBOARD }, |
432 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING3_JIS), | 432 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING3_JIS), |
433 | .driver_data = APPLE_HAS_FN | APPLE_RDESC_JIS }, | 433 | .driver_data = APPLE_HAS_FN | APPLE_RDESC_JIS }, |
434 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ANSI), | ||
435 | .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN }, | ||
436 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ISO), | ||
437 | .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN | | ||
438 | APPLE_ISO_KEYBOARD }, | ||
439 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_JIS), | ||
440 | .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN }, | ||
434 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_TP_ONLY), | 441 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_TP_ONLY), |
435 | .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN }, | 442 | .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN }, |
436 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY), | 443 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY), |
diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index 80792d38d25c..eabe5f87c6c1 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c | |||
@@ -1285,6 +1285,9 @@ static const struct hid_device_id hid_blacklist[] = { | |||
1285 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING3_ANSI) }, | 1285 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING3_ANSI) }, |
1286 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING3_ISO) }, | 1286 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING3_ISO) }, |
1287 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING3_JIS) }, | 1287 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING3_JIS) }, |
1288 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ANSI) }, | ||
1289 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ISO) }, | ||
1290 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_JIS) }, | ||
1288 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_TP_ONLY) }, | 1291 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_TP_ONLY) }, |
1289 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY) }, | 1292 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY) }, |
1290 | { HID_USB_DEVICE(USB_VENDOR_ID_BELKIN, USB_DEVICE_ID_FLIP_KVM) }, | 1293 | { HID_USB_DEVICE(USB_VENDOR_ID_BELKIN, USB_DEVICE_ID_FLIP_KVM) }, |
@@ -1553,6 +1556,7 @@ static const struct hid_device_id hid_ignore_list[] = { | |||
1553 | { HID_USB_DEVICE(USB_VENDOR_ID_DELORME, USB_DEVICE_ID_DELORME_EARTHMATE) }, | 1556 | { HID_USB_DEVICE(USB_VENDOR_ID_DELORME, USB_DEVICE_ID_DELORME_EARTHMATE) }, |
1554 | { HID_USB_DEVICE(USB_VENDOR_ID_DELORME, USB_DEVICE_ID_DELORME_EM_LT20) }, | 1557 | { HID_USB_DEVICE(USB_VENDOR_ID_DELORME, USB_DEVICE_ID_DELORME_EM_LT20) }, |
1555 | { HID_USB_DEVICE(USB_VENDOR_ID_ESSENTIAL_REALITY, USB_DEVICE_ID_ESSENTIAL_REALITY_P5) }, | 1558 | { HID_USB_DEVICE(USB_VENDOR_ID_ESSENTIAL_REALITY, USB_DEVICE_ID_ESSENTIAL_REALITY_P5) }, |
1559 | { HID_USB_DEVICE(USB_VENDOR_ID_ETT, USB_DEVICE_ID_TC5UH) }, | ||
1556 | { HID_USB_DEVICE(USB_VENDOR_ID_GENERAL_TOUCH, 0x0001) }, | 1560 | { HID_USB_DEVICE(USB_VENDOR_ID_GENERAL_TOUCH, 0x0001) }, |
1557 | { HID_USB_DEVICE(USB_VENDOR_ID_GENERAL_TOUCH, 0x0002) }, | 1561 | { HID_USB_DEVICE(USB_VENDOR_ID_GENERAL_TOUCH, 0x0002) }, |
1558 | { HID_USB_DEVICE(USB_VENDOR_ID_GENERAL_TOUCH, 0x0003) }, | 1562 | { HID_USB_DEVICE(USB_VENDOR_ID_GENERAL_TOUCH, 0x0003) }, |
diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h index 3839340e293a..010368e649ed 100644 --- a/drivers/hid/hid-ids.h +++ b/drivers/hid/hid-ids.h | |||
@@ -88,6 +88,9 @@ | |||
88 | #define USB_DEVICE_ID_APPLE_WELLSPRING3_ANSI 0x0236 | 88 | #define USB_DEVICE_ID_APPLE_WELLSPRING3_ANSI 0x0236 |
89 | #define USB_DEVICE_ID_APPLE_WELLSPRING3_ISO 0x0237 | 89 | #define USB_DEVICE_ID_APPLE_WELLSPRING3_ISO 0x0237 |
90 | #define USB_DEVICE_ID_APPLE_WELLSPRING3_JIS 0x0238 | 90 | #define USB_DEVICE_ID_APPLE_WELLSPRING3_JIS 0x0238 |
91 | #define USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ANSI 0x0239 | ||
92 | #define USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ISO 0x023a | ||
93 | #define USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_JIS 0x023b | ||
91 | #define USB_DEVICE_ID_APPLE_FOUNTAIN_TP_ONLY 0x030a | 94 | #define USB_DEVICE_ID_APPLE_FOUNTAIN_TP_ONLY 0x030a |
92 | #define USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY 0x030b | 95 | #define USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY 0x030b |
93 | #define USB_DEVICE_ID_APPLE_ATV_IRCONTROL 0x8241 | 96 | #define USB_DEVICE_ID_APPLE_ATV_IRCONTROL 0x8241 |
@@ -166,6 +169,9 @@ | |||
166 | #define USB_VENDOR_ID_ESSENTIAL_REALITY 0x0d7f | 169 | #define USB_VENDOR_ID_ESSENTIAL_REALITY 0x0d7f |
167 | #define USB_DEVICE_ID_ESSENTIAL_REALITY_P5 0x0100 | 170 | #define USB_DEVICE_ID_ESSENTIAL_REALITY_P5 0x0100 |
168 | 171 | ||
172 | #define USB_VENDOR_ID_ETT 0x0664 | ||
173 | #define USB_DEVICE_ID_TC5UH 0x0309 | ||
174 | |||
169 | #define USB_VENDOR_ID_EZKEY 0x0518 | 175 | #define USB_VENDOR_ID_EZKEY 0x0518 |
170 | #define USB_DEVICE_ID_BTC_8193 0x0002 | 176 | #define USB_DEVICE_ID_BTC_8193 0x0002 |
171 | 177 | ||
diff --git a/drivers/hid/hid-samsung.c b/drivers/hid/hid-samsung.c index 5b222eed0692..510dd1340597 100644 --- a/drivers/hid/hid-samsung.c +++ b/drivers/hid/hid-samsung.c | |||
@@ -39,7 +39,17 @@ | |||
39 | * | 39 | * |
40 | * 3. 135 byte report descriptor | 40 | * 3. 135 byte report descriptor |
41 | * Report #4 has an array field with logical range 0..17 instead of 1..14. | 41 | * Report #4 has an array field with logical range 0..17 instead of 1..14. |
42 | * | ||
43 | * 4. 171 byte report descriptor | ||
44 | * Report #3 has an array field with logical range 0..1 instead of 1..3. | ||
42 | */ | 45 | */ |
46 | static inline void samsung_dev_trace(struct hid_device *hdev, | ||
47 | unsigned int rsize) | ||
48 | { | ||
49 | dev_info(&hdev->dev, "fixing up Samsung IrDA %d byte report " | ||
50 | "descriptor\n", rsize); | ||
51 | } | ||
52 | |||
43 | static void samsung_report_fixup(struct hid_device *hdev, __u8 *rdesc, | 53 | static void samsung_report_fixup(struct hid_device *hdev, __u8 *rdesc, |
44 | unsigned int rsize) | 54 | unsigned int rsize) |
45 | { | 55 | { |
@@ -47,8 +57,7 @@ static void samsung_report_fixup(struct hid_device *hdev, __u8 *rdesc, | |||
47 | rdesc[177] == 0x75 && rdesc[178] == 0x30 && | 57 | rdesc[177] == 0x75 && rdesc[178] == 0x30 && |
48 | rdesc[179] == 0x95 && rdesc[180] == 0x01 && | 58 | rdesc[179] == 0x95 && rdesc[180] == 0x01 && |
49 | rdesc[182] == 0x40) { | 59 | rdesc[182] == 0x40) { |
50 | dev_info(&hdev->dev, "fixing up Samsung IrDA %d byte report " | 60 | samsung_dev_trace(hdev, 184); |
51 | "descriptor\n", 184); | ||
52 | rdesc[176] = 0xff; | 61 | rdesc[176] = 0xff; |
53 | rdesc[178] = 0x08; | 62 | rdesc[178] = 0x08; |
54 | rdesc[180] = 0x06; | 63 | rdesc[180] = 0x06; |
@@ -56,17 +65,21 @@ static void samsung_report_fixup(struct hid_device *hdev, __u8 *rdesc, | |||
56 | } else | 65 | } else |
57 | if (rsize == 203 && rdesc[192] == 0x15 && rdesc[193] == 0x0 && | 66 | if (rsize == 203 && rdesc[192] == 0x15 && rdesc[193] == 0x0 && |
58 | rdesc[194] == 0x25 && rdesc[195] == 0x12) { | 67 | rdesc[194] == 0x25 && rdesc[195] == 0x12) { |
59 | dev_info(&hdev->dev, "fixing up Samsung IrDA %d byte report " | 68 | samsung_dev_trace(hdev, 203); |
60 | "descriptor\n", 203); | ||
61 | rdesc[193] = 0x1; | 69 | rdesc[193] = 0x1; |
62 | rdesc[195] = 0xf; | 70 | rdesc[195] = 0xf; |
63 | } else | 71 | } else |
64 | if (rsize == 135 && rdesc[124] == 0x15 && rdesc[125] == 0x0 && | 72 | if (rsize == 135 && rdesc[124] == 0x15 && rdesc[125] == 0x0 && |
65 | rdesc[126] == 0x25 && rdesc[127] == 0x11) { | 73 | rdesc[126] == 0x25 && rdesc[127] == 0x11) { |
66 | dev_info(&hdev->dev, "fixing up Samsung IrDA %d byte report " | 74 | samsung_dev_trace(hdev, 135); |
67 | "descriptor\n", 135); | ||
68 | rdesc[125] = 0x1; | 75 | rdesc[125] = 0x1; |
69 | rdesc[127] = 0xe; | 76 | rdesc[127] = 0xe; |
77 | } else | ||
78 | if (rsize == 171 && rdesc[160] == 0x15 && rdesc[161] == 0x0 && | ||
79 | rdesc[162] == 0x25 && rdesc[163] == 0x01) { | ||
80 | samsung_dev_trace(hdev, 171); | ||
81 | rdesc[161] = 0x1; | ||
82 | rdesc[163] = 0x3; | ||
70 | } | 83 | } |
71 | } | 84 | } |
72 | 85 | ||
diff --git a/drivers/hid/hid-wacom.c b/drivers/hid/hid-wacom.c index 747542172242..12dcda529201 100644 --- a/drivers/hid/hid-wacom.c +++ b/drivers/hid/hid-wacom.c | |||
@@ -142,6 +142,7 @@ static int wacom_raw_event(struct hid_device *hdev, struct hid_report *report, | |||
142 | wdata->butstate = rw; | 142 | wdata->butstate = rw; |
143 | input_report_key(input, BTN_0, rw & 0x02); | 143 | input_report_key(input, BTN_0, rw & 0x02); |
144 | input_report_key(input, BTN_1, rw & 0x01); | 144 | input_report_key(input, BTN_1, rw & 0x01); |
145 | input_report_key(input, BTN_TOOL_FINGER, 0xf0); | ||
145 | input_event(input, EV_MSC, MSC_SERIAL, 0xf0); | 146 | input_event(input, EV_MSC, MSC_SERIAL, 0xf0); |
146 | input_sync(input); | 147 | input_sync(input); |
147 | } | 148 | } |
@@ -196,6 +197,9 @@ static int wacom_probe(struct hid_device *hdev, | |||
196 | /* Pad */ | 197 | /* Pad */ |
197 | input->evbit[0] |= BIT(EV_MSC); | 198 | input->evbit[0] |= BIT(EV_MSC); |
198 | input->mscbit[0] |= BIT(MSC_SERIAL); | 199 | input->mscbit[0] |= BIT(MSC_SERIAL); |
200 | set_bit(BTN_0, input->keybit); | ||
201 | set_bit(BTN_1, input->keybit); | ||
202 | set_bit(BTN_TOOL_FINGER, input->keybit); | ||
199 | 203 | ||
200 | /* Distance, rubber and mouse */ | 204 | /* Distance, rubber and mouse */ |
201 | input->absbit[0] |= BIT(ABS_DISTANCE); | 205 | input->absbit[0] |= BIT(ABS_DISTANCE); |
diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig index 46c3c566307e..68cf87749a42 100644 --- a/drivers/hwmon/Kconfig +++ b/drivers/hwmon/Kconfig | |||
@@ -392,7 +392,7 @@ config SENSORS_GL520SM | |||
392 | 392 | ||
393 | config SENSORS_CORETEMP | 393 | config SENSORS_CORETEMP |
394 | tristate "Intel Core/Core2/Atom temperature sensor" | 394 | tristate "Intel Core/Core2/Atom temperature sensor" |
395 | depends on X86 && EXPERIMENTAL | 395 | depends on X86 && PCI && EXPERIMENTAL |
396 | help | 396 | help |
397 | If you say yes here you get support for the temperature | 397 | If you say yes here you get support for the temperature |
398 | sensor inside your CPU. Most of the family 6 CPUs | 398 | sensor inside your CPU. Most of the family 6 CPUs |
@@ -792,6 +792,16 @@ config SENSORS_ADS7828 | |||
792 | This driver can also be built as a module. If so, the module | 792 | This driver can also be built as a module. If so, the module |
793 | will be called ads7828. | 793 | will be called ads7828. |
794 | 794 | ||
795 | config SENSORS_AMC6821 | ||
796 | tristate "Texas Instruments AMC6821" | ||
797 | depends on I2C && EXPERIMENTAL | ||
798 | help | ||
799 | If you say yes here you get support for the Texas Instruments | ||
800 | AMC6821 hardware monitoring chips. | ||
801 | |||
802 | This driver can also be build as a module. If so, the module | ||
803 | will be called amc6821. | ||
804 | |||
795 | config SENSORS_THMC50 | 805 | config SENSORS_THMC50 |
796 | tristate "Texas Instruments THMC50 / Analog Devices ADM1022" | 806 | tristate "Texas Instruments THMC50 / Analog Devices ADM1022" |
797 | depends on I2C && EXPERIMENTAL | 807 | depends on I2C && EXPERIMENTAL |
diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile index 450c8e894277..4bc215c0953f 100644 --- a/drivers/hwmon/Makefile +++ b/drivers/hwmon/Makefile | |||
@@ -86,6 +86,7 @@ obj-$(CONFIG_SENSORS_SIS5595) += sis5595.o | |||
86 | obj-$(CONFIG_SENSORS_SMSC47B397)+= smsc47b397.o | 86 | obj-$(CONFIG_SENSORS_SMSC47B397)+= smsc47b397.o |
87 | obj-$(CONFIG_SENSORS_SMSC47M1) += smsc47m1.o | 87 | obj-$(CONFIG_SENSORS_SMSC47M1) += smsc47m1.o |
88 | obj-$(CONFIG_SENSORS_SMSC47M192)+= smsc47m192.o | 88 | obj-$(CONFIG_SENSORS_SMSC47M192)+= smsc47m192.o |
89 | obj-$(CONFIG_SENSORS_AMC6821) += amc6821.o | ||
89 | obj-$(CONFIG_SENSORS_THMC50) += thmc50.o | 90 | obj-$(CONFIG_SENSORS_THMC50) += thmc50.o |
90 | obj-$(CONFIG_SENSORS_TMP401) += tmp401.o | 91 | obj-$(CONFIG_SENSORS_TMP401) += tmp401.o |
91 | obj-$(CONFIG_SENSORS_TMP421) += tmp421.o | 92 | obj-$(CONFIG_SENSORS_TMP421) += tmp421.o |
diff --git a/drivers/hwmon/adt7462.c b/drivers/hwmon/adt7462.c index a1a7ef14b519..a31e77c776ae 100644 --- a/drivers/hwmon/adt7462.c +++ b/drivers/hwmon/adt7462.c | |||
@@ -94,7 +94,7 @@ static const unsigned short normal_i2c[] = { 0x58, 0x5C, I2C_CLIENT_END }; | |||
94 | #define ADT7462_PIN24_SHIFT 6 | 94 | #define ADT7462_PIN24_SHIFT 6 |
95 | #define ADT7462_PIN26_VOLT_INPUT 0x08 | 95 | #define ADT7462_PIN26_VOLT_INPUT 0x08 |
96 | #define ADT7462_PIN25_VOLT_INPUT 0x20 | 96 | #define ADT7462_PIN25_VOLT_INPUT 0x20 |
97 | #define ADT7462_PIN28_SHIFT 6 /* cfg3 */ | 97 | #define ADT7462_PIN28_SHIFT 4 /* cfg3 */ |
98 | #define ADT7462_PIN28_VOLT 0x5 | 98 | #define ADT7462_PIN28_VOLT 0x5 |
99 | 99 | ||
100 | #define ADT7462_REG_ALARM1 0xB8 | 100 | #define ADT7462_REG_ALARM1 0xB8 |
diff --git a/drivers/hwmon/amc6821.c b/drivers/hwmon/amc6821.c new file mode 100644 index 000000000000..1c89d922d619 --- /dev/null +++ b/drivers/hwmon/amc6821.c | |||
@@ -0,0 +1,1116 @@ | |||
1 | /* | ||
2 | amc6821.c - Part of lm_sensors, Linux kernel modules for hardware | ||
3 | monitoring | ||
4 | Copyright (C) 2009 T. Mertelj <tomaz.mertelj@guest.arnes.si> | ||
5 | |||
6 | Based on max6650.c: | ||
7 | Copyright (C) 2007 Hans J. Koch <hjk@linutronix.de> | ||
8 | |||
9 | This program is free software; you can redistribute it and/or modify | ||
10 | it under the terms of the GNU General Public License as published by | ||
11 | the Free Software Foundation; either version 2 of the License, or | ||
12 | (at your option) any later version. | ||
13 | |||
14 | This program is distributed in the hope that it will be useful, | ||
15 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
17 | GNU General Public License for more details. | ||
18 | |||
19 | You should have received a copy of the GNU General Public License | ||
20 | along with this program; if not, write to the Free Software | ||
21 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
22 | */ | ||
23 | |||
24 | |||
25 | #include <linux/kernel.h> /* Needed for KERN_INFO */ | ||
26 | #include <linux/module.h> | ||
27 | #include <linux/init.h> | ||
28 | #include <linux/slab.h> | ||
29 | #include <linux/jiffies.h> | ||
30 | #include <linux/i2c.h> | ||
31 | #include <linux/hwmon.h> | ||
32 | #include <linux/hwmon-sysfs.h> | ||
33 | #include <linux/err.h> | ||
34 | #include <linux/mutex.h> | ||
35 | |||
36 | |||
37 | /* | ||
38 | * Addresses to scan. | ||
39 | */ | ||
40 | |||
41 | static const unsigned short normal_i2c[] = {0x18, 0x19, 0x1a, 0x2c, 0x2d, 0x2e, | ||
42 | 0x4c, 0x4d, 0x4e, I2C_CLIENT_END}; | ||
43 | |||
44 | |||
45 | |||
46 | /* | ||
47 | * Insmod parameters | ||
48 | */ | ||
49 | |||
50 | static int pwminv = 0; /*Inverted PWM output. */ | ||
51 | module_param(pwminv, int, S_IRUGO); | ||
52 | |||
53 | static int init = 1; /*Power-on initialization.*/ | ||
54 | module_param(init, int, S_IRUGO); | ||
55 | |||
56 | |||
57 | enum chips { amc6821 }; | ||
58 | |||
59 | #define AMC6821_REG_DEV_ID 0x3D | ||
60 | #define AMC6821_REG_COMP_ID 0x3E | ||
61 | #define AMC6821_REG_CONF1 0x00 | ||
62 | #define AMC6821_REG_CONF2 0x01 | ||
63 | #define AMC6821_REG_CONF3 0x3F | ||
64 | #define AMC6821_REG_CONF4 0x04 | ||
65 | #define AMC6821_REG_STAT1 0x02 | ||
66 | #define AMC6821_REG_STAT2 0x03 | ||
67 | #define AMC6821_REG_TDATA_LOW 0x08 | ||
68 | #define AMC6821_REG_TDATA_HI 0x09 | ||
69 | #define AMC6821_REG_LTEMP_HI 0x0A | ||
70 | #define AMC6821_REG_RTEMP_HI 0x0B | ||
71 | #define AMC6821_REG_LTEMP_LIMIT_MIN 0x15 | ||
72 | #define AMC6821_REG_LTEMP_LIMIT_MAX 0x14 | ||
73 | #define AMC6821_REG_RTEMP_LIMIT_MIN 0x19 | ||
74 | #define AMC6821_REG_RTEMP_LIMIT_MAX 0x18 | ||
75 | #define AMC6821_REG_LTEMP_CRIT 0x1B | ||
76 | #define AMC6821_REG_RTEMP_CRIT 0x1D | ||
77 | #define AMC6821_REG_PSV_TEMP 0x1C | ||
78 | #define AMC6821_REG_DCY 0x22 | ||
79 | #define AMC6821_REG_LTEMP_FAN_CTRL 0x24 | ||
80 | #define AMC6821_REG_RTEMP_FAN_CTRL 0x25 | ||
81 | #define AMC6821_REG_DCY_LOW_TEMP 0x21 | ||
82 | |||
83 | #define AMC6821_REG_TACH_LLIMITL 0x10 | ||
84 | #define AMC6821_REG_TACH_LLIMITH 0x11 | ||
85 | #define AMC6821_REG_TACH_HLIMITL 0x12 | ||
86 | #define AMC6821_REG_TACH_HLIMITH 0x13 | ||
87 | |||
88 | #define AMC6821_CONF1_START 0x01 | ||
89 | #define AMC6821_CONF1_FAN_INT_EN 0x02 | ||
90 | #define AMC6821_CONF1_FANIE 0x04 | ||
91 | #define AMC6821_CONF1_PWMINV 0x08 | ||
92 | #define AMC6821_CONF1_FAN_FAULT_EN 0x10 | ||
93 | #define AMC6821_CONF1_FDRC0 0x20 | ||
94 | #define AMC6821_CONF1_FDRC1 0x40 | ||
95 | #define AMC6821_CONF1_THERMOVIE 0x80 | ||
96 | |||
97 | #define AMC6821_CONF2_PWM_EN 0x01 | ||
98 | #define AMC6821_CONF2_TACH_MODE 0x02 | ||
99 | #define AMC6821_CONF2_TACH_EN 0x04 | ||
100 | #define AMC6821_CONF2_RTFIE 0x08 | ||
101 | #define AMC6821_CONF2_LTOIE 0x10 | ||
102 | #define AMC6821_CONF2_RTOIE 0x20 | ||
103 | #define AMC6821_CONF2_PSVIE 0x40 | ||
104 | #define AMC6821_CONF2_RST 0x80 | ||
105 | |||
106 | #define AMC6821_CONF3_THERM_FAN_EN 0x80 | ||
107 | #define AMC6821_CONF3_REV_MASK 0x0F | ||
108 | |||
109 | #define AMC6821_CONF4_OVREN 0x10 | ||
110 | #define AMC6821_CONF4_TACH_FAST 0x20 | ||
111 | #define AMC6821_CONF4_PSPR 0x40 | ||
112 | #define AMC6821_CONF4_MODE 0x80 | ||
113 | |||
114 | #define AMC6821_STAT1_RPM_ALARM 0x01 | ||
115 | #define AMC6821_STAT1_FANS 0x02 | ||
116 | #define AMC6821_STAT1_RTH 0x04 | ||
117 | #define AMC6821_STAT1_RTL 0x08 | ||
118 | #define AMC6821_STAT1_R_THERM 0x10 | ||
119 | #define AMC6821_STAT1_RTF 0x20 | ||
120 | #define AMC6821_STAT1_LTH 0x40 | ||
121 | #define AMC6821_STAT1_LTL 0x80 | ||
122 | |||
123 | #define AMC6821_STAT2_RTC 0x08 | ||
124 | #define AMC6821_STAT2_LTC 0x10 | ||
125 | #define AMC6821_STAT2_LPSV 0x20 | ||
126 | #define AMC6821_STAT2_L_THERM 0x40 | ||
127 | #define AMC6821_STAT2_THERM_IN 0x80 | ||
128 | |||
129 | enum {IDX_TEMP1_INPUT = 0, IDX_TEMP1_MIN, IDX_TEMP1_MAX, | ||
130 | IDX_TEMP1_CRIT, IDX_TEMP2_INPUT, IDX_TEMP2_MIN, | ||
131 | IDX_TEMP2_MAX, IDX_TEMP2_CRIT, | ||
132 | TEMP_IDX_LEN, }; | ||
133 | |||
134 | static const u8 temp_reg[] = {AMC6821_REG_LTEMP_HI, | ||
135 | AMC6821_REG_LTEMP_LIMIT_MIN, | ||
136 | AMC6821_REG_LTEMP_LIMIT_MAX, | ||
137 | AMC6821_REG_LTEMP_CRIT, | ||
138 | AMC6821_REG_RTEMP_HI, | ||
139 | AMC6821_REG_RTEMP_LIMIT_MIN, | ||
140 | AMC6821_REG_RTEMP_LIMIT_MAX, | ||
141 | AMC6821_REG_RTEMP_CRIT, }; | ||
142 | |||
143 | enum {IDX_FAN1_INPUT = 0, IDX_FAN1_MIN, IDX_FAN1_MAX, | ||
144 | FAN1_IDX_LEN, }; | ||
145 | |||
146 | static const u8 fan_reg_low[] = {AMC6821_REG_TDATA_LOW, | ||
147 | AMC6821_REG_TACH_LLIMITL, | ||
148 | AMC6821_REG_TACH_HLIMITL, }; | ||
149 | |||
150 | |||
151 | static const u8 fan_reg_hi[] = {AMC6821_REG_TDATA_HI, | ||
152 | AMC6821_REG_TACH_LLIMITH, | ||
153 | AMC6821_REG_TACH_HLIMITH, }; | ||
154 | |||
155 | static int amc6821_probe( | ||
156 | struct i2c_client *client, | ||
157 | const struct i2c_device_id *id); | ||
158 | static int amc6821_detect( | ||
159 | struct i2c_client *client, | ||
160 | struct i2c_board_info *info); | ||
161 | static int amc6821_init_client(struct i2c_client *client); | ||
162 | static int amc6821_remove(struct i2c_client *client); | ||
163 | static struct amc6821_data *amc6821_update_device(struct device *dev); | ||
164 | |||
165 | /* | ||
166 | * Driver data (common to all clients) | ||
167 | */ | ||
168 | |||
169 | static const struct i2c_device_id amc6821_id[] = { | ||
170 | { "amc6821", amc6821 }, | ||
171 | { } | ||
172 | }; | ||
173 | |||
174 | MODULE_DEVICE_TABLE(i2c, amc6821_id); | ||
175 | |||
176 | static struct i2c_driver amc6821_driver = { | ||
177 | .class = I2C_CLASS_HWMON, | ||
178 | .driver = { | ||
179 | .name = "amc6821", | ||
180 | }, | ||
181 | .probe = amc6821_probe, | ||
182 | .remove = amc6821_remove, | ||
183 | .id_table = amc6821_id, | ||
184 | .detect = amc6821_detect, | ||
185 | .address_list = normal_i2c, | ||
186 | }; | ||
187 | |||
188 | |||
189 | /* | ||
190 | * Client data (each client gets its own) | ||
191 | */ | ||
192 | |||
193 | struct amc6821_data { | ||
194 | struct device *hwmon_dev; | ||
195 | struct mutex update_lock; | ||
196 | char valid; /* zero until following fields are valid */ | ||
197 | unsigned long last_updated; /* in jiffies */ | ||
198 | |||
199 | /* register values */ | ||
200 | int temp[TEMP_IDX_LEN]; | ||
201 | |||
202 | u16 fan[FAN1_IDX_LEN]; | ||
203 | u8 fan1_div; | ||
204 | |||
205 | u8 pwm1; | ||
206 | u8 temp1_auto_point_temp[3]; | ||
207 | u8 temp2_auto_point_temp[3]; | ||
208 | u8 pwm1_auto_point_pwm[3]; | ||
209 | u8 pwm1_enable; | ||
210 | u8 pwm1_auto_channels_temp; | ||
211 | |||
212 | u8 stat1; | ||
213 | u8 stat2; | ||
214 | }; | ||
215 | |||
216 | |||
217 | static ssize_t get_temp( | ||
218 | struct device *dev, | ||
219 | struct device_attribute *devattr, | ||
220 | char *buf) | ||
221 | { | ||
222 | struct amc6821_data *data = amc6821_update_device(dev); | ||
223 | int ix = to_sensor_dev_attr(devattr)->index; | ||
224 | |||
225 | return sprintf(buf, "%d\n", data->temp[ix] * 1000); | ||
226 | } | ||
227 | |||
228 | |||
229 | |||
230 | static ssize_t set_temp( | ||
231 | struct device *dev, | ||
232 | struct device_attribute *attr, | ||
233 | const char *buf, | ||
234 | size_t count) | ||
235 | { | ||
236 | struct i2c_client *client = to_i2c_client(dev); | ||
237 | struct amc6821_data *data = i2c_get_clientdata(client); | ||
238 | int ix = to_sensor_dev_attr(attr)->index; | ||
239 | long val; | ||
240 | |||
241 | int ret = strict_strtol(buf, 10, &val); | ||
242 | if (ret) | ||
243 | return ret; | ||
244 | val = SENSORS_LIMIT(val / 1000, -128, 127); | ||
245 | |||
246 | mutex_lock(&data->update_lock); | ||
247 | data->temp[ix] = val; | ||
248 | if (i2c_smbus_write_byte_data(client, temp_reg[ix], data->temp[ix])) { | ||
249 | dev_err(&client->dev, "Register write error, aborting.\n"); | ||
250 | count = -EIO; | ||
251 | } | ||
252 | mutex_unlock(&data->update_lock); | ||
253 | return count; | ||
254 | } | ||
255 | |||
256 | |||
257 | |||
258 | |||
259 | static ssize_t get_temp_alarm( | ||
260 | struct device *dev, | ||
261 | struct device_attribute *devattr, | ||
262 | char *buf) | ||
263 | { | ||
264 | struct amc6821_data *data = amc6821_update_device(dev); | ||
265 | int ix = to_sensor_dev_attr(devattr)->index; | ||
266 | u8 flag; | ||
267 | |||
268 | switch (ix) { | ||
269 | case IDX_TEMP1_MIN: | ||
270 | flag = data->stat1 & AMC6821_STAT1_LTL; | ||
271 | break; | ||
272 | case IDX_TEMP1_MAX: | ||
273 | flag = data->stat1 & AMC6821_STAT1_LTH; | ||
274 | break; | ||
275 | case IDX_TEMP1_CRIT: | ||
276 | flag = data->stat2 & AMC6821_STAT2_LTC; | ||
277 | break; | ||
278 | case IDX_TEMP2_MIN: | ||
279 | flag = data->stat1 & AMC6821_STAT1_RTL; | ||
280 | break; | ||
281 | case IDX_TEMP2_MAX: | ||
282 | flag = data->stat1 & AMC6821_STAT1_RTH; | ||
283 | break; | ||
284 | case IDX_TEMP2_CRIT: | ||
285 | flag = data->stat2 & AMC6821_STAT2_RTC; | ||
286 | break; | ||
287 | default: | ||
288 | dev_dbg(dev, "Unknown attr->index (%d).\n", ix); | ||
289 | return -EINVAL; | ||
290 | } | ||
291 | if (flag) | ||
292 | return sprintf(buf, "1"); | ||
293 | else | ||
294 | return sprintf(buf, "0"); | ||
295 | } | ||
296 | |||
297 | |||
298 | |||
299 | |||
300 | static ssize_t get_temp2_fault( | ||
301 | struct device *dev, | ||
302 | struct device_attribute *devattr, | ||
303 | char *buf) | ||
304 | { | ||
305 | struct amc6821_data *data = amc6821_update_device(dev); | ||
306 | if (data->stat1 & AMC6821_STAT1_RTF) | ||
307 | return sprintf(buf, "1"); | ||
308 | else | ||
309 | return sprintf(buf, "0"); | ||
310 | } | ||
311 | |||
312 | static ssize_t get_pwm1( | ||
313 | struct device *dev, | ||
314 | struct device_attribute *devattr, | ||
315 | char *buf) | ||
316 | { | ||
317 | struct amc6821_data *data = amc6821_update_device(dev); | ||
318 | return sprintf(buf, "%d\n", data->pwm1); | ||
319 | } | ||
320 | |||
321 | static ssize_t set_pwm1( | ||
322 | struct device *dev, | ||
323 | struct device_attribute *devattr, | ||
324 | const char *buf, | ||
325 | size_t count) | ||
326 | { | ||
327 | struct i2c_client *client = to_i2c_client(dev); | ||
328 | struct amc6821_data *data = i2c_get_clientdata(client); | ||
329 | long val; | ||
330 | int ret = strict_strtol(buf, 10, &val); | ||
331 | if (ret) | ||
332 | return ret; | ||
333 | |||
334 | mutex_lock(&data->update_lock); | ||
335 | data->pwm1 = SENSORS_LIMIT(val , 0, 255); | ||
336 | i2c_smbus_write_byte_data(client, AMC6821_REG_DCY, data->pwm1); | ||
337 | mutex_unlock(&data->update_lock); | ||
338 | return count; | ||
339 | } | ||
340 | |||
341 | static ssize_t get_pwm1_enable( | ||
342 | struct device *dev, | ||
343 | struct device_attribute *devattr, | ||
344 | char *buf) | ||
345 | { | ||
346 | struct amc6821_data *data = amc6821_update_device(dev); | ||
347 | return sprintf(buf, "%d\n", data->pwm1_enable); | ||
348 | } | ||
349 | |||
350 | static ssize_t set_pwm1_enable( | ||
351 | struct device *dev, | ||
352 | struct device_attribute *attr, | ||
353 | const char *buf, | ||
354 | size_t count) | ||
355 | { | ||
356 | struct i2c_client *client = to_i2c_client(dev); | ||
357 | struct amc6821_data *data = i2c_get_clientdata(client); | ||
358 | long val; | ||
359 | int config = strict_strtol(buf, 10, &val); | ||
360 | if (config) | ||
361 | return config; | ||
362 | |||
363 | config = i2c_smbus_read_byte_data(client, AMC6821_REG_CONF1); | ||
364 | if (config < 0) { | ||
365 | dev_err(&client->dev, | ||
366 | "Error reading configuration register, aborting.\n"); | ||
367 | return -EIO; | ||
368 | } | ||
369 | |||
370 | switch (val) { | ||
371 | case 1: | ||
372 | config &= ~AMC6821_CONF1_FDRC0; | ||
373 | config &= ~AMC6821_CONF1_FDRC1; | ||
374 | break; | ||
375 | case 2: | ||
376 | config &= ~AMC6821_CONF1_FDRC0; | ||
377 | config |= AMC6821_CONF1_FDRC1; | ||
378 | break; | ||
379 | case 3: | ||
380 | config |= AMC6821_CONF1_FDRC0; | ||
381 | config |= AMC6821_CONF1_FDRC1; | ||
382 | break; | ||
383 | default: | ||
384 | return -EINVAL; | ||
385 | } | ||
386 | mutex_lock(&data->update_lock); | ||
387 | if (i2c_smbus_write_byte_data(client, AMC6821_REG_CONF1, config)) { | ||
388 | dev_err(&client->dev, | ||
389 | "Configuration register write error, aborting.\n"); | ||
390 | count = -EIO; | ||
391 | } | ||
392 | mutex_unlock(&data->update_lock); | ||
393 | return count; | ||
394 | } | ||
395 | |||
396 | |||
397 | static ssize_t get_pwm1_auto_channels_temp( | ||
398 | struct device *dev, | ||
399 | struct device_attribute *devattr, | ||
400 | char *buf) | ||
401 | { | ||
402 | struct amc6821_data *data = amc6821_update_device(dev); | ||
403 | return sprintf(buf, "%d\n", data->pwm1_auto_channels_temp); | ||
404 | } | ||
405 | |||
406 | |||
407 | static ssize_t get_temp_auto_point_temp( | ||
408 | struct device *dev, | ||
409 | struct device_attribute *devattr, | ||
410 | char *buf) | ||
411 | { | ||
412 | int ix = to_sensor_dev_attr_2(devattr)->index; | ||
413 | int nr = to_sensor_dev_attr_2(devattr)->nr; | ||
414 | struct amc6821_data *data = amc6821_update_device(dev); | ||
415 | switch (nr) { | ||
416 | case 1: | ||
417 | return sprintf(buf, "%d\n", | ||
418 | data->temp1_auto_point_temp[ix] * 1000); | ||
419 | break; | ||
420 | case 2: | ||
421 | return sprintf(buf, "%d\n", | ||
422 | data->temp2_auto_point_temp[ix] * 1000); | ||
423 | break; | ||
424 | default: | ||
425 | dev_dbg(dev, "Unknown attr->nr (%d).\n", nr); | ||
426 | return -EINVAL; | ||
427 | } | ||
428 | } | ||
429 | |||
430 | |||
431 | static ssize_t get_pwm1_auto_point_pwm( | ||
432 | struct device *dev, | ||
433 | struct device_attribute *devattr, | ||
434 | char *buf) | ||
435 | { | ||
436 | int ix = to_sensor_dev_attr(devattr)->index; | ||
437 | struct amc6821_data *data = amc6821_update_device(dev); | ||
438 | return sprintf(buf, "%d\n", data->pwm1_auto_point_pwm[ix]); | ||
439 | } | ||
440 | |||
441 | |||
442 | static inline ssize_t set_slope_register(struct i2c_client *client, | ||
443 | u8 reg, | ||
444 | u8 dpwm, | ||
445 | u8 *ptemp) | ||
446 | { | ||
447 | int dt; | ||
448 | u8 tmp; | ||
449 | |||
450 | dt = ptemp[2]-ptemp[1]; | ||
451 | for (tmp = 4; tmp > 0; tmp--) { | ||
452 | if (dt * (0x20 >> tmp) >= dpwm) | ||
453 | break; | ||
454 | } | ||
455 | tmp |= (ptemp[1] & 0x7C) << 1; | ||
456 | if (i2c_smbus_write_byte_data(client, | ||
457 | reg, tmp)) { | ||
458 | dev_err(&client->dev, "Register write error, aborting.\n"); | ||
459 | return -EIO; | ||
460 | } | ||
461 | return 0; | ||
462 | } | ||
463 | |||
464 | |||
465 | |||
466 | static ssize_t set_temp_auto_point_temp( | ||
467 | struct device *dev, | ||
468 | struct device_attribute *attr, | ||
469 | const char *buf, | ||
470 | size_t count) | ||
471 | { | ||
472 | struct i2c_client *client = to_i2c_client(dev); | ||
473 | struct amc6821_data *data = amc6821_update_device(dev); | ||
474 | int ix = to_sensor_dev_attr_2(attr)->index; | ||
475 | int nr = to_sensor_dev_attr_2(attr)->nr; | ||
476 | u8 *ptemp; | ||
477 | u8 reg; | ||
478 | int dpwm; | ||
479 | long val; | ||
480 | int ret = strict_strtol(buf, 10, &val); | ||
481 | if (ret) | ||
482 | return ret; | ||
483 | |||
484 | switch (nr) { | ||
485 | case 1: | ||
486 | ptemp = data->temp1_auto_point_temp; | ||
487 | reg = AMC6821_REG_LTEMP_FAN_CTRL; | ||
488 | break; | ||
489 | case 2: | ||
490 | ptemp = data->temp2_auto_point_temp; | ||
491 | reg = AMC6821_REG_RTEMP_FAN_CTRL; | ||
492 | break; | ||
493 | default: | ||
494 | dev_dbg(dev, "Unknown attr->nr (%d).\n", nr); | ||
495 | return -EINVAL; | ||
496 | } | ||
497 | |||
498 | data->valid = 0; | ||
499 | mutex_lock(&data->update_lock); | ||
500 | switch (ix) { | ||
501 | case 0: | ||
502 | ptemp[0] = SENSORS_LIMIT(val / 1000, 0, | ||
503 | data->temp1_auto_point_temp[1]); | ||
504 | ptemp[0] = SENSORS_LIMIT(ptemp[0], 0, | ||
505 | data->temp2_auto_point_temp[1]); | ||
506 | ptemp[0] = SENSORS_LIMIT(ptemp[0], 0, 63); | ||
507 | if (i2c_smbus_write_byte_data( | ||
508 | client, | ||
509 | AMC6821_REG_PSV_TEMP, | ||
510 | ptemp[0])) { | ||
511 | dev_err(&client->dev, | ||
512 | "Register write error, aborting.\n"); | ||
513 | count = -EIO; | ||
514 | } | ||
515 | goto EXIT; | ||
516 | break; | ||
517 | case 1: | ||
518 | ptemp[1] = SENSORS_LIMIT( | ||
519 | val / 1000, | ||
520 | (ptemp[0] & 0x7C) + 4, | ||
521 | 124); | ||
522 | ptemp[1] &= 0x7C; | ||
523 | ptemp[2] = SENSORS_LIMIT( | ||
524 | ptemp[2], ptemp[1] + 1, | ||
525 | 255); | ||
526 | break; | ||
527 | case 2: | ||
528 | ptemp[2] = SENSORS_LIMIT( | ||
529 | val / 1000, | ||
530 | ptemp[1]+1, | ||
531 | 255); | ||
532 | break; | ||
533 | default: | ||
534 | dev_dbg(dev, "Unknown attr->index (%d).\n", ix); | ||
535 | count = -EINVAL; | ||
536 | goto EXIT; | ||
537 | } | ||
538 | dpwm = data->pwm1_auto_point_pwm[2] - data->pwm1_auto_point_pwm[1]; | ||
539 | if (set_slope_register(client, reg, dpwm, ptemp)) | ||
540 | count = -EIO; | ||
541 | |||
542 | EXIT: | ||
543 | mutex_unlock(&data->update_lock); | ||
544 | return count; | ||
545 | } | ||
546 | |||
547 | |||
548 | |||
549 | static ssize_t set_pwm1_auto_point_pwm( | ||
550 | struct device *dev, | ||
551 | struct device_attribute *attr, | ||
552 | const char *buf, | ||
553 | size_t count) | ||
554 | { | ||
555 | struct i2c_client *client = to_i2c_client(dev); | ||
556 | struct amc6821_data *data = i2c_get_clientdata(client); | ||
557 | int dpwm; | ||
558 | long val; | ||
559 | int ret = strict_strtol(buf, 10, &val); | ||
560 | if (ret) | ||
561 | return ret; | ||
562 | |||
563 | mutex_lock(&data->update_lock); | ||
564 | data->pwm1_auto_point_pwm[1] = SENSORS_LIMIT(val, 0, 254); | ||
565 | if (i2c_smbus_write_byte_data(client, AMC6821_REG_DCY_LOW_TEMP, | ||
566 | data->pwm1_auto_point_pwm[1])) { | ||
567 | dev_err(&client->dev, "Register write error, aborting.\n"); | ||
568 | count = -EIO; | ||
569 | goto EXIT; | ||
570 | } | ||
571 | dpwm = data->pwm1_auto_point_pwm[2] - data->pwm1_auto_point_pwm[1]; | ||
572 | if (set_slope_register(client, AMC6821_REG_LTEMP_FAN_CTRL, dpwm, | ||
573 | data->temp1_auto_point_temp)) { | ||
574 | count = -EIO; | ||
575 | goto EXIT; | ||
576 | } | ||
577 | if (set_slope_register(client, AMC6821_REG_RTEMP_FAN_CTRL, dpwm, | ||
578 | data->temp2_auto_point_temp)) { | ||
579 | count = -EIO; | ||
580 | goto EXIT; | ||
581 | } | ||
582 | |||
583 | EXIT: | ||
584 | data->valid = 0; | ||
585 | mutex_unlock(&data->update_lock); | ||
586 | return count; | ||
587 | } | ||
588 | |||
589 | static ssize_t get_fan( | ||
590 | struct device *dev, | ||
591 | struct device_attribute *devattr, | ||
592 | char *buf) | ||
593 | { | ||
594 | struct amc6821_data *data = amc6821_update_device(dev); | ||
595 | int ix = to_sensor_dev_attr(devattr)->index; | ||
596 | if (0 == data->fan[ix]) | ||
597 | return sprintf(buf, "0"); | ||
598 | return sprintf(buf, "%d\n", (int)(6000000 / data->fan[ix])); | ||
599 | } | ||
600 | |||
601 | |||
602 | |||
603 | static ssize_t get_fan1_fault( | ||
604 | struct device *dev, | ||
605 | struct device_attribute *devattr, | ||
606 | char *buf) | ||
607 | { | ||
608 | struct amc6821_data *data = amc6821_update_device(dev); | ||
609 | if (data->stat1 & AMC6821_STAT1_FANS) | ||
610 | return sprintf(buf, "1"); | ||
611 | else | ||
612 | return sprintf(buf, "0"); | ||
613 | } | ||
614 | |||
615 | |||
616 | |||
617 | static ssize_t set_fan( | ||
618 | struct device *dev, | ||
619 | struct device_attribute *attr, | ||
620 | const char *buf, size_t count) | ||
621 | { | ||
622 | struct i2c_client *client = to_i2c_client(dev); | ||
623 | struct amc6821_data *data = i2c_get_clientdata(client); | ||
624 | long val; | ||
625 | int ix = to_sensor_dev_attr(attr)->index; | ||
626 | int ret = strict_strtol(buf, 10, &val); | ||
627 | if (ret) | ||
628 | return ret; | ||
629 | val = 1 > val ? 0xFFFF : 6000000/val; | ||
630 | |||
631 | mutex_lock(&data->update_lock); | ||
632 | data->fan[ix] = (u16) SENSORS_LIMIT(val, 1, 0xFFFF); | ||
633 | if (i2c_smbus_write_byte_data(client, fan_reg_low[ix], | ||
634 | data->fan[ix] & 0xFF)) { | ||
635 | dev_err(&client->dev, "Register write error, aborting.\n"); | ||
636 | count = -EIO; | ||
637 | goto EXIT; | ||
638 | } | ||
639 | if (i2c_smbus_write_byte_data(client, | ||
640 | fan_reg_hi[ix], data->fan[ix] >> 8)) { | ||
641 | dev_err(&client->dev, "Register write error, aborting.\n"); | ||
642 | count = -EIO; | ||
643 | } | ||
644 | EXIT: | ||
645 | mutex_unlock(&data->update_lock); | ||
646 | return count; | ||
647 | } | ||
648 | |||
649 | |||
650 | |||
651 | static ssize_t get_fan1_div( | ||
652 | struct device *dev, | ||
653 | struct device_attribute *devattr, | ||
654 | char *buf) | ||
655 | { | ||
656 | struct amc6821_data *data = amc6821_update_device(dev); | ||
657 | return sprintf(buf, "%d\n", data->fan1_div); | ||
658 | } | ||
659 | |||
660 | static ssize_t set_fan1_div( | ||
661 | struct device *dev, | ||
662 | struct device_attribute *attr, | ||
663 | const char *buf, size_t count) | ||
664 | { | ||
665 | struct i2c_client *client = to_i2c_client(dev); | ||
666 | struct amc6821_data *data = i2c_get_clientdata(client); | ||
667 | long val; | ||
668 | int config = strict_strtol(buf, 10, &val); | ||
669 | if (config) | ||
670 | return config; | ||
671 | |||
672 | config = i2c_smbus_read_byte_data(client, AMC6821_REG_CONF4); | ||
673 | if (config < 0) { | ||
674 | dev_err(&client->dev, | ||
675 | "Error reading configuration register, aborting.\n"); | ||
676 | return -EIO; | ||
677 | } | ||
678 | mutex_lock(&data->update_lock); | ||
679 | switch (val) { | ||
680 | case 2: | ||
681 | config &= ~AMC6821_CONF4_PSPR; | ||
682 | data->fan1_div = 2; | ||
683 | break; | ||
684 | case 4: | ||
685 | config |= AMC6821_CONF4_PSPR; | ||
686 | data->fan1_div = 4; | ||
687 | break; | ||
688 | default: | ||
689 | mutex_unlock(&data->update_lock); | ||
690 | count = -EINVAL; | ||
691 | goto EXIT; | ||
692 | } | ||
693 | if (i2c_smbus_write_byte_data(client, AMC6821_REG_CONF4, config)) { | ||
694 | dev_err(&client->dev, | ||
695 | "Configuration register write error, aborting.\n"); | ||
696 | count = -EIO; | ||
697 | } | ||
698 | EXIT: | ||
699 | mutex_unlock(&data->update_lock); | ||
700 | return count; | ||
701 | } | ||
702 | |||
703 | |||
704 | |||
705 | static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, | ||
706 | get_temp, NULL, IDX_TEMP1_INPUT); | ||
707 | static SENSOR_DEVICE_ATTR(temp1_min, S_IRUGO | S_IWUSR, get_temp, | ||
708 | set_temp, IDX_TEMP1_MIN); | ||
709 | static SENSOR_DEVICE_ATTR(temp1_max, S_IRUGO | S_IWUSR, get_temp, | ||
710 | set_temp, IDX_TEMP1_MAX); | ||
711 | static SENSOR_DEVICE_ATTR(temp1_crit, S_IRUGO | S_IWUSR, get_temp, | ||
712 | set_temp, IDX_TEMP1_CRIT); | ||
713 | static SENSOR_DEVICE_ATTR(temp1_min_alarm, S_IRUGO, | ||
714 | get_temp_alarm, NULL, IDX_TEMP1_MIN); | ||
715 | static SENSOR_DEVICE_ATTR(temp1_max_alarm, S_IRUGO, | ||
716 | get_temp_alarm, NULL, IDX_TEMP1_MAX); | ||
717 | static SENSOR_DEVICE_ATTR(temp1_crit_alarm, S_IRUGO, | ||
718 | get_temp_alarm, NULL, IDX_TEMP1_CRIT); | ||
719 | static SENSOR_DEVICE_ATTR(temp2_input, S_IRUGO | S_IWUSR, | ||
720 | get_temp, NULL, IDX_TEMP2_INPUT); | ||
721 | static SENSOR_DEVICE_ATTR(temp2_min, S_IRUGO | S_IWUSR, get_temp, | ||
722 | set_temp, IDX_TEMP2_MIN); | ||
723 | static SENSOR_DEVICE_ATTR(temp2_max, S_IRUGO | S_IWUSR, get_temp, | ||
724 | set_temp, IDX_TEMP2_MAX); | ||
725 | static SENSOR_DEVICE_ATTR(temp2_crit, S_IRUGO | S_IWUSR, get_temp, | ||
726 | set_temp, IDX_TEMP2_CRIT); | ||
727 | static SENSOR_DEVICE_ATTR(temp2_fault, S_IRUGO, | ||
728 | get_temp2_fault, NULL, 0); | ||
729 | static SENSOR_DEVICE_ATTR(temp2_min_alarm, S_IRUGO, | ||
730 | get_temp_alarm, NULL, IDX_TEMP2_MIN); | ||
731 | static SENSOR_DEVICE_ATTR(temp2_max_alarm, S_IRUGO, | ||
732 | get_temp_alarm, NULL, IDX_TEMP2_MAX); | ||
733 | static SENSOR_DEVICE_ATTR(temp2_crit_alarm, S_IRUGO, | ||
734 | get_temp_alarm, NULL, IDX_TEMP2_CRIT); | ||
735 | static SENSOR_DEVICE_ATTR(fan1_input, S_IRUGO, get_fan, NULL, IDX_FAN1_INPUT); | ||
736 | static SENSOR_DEVICE_ATTR(fan1_min, S_IRUGO | S_IWUSR, | ||
737 | get_fan, set_fan, IDX_FAN1_MIN); | ||
738 | static SENSOR_DEVICE_ATTR(fan1_max, S_IRUGO | S_IWUSR, | ||
739 | get_fan, set_fan, IDX_FAN1_MAX); | ||
740 | static SENSOR_DEVICE_ATTR(fan1_fault, S_IRUGO, get_fan1_fault, NULL, 0); | ||
741 | static SENSOR_DEVICE_ATTR(fan1_div, S_IRUGO | S_IWUSR, | ||
742 | get_fan1_div, set_fan1_div, 0); | ||
743 | |||
744 | static SENSOR_DEVICE_ATTR(pwm1, S_IWUSR | S_IRUGO, get_pwm1, set_pwm1, 0); | ||
745 | static SENSOR_DEVICE_ATTR(pwm1_enable, S_IWUSR | S_IRUGO, | ||
746 | get_pwm1_enable, set_pwm1_enable, 0); | ||
747 | static SENSOR_DEVICE_ATTR(pwm1_auto_point1_pwm, S_IRUGO, | ||
748 | get_pwm1_auto_point_pwm, NULL, 0); | ||
749 | static SENSOR_DEVICE_ATTR(pwm1_auto_point2_pwm, S_IWUSR | S_IRUGO, | ||
750 | get_pwm1_auto_point_pwm, set_pwm1_auto_point_pwm, 1); | ||
751 | static SENSOR_DEVICE_ATTR(pwm1_auto_point3_pwm, S_IRUGO, | ||
752 | get_pwm1_auto_point_pwm, NULL, 2); | ||
753 | static SENSOR_DEVICE_ATTR(pwm1_auto_channels_temp, S_IRUGO, | ||
754 | get_pwm1_auto_channels_temp, NULL, 0); | ||
755 | static SENSOR_DEVICE_ATTR_2(temp1_auto_point1_temp, S_IRUGO, | ||
756 | get_temp_auto_point_temp, NULL, 1, 0); | ||
757 | static SENSOR_DEVICE_ATTR_2(temp1_auto_point2_temp, S_IWUSR | S_IRUGO, | ||
758 | get_temp_auto_point_temp, set_temp_auto_point_temp, 1, 1); | ||
759 | static SENSOR_DEVICE_ATTR_2(temp1_auto_point3_temp, S_IWUSR | S_IRUGO, | ||
760 | get_temp_auto_point_temp, set_temp_auto_point_temp, 1, 2); | ||
761 | |||
762 | static SENSOR_DEVICE_ATTR_2(temp2_auto_point1_temp, S_IWUSR | S_IRUGO, | ||
763 | get_temp_auto_point_temp, set_temp_auto_point_temp, 2, 0); | ||
764 | static SENSOR_DEVICE_ATTR_2(temp2_auto_point2_temp, S_IWUSR | S_IRUGO, | ||
765 | get_temp_auto_point_temp, set_temp_auto_point_temp, 2, 1); | ||
766 | static SENSOR_DEVICE_ATTR_2(temp2_auto_point3_temp, S_IWUSR | S_IRUGO, | ||
767 | get_temp_auto_point_temp, set_temp_auto_point_temp, 2, 2); | ||
768 | |||
769 | |||
770 | |||
771 | static struct attribute *amc6821_attrs[] = { | ||
772 | &sensor_dev_attr_temp1_input.dev_attr.attr, | ||
773 | &sensor_dev_attr_temp1_min.dev_attr.attr, | ||
774 | &sensor_dev_attr_temp1_max.dev_attr.attr, | ||
775 | &sensor_dev_attr_temp1_crit.dev_attr.attr, | ||
776 | &sensor_dev_attr_temp1_min_alarm.dev_attr.attr, | ||
777 | &sensor_dev_attr_temp1_max_alarm.dev_attr.attr, | ||
778 | &sensor_dev_attr_temp1_crit_alarm.dev_attr.attr, | ||
779 | &sensor_dev_attr_temp2_input.dev_attr.attr, | ||
780 | &sensor_dev_attr_temp2_min.dev_attr.attr, | ||
781 | &sensor_dev_attr_temp2_max.dev_attr.attr, | ||
782 | &sensor_dev_attr_temp2_crit.dev_attr.attr, | ||
783 | &sensor_dev_attr_temp2_min_alarm.dev_attr.attr, | ||
784 | &sensor_dev_attr_temp2_max_alarm.dev_attr.attr, | ||
785 | &sensor_dev_attr_temp2_crit_alarm.dev_attr.attr, | ||
786 | &sensor_dev_attr_temp2_fault.dev_attr.attr, | ||
787 | &sensor_dev_attr_fan1_input.dev_attr.attr, | ||
788 | &sensor_dev_attr_fan1_min.dev_attr.attr, | ||
789 | &sensor_dev_attr_fan1_max.dev_attr.attr, | ||
790 | &sensor_dev_attr_fan1_fault.dev_attr.attr, | ||
791 | &sensor_dev_attr_fan1_div.dev_attr.attr, | ||
792 | &sensor_dev_attr_pwm1.dev_attr.attr, | ||
793 | &sensor_dev_attr_pwm1_enable.dev_attr.attr, | ||
794 | &sensor_dev_attr_pwm1_auto_channels_temp.dev_attr.attr, | ||
795 | &sensor_dev_attr_pwm1_auto_point1_pwm.dev_attr.attr, | ||
796 | &sensor_dev_attr_pwm1_auto_point2_pwm.dev_attr.attr, | ||
797 | &sensor_dev_attr_pwm1_auto_point3_pwm.dev_attr.attr, | ||
798 | &sensor_dev_attr_temp1_auto_point1_temp.dev_attr.attr, | ||
799 | &sensor_dev_attr_temp1_auto_point2_temp.dev_attr.attr, | ||
800 | &sensor_dev_attr_temp1_auto_point3_temp.dev_attr.attr, | ||
801 | &sensor_dev_attr_temp2_auto_point1_temp.dev_attr.attr, | ||
802 | &sensor_dev_attr_temp2_auto_point2_temp.dev_attr.attr, | ||
803 | &sensor_dev_attr_temp2_auto_point3_temp.dev_attr.attr, | ||
804 | NULL | ||
805 | }; | ||
806 | |||
807 | static struct attribute_group amc6821_attr_grp = { | ||
808 | .attrs = amc6821_attrs, | ||
809 | }; | ||
810 | |||
811 | |||
812 | |||
813 | /* Return 0 if detection is successful, -ENODEV otherwise */ | ||
814 | static int amc6821_detect( | ||
815 | struct i2c_client *client, | ||
816 | struct i2c_board_info *info) | ||
817 | { | ||
818 | struct i2c_adapter *adapter = client->adapter; | ||
819 | int address = client->addr; | ||
820 | int dev_id, comp_id; | ||
821 | |||
822 | dev_dbg(&adapter->dev, "amc6821_detect called.\n"); | ||
823 | |||
824 | if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) { | ||
825 | dev_dbg(&adapter->dev, | ||
826 | "amc6821: I2C bus doesn't support byte mode, " | ||
827 | "skipping.\n"); | ||
828 | return -ENODEV; | ||
829 | } | ||
830 | |||
831 | dev_id = i2c_smbus_read_byte_data(client, AMC6821_REG_DEV_ID); | ||
832 | comp_id = i2c_smbus_read_byte_data(client, AMC6821_REG_COMP_ID); | ||
833 | if (dev_id != 0x21 || comp_id != 0x49) { | ||
834 | dev_dbg(&adapter->dev, | ||
835 | "amc6821: detection failed at 0x%02x.\n", | ||
836 | address); | ||
837 | return -ENODEV; | ||
838 | } | ||
839 | |||
840 | /* Bit 7 of the address register is ignored, so we can check the | ||
841 | ID registers again */ | ||
842 | dev_id = i2c_smbus_read_byte_data(client, 0x80 | AMC6821_REG_DEV_ID); | ||
843 | comp_id = i2c_smbus_read_byte_data(client, 0x80 | AMC6821_REG_COMP_ID); | ||
844 | if (dev_id != 0x21 || comp_id != 0x49) { | ||
845 | dev_dbg(&adapter->dev, | ||
846 | "amc6821: detection failed at 0x%02x.\n", | ||
847 | address); | ||
848 | return -ENODEV; | ||
849 | } | ||
850 | |||
851 | dev_info(&adapter->dev, "amc6821: chip found at 0x%02x.\n", address); | ||
852 | strlcpy(info->type, "amc6821", I2C_NAME_SIZE); | ||
853 | |||
854 | return 0; | ||
855 | } | ||
856 | |||
857 | static int amc6821_probe( | ||
858 | struct i2c_client *client, | ||
859 | const struct i2c_device_id *id) | ||
860 | { | ||
861 | struct amc6821_data *data; | ||
862 | int err; | ||
863 | |||
864 | data = kzalloc(sizeof(struct amc6821_data), GFP_KERNEL); | ||
865 | if (!data) { | ||
866 | dev_err(&client->dev, "out of memory.\n"); | ||
867 | return -ENOMEM; | ||
868 | } | ||
869 | |||
870 | |||
871 | i2c_set_clientdata(client, data); | ||
872 | mutex_init(&data->update_lock); | ||
873 | |||
874 | /* | ||
875 | * Initialize the amc6821 chip | ||
876 | */ | ||
877 | err = amc6821_init_client(client); | ||
878 | if (err) | ||
879 | goto err_free; | ||
880 | |||
881 | err = sysfs_create_group(&client->dev.kobj, &amc6821_attr_grp); | ||
882 | if (err) | ||
883 | goto err_free; | ||
884 | |||
885 | data->hwmon_dev = hwmon_device_register(&client->dev); | ||
886 | if (!IS_ERR(data->hwmon_dev)) | ||
887 | return 0; | ||
888 | |||
889 | err = PTR_ERR(data->hwmon_dev); | ||
890 | dev_err(&client->dev, "error registering hwmon device.\n"); | ||
891 | sysfs_remove_group(&client->dev.kobj, &amc6821_attr_grp); | ||
892 | err_free: | ||
893 | kfree(data); | ||
894 | return err; | ||
895 | } | ||
896 | |||
897 | static int amc6821_remove(struct i2c_client *client) | ||
898 | { | ||
899 | struct amc6821_data *data = i2c_get_clientdata(client); | ||
900 | |||
901 | hwmon_device_unregister(data->hwmon_dev); | ||
902 | sysfs_remove_group(&client->dev.kobj, &amc6821_attr_grp); | ||
903 | |||
904 | kfree(data); | ||
905 | |||
906 | return 0; | ||
907 | } | ||
908 | |||
909 | |||
910 | static int amc6821_init_client(struct i2c_client *client) | ||
911 | { | ||
912 | int config; | ||
913 | int err = -EIO; | ||
914 | |||
915 | if (init) { | ||
916 | config = i2c_smbus_read_byte_data(client, AMC6821_REG_CONF4); | ||
917 | |||
918 | if (config < 0) { | ||
919 | dev_err(&client->dev, | ||
920 | "Error reading configuration register, aborting.\n"); | ||
921 | return err; | ||
922 | } | ||
923 | |||
924 | config |= AMC6821_CONF4_MODE; | ||
925 | |||
926 | if (i2c_smbus_write_byte_data(client, AMC6821_REG_CONF4, | ||
927 | config)) { | ||
928 | dev_err(&client->dev, | ||
929 | "Configuration register write error, aborting.\n"); | ||
930 | return err; | ||
931 | } | ||
932 | |||
933 | config = i2c_smbus_read_byte_data(client, AMC6821_REG_CONF3); | ||
934 | |||
935 | if (config < 0) { | ||
936 | dev_err(&client->dev, | ||
937 | "Error reading configuration register, aborting.\n"); | ||
938 | return err; | ||
939 | } | ||
940 | |||
941 | dev_info(&client->dev, "Revision %d\n", config & 0x0f); | ||
942 | |||
943 | config &= ~AMC6821_CONF3_THERM_FAN_EN; | ||
944 | |||
945 | if (i2c_smbus_write_byte_data(client, AMC6821_REG_CONF3, | ||
946 | config)) { | ||
947 | dev_err(&client->dev, | ||
948 | "Configuration register write error, aborting.\n"); | ||
949 | return err; | ||
950 | } | ||
951 | |||
952 | config = i2c_smbus_read_byte_data(client, AMC6821_REG_CONF2); | ||
953 | |||
954 | if (config < 0) { | ||
955 | dev_err(&client->dev, | ||
956 | "Error reading configuration register, aborting.\n"); | ||
957 | return err; | ||
958 | } | ||
959 | |||
960 | config &= ~AMC6821_CONF2_RTFIE; | ||
961 | config &= ~AMC6821_CONF2_LTOIE; | ||
962 | config &= ~AMC6821_CONF2_RTOIE; | ||
963 | if (i2c_smbus_write_byte_data(client, | ||
964 | AMC6821_REG_CONF2, config)) { | ||
965 | dev_err(&client->dev, | ||
966 | "Configuration register write error, aborting.\n"); | ||
967 | return err; | ||
968 | } | ||
969 | |||
970 | config = i2c_smbus_read_byte_data(client, AMC6821_REG_CONF1); | ||
971 | |||
972 | if (config < 0) { | ||
973 | dev_err(&client->dev, | ||
974 | "Error reading configuration register, aborting.\n"); | ||
975 | return err; | ||
976 | } | ||
977 | |||
978 | config &= ~AMC6821_CONF1_THERMOVIE; | ||
979 | config &= ~AMC6821_CONF1_FANIE; | ||
980 | config |= AMC6821_CONF1_START; | ||
981 | if (pwminv) | ||
982 | config |= AMC6821_CONF1_PWMINV; | ||
983 | else | ||
984 | config &= ~AMC6821_CONF1_PWMINV; | ||
985 | |||
986 | if (i2c_smbus_write_byte_data( | ||
987 | client, AMC6821_REG_CONF1, config)) { | ||
988 | dev_err(&client->dev, | ||
989 | "Configuration register write error, aborting.\n"); | ||
990 | return err; | ||
991 | } | ||
992 | } | ||
993 | return 0; | ||
994 | } | ||
995 | |||
996 | |||
997 | static struct amc6821_data *amc6821_update_device(struct device *dev) | ||
998 | { | ||
999 | struct i2c_client *client = to_i2c_client(dev); | ||
1000 | struct amc6821_data *data = i2c_get_clientdata(client); | ||
1001 | int timeout = HZ; | ||
1002 | u8 reg; | ||
1003 | int i; | ||
1004 | |||
1005 | mutex_lock(&data->update_lock); | ||
1006 | |||
1007 | if (time_after(jiffies, data->last_updated + timeout) || | ||
1008 | !data->valid) { | ||
1009 | |||
1010 | for (i = 0; i < TEMP_IDX_LEN; i++) | ||
1011 | data->temp[i] = i2c_smbus_read_byte_data(client, | ||
1012 | temp_reg[i]); | ||
1013 | |||
1014 | data->stat1 = i2c_smbus_read_byte_data(client, | ||
1015 | AMC6821_REG_STAT1); | ||
1016 | data->stat2 = i2c_smbus_read_byte_data(client, | ||
1017 | AMC6821_REG_STAT2); | ||
1018 | |||
1019 | data->pwm1 = i2c_smbus_read_byte_data(client, | ||
1020 | AMC6821_REG_DCY); | ||
1021 | for (i = 0; i < FAN1_IDX_LEN; i++) { | ||
1022 | data->fan[i] = i2c_smbus_read_byte_data( | ||
1023 | client, | ||
1024 | fan_reg_low[i]); | ||
1025 | data->fan[i] += i2c_smbus_read_byte_data( | ||
1026 | client, | ||
1027 | fan_reg_hi[i]) << 8; | ||
1028 | } | ||
1029 | data->fan1_div = i2c_smbus_read_byte_data(client, | ||
1030 | AMC6821_REG_CONF4); | ||
1031 | data->fan1_div = data->fan1_div & AMC6821_CONF4_PSPR ? 4 : 2; | ||
1032 | |||
1033 | data->pwm1_auto_point_pwm[0] = 0; | ||
1034 | data->pwm1_auto_point_pwm[2] = 255; | ||
1035 | data->pwm1_auto_point_pwm[1] = i2c_smbus_read_byte_data(client, | ||
1036 | AMC6821_REG_DCY_LOW_TEMP); | ||
1037 | |||
1038 | data->temp1_auto_point_temp[0] = | ||
1039 | i2c_smbus_read_byte_data(client, | ||
1040 | AMC6821_REG_PSV_TEMP); | ||
1041 | data->temp2_auto_point_temp[0] = | ||
1042 | data->temp1_auto_point_temp[0]; | ||
1043 | reg = i2c_smbus_read_byte_data(client, | ||
1044 | AMC6821_REG_LTEMP_FAN_CTRL); | ||
1045 | data->temp1_auto_point_temp[1] = (reg & 0xF8) >> 1; | ||
1046 | reg &= 0x07; | ||
1047 | reg = 0x20 >> reg; | ||
1048 | if (reg > 0) | ||
1049 | data->temp1_auto_point_temp[2] = | ||
1050 | data->temp1_auto_point_temp[1] + | ||
1051 | (data->pwm1_auto_point_pwm[2] - | ||
1052 | data->pwm1_auto_point_pwm[1]) / reg; | ||
1053 | else | ||
1054 | data->temp1_auto_point_temp[2] = 255; | ||
1055 | |||
1056 | reg = i2c_smbus_read_byte_data(client, | ||
1057 | AMC6821_REG_RTEMP_FAN_CTRL); | ||
1058 | data->temp2_auto_point_temp[1] = (reg & 0xF8) >> 1; | ||
1059 | reg &= 0x07; | ||
1060 | reg = 0x20 >> reg; | ||
1061 | if (reg > 0) | ||
1062 | data->temp2_auto_point_temp[2] = | ||
1063 | data->temp2_auto_point_temp[1] + | ||
1064 | (data->pwm1_auto_point_pwm[2] - | ||
1065 | data->pwm1_auto_point_pwm[1]) / reg; | ||
1066 | else | ||
1067 | data->temp2_auto_point_temp[2] = 255; | ||
1068 | |||
1069 | reg = i2c_smbus_read_byte_data(client, AMC6821_REG_CONF1); | ||
1070 | reg = (reg >> 5) & 0x3; | ||
1071 | switch (reg) { | ||
1072 | case 0: /*open loop: software sets pwm1*/ | ||
1073 | data->pwm1_auto_channels_temp = 0; | ||
1074 | data->pwm1_enable = 1; | ||
1075 | break; | ||
1076 | case 2: /*closed loop: remote T (temp2)*/ | ||
1077 | data->pwm1_auto_channels_temp = 2; | ||
1078 | data->pwm1_enable = 2; | ||
1079 | break; | ||
1080 | case 3: /*closed loop: local and remote T (temp2)*/ | ||
1081 | data->pwm1_auto_channels_temp = 3; | ||
1082 | data->pwm1_enable = 3; | ||
1083 | break; | ||
1084 | case 1: /*semi-open loop: software sets rpm, chip controls pwm1, | ||
1085 | *currently not implemented | ||
1086 | */ | ||
1087 | data->pwm1_auto_channels_temp = 0; | ||
1088 | data->pwm1_enable = 0; | ||
1089 | break; | ||
1090 | } | ||
1091 | |||
1092 | data->last_updated = jiffies; | ||
1093 | data->valid = 1; | ||
1094 | } | ||
1095 | mutex_unlock(&data->update_lock); | ||
1096 | return data; | ||
1097 | } | ||
1098 | |||
1099 | |||
1100 | static int __init amc6821_init(void) | ||
1101 | { | ||
1102 | return i2c_add_driver(&amc6821_driver); | ||
1103 | } | ||
1104 | |||
1105 | static void __exit amc6821_exit(void) | ||
1106 | { | ||
1107 | i2c_del_driver(&amc6821_driver); | ||
1108 | } | ||
1109 | |||
1110 | module_init(amc6821_init); | ||
1111 | module_exit(amc6821_exit); | ||
1112 | |||
1113 | |||
1114 | MODULE_LICENSE("GPL"); | ||
1115 | MODULE_AUTHOR("T. Mertelj <tomaz.mertelj@guest.arnes.si>"); | ||
1116 | MODULE_DESCRIPTION("Texas Instruments amc6821 hwmon driver"); | ||
diff --git a/drivers/hwmon/asus_atk0110.c b/drivers/hwmon/asus_atk0110.c index 5a3ee00c0e7d..6811346c1c62 100644 --- a/drivers/hwmon/asus_atk0110.c +++ b/drivers/hwmon/asus_atk0110.c | |||
@@ -5,6 +5,7 @@ | |||
5 | * See COPYING in the top level directory of the kernel tree. | 5 | * See COPYING in the top level directory of the kernel tree. |
6 | */ | 6 | */ |
7 | 7 | ||
8 | #include <linux/debugfs.h> | ||
8 | #include <linux/kernel.h> | 9 | #include <linux/kernel.h> |
9 | #include <linux/hwmon.h> | 10 | #include <linux/hwmon.h> |
10 | #include <linux/list.h> | 11 | #include <linux/list.h> |
@@ -101,6 +102,11 @@ struct atk_data { | |||
101 | int temperature_count; | 102 | int temperature_count; |
102 | int fan_count; | 103 | int fan_count; |
103 | struct list_head sensor_list; | 104 | struct list_head sensor_list; |
105 | |||
106 | struct { | ||
107 | struct dentry *root; | ||
108 | u32 id; | ||
109 | } debugfs; | ||
104 | }; | 110 | }; |
105 | 111 | ||
106 | 112 | ||
@@ -624,6 +630,187 @@ static int atk_read_value(struct atk_sensor_data *sensor, u64 *value) | |||
624 | return err; | 630 | return err; |
625 | } | 631 | } |
626 | 632 | ||
633 | #ifdef CONFIG_DEBUG_FS | ||
634 | static int atk_debugfs_gitm_get(void *p, u64 *val) | ||
635 | { | ||
636 | struct atk_data *data = p; | ||
637 | union acpi_object *ret; | ||
638 | struct atk_acpi_ret_buffer *buf; | ||
639 | int err = 0; | ||
640 | |||
641 | if (!data->read_handle) | ||
642 | return -ENODEV; | ||
643 | |||
644 | if (!data->debugfs.id) | ||
645 | return -EINVAL; | ||
646 | |||
647 | ret = atk_gitm(data, data->debugfs.id); | ||
648 | if (IS_ERR(ret)) | ||
649 | return PTR_ERR(ret); | ||
650 | |||
651 | buf = (struct atk_acpi_ret_buffer *)ret->buffer.pointer; | ||
652 | if (buf->flags) | ||
653 | *val = buf->value; | ||
654 | else | ||
655 | err = -EIO; | ||
656 | |||
657 | return err; | ||
658 | } | ||
659 | |||
660 | DEFINE_SIMPLE_ATTRIBUTE(atk_debugfs_gitm, | ||
661 | atk_debugfs_gitm_get, | ||
662 | NULL, | ||
663 | "0x%08llx\n") | ||
664 | |||
665 | static int atk_acpi_print(char *buf, size_t sz, union acpi_object *obj) | ||
666 | { | ||
667 | int ret = 0; | ||
668 | |||
669 | switch (obj->type) { | ||
670 | case ACPI_TYPE_INTEGER: | ||
671 | ret = snprintf(buf, sz, "0x%08llx\n", obj->integer.value); | ||
672 | break; | ||
673 | case ACPI_TYPE_STRING: | ||
674 | ret = snprintf(buf, sz, "%s\n", obj->string.pointer); | ||
675 | break; | ||
676 | } | ||
677 | |||
678 | return ret; | ||
679 | } | ||
680 | |||
681 | static void atk_pack_print(char *buf, size_t sz, union acpi_object *pack) | ||
682 | { | ||
683 | int ret; | ||
684 | int i; | ||
685 | |||
686 | for (i = 0; i < pack->package.count; i++) { | ||
687 | union acpi_object *obj = &pack->package.elements[i]; | ||
688 | |||
689 | ret = atk_acpi_print(buf, sz, obj); | ||
690 | if (ret >= sz) | ||
691 | break; | ||
692 | buf += ret; | ||
693 | sz -= ret; | ||
694 | } | ||
695 | } | ||
696 | |||
697 | static int atk_debugfs_ggrp_open(struct inode *inode, struct file *file) | ||
698 | { | ||
699 | struct atk_data *data = inode->i_private; | ||
700 | char *buf = NULL; | ||
701 | union acpi_object *ret; | ||
702 | u8 cls; | ||
703 | int i; | ||
704 | |||
705 | if (!data->enumerate_handle) | ||
706 | return -ENODEV; | ||
707 | if (!data->debugfs.id) | ||
708 | return -EINVAL; | ||
709 | |||
710 | cls = (data->debugfs.id & 0xff000000) >> 24; | ||
711 | ret = atk_ggrp(data, cls); | ||
712 | if (IS_ERR(ret)) | ||
713 | return PTR_ERR(ret); | ||
714 | |||
715 | for (i = 0; i < ret->package.count; i++) { | ||
716 | union acpi_object *pack = &ret->package.elements[i]; | ||
717 | union acpi_object *id; | ||
718 | |||
719 | if (pack->type != ACPI_TYPE_PACKAGE) | ||
720 | continue; | ||
721 | if (!pack->package.count) | ||
722 | continue; | ||
723 | id = &pack->package.elements[0]; | ||
724 | if (id->integer.value == data->debugfs.id) { | ||
725 | /* Print the package */ | ||
726 | buf = kzalloc(512, GFP_KERNEL); | ||
727 | if (!buf) { | ||
728 | ACPI_FREE(ret); | ||
729 | return -ENOMEM; | ||
730 | } | ||
731 | atk_pack_print(buf, 512, pack); | ||
732 | break; | ||
733 | } | ||
734 | } | ||
735 | ACPI_FREE(ret); | ||
736 | |||
737 | if (!buf) | ||
738 | return -EINVAL; | ||
739 | |||
740 | file->private_data = buf; | ||
741 | |||
742 | return nonseekable_open(inode, file); | ||
743 | } | ||
744 | |||
745 | static ssize_t atk_debugfs_ggrp_read(struct file *file, char __user *buf, | ||
746 | size_t count, loff_t *pos) | ||
747 | { | ||
748 | char *str = file->private_data; | ||
749 | size_t len = strlen(str); | ||
750 | |||
751 | return simple_read_from_buffer(buf, count, pos, str, len); | ||
752 | } | ||
753 | |||
754 | static int atk_debugfs_ggrp_release(struct inode *inode, struct file *file) | ||
755 | { | ||
756 | kfree(file->private_data); | ||
757 | return 0; | ||
758 | } | ||
759 | |||
760 | static const struct file_operations atk_debugfs_ggrp_fops = { | ||
761 | .read = atk_debugfs_ggrp_read, | ||
762 | .open = atk_debugfs_ggrp_open, | ||
763 | .release = atk_debugfs_ggrp_release, | ||
764 | }; | ||
765 | |||
766 | static void atk_debugfs_init(struct atk_data *data) | ||
767 | { | ||
768 | struct dentry *d; | ||
769 | struct dentry *f; | ||
770 | |||
771 | data->debugfs.id = 0; | ||
772 | |||
773 | d = debugfs_create_dir("asus_atk0110", NULL); | ||
774 | if (!d || IS_ERR(d)) | ||
775 | return; | ||
776 | |||
777 | f = debugfs_create_x32("id", S_IRUSR | S_IWUSR, d, &data->debugfs.id); | ||
778 | if (!f || IS_ERR(f)) | ||
779 | goto cleanup; | ||
780 | |||
781 | f = debugfs_create_file("gitm", S_IRUSR, d, data, | ||
782 | &atk_debugfs_gitm); | ||
783 | if (!f || IS_ERR(f)) | ||
784 | goto cleanup; | ||
785 | |||
786 | f = debugfs_create_file("ggrp", S_IRUSR, d, data, | ||
787 | &atk_debugfs_ggrp_fops); | ||
788 | if (!f || IS_ERR(f)) | ||
789 | goto cleanup; | ||
790 | |||
791 | data->debugfs.root = d; | ||
792 | |||
793 | return; | ||
794 | cleanup: | ||
795 | debugfs_remove_recursive(d); | ||
796 | } | ||
797 | |||
798 | static void atk_debugfs_cleanup(struct atk_data *data) | ||
799 | { | ||
800 | debugfs_remove_recursive(data->debugfs.root); | ||
801 | } | ||
802 | |||
803 | #else /* CONFIG_DEBUG_FS */ | ||
804 | |||
805 | static void atk_debugfs_init(struct atk_data *data) | ||
806 | { | ||
807 | } | ||
808 | |||
809 | static void atk_debugfs_cleanup(struct atk_data *data) | ||
810 | { | ||
811 | } | ||
812 | #endif | ||
813 | |||
627 | static int atk_add_sensor(struct atk_data *data, union acpi_object *obj) | 814 | static int atk_add_sensor(struct atk_data *data, union acpi_object *obj) |
628 | { | 815 | { |
629 | struct device *dev = &data->acpi_dev->dev; | 816 | struct device *dev = &data->acpi_dev->dev; |
@@ -1047,76 +1234,75 @@ remove: | |||
1047 | return err; | 1234 | return err; |
1048 | } | 1235 | } |
1049 | 1236 | ||
1050 | static int atk_check_old_if(struct atk_data *data) | 1237 | static int atk_probe_if(struct atk_data *data) |
1051 | { | 1238 | { |
1052 | struct device *dev = &data->acpi_dev->dev; | 1239 | struct device *dev = &data->acpi_dev->dev; |
1053 | acpi_handle ret; | 1240 | acpi_handle ret; |
1054 | acpi_status status; | 1241 | acpi_status status; |
1242 | int err = 0; | ||
1055 | 1243 | ||
1056 | /* RTMP: read temperature */ | 1244 | /* RTMP: read temperature */ |
1057 | status = acpi_get_handle(data->atk_handle, METHOD_OLD_READ_TMP, &ret); | 1245 | status = acpi_get_handle(data->atk_handle, METHOD_OLD_READ_TMP, &ret); |
1058 | if (status != AE_OK) { | 1246 | if (ACPI_SUCCESS(status)) |
1247 | data->rtmp_handle = ret; | ||
1248 | else | ||
1059 | dev_dbg(dev, "method " METHOD_OLD_READ_TMP " not found: %s\n", | 1249 | dev_dbg(dev, "method " METHOD_OLD_READ_TMP " not found: %s\n", |
1060 | acpi_format_exception(status)); | 1250 | acpi_format_exception(status)); |
1061 | return -ENODEV; | ||
1062 | } | ||
1063 | data->rtmp_handle = ret; | ||
1064 | 1251 | ||
1065 | /* RVLT: read voltage */ | 1252 | /* RVLT: read voltage */ |
1066 | status = acpi_get_handle(data->atk_handle, METHOD_OLD_READ_VLT, &ret); | 1253 | status = acpi_get_handle(data->atk_handle, METHOD_OLD_READ_VLT, &ret); |
1067 | if (status != AE_OK) { | 1254 | if (ACPI_SUCCESS(status)) |
1255 | data->rvlt_handle = ret; | ||
1256 | else | ||
1068 | dev_dbg(dev, "method " METHOD_OLD_READ_VLT " not found: %s\n", | 1257 | dev_dbg(dev, "method " METHOD_OLD_READ_VLT " not found: %s\n", |
1069 | acpi_format_exception(status)); | 1258 | acpi_format_exception(status)); |
1070 | return -ENODEV; | ||
1071 | } | ||
1072 | data->rvlt_handle = ret; | ||
1073 | 1259 | ||
1074 | /* RFAN: read fan status */ | 1260 | /* RFAN: read fan status */ |
1075 | status = acpi_get_handle(data->atk_handle, METHOD_OLD_READ_FAN, &ret); | 1261 | status = acpi_get_handle(data->atk_handle, METHOD_OLD_READ_FAN, &ret); |
1076 | if (status != AE_OK) { | 1262 | if (ACPI_SUCCESS(status)) |
1263 | data->rfan_handle = ret; | ||
1264 | else | ||
1077 | dev_dbg(dev, "method " METHOD_OLD_READ_FAN " not found: %s\n", | 1265 | dev_dbg(dev, "method " METHOD_OLD_READ_FAN " not found: %s\n", |
1078 | acpi_format_exception(status)); | 1266 | acpi_format_exception(status)); |
1079 | return -ENODEV; | ||
1080 | } | ||
1081 | data->rfan_handle = ret; | ||
1082 | |||
1083 | return 0; | ||
1084 | } | ||
1085 | |||
1086 | static int atk_check_new_if(struct atk_data *data) | ||
1087 | { | ||
1088 | struct device *dev = &data->acpi_dev->dev; | ||
1089 | acpi_handle ret; | ||
1090 | acpi_status status; | ||
1091 | 1267 | ||
1092 | /* Enumeration */ | 1268 | /* Enumeration */ |
1093 | status = acpi_get_handle(data->atk_handle, METHOD_ENUMERATE, &ret); | 1269 | status = acpi_get_handle(data->atk_handle, METHOD_ENUMERATE, &ret); |
1094 | if (status != AE_OK) { | 1270 | if (ACPI_SUCCESS(status)) |
1271 | data->enumerate_handle = ret; | ||
1272 | else | ||
1095 | dev_dbg(dev, "method " METHOD_ENUMERATE " not found: %s\n", | 1273 | dev_dbg(dev, "method " METHOD_ENUMERATE " not found: %s\n", |
1096 | acpi_format_exception(status)); | 1274 | acpi_format_exception(status)); |
1097 | return -ENODEV; | ||
1098 | } | ||
1099 | data->enumerate_handle = ret; | ||
1100 | 1275 | ||
1101 | /* De-multiplexer (read) */ | 1276 | /* De-multiplexer (read) */ |
1102 | status = acpi_get_handle(data->atk_handle, METHOD_READ, &ret); | 1277 | status = acpi_get_handle(data->atk_handle, METHOD_READ, &ret); |
1103 | if (status != AE_OK) { | 1278 | if (ACPI_SUCCESS(status)) |
1279 | data->read_handle = ret; | ||
1280 | else | ||
1104 | dev_dbg(dev, "method " METHOD_READ " not found: %s\n", | 1281 | dev_dbg(dev, "method " METHOD_READ " not found: %s\n", |
1105 | acpi_format_exception(status)); | 1282 | acpi_format_exception(status)); |
1106 | return -ENODEV; | ||
1107 | } | ||
1108 | data->read_handle = ret; | ||
1109 | 1283 | ||
1110 | /* De-multiplexer (write) */ | 1284 | /* De-multiplexer (write) */ |
1111 | status = acpi_get_handle(data->atk_handle, METHOD_WRITE, &ret); | 1285 | status = acpi_get_handle(data->atk_handle, METHOD_WRITE, &ret); |
1112 | if (status != AE_OK) { | 1286 | if (ACPI_SUCCESS(status)) |
1113 | dev_dbg(dev, "method " METHOD_READ " not found: %s\n", | 1287 | data->write_handle = ret; |
1288 | else | ||
1289 | dev_dbg(dev, "method " METHOD_WRITE " not found: %s\n", | ||
1114 | acpi_format_exception(status)); | 1290 | acpi_format_exception(status)); |
1115 | return -ENODEV; | ||
1116 | } | ||
1117 | data->write_handle = ret; | ||
1118 | 1291 | ||
1119 | return 0; | 1292 | /* Check for hwmon methods: first check "old" style methods; note that |
1293 | * both may be present: in this case we stick to the old interface; | ||
1294 | * analysis of multiple DSDTs indicates that when both interfaces | ||
1295 | * are present the new one (GGRP/GITM) is not functional. | ||
1296 | */ | ||
1297 | if (data->rtmp_handle && data->rvlt_handle && data->rfan_handle) | ||
1298 | data->old_interface = true; | ||
1299 | else if (data->enumerate_handle && data->read_handle && | ||
1300 | data->write_handle) | ||
1301 | data->old_interface = false; | ||
1302 | else | ||
1303 | err = -ENODEV; | ||
1304 | |||
1305 | return err; | ||
1120 | } | 1306 | } |
1121 | 1307 | ||
1122 | static int atk_add(struct acpi_device *device) | 1308 | static int atk_add(struct acpi_device *device) |
@@ -1155,28 +1341,19 @@ static int atk_add(struct acpi_device *device) | |||
1155 | } | 1341 | } |
1156 | ACPI_FREE(buf.pointer); | 1342 | ACPI_FREE(buf.pointer); |
1157 | 1343 | ||
1158 | /* Check for hwmon methods: first check "old" style methods; note that | 1344 | err = atk_probe_if(data); |
1159 | * both may be present: in this case we stick to the old interface; | 1345 | if (err) { |
1160 | * analysis of multiple DSDTs indicates that when both interfaces | 1346 | dev_err(&device->dev, "No usable hwmon interface detected\n"); |
1161 | * are present the new one (GGRP/GITM) is not functional. | 1347 | goto out; |
1162 | */ | ||
1163 | err = atk_check_old_if(data); | ||
1164 | if (!err) { | ||
1165 | dev_dbg(&device->dev, "Using old hwmon interface\n"); | ||
1166 | data->old_interface = true; | ||
1167 | } else { | ||
1168 | err = atk_check_new_if(data); | ||
1169 | if (err) | ||
1170 | goto out; | ||
1171 | |||
1172 | dev_dbg(&device->dev, "Using new hwmon interface\n"); | ||
1173 | data->old_interface = false; | ||
1174 | } | 1348 | } |
1175 | 1349 | ||
1176 | if (data->old_interface) | 1350 | if (data->old_interface) { |
1351 | dev_dbg(&device->dev, "Using old hwmon interface\n"); | ||
1177 | err = atk_enumerate_old_hwmon(data); | 1352 | err = atk_enumerate_old_hwmon(data); |
1178 | else | 1353 | } else { |
1354 | dev_dbg(&device->dev, "Using new hwmon interface\n"); | ||
1179 | err = atk_enumerate_new_hwmon(data); | 1355 | err = atk_enumerate_new_hwmon(data); |
1356 | } | ||
1180 | if (err < 0) | 1357 | if (err < 0) |
1181 | goto out; | 1358 | goto out; |
1182 | if (err == 0) { | 1359 | if (err == 0) { |
@@ -1190,6 +1367,8 @@ static int atk_add(struct acpi_device *device) | |||
1190 | if (err) | 1367 | if (err) |
1191 | goto cleanup; | 1368 | goto cleanup; |
1192 | 1369 | ||
1370 | atk_debugfs_init(data); | ||
1371 | |||
1193 | device->driver_data = data; | 1372 | device->driver_data = data; |
1194 | return 0; | 1373 | return 0; |
1195 | cleanup: | 1374 | cleanup: |
@@ -1208,6 +1387,8 @@ static int atk_remove(struct acpi_device *device, int type) | |||
1208 | 1387 | ||
1209 | device->driver_data = NULL; | 1388 | device->driver_data = NULL; |
1210 | 1389 | ||
1390 | atk_debugfs_cleanup(data); | ||
1391 | |||
1211 | atk_remove_files(data); | 1392 | atk_remove_files(data); |
1212 | atk_free_sensors(data); | 1393 | atk_free_sensors(data); |
1213 | hwmon_device_unregister(data->hwmon_dev); | 1394 | hwmon_device_unregister(data->hwmon_dev); |
diff --git a/drivers/hwmon/coretemp.c b/drivers/hwmon/coretemp.c index caef39cda8c8..2d7bceeed0bc 100644 --- a/drivers/hwmon/coretemp.c +++ b/drivers/hwmon/coretemp.c | |||
@@ -33,6 +33,7 @@ | |||
33 | #include <linux/list.h> | 33 | #include <linux/list.h> |
34 | #include <linux/platform_device.h> | 34 | #include <linux/platform_device.h> |
35 | #include <linux/cpu.h> | 35 | #include <linux/cpu.h> |
36 | #include <linux/pci.h> | ||
36 | #include <asm/msr.h> | 37 | #include <asm/msr.h> |
37 | #include <asm/processor.h> | 38 | #include <asm/processor.h> |
38 | 39 | ||
@@ -161,6 +162,7 @@ static int __devinit adjust_tjmax(struct cpuinfo_x86 *c, u32 id, struct device * | |||
161 | int usemsr_ee = 1; | 162 | int usemsr_ee = 1; |
162 | int err; | 163 | int err; |
163 | u32 eax, edx; | 164 | u32 eax, edx; |
165 | struct pci_dev *host_bridge; | ||
164 | 166 | ||
165 | /* Early chips have no MSR for TjMax */ | 167 | /* Early chips have no MSR for TjMax */ |
166 | 168 | ||
@@ -168,11 +170,21 @@ static int __devinit adjust_tjmax(struct cpuinfo_x86 *c, u32 id, struct device * | |||
168 | usemsr_ee = 0; | 170 | usemsr_ee = 0; |
169 | } | 171 | } |
170 | 172 | ||
171 | /* Atoms seems to have TjMax at 90C */ | 173 | /* Atom CPUs */ |
172 | 174 | ||
173 | if (c->x86_model == 0x1c) { | 175 | if (c->x86_model == 0x1c) { |
174 | usemsr_ee = 0; | 176 | usemsr_ee = 0; |
175 | tjmax = 90000; | 177 | |
178 | host_bridge = pci_get_bus_and_slot(0, PCI_DEVFN(0, 0)); | ||
179 | |||
180 | if (host_bridge && host_bridge->vendor == PCI_VENDOR_ID_INTEL | ||
181 | && (host_bridge->device == 0xa000 /* NM10 based nettop */ | ||
182 | || host_bridge->device == 0xa010)) /* NM10 based netbook */ | ||
183 | tjmax = 100000; | ||
184 | else | ||
185 | tjmax = 90000; | ||
186 | |||
187 | pci_dev_put(host_bridge); | ||
176 | } | 188 | } |
177 | 189 | ||
178 | if ((c->x86_model > 0xe) && (usemsr_ee)) { | 190 | if ((c->x86_model > 0xe) && (usemsr_ee)) { |
diff --git a/drivers/hwmon/k10temp.c b/drivers/hwmon/k10temp.c index d8a26d16d948..099a2138cdf6 100644 --- a/drivers/hwmon/k10temp.c +++ b/drivers/hwmon/k10temp.c | |||
@@ -33,6 +33,16 @@ static bool force; | |||
33 | module_param(force, bool, 0444); | 33 | module_param(force, bool, 0444); |
34 | MODULE_PARM_DESC(force, "force loading on processors with erratum 319"); | 34 | MODULE_PARM_DESC(force, "force loading on processors with erratum 319"); |
35 | 35 | ||
36 | /* CPUID function 0x80000001, ebx */ | ||
37 | #define CPUID_PKGTYPE_MASK 0xf0000000 | ||
38 | #define CPUID_PKGTYPE_F 0x00000000 | ||
39 | #define CPUID_PKGTYPE_AM2R2_AM3 0x10000000 | ||
40 | |||
41 | /* DRAM controller (PCI function 2) */ | ||
42 | #define REG_DCT0_CONFIG_HIGH 0x094 | ||
43 | #define DDR3_MODE 0x00000100 | ||
44 | |||
45 | /* miscellaneous (PCI function 3) */ | ||
36 | #define REG_HARDWARE_THERMAL_CONTROL 0x64 | 46 | #define REG_HARDWARE_THERMAL_CONTROL 0x64 |
37 | #define HTC_ENABLE 0x00000001 | 47 | #define HTC_ENABLE 0x00000001 |
38 | 48 | ||
@@ -85,13 +95,28 @@ static SENSOR_DEVICE_ATTR(temp1_crit, S_IRUGO, show_temp_crit, NULL, 0); | |||
85 | static SENSOR_DEVICE_ATTR(temp1_crit_hyst, S_IRUGO, show_temp_crit, NULL, 1); | 95 | static SENSOR_DEVICE_ATTR(temp1_crit_hyst, S_IRUGO, show_temp_crit, NULL, 1); |
86 | static DEVICE_ATTR(name, S_IRUGO, show_name, NULL); | 96 | static DEVICE_ATTR(name, S_IRUGO, show_name, NULL); |
87 | 97 | ||
88 | static bool __devinit has_erratum_319(void) | 98 | static bool __devinit has_erratum_319(struct pci_dev *pdev) |
89 | { | 99 | { |
100 | u32 pkg_type, reg_dram_cfg; | ||
101 | |||
102 | if (boot_cpu_data.x86 != 0x10) | ||
103 | return false; | ||
104 | |||
90 | /* | 105 | /* |
91 | * Erratum 319: The thermal sensor of older Family 10h processors | 106 | * Erratum 319: The thermal sensor of Socket F/AM2+ processors |
92 | * (B steppings) may be unreliable. | 107 | * may be unreliable. |
93 | */ | 108 | */ |
94 | return boot_cpu_data.x86 == 0x10 && boot_cpu_data.x86_model <= 2; | 109 | pkg_type = cpuid_ebx(0x80000001) & CPUID_PKGTYPE_MASK; |
110 | if (pkg_type == CPUID_PKGTYPE_F) | ||
111 | return true; | ||
112 | if (pkg_type != CPUID_PKGTYPE_AM2R2_AM3) | ||
113 | return false; | ||
114 | |||
115 | /* Differentiate between AM2+ (bad) and AM3 (good) */ | ||
116 | pci_bus_read_config_dword(pdev->bus, | ||
117 | PCI_DEVFN(PCI_SLOT(pdev->devfn), 2), | ||
118 | REG_DCT0_CONFIG_HIGH, ®_dram_cfg); | ||
119 | return !(reg_dram_cfg & DDR3_MODE); | ||
95 | } | 120 | } |
96 | 121 | ||
97 | static int __devinit k10temp_probe(struct pci_dev *pdev, | 122 | static int __devinit k10temp_probe(struct pci_dev *pdev, |
@@ -99,9 +124,10 @@ static int __devinit k10temp_probe(struct pci_dev *pdev, | |||
99 | { | 124 | { |
100 | struct device *hwmon_dev; | 125 | struct device *hwmon_dev; |
101 | u32 reg_caps, reg_htc; | 126 | u32 reg_caps, reg_htc; |
127 | int unreliable = has_erratum_319(pdev); | ||
102 | int err; | 128 | int err; |
103 | 129 | ||
104 | if (has_erratum_319() && !force) { | 130 | if (unreliable && !force) { |
105 | dev_err(&pdev->dev, | 131 | dev_err(&pdev->dev, |
106 | "unreliable CPU thermal sensor; monitoring disabled\n"); | 132 | "unreliable CPU thermal sensor; monitoring disabled\n"); |
107 | err = -ENODEV; | 133 | err = -ENODEV; |
@@ -139,7 +165,7 @@ static int __devinit k10temp_probe(struct pci_dev *pdev, | |||
139 | } | 165 | } |
140 | dev_set_drvdata(&pdev->dev, hwmon_dev); | 166 | dev_set_drvdata(&pdev->dev, hwmon_dev); |
141 | 167 | ||
142 | if (has_erratum_319() && force) | 168 | if (unreliable && force) |
143 | dev_warn(&pdev->dev, | 169 | dev_warn(&pdev->dev, |
144 | "unreliable CPU thermal sensor; check erratum 319\n"); | 170 | "unreliable CPU thermal sensor; check erratum 319\n"); |
145 | return 0; | 171 | return 0; |
@@ -169,7 +195,7 @@ static void __devexit k10temp_remove(struct pci_dev *pdev) | |||
169 | dev_set_drvdata(&pdev->dev, NULL); | 195 | dev_set_drvdata(&pdev->dev, NULL); |
170 | } | 196 | } |
171 | 197 | ||
172 | static struct pci_device_id k10temp_id_table[] = { | 198 | static const struct pci_device_id k10temp_id_table[] = { |
173 | { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_10H_NB_MISC) }, | 199 | { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_10H_NB_MISC) }, |
174 | { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_11H_NB_MISC) }, | 200 | { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_11H_NB_MISC) }, |
175 | {} | 201 | {} |
diff --git a/drivers/hwmon/k8temp.c b/drivers/hwmon/k8temp.c index 1fe995111841..0ceb6d6200a3 100644 --- a/drivers/hwmon/k8temp.c +++ b/drivers/hwmon/k8temp.c | |||
@@ -136,7 +136,7 @@ static SENSOR_DEVICE_ATTR_2(temp3_input, S_IRUGO, show_temp, NULL, 1, 0); | |||
136 | static SENSOR_DEVICE_ATTR_2(temp4_input, S_IRUGO, show_temp, NULL, 1, 1); | 136 | static SENSOR_DEVICE_ATTR_2(temp4_input, S_IRUGO, show_temp, NULL, 1, 1); |
137 | static DEVICE_ATTR(name, S_IRUGO, show_name, NULL); | 137 | static DEVICE_ATTR(name, S_IRUGO, show_name, NULL); |
138 | 138 | ||
139 | static struct pci_device_id k8temp_ids[] = { | 139 | static const struct pci_device_id k8temp_ids[] = { |
140 | { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_K8_NB_MISC) }, | 140 | { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_K8_NB_MISC) }, |
141 | { 0 }, | 141 | { 0 }, |
142 | }; | 142 | }; |
diff --git a/drivers/hwmon/sis5595.c b/drivers/hwmon/sis5595.c index 12f2e7086560..79c2931e3008 100644 --- a/drivers/hwmon/sis5595.c +++ b/drivers/hwmon/sis5595.c | |||
@@ -697,7 +697,7 @@ static struct sis5595_data *sis5595_update_device(struct device *dev) | |||
697 | return data; | 697 | return data; |
698 | } | 698 | } |
699 | 699 | ||
700 | static struct pci_device_id sis5595_pci_ids[] = { | 700 | static const struct pci_device_id sis5595_pci_ids[] = { |
701 | { PCI_DEVICE(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_503) }, | 701 | { PCI_DEVICE(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_503) }, |
702 | { 0, } | 702 | { 0, } |
703 | }; | 703 | }; |
diff --git a/drivers/hwmon/via686a.c b/drivers/hwmon/via686a.c index 39e82a492f26..f397ce7ad598 100644 --- a/drivers/hwmon/via686a.c +++ b/drivers/hwmon/via686a.c | |||
@@ -767,7 +767,7 @@ static struct via686a_data *via686a_update_device(struct device *dev) | |||
767 | return data; | 767 | return data; |
768 | } | 768 | } |
769 | 769 | ||
770 | static struct pci_device_id via686a_pci_ids[] = { | 770 | static const struct pci_device_id via686a_pci_ids[] = { |
771 | { PCI_DEVICE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686_4) }, | 771 | { PCI_DEVICE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686_4) }, |
772 | { 0, } | 772 | { 0, } |
773 | }; | 773 | }; |
diff --git a/drivers/hwmon/vt8231.c b/drivers/hwmon/vt8231.c index 470a1226ba2b..d47b4c9949c2 100644 --- a/drivers/hwmon/vt8231.c +++ b/drivers/hwmon/vt8231.c | |||
@@ -697,7 +697,7 @@ static struct platform_driver vt8231_driver = { | |||
697 | .remove = __devexit_p(vt8231_remove), | 697 | .remove = __devexit_p(vt8231_remove), |
698 | }; | 698 | }; |
699 | 699 | ||
700 | static struct pci_device_id vt8231_pci_ids[] = { | 700 | static const struct pci_device_id vt8231_pci_ids[] = { |
701 | { PCI_DEVICE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8231_4) }, | 701 | { PCI_DEVICE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8231_4) }, |
702 | { 0, } | 702 | { 0, } |
703 | }; | 703 | }; |
diff --git a/drivers/i2c/busses/i2c-ali1563.c b/drivers/i2c/busses/i2c-ali1563.c index f70f46582c6c..4687af40dd50 100644 --- a/drivers/i2c/busses/i2c-ali1563.c +++ b/drivers/i2c/busses/i2c-ali1563.c | |||
@@ -87,9 +87,9 @@ static int ali1563_transaction(struct i2c_adapter * a, int size) | |||
87 | outb_p(inb_p(SMB_HST_CNTL2) | HST_CNTL2_START, SMB_HST_CNTL2); | 87 | outb_p(inb_p(SMB_HST_CNTL2) | HST_CNTL2_START, SMB_HST_CNTL2); |
88 | 88 | ||
89 | timeout = ALI1563_MAX_TIMEOUT; | 89 | timeout = ALI1563_MAX_TIMEOUT; |
90 | do | 90 | do { |
91 | msleep(1); | 91 | msleep(1); |
92 | while (((data = inb_p(SMB_HST_STS)) & HST_STS_BUSY) && --timeout); | 92 | } while (((data = inb_p(SMB_HST_STS)) & HST_STS_BUSY) && --timeout); |
93 | 93 | ||
94 | dev_dbg(&a->dev, "Transaction (post): STS=%02x, CNTL1=%02x, " | 94 | dev_dbg(&a->dev, "Transaction (post): STS=%02x, CNTL1=%02x, " |
95 | "CNTL2=%02x, CMD=%02x, ADD=%02x, DAT0=%02x, DAT1=%02x\n", | 95 | "CNTL2=%02x, CMD=%02x, ADD=%02x, DAT0=%02x, DAT1=%02x\n", |
@@ -157,9 +157,9 @@ static int ali1563_block_start(struct i2c_adapter * a) | |||
157 | outb_p(inb_p(SMB_HST_CNTL2) | HST_CNTL2_START, SMB_HST_CNTL2); | 157 | outb_p(inb_p(SMB_HST_CNTL2) | HST_CNTL2_START, SMB_HST_CNTL2); |
158 | 158 | ||
159 | timeout = ALI1563_MAX_TIMEOUT; | 159 | timeout = ALI1563_MAX_TIMEOUT; |
160 | do | 160 | do { |
161 | msleep(1); | 161 | msleep(1); |
162 | while (!((data = inb_p(SMB_HST_STS)) & HST_STS_DONE) && --timeout); | 162 | } while (!((data = inb_p(SMB_HST_STS)) & HST_STS_DONE) && --timeout); |
163 | 163 | ||
164 | dev_dbg(&a->dev, "Block (post): STS=%02x, CNTL1=%02x, " | 164 | dev_dbg(&a->dev, "Block (post): STS=%02x, CNTL1=%02x, " |
165 | "CNTL2=%02x, CMD=%02x, ADD=%02x, DAT0=%02x, DAT1=%02x\n", | 165 | "CNTL2=%02x, CMD=%02x, ADD=%02x, DAT0=%02x, DAT1=%02x\n", |
diff --git a/drivers/i2c/busses/i2c-pca-isa.c b/drivers/i2c/busses/i2c-pca-isa.c index 0ed68e2ccd22..f7346a9bd95f 100644 --- a/drivers/i2c/busses/i2c-pca-isa.c +++ b/drivers/i2c/busses/i2c-pca-isa.c | |||
@@ -75,7 +75,7 @@ static int pca_isa_waitforcompletion(void *pd) | |||
75 | unsigned long timeout; | 75 | unsigned long timeout; |
76 | 76 | ||
77 | if (irq > -1) { | 77 | if (irq > -1) { |
78 | ret = wait_event_interruptible_timeout(pca_wait, | 78 | ret = wait_event_timeout(pca_wait, |
79 | pca_isa_readbyte(pd, I2C_PCA_CON) | 79 | pca_isa_readbyte(pd, I2C_PCA_CON) |
80 | & I2C_PCA_CON_SI, pca_isa_ops.timeout); | 80 | & I2C_PCA_CON_SI, pca_isa_ops.timeout); |
81 | } else { | 81 | } else { |
@@ -96,7 +96,7 @@ static void pca_isa_resetchip(void *pd) | |||
96 | } | 96 | } |
97 | 97 | ||
98 | static irqreturn_t pca_handler(int this_irq, void *dev_id) { | 98 | static irqreturn_t pca_handler(int this_irq, void *dev_id) { |
99 | wake_up_interruptible(&pca_wait); | 99 | wake_up(&pca_wait); |
100 | return IRQ_HANDLED; | 100 | return IRQ_HANDLED; |
101 | } | 101 | } |
102 | 102 | ||
diff --git a/drivers/i2c/busses/i2c-pca-platform.c b/drivers/i2c/busses/i2c-pca-platform.c index c4df9d411cd5..5b2213df5ed0 100644 --- a/drivers/i2c/busses/i2c-pca-platform.c +++ b/drivers/i2c/busses/i2c-pca-platform.c | |||
@@ -84,7 +84,7 @@ static int i2c_pca_pf_waitforcompletion(void *pd) | |||
84 | unsigned long timeout; | 84 | unsigned long timeout; |
85 | 85 | ||
86 | if (i2c->irq) { | 86 | if (i2c->irq) { |
87 | ret = wait_event_interruptible_timeout(i2c->wait, | 87 | ret = wait_event_timeout(i2c->wait, |
88 | i2c->algo_data.read_byte(i2c, I2C_PCA_CON) | 88 | i2c->algo_data.read_byte(i2c, I2C_PCA_CON) |
89 | & I2C_PCA_CON_SI, i2c->adap.timeout); | 89 | & I2C_PCA_CON_SI, i2c->adap.timeout); |
90 | } else { | 90 | } else { |
@@ -122,7 +122,7 @@ static irqreturn_t i2c_pca_pf_handler(int this_irq, void *dev_id) | |||
122 | if ((i2c->algo_data.read_byte(i2c, I2C_PCA_CON) & I2C_PCA_CON_SI) == 0) | 122 | if ((i2c->algo_data.read_byte(i2c, I2C_PCA_CON) & I2C_PCA_CON_SI) == 0) |
123 | return IRQ_NONE; | 123 | return IRQ_NONE; |
124 | 124 | ||
125 | wake_up_interruptible(&i2c->wait); | 125 | wake_up(&i2c->wait); |
126 | 126 | ||
127 | return IRQ_HANDLED; | 127 | return IRQ_HANDLED; |
128 | } | 128 | } |
diff --git a/drivers/i2c/busses/i2c-piix4.c b/drivers/i2c/busses/i2c-piix4.c index 1e245e9cad31..e56e4b6823ca 100644 --- a/drivers/i2c/busses/i2c-piix4.c +++ b/drivers/i2c/busses/i2c-piix4.c | |||
@@ -324,12 +324,12 @@ static int piix4_transaction(void) | |||
324 | else | 324 | else |
325 | msleep(1); | 325 | msleep(1); |
326 | 326 | ||
327 | while ((timeout++ < MAX_TIMEOUT) && | 327 | while ((++timeout < MAX_TIMEOUT) && |
328 | ((temp = inb_p(SMBHSTSTS)) & 0x01)) | 328 | ((temp = inb_p(SMBHSTSTS)) & 0x01)) |
329 | msleep(1); | 329 | msleep(1); |
330 | 330 | ||
331 | /* If the SMBus is still busy, we give up */ | 331 | /* If the SMBus is still busy, we give up */ |
332 | if (timeout >= MAX_TIMEOUT) { | 332 | if (timeout == MAX_TIMEOUT) { |
333 | dev_err(&piix4_adapter.dev, "SMBus Timeout!\n"); | 333 | dev_err(&piix4_adapter.dev, "SMBus Timeout!\n"); |
334 | result = -ETIMEDOUT; | 334 | result = -ETIMEDOUT; |
335 | } | 335 | } |
diff --git a/drivers/i2c/busses/i2c-viapro.c b/drivers/i2c/busses/i2c-viapro.c index e4b1543015af..a84a909e1234 100644 --- a/drivers/i2c/busses/i2c-viapro.c +++ b/drivers/i2c/busses/i2c-viapro.c | |||
@@ -165,10 +165,10 @@ static int vt596_transaction(u8 size) | |||
165 | do { | 165 | do { |
166 | msleep(1); | 166 | msleep(1); |
167 | temp = inb_p(SMBHSTSTS); | 167 | temp = inb_p(SMBHSTSTS); |
168 | } while ((temp & 0x01) && (timeout++ < MAX_TIMEOUT)); | 168 | } while ((temp & 0x01) && (++timeout < MAX_TIMEOUT)); |
169 | 169 | ||
170 | /* If the SMBus is still busy, we give up */ | 170 | /* If the SMBus is still busy, we give up */ |
171 | if (timeout >= MAX_TIMEOUT) { | 171 | if (timeout == MAX_TIMEOUT) { |
172 | result = -ETIMEDOUT; | 172 | result = -ETIMEDOUT; |
173 | dev_err(&vt596_adapter.dev, "SMBus timeout!\n"); | 173 | dev_err(&vt596_adapter.dev, "SMBus timeout!\n"); |
174 | } | 174 | } |
diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c index 0ac2f90ab840..10be7b5fbe97 100644 --- a/drivers/i2c/i2c-core.c +++ b/drivers/i2c/i2c-core.c | |||
@@ -248,7 +248,7 @@ static const struct attribute_group *i2c_dev_attr_groups[] = { | |||
248 | NULL | 248 | NULL |
249 | }; | 249 | }; |
250 | 250 | ||
251 | const static struct dev_pm_ops i2c_device_pm_ops = { | 251 | static const struct dev_pm_ops i2c_device_pm_ops = { |
252 | .suspend = i2c_device_pm_suspend, | 252 | .suspend = i2c_device_pm_suspend, |
253 | .resume = i2c_device_pm_resume, | 253 | .resume = i2c_device_pm_resume, |
254 | }; | 254 | }; |
@@ -843,6 +843,9 @@ int i2c_del_adapter(struct i2c_adapter *adap) | |||
843 | adap->dev.parent); | 843 | adap->dev.parent); |
844 | #endif | 844 | #endif |
845 | 845 | ||
846 | /* device name is gone after device_unregister */ | ||
847 | dev_dbg(&adap->dev, "adapter [%s] unregistered\n", adap->name); | ||
848 | |||
846 | /* clean up the sysfs representation */ | 849 | /* clean up the sysfs representation */ |
847 | init_completion(&adap->dev_released); | 850 | init_completion(&adap->dev_released); |
848 | device_unregister(&adap->dev); | 851 | device_unregister(&adap->dev); |
@@ -855,8 +858,6 @@ int i2c_del_adapter(struct i2c_adapter *adap) | |||
855 | idr_remove(&i2c_adapter_idr, adap->nr); | 858 | idr_remove(&i2c_adapter_idr, adap->nr); |
856 | mutex_unlock(&core_lock); | 859 | mutex_unlock(&core_lock); |
857 | 860 | ||
858 | dev_dbg(&adap->dev, "adapter [%s] unregistered\n", adap->name); | ||
859 | |||
860 | /* Clear the device structure in case this adapter is ever going to be | 861 | /* Clear the device structure in case this adapter is ever going to be |
861 | added again */ | 862 | added again */ |
862 | memset(&adap->dev, 0, sizeof(adap->dev)); | 863 | memset(&adap->dev, 0, sizeof(adap->dev)); |
diff --git a/drivers/infiniband/core/cma.c b/drivers/infiniband/core/cma.c index fbdd73106000..cc9b5940fa97 100644 --- a/drivers/infiniband/core/cma.c +++ b/drivers/infiniband/core/cma.c | |||
@@ -2083,7 +2083,7 @@ static int cma_get_port(struct rdma_id_private *id_priv) | |||
2083 | static int cma_check_linklocal(struct rdma_dev_addr *dev_addr, | 2083 | static int cma_check_linklocal(struct rdma_dev_addr *dev_addr, |
2084 | struct sockaddr *addr) | 2084 | struct sockaddr *addr) |
2085 | { | 2085 | { |
2086 | #if defined(CONFIG_IPv6) || defined(CONFIG_IPV6_MODULE) | 2086 | #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) |
2087 | struct sockaddr_in6 *sin6; | 2087 | struct sockaddr_in6 *sin6; |
2088 | 2088 | ||
2089 | if (addr->sa_family != AF_INET6) | 2089 | if (addr->sa_family != AF_INET6) |
diff --git a/drivers/infiniband/hw/mlx4/qp.c b/drivers/infiniband/hw/mlx4/qp.c index 989555cee883..2a97c964b9ef 100644 --- a/drivers/infiniband/hw/mlx4/qp.c +++ b/drivers/infiniband/hw/mlx4/qp.c | |||
@@ -1752,7 +1752,7 @@ int mlx4_ib_post_recv(struct ib_qp *ibqp, struct ib_recv_wr *wr, | |||
1752 | ind = qp->rq.head & (qp->rq.wqe_cnt - 1); | 1752 | ind = qp->rq.head & (qp->rq.wqe_cnt - 1); |
1753 | 1753 | ||
1754 | for (nreq = 0; wr; ++nreq, wr = wr->next) { | 1754 | for (nreq = 0; wr; ++nreq, wr = wr->next) { |
1755 | if (mlx4_wq_overflow(&qp->rq, nreq, qp->ibqp.send_cq)) { | 1755 | if (mlx4_wq_overflow(&qp->rq, nreq, qp->ibqp.recv_cq)) { |
1756 | err = -ENOMEM; | 1756 | err = -ENOMEM; |
1757 | *bad_wr = wr; | 1757 | *bad_wr = wr; |
1758 | goto out; | 1758 | goto out; |
diff --git a/drivers/infiniband/hw/mlx4/srq.c b/drivers/infiniband/hw/mlx4/srq.c index d42565258fb7..cf8085bcbd6d 100644 --- a/drivers/infiniband/hw/mlx4/srq.c +++ b/drivers/infiniband/hw/mlx4/srq.c | |||
@@ -74,6 +74,7 @@ struct ib_srq *mlx4_ib_create_srq(struct ib_pd *pd, | |||
74 | struct mlx4_ib_dev *dev = to_mdev(pd->device); | 74 | struct mlx4_ib_dev *dev = to_mdev(pd->device); |
75 | struct mlx4_ib_srq *srq; | 75 | struct mlx4_ib_srq *srq; |
76 | struct mlx4_wqe_srq_next_seg *next; | 76 | struct mlx4_wqe_srq_next_seg *next; |
77 | struct mlx4_wqe_data_seg *scatter; | ||
77 | int desc_size; | 78 | int desc_size; |
78 | int buf_size; | 79 | int buf_size; |
79 | int err; | 80 | int err; |
@@ -149,6 +150,11 @@ struct ib_srq *mlx4_ib_create_srq(struct ib_pd *pd, | |||
149 | next = get_wqe(srq, i); | 150 | next = get_wqe(srq, i); |
150 | next->next_wqe_index = | 151 | next->next_wqe_index = |
151 | cpu_to_be16((i + 1) & (srq->msrq.max - 1)); | 152 | cpu_to_be16((i + 1) & (srq->msrq.max - 1)); |
153 | |||
154 | for (scatter = (void *) (next + 1); | ||
155 | (void *) scatter < (void *) next + desc_size; | ||
156 | ++scatter) | ||
157 | scatter->lkey = cpu_to_be32(MLX4_INVALID_LKEY); | ||
152 | } | 158 | } |
153 | 159 | ||
154 | err = mlx4_mtt_init(dev->dev, srq->buf.npages, srq->buf.page_shift, | 160 | err = mlx4_mtt_init(dev->dev, srq->buf.npages, srq->buf.page_shift, |
diff --git a/drivers/input/evdev.c b/drivers/input/evdev.c index dee6706038aa..258c639571b5 100644 --- a/drivers/input/evdev.c +++ b/drivers/input/evdev.c | |||
@@ -59,7 +59,8 @@ static void evdev_pass_event(struct evdev_client *client, | |||
59 | client->head &= EVDEV_BUFFER_SIZE - 1; | 59 | client->head &= EVDEV_BUFFER_SIZE - 1; |
60 | spin_unlock(&client->buffer_lock); | 60 | spin_unlock(&client->buffer_lock); |
61 | 61 | ||
62 | kill_fasync(&client->fasync, SIGIO, POLL_IN); | 62 | if (event->type == EV_SYN) |
63 | kill_fasync(&client->fasync, SIGIO, POLL_IN); | ||
63 | } | 64 | } |
64 | 65 | ||
65 | /* | 66 | /* |
diff --git a/drivers/input/input.c b/drivers/input/input.c index ab060710688f..30b503b8d67b 100644 --- a/drivers/input/input.c +++ b/drivers/input/input.c | |||
@@ -24,6 +24,7 @@ | |||
24 | #include <linux/mutex.h> | 24 | #include <linux/mutex.h> |
25 | #include <linux/rcupdate.h> | 25 | #include <linux/rcupdate.h> |
26 | #include <linux/smp_lock.h> | 26 | #include <linux/smp_lock.h> |
27 | #include "input-compat.h" | ||
27 | 28 | ||
28 | MODULE_AUTHOR("Vojtech Pavlik <vojtech@suse.cz>"); | 29 | MODULE_AUTHOR("Vojtech Pavlik <vojtech@suse.cz>"); |
29 | MODULE_DESCRIPTION("Input core"); | 30 | MODULE_DESCRIPTION("Input core"); |
@@ -764,6 +765,40 @@ static int input_attach_handler(struct input_dev *dev, struct input_handler *han | |||
764 | return error; | 765 | return error; |
765 | } | 766 | } |
766 | 767 | ||
768 | #ifdef CONFIG_COMPAT | ||
769 | |||
770 | static int input_bits_to_string(char *buf, int buf_size, | ||
771 | unsigned long bits, bool skip_empty) | ||
772 | { | ||
773 | int len = 0; | ||
774 | |||
775 | if (INPUT_COMPAT_TEST) { | ||
776 | u32 dword = bits >> 32; | ||
777 | if (dword || !skip_empty) | ||
778 | len += snprintf(buf, buf_size, "%x ", dword); | ||
779 | |||
780 | dword = bits & 0xffffffffUL; | ||
781 | if (dword || !skip_empty || len) | ||
782 | len += snprintf(buf + len, max(buf_size - len, 0), | ||
783 | "%x", dword); | ||
784 | } else { | ||
785 | if (bits || !skip_empty) | ||
786 | len += snprintf(buf, buf_size, "%lx", bits); | ||
787 | } | ||
788 | |||
789 | return len; | ||
790 | } | ||
791 | |||
792 | #else /* !CONFIG_COMPAT */ | ||
793 | |||
794 | static int input_bits_to_string(char *buf, int buf_size, | ||
795 | unsigned long bits, bool skip_empty) | ||
796 | { | ||
797 | return bits || !skip_empty ? | ||
798 | snprintf(buf, buf_size, "%lx", bits) : 0; | ||
799 | } | ||
800 | |||
801 | #endif | ||
767 | 802 | ||
768 | #ifdef CONFIG_PROC_FS | 803 | #ifdef CONFIG_PROC_FS |
769 | 804 | ||
@@ -832,14 +867,25 @@ static void input_seq_print_bitmap(struct seq_file *seq, const char *name, | |||
832 | unsigned long *bitmap, int max) | 867 | unsigned long *bitmap, int max) |
833 | { | 868 | { |
834 | int i; | 869 | int i; |
835 | 870 | bool skip_empty = true; | |
836 | for (i = BITS_TO_LONGS(max) - 1; i > 0; i--) | 871 | char buf[18]; |
837 | if (bitmap[i]) | ||
838 | break; | ||
839 | 872 | ||
840 | seq_printf(seq, "B: %s=", name); | 873 | seq_printf(seq, "B: %s=", name); |
841 | for (; i >= 0; i--) | 874 | |
842 | seq_printf(seq, "%lx%s", bitmap[i], i > 0 ? " " : ""); | 875 | for (i = BITS_TO_LONGS(max) - 1; i >= 0; i--) { |
876 | if (input_bits_to_string(buf, sizeof(buf), | ||
877 | bitmap[i], skip_empty)) { | ||
878 | skip_empty = false; | ||
879 | seq_printf(seq, "%s%s", buf, i > 0 ? " " : ""); | ||
880 | } | ||
881 | } | ||
882 | |||
883 | /* | ||
884 | * If no output was produced print a single 0. | ||
885 | */ | ||
886 | if (skip_empty) | ||
887 | seq_puts(seq, "0"); | ||
888 | |||
843 | seq_putc(seq, '\n'); | 889 | seq_putc(seq, '\n'); |
844 | } | 890 | } |
845 | 891 | ||
@@ -1128,14 +1174,23 @@ static int input_print_bitmap(char *buf, int buf_size, unsigned long *bitmap, | |||
1128 | { | 1174 | { |
1129 | int i; | 1175 | int i; |
1130 | int len = 0; | 1176 | int len = 0; |
1177 | bool skip_empty = true; | ||
1178 | |||
1179 | for (i = BITS_TO_LONGS(max) - 1; i >= 0; i--) { | ||
1180 | len += input_bits_to_string(buf + len, max(buf_size - len, 0), | ||
1181 | bitmap[i], skip_empty); | ||
1182 | if (len) { | ||
1183 | skip_empty = false; | ||
1184 | if (i > 0) | ||
1185 | len += snprintf(buf + len, max(buf_size - len, 0), " "); | ||
1186 | } | ||
1187 | } | ||
1131 | 1188 | ||
1132 | for (i = BITS_TO_LONGS(max) - 1; i > 0; i--) | 1189 | /* |
1133 | if (bitmap[i]) | 1190 | * If no output was produced print a single 0. |
1134 | break; | 1191 | */ |
1135 | 1192 | if (len == 0) | |
1136 | for (; i >= 0; i--) | 1193 | len = snprintf(buf, buf_size, "%d", 0); |
1137 | len += snprintf(buf + len, max(buf_size - len, 0), | ||
1138 | "%lx%s", bitmap[i], i > 0 ? " " : ""); | ||
1139 | 1194 | ||
1140 | if (add_cr) | 1195 | if (add_cr) |
1141 | len += snprintf(buf + len, max(buf_size - len, 0), "\n"); | 1196 | len += snprintf(buf + len, max(buf_size - len, 0), "\n"); |
@@ -1150,7 +1205,8 @@ static ssize_t input_dev_show_cap_##bm(struct device *dev, \ | |||
1150 | { \ | 1205 | { \ |
1151 | struct input_dev *input_dev = to_input_dev(dev); \ | 1206 | struct input_dev *input_dev = to_input_dev(dev); \ |
1152 | int len = input_print_bitmap(buf, PAGE_SIZE, \ | 1207 | int len = input_print_bitmap(buf, PAGE_SIZE, \ |
1153 | input_dev->bm##bit, ev##_MAX, 1); \ | 1208 | input_dev->bm##bit, ev##_MAX, \ |
1209 | true); \ | ||
1154 | return min_t(int, len, PAGE_SIZE); \ | 1210 | return min_t(int, len, PAGE_SIZE); \ |
1155 | } \ | 1211 | } \ |
1156 | static DEVICE_ATTR(bm, S_IRUGO, input_dev_show_cap_##bm, NULL) | 1212 | static DEVICE_ATTR(bm, S_IRUGO, input_dev_show_cap_##bm, NULL) |
@@ -1214,7 +1270,7 @@ static int input_add_uevent_bm_var(struct kobj_uevent_env *env, | |||
1214 | 1270 | ||
1215 | len = input_print_bitmap(&env->buf[env->buflen - 1], | 1271 | len = input_print_bitmap(&env->buf[env->buflen - 1], |
1216 | sizeof(env->buf) - env->buflen, | 1272 | sizeof(env->buf) - env->buflen, |
1217 | bitmap, max, 0); | 1273 | bitmap, max, false); |
1218 | if (len >= (sizeof(env->buf) - env->buflen)) | 1274 | if (len >= (sizeof(env->buf) - env->buflen)) |
1219 | return -ENOMEM; | 1275 | return -ENOMEM; |
1220 | 1276 | ||
diff --git a/drivers/input/joystick/gf2k.c b/drivers/input/joystick/gf2k.c index 67c207f5b1a1..45ac70eae0aa 100644 --- a/drivers/input/joystick/gf2k.c +++ b/drivers/input/joystick/gf2k.c | |||
@@ -277,7 +277,7 @@ static int gf2k_connect(struct gameport *gameport, struct gameport_driver *drv) | |||
277 | } | 277 | } |
278 | 278 | ||
279 | #ifdef RESET_WORKS | 279 | #ifdef RESET_WORKS |
280 | if ((gf2k->id != (GB(19,2,0) | GB(15,3,2) | GB(12,3,5))) || | 280 | if ((gf2k->id != (GB(19,2,0) | GB(15,3,2) | GB(12,3,5))) && |
281 | (gf2k->id != (GB(31,2,0) | GB(27,3,2) | GB(24,3,5)))) { | 281 | (gf2k->id != (GB(31,2,0) | GB(27,3,2) | GB(24,3,5)))) { |
282 | err = -ENODEV; | 282 | err = -ENODEV; |
283 | goto fail2; | 283 | goto fail2; |
diff --git a/drivers/input/joystick/xpad.c b/drivers/input/joystick/xpad.c index 482cb1204e43..8a28fb7846dc 100644 --- a/drivers/input/joystick/xpad.c +++ b/drivers/input/joystick/xpad.c | |||
@@ -446,7 +446,7 @@ static void xpad_irq_in(struct urb *urb) | |||
446 | } | 446 | } |
447 | 447 | ||
448 | exit: | 448 | exit: |
449 | retval = usb_submit_urb (urb, GFP_ATOMIC); | 449 | retval = usb_submit_urb(urb, GFP_ATOMIC); |
450 | if (retval) | 450 | if (retval) |
451 | err ("%s - usb_submit_urb failed with result %d", | 451 | err ("%s - usb_submit_urb failed with result %d", |
452 | __func__, retval); | 452 | __func__, retval); |
@@ -571,7 +571,7 @@ static int xpad_play_effect(struct input_dev *dev, void *data, | |||
571 | xpad->odata[6] = 0x00; | 571 | xpad->odata[6] = 0x00; |
572 | xpad->odata[7] = 0x00; | 572 | xpad->odata[7] = 0x00; |
573 | xpad->irq_out->transfer_buffer_length = 8; | 573 | xpad->irq_out->transfer_buffer_length = 8; |
574 | usb_submit_urb(xpad->irq_out, GFP_KERNEL); | 574 | usb_submit_urb(xpad->irq_out, GFP_ATOMIC); |
575 | } | 575 | } |
576 | 576 | ||
577 | return 0; | 577 | return 0; |
diff --git a/drivers/input/keyboard/atkbd.c b/drivers/input/keyboard/atkbd.c index 1f5e2ce327d6..7b4056292eaf 100644 --- a/drivers/input/keyboard/atkbd.c +++ b/drivers/input/keyboard/atkbd.c | |||
@@ -225,8 +225,10 @@ struct atkbd { | |||
225 | 225 | ||
226 | struct delayed_work event_work; | 226 | struct delayed_work event_work; |
227 | unsigned long event_jiffies; | 227 | unsigned long event_jiffies; |
228 | struct mutex event_mutex; | ||
229 | unsigned long event_mask; | 228 | unsigned long event_mask; |
229 | |||
230 | /* Serializes reconnect(), attr->set() and event work */ | ||
231 | struct mutex mutex; | ||
230 | }; | 232 | }; |
231 | 233 | ||
232 | /* | 234 | /* |
@@ -577,7 +579,7 @@ static void atkbd_event_work(struct work_struct *work) | |||
577 | { | 579 | { |
578 | struct atkbd *atkbd = container_of(work, struct atkbd, event_work.work); | 580 | struct atkbd *atkbd = container_of(work, struct atkbd, event_work.work); |
579 | 581 | ||
580 | mutex_lock(&atkbd->event_mutex); | 582 | mutex_lock(&atkbd->mutex); |
581 | 583 | ||
582 | if (!atkbd->enabled) { | 584 | if (!atkbd->enabled) { |
583 | /* | 585 | /* |
@@ -596,7 +598,7 @@ static void atkbd_event_work(struct work_struct *work) | |||
596 | atkbd_set_repeat_rate(atkbd); | 598 | atkbd_set_repeat_rate(atkbd); |
597 | } | 599 | } |
598 | 600 | ||
599 | mutex_unlock(&atkbd->event_mutex); | 601 | mutex_unlock(&atkbd->mutex); |
600 | } | 602 | } |
601 | 603 | ||
602 | /* | 604 | /* |
@@ -612,7 +614,7 @@ static void atkbd_schedule_event_work(struct atkbd *atkbd, int event_bit) | |||
612 | 614 | ||
613 | atkbd->event_jiffies = jiffies; | 615 | atkbd->event_jiffies = jiffies; |
614 | set_bit(event_bit, &atkbd->event_mask); | 616 | set_bit(event_bit, &atkbd->event_mask); |
615 | wmb(); | 617 | mb(); |
616 | schedule_delayed_work(&atkbd->event_work, delay); | 618 | schedule_delayed_work(&atkbd->event_work, delay); |
617 | } | 619 | } |
618 | 620 | ||
@@ -849,13 +851,20 @@ static void atkbd_disconnect(struct serio *serio) | |||
849 | { | 851 | { |
850 | struct atkbd *atkbd = serio_get_drvdata(serio); | 852 | struct atkbd *atkbd = serio_get_drvdata(serio); |
851 | 853 | ||
854 | sysfs_remove_group(&serio->dev.kobj, &atkbd_attribute_group); | ||
855 | |||
852 | atkbd_disable(atkbd); | 856 | atkbd_disable(atkbd); |
853 | 857 | ||
854 | /* make sure we don't have a command in flight */ | 858 | input_unregister_device(atkbd->dev); |
859 | |||
860 | /* | ||
861 | * Make sure we don't have a command in flight. | ||
862 | * Note that since atkbd->enabled is false event work will keep | ||
863 | * rescheduling itself until it gets canceled and will not try | ||
864 | * accessing freed input device or serio port. | ||
865 | */ | ||
855 | cancel_delayed_work_sync(&atkbd->event_work); | 866 | cancel_delayed_work_sync(&atkbd->event_work); |
856 | 867 | ||
857 | sysfs_remove_group(&serio->dev.kobj, &atkbd_attribute_group); | ||
858 | input_unregister_device(atkbd->dev); | ||
859 | serio_close(serio); | 868 | serio_close(serio); |
860 | serio_set_drvdata(serio, NULL); | 869 | serio_set_drvdata(serio, NULL); |
861 | kfree(atkbd); | 870 | kfree(atkbd); |
@@ -1087,7 +1096,7 @@ static int atkbd_connect(struct serio *serio, struct serio_driver *drv) | |||
1087 | atkbd->dev = dev; | 1096 | atkbd->dev = dev; |
1088 | ps2_init(&atkbd->ps2dev, serio); | 1097 | ps2_init(&atkbd->ps2dev, serio); |
1089 | INIT_DELAYED_WORK(&atkbd->event_work, atkbd_event_work); | 1098 | INIT_DELAYED_WORK(&atkbd->event_work, atkbd_event_work); |
1090 | mutex_init(&atkbd->event_mutex); | 1099 | mutex_init(&atkbd->mutex); |
1091 | 1100 | ||
1092 | switch (serio->id.type) { | 1101 | switch (serio->id.type) { |
1093 | 1102 | ||
@@ -1160,19 +1169,23 @@ static int atkbd_reconnect(struct serio *serio) | |||
1160 | { | 1169 | { |
1161 | struct atkbd *atkbd = serio_get_drvdata(serio); | 1170 | struct atkbd *atkbd = serio_get_drvdata(serio); |
1162 | struct serio_driver *drv = serio->drv; | 1171 | struct serio_driver *drv = serio->drv; |
1172 | int retval = -1; | ||
1163 | 1173 | ||
1164 | if (!atkbd || !drv) { | 1174 | if (!atkbd || !drv) { |
1165 | printk(KERN_DEBUG "atkbd: reconnect request, but serio is disconnected, ignoring...\n"); | 1175 | printk(KERN_DEBUG "atkbd: reconnect request, but serio is disconnected, ignoring...\n"); |
1166 | return -1; | 1176 | return -1; |
1167 | } | 1177 | } |
1168 | 1178 | ||
1179 | mutex_lock(&atkbd->mutex); | ||
1180 | |||
1169 | atkbd_disable(atkbd); | 1181 | atkbd_disable(atkbd); |
1170 | 1182 | ||
1171 | if (atkbd->write) { | 1183 | if (atkbd->write) { |
1172 | if (atkbd_probe(atkbd)) | 1184 | if (atkbd_probe(atkbd)) |
1173 | return -1; | 1185 | goto out; |
1186 | |||
1174 | if (atkbd->set != atkbd_select_set(atkbd, atkbd->set, atkbd->extra)) | 1187 | if (atkbd->set != atkbd_select_set(atkbd, atkbd->set, atkbd->extra)) |
1175 | return -1; | 1188 | goto out; |
1176 | 1189 | ||
1177 | atkbd_activate(atkbd); | 1190 | atkbd_activate(atkbd); |
1178 | 1191 | ||
@@ -1190,8 +1203,11 @@ static int atkbd_reconnect(struct serio *serio) | |||
1190 | } | 1203 | } |
1191 | 1204 | ||
1192 | atkbd_enable(atkbd); | 1205 | atkbd_enable(atkbd); |
1206 | retval = 0; | ||
1193 | 1207 | ||
1194 | return 0; | 1208 | out: |
1209 | mutex_unlock(&atkbd->mutex); | ||
1210 | return retval; | ||
1195 | } | 1211 | } |
1196 | 1212 | ||
1197 | static struct serio_device_id atkbd_serio_ids[] = { | 1213 | static struct serio_device_id atkbd_serio_ids[] = { |
@@ -1235,47 +1251,28 @@ static ssize_t atkbd_attr_show_helper(struct device *dev, char *buf, | |||
1235 | ssize_t (*handler)(struct atkbd *, char *)) | 1251 | ssize_t (*handler)(struct atkbd *, char *)) |
1236 | { | 1252 | { |
1237 | struct serio *serio = to_serio_port(dev); | 1253 | struct serio *serio = to_serio_port(dev); |
1238 | int retval; | 1254 | struct atkbd *atkbd = serio_get_drvdata(serio); |
1239 | |||
1240 | retval = serio_pin_driver(serio); | ||
1241 | if (retval) | ||
1242 | return retval; | ||
1243 | |||
1244 | if (serio->drv != &atkbd_drv) { | ||
1245 | retval = -ENODEV; | ||
1246 | goto out; | ||
1247 | } | ||
1248 | |||
1249 | retval = handler((struct atkbd *)serio_get_drvdata(serio), buf); | ||
1250 | 1255 | ||
1251 | out: | 1256 | return handler(atkbd, buf); |
1252 | serio_unpin_driver(serio); | ||
1253 | return retval; | ||
1254 | } | 1257 | } |
1255 | 1258 | ||
1256 | static ssize_t atkbd_attr_set_helper(struct device *dev, const char *buf, size_t count, | 1259 | static ssize_t atkbd_attr_set_helper(struct device *dev, const char *buf, size_t count, |
1257 | ssize_t (*handler)(struct atkbd *, const char *, size_t)) | 1260 | ssize_t (*handler)(struct atkbd *, const char *, size_t)) |
1258 | { | 1261 | { |
1259 | struct serio *serio = to_serio_port(dev); | 1262 | struct serio *serio = to_serio_port(dev); |
1260 | struct atkbd *atkbd; | 1263 | struct atkbd *atkbd = serio_get_drvdata(serio); |
1261 | int retval; | 1264 | int retval; |
1262 | 1265 | ||
1263 | retval = serio_pin_driver(serio); | 1266 | retval = mutex_lock_interruptible(&atkbd->mutex); |
1264 | if (retval) | 1267 | if (retval) |
1265 | return retval; | 1268 | return retval; |
1266 | 1269 | ||
1267 | if (serio->drv != &atkbd_drv) { | ||
1268 | retval = -ENODEV; | ||
1269 | goto out; | ||
1270 | } | ||
1271 | |||
1272 | atkbd = serio_get_drvdata(serio); | ||
1273 | atkbd_disable(atkbd); | 1270 | atkbd_disable(atkbd); |
1274 | retval = handler(atkbd, buf, count); | 1271 | retval = handler(atkbd, buf, count); |
1275 | atkbd_enable(atkbd); | 1272 | atkbd_enable(atkbd); |
1276 | 1273 | ||
1277 | out: | 1274 | mutex_unlock(&atkbd->mutex); |
1278 | serio_unpin_driver(serio); | 1275 | |
1279 | return retval; | 1276 | return retval; |
1280 | } | 1277 | } |
1281 | 1278 | ||
diff --git a/drivers/input/keyboard/davinci_keyscan.c b/drivers/input/keyboard/davinci_keyscan.c index 6e52d855f637..d410d7a52f1d 100644 --- a/drivers/input/keyboard/davinci_keyscan.c +++ b/drivers/input/keyboard/davinci_keyscan.c | |||
@@ -174,6 +174,14 @@ static int __init davinci_ks_probe(struct platform_device *pdev) | |||
174 | struct davinci_ks_platform_data *pdata = pdev->dev.platform_data; | 174 | struct davinci_ks_platform_data *pdata = pdev->dev.platform_data; |
175 | int error, i; | 175 | int error, i; |
176 | 176 | ||
177 | if (pdata->device_enable) { | ||
178 | error = pdata->device_enable(dev); | ||
179 | if (error < 0) { | ||
180 | dev_dbg(dev, "device enable function failed\n"); | ||
181 | return error; | ||
182 | } | ||
183 | } | ||
184 | |||
177 | if (!pdata->keymap) { | 185 | if (!pdata->keymap) { |
178 | dev_dbg(dev, "no keymap from pdata\n"); | 186 | dev_dbg(dev, "no keymap from pdata\n"); |
179 | return -EINVAL; | 187 | return -EINVAL; |
diff --git a/drivers/input/mouse/bcm5974.c b/drivers/input/mouse/bcm5974.c index 0d1d33468b43..4f8fe0886b2a 100644 --- a/drivers/input/mouse/bcm5974.c +++ b/drivers/input/mouse/bcm5974.c | |||
@@ -139,6 +139,7 @@ struct tp_finger { | |||
139 | /* trackpad finger data size, empirically at least ten fingers */ | 139 | /* trackpad finger data size, empirically at least ten fingers */ |
140 | #define SIZEOF_FINGER sizeof(struct tp_finger) | 140 | #define SIZEOF_FINGER sizeof(struct tp_finger) |
141 | #define SIZEOF_ALL_FINGERS (16 * SIZEOF_FINGER) | 141 | #define SIZEOF_ALL_FINGERS (16 * SIZEOF_FINGER) |
142 | #define MAX_FINGER_ORIENTATION 16384 | ||
142 | 143 | ||
143 | /* device-specific parameters */ | 144 | /* device-specific parameters */ |
144 | struct bcm5974_param { | 145 | struct bcm5974_param { |
@@ -284,6 +285,26 @@ static void setup_events_to_report(struct input_dev *input_dev, | |||
284 | input_set_abs_params(input_dev, ABS_Y, | 285 | input_set_abs_params(input_dev, ABS_Y, |
285 | 0, cfg->y.dim, cfg->y.fuzz, 0); | 286 | 0, cfg->y.dim, cfg->y.fuzz, 0); |
286 | 287 | ||
288 | /* finger touch area */ | ||
289 | input_set_abs_params(input_dev, ABS_MT_TOUCH_MAJOR, | ||
290 | cfg->w.devmin, cfg->w.devmax, 0, 0); | ||
291 | input_set_abs_params(input_dev, ABS_MT_TOUCH_MINOR, | ||
292 | cfg->w.devmin, cfg->w.devmax, 0, 0); | ||
293 | /* finger approach area */ | ||
294 | input_set_abs_params(input_dev, ABS_MT_WIDTH_MAJOR, | ||
295 | cfg->w.devmin, cfg->w.devmax, 0, 0); | ||
296 | input_set_abs_params(input_dev, ABS_MT_WIDTH_MINOR, | ||
297 | cfg->w.devmin, cfg->w.devmax, 0, 0); | ||
298 | /* finger orientation */ | ||
299 | input_set_abs_params(input_dev, ABS_MT_ORIENTATION, | ||
300 | -MAX_FINGER_ORIENTATION, | ||
301 | MAX_FINGER_ORIENTATION, 0, 0); | ||
302 | /* finger position */ | ||
303 | input_set_abs_params(input_dev, ABS_MT_POSITION_X, | ||
304 | cfg->x.devmin, cfg->x.devmax, 0, 0); | ||
305 | input_set_abs_params(input_dev, ABS_MT_POSITION_Y, | ||
306 | cfg->y.devmin, cfg->y.devmax, 0, 0); | ||
307 | |||
287 | __set_bit(EV_KEY, input_dev->evbit); | 308 | __set_bit(EV_KEY, input_dev->evbit); |
288 | __set_bit(BTN_TOUCH, input_dev->keybit); | 309 | __set_bit(BTN_TOUCH, input_dev->keybit); |
289 | __set_bit(BTN_TOOL_FINGER, input_dev->keybit); | 310 | __set_bit(BTN_TOOL_FINGER, input_dev->keybit); |
@@ -310,13 +331,29 @@ static int report_bt_state(struct bcm5974 *dev, int size) | |||
310 | return 0; | 331 | return 0; |
311 | } | 332 | } |
312 | 333 | ||
334 | static void report_finger_data(struct input_dev *input, | ||
335 | const struct bcm5974_config *cfg, | ||
336 | const struct tp_finger *f) | ||
337 | { | ||
338 | input_report_abs(input, ABS_MT_TOUCH_MAJOR, raw2int(f->force_major)); | ||
339 | input_report_abs(input, ABS_MT_TOUCH_MINOR, raw2int(f->force_minor)); | ||
340 | input_report_abs(input, ABS_MT_WIDTH_MAJOR, raw2int(f->size_major)); | ||
341 | input_report_abs(input, ABS_MT_WIDTH_MINOR, raw2int(f->size_minor)); | ||
342 | input_report_abs(input, ABS_MT_ORIENTATION, | ||
343 | MAX_FINGER_ORIENTATION - raw2int(f->orientation)); | ||
344 | input_report_abs(input, ABS_MT_POSITION_X, raw2int(f->abs_x)); | ||
345 | input_report_abs(input, ABS_MT_POSITION_Y, | ||
346 | cfg->y.devmin + cfg->y.devmax - raw2int(f->abs_y)); | ||
347 | input_mt_sync(input); | ||
348 | } | ||
349 | |||
313 | /* report trackpad data as logical trackpad state */ | 350 | /* report trackpad data as logical trackpad state */ |
314 | static int report_tp_state(struct bcm5974 *dev, int size) | 351 | static int report_tp_state(struct bcm5974 *dev, int size) |
315 | { | 352 | { |
316 | const struct bcm5974_config *c = &dev->cfg; | 353 | const struct bcm5974_config *c = &dev->cfg; |
317 | const struct tp_finger *f; | 354 | const struct tp_finger *f; |
318 | struct input_dev *input = dev->input; | 355 | struct input_dev *input = dev->input; |
319 | int raw_p, raw_w, raw_x, raw_y, raw_n; | 356 | int raw_p, raw_w, raw_x, raw_y, raw_n, i; |
320 | int ptest, origin, ibt = 0, nmin = 0, nmax = 0; | 357 | int ptest, origin, ibt = 0, nmin = 0, nmax = 0; |
321 | int abs_p = 0, abs_w = 0, abs_x = 0, abs_y = 0; | 358 | int abs_p = 0, abs_w = 0, abs_x = 0, abs_y = 0; |
322 | 359 | ||
@@ -329,6 +366,11 @@ static int report_tp_state(struct bcm5974 *dev, int size) | |||
329 | 366 | ||
330 | /* always track the first finger; when detached, start over */ | 367 | /* always track the first finger; when detached, start over */ |
331 | if (raw_n) { | 368 | if (raw_n) { |
369 | |||
370 | /* report raw trackpad data */ | ||
371 | for (i = 0; i < raw_n; i++) | ||
372 | report_finger_data(input, c, &f[i]); | ||
373 | |||
332 | raw_p = raw2int(f->force_major); | 374 | raw_p = raw2int(f->force_major); |
333 | raw_w = raw2int(f->size_major); | 375 | raw_w = raw2int(f->size_major); |
334 | raw_x = raw2int(f->abs_x); | 376 | raw_x = raw2int(f->abs_x); |
diff --git a/drivers/input/mouse/psmouse-base.c b/drivers/input/mouse/psmouse-base.c index 401ac6b6edd4..9774bdfaa482 100644 --- a/drivers/input/mouse/psmouse-base.c +++ b/drivers/input/mouse/psmouse-base.c | |||
@@ -627,8 +627,15 @@ static int psmouse_extensions(struct psmouse *psmouse, | |||
627 | synaptics_hardware = true; | 627 | synaptics_hardware = true; |
628 | 628 | ||
629 | if (max_proto > PSMOUSE_IMEX) { | 629 | if (max_proto > PSMOUSE_IMEX) { |
630 | if (!set_properties || synaptics_init(psmouse) == 0) | 630 | /* |
631 | * Try activating protocol, but check if support is enabled first, since | ||
632 | * we try detecting Synaptics even when protocol is disabled. | ||
633 | */ | ||
634 | if (synaptics_supported() && | ||
635 | (!set_properties || synaptics_init(psmouse) == 0)) { | ||
631 | return PSMOUSE_SYNAPTICS; | 636 | return PSMOUSE_SYNAPTICS; |
637 | } | ||
638 | |||
632 | /* | 639 | /* |
633 | * Some Synaptics touchpads can emulate extended protocols (like IMPS/2). | 640 | * Some Synaptics touchpads can emulate extended protocols (like IMPS/2). |
634 | * Unfortunately Logitech/Genius probes confuse some firmware versions so | 641 | * Unfortunately Logitech/Genius probes confuse some firmware versions so |
@@ -683,19 +690,6 @@ static int psmouse_extensions(struct psmouse *psmouse, | |||
683 | max_proto = PSMOUSE_IMEX; | 690 | max_proto = PSMOUSE_IMEX; |
684 | } | 691 | } |
685 | 692 | ||
686 | /* | ||
687 | * Try Finger Sensing Pad | ||
688 | */ | ||
689 | if (max_proto > PSMOUSE_IMEX) { | ||
690 | if (fsp_detect(psmouse, set_properties) == 0) { | ||
691 | if (!set_properties || fsp_init(psmouse) == 0) | ||
692 | return PSMOUSE_FSP; | ||
693 | /* | ||
694 | * Init failed, try basic relative protocols | ||
695 | */ | ||
696 | max_proto = PSMOUSE_IMEX; | ||
697 | } | ||
698 | } | ||
699 | 693 | ||
700 | if (max_proto > PSMOUSE_IMEX) { | 694 | if (max_proto > PSMOUSE_IMEX) { |
701 | if (genius_detect(psmouse, set_properties) == 0) | 695 | if (genius_detect(psmouse, set_properties) == 0) |
@@ -712,6 +706,21 @@ static int psmouse_extensions(struct psmouse *psmouse, | |||
712 | } | 706 | } |
713 | 707 | ||
714 | /* | 708 | /* |
709 | * Try Finger Sensing Pad. We do it here because its probe upsets | ||
710 | * Trackpoint devices (causing TP_READ_ID command to time out). | ||
711 | */ | ||
712 | if (max_proto > PSMOUSE_IMEX) { | ||
713 | if (fsp_detect(psmouse, set_properties) == 0) { | ||
714 | if (!set_properties || fsp_init(psmouse) == 0) | ||
715 | return PSMOUSE_FSP; | ||
716 | /* | ||
717 | * Init failed, try basic relative protocols | ||
718 | */ | ||
719 | max_proto = PSMOUSE_IMEX; | ||
720 | } | ||
721 | } | ||
722 | |||
723 | /* | ||
715 | * Reset to defaults in case the device got confused by extended | 724 | * Reset to defaults in case the device got confused by extended |
716 | * protocol probes. Note that we follow up with full reset because | 725 | * protocol probes. Note that we follow up with full reset because |
717 | * some mice put themselves to sleep when they see PSMOUSE_RESET_DIS. | 726 | * some mice put themselves to sleep when they see PSMOUSE_RESET_DIS. |
@@ -1450,24 +1459,10 @@ ssize_t psmouse_attr_show_helper(struct device *dev, struct device_attribute *de | |||
1450 | struct serio *serio = to_serio_port(dev); | 1459 | struct serio *serio = to_serio_port(dev); |
1451 | struct psmouse_attribute *attr = to_psmouse_attr(devattr); | 1460 | struct psmouse_attribute *attr = to_psmouse_attr(devattr); |
1452 | struct psmouse *psmouse; | 1461 | struct psmouse *psmouse; |
1453 | int retval; | ||
1454 | |||
1455 | retval = serio_pin_driver(serio); | ||
1456 | if (retval) | ||
1457 | return retval; | ||
1458 | |||
1459 | if (serio->drv != &psmouse_drv) { | ||
1460 | retval = -ENODEV; | ||
1461 | goto out; | ||
1462 | } | ||
1463 | 1462 | ||
1464 | psmouse = serio_get_drvdata(serio); | 1463 | psmouse = serio_get_drvdata(serio); |
1465 | 1464 | ||
1466 | retval = attr->show(psmouse, attr->data, buf); | 1465 | return attr->show(psmouse, attr->data, buf); |
1467 | |||
1468 | out: | ||
1469 | serio_unpin_driver(serio); | ||
1470 | return retval; | ||
1471 | } | 1466 | } |
1472 | 1467 | ||
1473 | ssize_t psmouse_attr_set_helper(struct device *dev, struct device_attribute *devattr, | 1468 | ssize_t psmouse_attr_set_helper(struct device *dev, struct device_attribute *devattr, |
@@ -1478,18 +1473,9 @@ ssize_t psmouse_attr_set_helper(struct device *dev, struct device_attribute *dev | |||
1478 | struct psmouse *psmouse, *parent = NULL; | 1473 | struct psmouse *psmouse, *parent = NULL; |
1479 | int retval; | 1474 | int retval; |
1480 | 1475 | ||
1481 | retval = serio_pin_driver(serio); | ||
1482 | if (retval) | ||
1483 | return retval; | ||
1484 | |||
1485 | if (serio->drv != &psmouse_drv) { | ||
1486 | retval = -ENODEV; | ||
1487 | goto out_unpin; | ||
1488 | } | ||
1489 | |||
1490 | retval = mutex_lock_interruptible(&psmouse_mutex); | 1476 | retval = mutex_lock_interruptible(&psmouse_mutex); |
1491 | if (retval) | 1477 | if (retval) |
1492 | goto out_unpin; | 1478 | goto out; |
1493 | 1479 | ||
1494 | psmouse = serio_get_drvdata(serio); | 1480 | psmouse = serio_get_drvdata(serio); |
1495 | 1481 | ||
@@ -1519,8 +1505,7 @@ ssize_t psmouse_attr_set_helper(struct device *dev, struct device_attribute *dev | |||
1519 | 1505 | ||
1520 | out_unlock: | 1506 | out_unlock: |
1521 | mutex_unlock(&psmouse_mutex); | 1507 | mutex_unlock(&psmouse_mutex); |
1522 | out_unpin: | 1508 | out: |
1523 | serio_unpin_driver(serio); | ||
1524 | return retval; | 1509 | return retval; |
1525 | } | 1510 | } |
1526 | 1511 | ||
@@ -1582,9 +1567,7 @@ static ssize_t psmouse_attr_set_protocol(struct psmouse *psmouse, void *data, co | |||
1582 | } | 1567 | } |
1583 | 1568 | ||
1584 | mutex_unlock(&psmouse_mutex); | 1569 | mutex_unlock(&psmouse_mutex); |
1585 | serio_unpin_driver(serio); | ||
1586 | serio_unregister_child_port(serio); | 1570 | serio_unregister_child_port(serio); |
1587 | serio_pin_driver_uninterruptible(serio); | ||
1588 | mutex_lock(&psmouse_mutex); | 1571 | mutex_lock(&psmouse_mutex); |
1589 | 1572 | ||
1590 | if (serio->drv != &psmouse_drv) { | 1573 | if (serio->drv != &psmouse_drv) { |
diff --git a/drivers/input/mouse/sentelic.c b/drivers/input/mouse/sentelic.c index 77b9fd0b3fbf..81a6b81cb2fe 100644 --- a/drivers/input/mouse/sentelic.c +++ b/drivers/input/mouse/sentelic.c | |||
@@ -2,7 +2,7 @@ | |||
2 | * Finger Sensing Pad PS/2 mouse driver. | 2 | * Finger Sensing Pad PS/2 mouse driver. |
3 | * | 3 | * |
4 | * Copyright (C) 2005-2007 Asia Vital Components Co., Ltd. | 4 | * Copyright (C) 2005-2007 Asia Vital Components Co., Ltd. |
5 | * Copyright (C) 2005-2009 Tai-hwa Liang, Sentelic Corporation. | 5 | * Copyright (C) 2005-2010 Tai-hwa Liang, Sentelic Corporation. |
6 | * | 6 | * |
7 | * This program is free software; you can redistribute it and/or | 7 | * This program is free software; you can redistribute it and/or |
8 | * modify it under the terms of the GNU General Public License | 8 | * modify it under the terms of the GNU General Public License |
@@ -658,9 +658,9 @@ static psmouse_ret_t fsp_process_byte(struct psmouse *psmouse) | |||
658 | if (packet[3] & BIT(1)) | 658 | if (packet[3] & BIT(1)) |
659 | button_status |= 0x0f; /* wheel up */ | 659 | button_status |= 0x0f; /* wheel up */ |
660 | if (packet[3] & BIT(2)) | 660 | if (packet[3] & BIT(2)) |
661 | button_status |= BIT(5);/* horizontal left */ | 661 | button_status |= BIT(4);/* horizontal left */ |
662 | if (packet[3] & BIT(3)) | 662 | if (packet[3] & BIT(3)) |
663 | button_status |= BIT(4);/* horizontal right */ | 663 | button_status |= BIT(5);/* horizontal right */ |
664 | /* push back to packet queue */ | 664 | /* push back to packet queue */ |
665 | if (button_status != 0) | 665 | if (button_status != 0) |
666 | packet[3] = button_status; | 666 | packet[3] = button_status; |
diff --git a/drivers/input/mouse/synaptics.c b/drivers/input/mouse/synaptics.c index 05689e732191..d3f5243fa093 100644 --- a/drivers/input/mouse/synaptics.c +++ b/drivers/input/mouse/synaptics.c | |||
@@ -743,6 +743,11 @@ int synaptics_init(struct psmouse *psmouse) | |||
743 | return -1; | 743 | return -1; |
744 | } | 744 | } |
745 | 745 | ||
746 | bool synaptics_supported(void) | ||
747 | { | ||
748 | return true; | ||
749 | } | ||
750 | |||
746 | #else /* CONFIG_MOUSE_PS2_SYNAPTICS */ | 751 | #else /* CONFIG_MOUSE_PS2_SYNAPTICS */ |
747 | 752 | ||
748 | void __init synaptics_module_init(void) | 753 | void __init synaptics_module_init(void) |
@@ -754,5 +759,10 @@ int synaptics_init(struct psmouse *psmouse) | |||
754 | return -ENOSYS; | 759 | return -ENOSYS; |
755 | } | 760 | } |
756 | 761 | ||
762 | bool synaptics_supported(void) | ||
763 | { | ||
764 | return false; | ||
765 | } | ||
766 | |||
757 | #endif /* CONFIG_MOUSE_PS2_SYNAPTICS */ | 767 | #endif /* CONFIG_MOUSE_PS2_SYNAPTICS */ |
758 | 768 | ||
diff --git a/drivers/input/mouse/synaptics.h b/drivers/input/mouse/synaptics.h index 838e7f2c9b30..f0f40a331dc8 100644 --- a/drivers/input/mouse/synaptics.h +++ b/drivers/input/mouse/synaptics.h | |||
@@ -109,5 +109,6 @@ void synaptics_module_init(void); | |||
109 | int synaptics_detect(struct psmouse *psmouse, bool set_properties); | 109 | int synaptics_detect(struct psmouse *psmouse, bool set_properties); |
110 | int synaptics_init(struct psmouse *psmouse); | 110 | int synaptics_init(struct psmouse *psmouse); |
111 | void synaptics_reset(struct psmouse *psmouse); | 111 | void synaptics_reset(struct psmouse *psmouse); |
112 | bool synaptics_supported(void); | ||
112 | 113 | ||
113 | #endif /* _SYNAPTICS_H */ | 114 | #endif /* _SYNAPTICS_H */ |
diff --git a/drivers/input/serio/i8042-x86ia64io.h b/drivers/input/serio/i8042-x86ia64io.h index 64b688daf48a..2a5982e532f8 100644 --- a/drivers/input/serio/i8042-x86ia64io.h +++ b/drivers/input/serio/i8042-x86ia64io.h | |||
@@ -524,6 +524,13 @@ static const struct dmi_system_id __initconst i8042_dmi_laptop_table[] = { | |||
524 | */ | 524 | */ |
525 | static const struct dmi_system_id __initconst i8042_dmi_dritek_table[] = { | 525 | static const struct dmi_system_id __initconst i8042_dmi_dritek_table[] = { |
526 | { | 526 | { |
527 | /* Acer Aspire 5610 */ | ||
528 | .matches = { | ||
529 | DMI_MATCH(DMI_SYS_VENDOR, "Acer"), | ||
530 | DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5610"), | ||
531 | }, | ||
532 | }, | ||
533 | { | ||
527 | /* Acer Aspire 5630 */ | 534 | /* Acer Aspire 5630 */ |
528 | .matches = { | 535 | .matches = { |
529 | DMI_MATCH(DMI_SYS_VENDOR, "Acer"), | 536 | DMI_MATCH(DMI_SYS_VENDOR, "Acer"), |
diff --git a/drivers/isdn/hardware/mISDN/hfcmulti.c b/drivers/isdn/hardware/mISDN/hfcmulti.c index a6624ad252c5..1a1420d7a828 100644 --- a/drivers/isdn/hardware/mISDN/hfcmulti.c +++ b/drivers/isdn/hardware/mISDN/hfcmulti.c | |||
@@ -3152,7 +3152,7 @@ static void | |||
3152 | hfcmulti_pcm(struct hfc_multi *hc, int ch, int slot_tx, int bank_tx, | 3152 | hfcmulti_pcm(struct hfc_multi *hc, int ch, int slot_tx, int bank_tx, |
3153 | int slot_rx, int bank_rx) | 3153 | int slot_rx, int bank_rx) |
3154 | { | 3154 | { |
3155 | if (slot_rx < 0 || slot_rx < 0 || bank_tx < 0 || bank_rx < 0) { | 3155 | if (slot_tx < 0 || slot_rx < 0 || bank_tx < 0 || bank_rx < 0) { |
3156 | /* disable PCM */ | 3156 | /* disable PCM */ |
3157 | mode_hfcmulti(hc, ch, hc->chan[ch].protocol, -1, 0, -1, 0); | 3157 | mode_hfcmulti(hc, ch, hc->chan[ch].protocol, -1, 0, -1, 0); |
3158 | return; | 3158 | return; |
diff --git a/drivers/macintosh/smu.c b/drivers/macintosh/smu.c index 96faa799b82a..f96feeb6b9ce 100644 --- a/drivers/macintosh/smu.c +++ b/drivers/macintosh/smu.c | |||
@@ -660,7 +660,7 @@ static int smu_platform_probe(struct of_device* dev, | |||
660 | return 0; | 660 | return 0; |
661 | } | 661 | } |
662 | 662 | ||
663 | static struct of_device_id smu_platform_match[] = | 663 | static const struct of_device_id smu_platform_match[] = |
664 | { | 664 | { |
665 | { | 665 | { |
666 | .type = "smu", | 666 | .type = "smu", |
diff --git a/drivers/macintosh/therm_pm72.c b/drivers/macintosh/therm_pm72.c index ea32c7e5a9af..454bc501df3c 100644 --- a/drivers/macintosh/therm_pm72.c +++ b/drivers/macintosh/therm_pm72.c | |||
@@ -2211,7 +2211,7 @@ static int fcu_of_remove(struct of_device* dev) | |||
2211 | return 0; | 2211 | return 0; |
2212 | } | 2212 | } |
2213 | 2213 | ||
2214 | static struct of_device_id fcu_match[] = | 2214 | static const struct of_device_id fcu_match[] = |
2215 | { | 2215 | { |
2216 | { | 2216 | { |
2217 | .type = "fcu", | 2217 | .type = "fcu", |
diff --git a/drivers/macintosh/therm_windtunnel.c b/drivers/macintosh/therm_windtunnel.c index 3fbe41b0ac07..ba48fd76396e 100644 --- a/drivers/macintosh/therm_windtunnel.c +++ b/drivers/macintosh/therm_windtunnel.c | |||
@@ -457,7 +457,7 @@ therm_of_remove( struct of_device *dev ) | |||
457 | return 0; | 457 | return 0; |
458 | } | 458 | } |
459 | 459 | ||
460 | static struct of_device_id therm_of_match[] = {{ | 460 | static const struct of_device_id therm_of_match[] = {{ |
461 | .name = "fan", | 461 | .name = "fan", |
462 | .compatible = "adm1030" | 462 | .compatible = "adm1030" |
463 | }, {} | 463 | }, {} |
diff --git a/drivers/media/IR/ir-keytable.c b/drivers/media/IR/ir-keytable.c index bff7a5356037..b521ed9d6e2e 100644 --- a/drivers/media/IR/ir-keytable.c +++ b/drivers/media/IR/ir-keytable.c | |||
@@ -13,7 +13,7 @@ | |||
13 | */ | 13 | */ |
14 | 14 | ||
15 | 15 | ||
16 | #include <linux/usb/input.h> | 16 | #include <linux/input.h> |
17 | #include <media/ir-common.h> | 17 | #include <media/ir-common.h> |
18 | 18 | ||
19 | #define IR_TAB_MIN_SIZE 32 | 19 | #define IR_TAB_MIN_SIZE 32 |
diff --git a/drivers/media/common/tuners/tda8290.c b/drivers/media/common/tuners/tda8290.c index c190b0dedee4..2833137fa819 100644 --- a/drivers/media/common/tuners/tda8290.c +++ b/drivers/media/common/tuners/tda8290.c | |||
@@ -144,7 +144,8 @@ static void set_audio(struct dvb_frontend *fe, | |||
144 | } | 144 | } |
145 | 145 | ||
146 | if (params->mode == V4L2_TUNER_RADIO) { | 146 | if (params->mode == V4L2_TUNER_RADIO) { |
147 | priv->tda8290_easy_mode = 0x01; /* Start with MN values */ | 147 | /* Set TDA8295 to FM radio; Start TDA8290 with MN values */ |
148 | priv->tda8290_easy_mode = (priv->ver & TDA8295) ? 0x80 : 0x01; | ||
148 | tuner_dbg("setting to radio FM\n"); | 149 | tuner_dbg("setting to radio FM\n"); |
149 | } else { | 150 | } else { |
150 | tuner_dbg("setting tda829x to system %s\n", mode); | 151 | tuner_dbg("setting tda829x to system %s\n", mode); |
@@ -672,16 +673,19 @@ static int tda8290_probe(struct tuner_i2c_props *i2c_props) | |||
672 | static int tda8295_probe(struct tuner_i2c_props *i2c_props) | 673 | static int tda8295_probe(struct tuner_i2c_props *i2c_props) |
673 | { | 674 | { |
674 | #define TDA8295_ID 0x8a | 675 | #define TDA8295_ID 0x8a |
676 | #define TDA8295C2_ID 0x8b | ||
675 | unsigned char tda8295_id[] = { 0x2f, 0x00 }; | 677 | unsigned char tda8295_id[] = { 0x2f, 0x00 }; |
676 | 678 | ||
677 | /* detect tda8295 */ | 679 | /* detect tda8295 */ |
678 | tuner_i2c_xfer_send(i2c_props, &tda8295_id[0], 1); | 680 | tuner_i2c_xfer_send(i2c_props, &tda8295_id[0], 1); |
679 | tuner_i2c_xfer_recv(i2c_props, &tda8295_id[1], 1); | 681 | tuner_i2c_xfer_recv(i2c_props, &tda8295_id[1], 1); |
680 | 682 | ||
681 | if (tda8295_id[1] == TDA8295_ID) { | 683 | if ((tda8295_id[1] & 0xfe) == TDA8295_ID) { |
682 | if (debug) | 684 | if (debug) |
683 | printk(KERN_DEBUG "%s: tda8295 detected @ %d-%04x\n", | 685 | printk(KERN_DEBUG "%s: %s detected @ %d-%04x\n", |
684 | __func__, i2c_adapter_id(i2c_props->adap), | 686 | __func__, (tda8295_id[1] == TDA8295_ID) ? |
687 | "tda8295c1" : "tda8295c2", | ||
688 | i2c_adapter_id(i2c_props->adap), | ||
685 | i2c_props->addr); | 689 | i2c_props->addr); |
686 | return 0; | 690 | return 0; |
687 | } | 691 | } |
diff --git a/drivers/media/dvb/Kconfig b/drivers/media/dvb/Kconfig index 35d0817126e9..cf8f65f309da 100644 --- a/drivers/media/dvb/Kconfig +++ b/drivers/media/dvb/Kconfig | |||
@@ -72,6 +72,10 @@ comment "Supported Earthsoft PT1 Adapters" | |||
72 | depends on DVB_CORE && PCI && I2C | 72 | depends on DVB_CORE && PCI && I2C |
73 | source "drivers/media/dvb/pt1/Kconfig" | 73 | source "drivers/media/dvb/pt1/Kconfig" |
74 | 74 | ||
75 | comment "Supported Mantis Adapters" | ||
76 | depends on DVB_CORE && PCI && I2C | ||
77 | source "drivers/media/dvb/mantis/Kconfig" | ||
78 | |||
75 | comment "Supported DVB Frontends" | 79 | comment "Supported DVB Frontends" |
76 | depends on DVB_CORE | 80 | depends on DVB_CORE |
77 | source "drivers/media/dvb/frontends/Kconfig" | 81 | source "drivers/media/dvb/frontends/Kconfig" |
diff --git a/drivers/media/dvb/Makefile b/drivers/media/dvb/Makefile index 16d262ddb45d..c12922c3659b 100644 --- a/drivers/media/dvb/Makefile +++ b/drivers/media/dvb/Makefile | |||
@@ -2,6 +2,18 @@ | |||
2 | # Makefile for the kernel multimedia device drivers. | 2 | # Makefile for the kernel multimedia device drivers. |
3 | # | 3 | # |
4 | 4 | ||
5 | obj-y := dvb-core/ frontends/ ttpci/ ttusb-dec/ ttusb-budget/ b2c2/ bt8xx/ dvb-usb/ pluto2/ siano/ dm1105/ pt1/ | 5 | obj-y := dvb-core/ \ |
6 | frontends/ \ | ||
7 | ttpci/ \ | ||
8 | ttusb-dec/ \ | ||
9 | ttusb-budget/ \ | ||
10 | b2c2/ \ | ||
11 | bt8xx/ \ | ||
12 | dvb-usb/ \ | ||
13 | pluto2/ \ | ||
14 | siano/ \ | ||
15 | dm1105/ \ | ||
16 | pt1/ \ | ||
17 | mantis/ | ||
6 | 18 | ||
7 | obj-$(CONFIG_DVB_FIREDTV) += firewire/ | 19 | obj-$(CONFIG_DVB_FIREDTV) += firewire/ |
diff --git a/drivers/media/dvb/frontends/Kconfig b/drivers/media/dvb/frontends/Kconfig index a3b8b697349b..cd7f9b7cbffa 100644 --- a/drivers/media/dvb/frontends/Kconfig +++ b/drivers/media/dvb/frontends/Kconfig | |||
@@ -208,6 +208,14 @@ config DVB_DS3000 | |||
208 | help | 208 | help |
209 | A DVB-S/S2 tuner module. Say Y when you want to support this frontend. | 209 | A DVB-S/S2 tuner module. Say Y when you want to support this frontend. |
210 | 210 | ||
211 | config DVB_MB86A16 | ||
212 | tristate "Fujitsu MB86A16 based" | ||
213 | depends on DVB_CORE && I2C | ||
214 | default m if DVB_FE_CUSTOMISE | ||
215 | help | ||
216 | A DVB-S/DSS Direct Conversion reveiver. | ||
217 | Say Y when you want to support this frontend. | ||
218 | |||
211 | comment "DVB-T (terrestrial) frontends" | 219 | comment "DVB-T (terrestrial) frontends" |
212 | depends on DVB_CORE | 220 | depends on DVB_CORE |
213 | 221 | ||
@@ -587,6 +595,17 @@ config DVB_ATBM8830 | |||
587 | help | 595 | help |
588 | A DMB-TH tuner module. Say Y when you want to support this frontend. | 596 | A DMB-TH tuner module. Say Y when you want to support this frontend. |
589 | 597 | ||
598 | config DVB_TDA665x | ||
599 | tristate "TDA665x tuner" | ||
600 | depends on DVB_CORE && I2C | ||
601 | default m if DVB_FE_CUSTOMISE | ||
602 | help | ||
603 | Support for tuner modules based on Philips TDA6650/TDA6651 chips. | ||
604 | Say Y when you want to support this chip. | ||
605 | |||
606 | Currently supported tuners: | ||
607 | * Panasonic ENV57H12D5 (ET-50DT) | ||
608 | |||
590 | comment "Tools to develop new frontends" | 609 | comment "Tools to develop new frontends" |
591 | 610 | ||
592 | config DVB_DUMMY_FE | 611 | config DVB_DUMMY_FE |
diff --git a/drivers/media/dvb/frontends/Makefile b/drivers/media/dvb/frontends/Makefile index 47575cc7b699..874e8ada4d1d 100644 --- a/drivers/media/dvb/frontends/Makefile +++ b/drivers/media/dvb/frontends/Makefile | |||
@@ -64,6 +64,7 @@ obj-$(CONFIG_DVB_TDA10048) += tda10048.o | |||
64 | obj-$(CONFIG_DVB_TUNER_CX24113) += cx24113.o | 64 | obj-$(CONFIG_DVB_TUNER_CX24113) += cx24113.o |
65 | obj-$(CONFIG_DVB_S5H1411) += s5h1411.o | 65 | obj-$(CONFIG_DVB_S5H1411) += s5h1411.o |
66 | obj-$(CONFIG_DVB_LGS8GL5) += lgs8gl5.o | 66 | obj-$(CONFIG_DVB_LGS8GL5) += lgs8gl5.o |
67 | obj-$(CONFIG_DVB_TDA665x) += tda665x.o | ||
67 | obj-$(CONFIG_DVB_LGS8GXX) += lgs8gxx.o | 68 | obj-$(CONFIG_DVB_LGS8GXX) += lgs8gxx.o |
68 | obj-$(CONFIG_DVB_ATBM8830) += atbm8830.o | 69 | obj-$(CONFIG_DVB_ATBM8830) += atbm8830.o |
69 | obj-$(CONFIG_DVB_DUMMY_FE) += dvb_dummy_fe.o | 70 | obj-$(CONFIG_DVB_DUMMY_FE) += dvb_dummy_fe.o |
@@ -80,3 +81,4 @@ obj-$(CONFIG_DVB_STV6110x) += stv6110x.o | |||
80 | obj-$(CONFIG_DVB_ISL6423) += isl6423.o | 81 | obj-$(CONFIG_DVB_ISL6423) += isl6423.o |
81 | obj-$(CONFIG_DVB_EC100) += ec100.o | 82 | obj-$(CONFIG_DVB_EC100) += ec100.o |
82 | obj-$(CONFIG_DVB_DS3000) += ds3000.o | 83 | obj-$(CONFIG_DVB_DS3000) += ds3000.o |
84 | obj-$(CONFIG_DVB_MB86A16) += mb86a16.o | ||
diff --git a/drivers/media/dvb/frontends/dib8000.h b/drivers/media/dvb/frontends/dib8000.h index d99619ae983c..b1ee20799639 100644 --- a/drivers/media/dvb/frontends/dib8000.h +++ b/drivers/media/dvb/frontends/dib8000.h | |||
@@ -100,7 +100,7 @@ static inline int dib8000_set_tune_state(struct dvb_frontend *fe, enum frontend_ | |||
100 | static inline enum frontend_tune_state dib8000_get_tune_state(struct dvb_frontend *fe) | 100 | static inline enum frontend_tune_state dib8000_get_tune_state(struct dvb_frontend *fe) |
101 | { | 101 | { |
102 | printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); | 102 | printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); |
103 | return CT_SHUTDOWN, | 103 | return CT_SHUTDOWN; |
104 | } | 104 | } |
105 | static inline void dib8000_pwm_agc_reset(struct dvb_frontend *fe) | 105 | static inline void dib8000_pwm_agc_reset(struct dvb_frontend *fe) |
106 | { | 106 | { |
diff --git a/drivers/media/dvb/frontends/lgdt3305.h b/drivers/media/dvb/frontends/lgdt3305.h index 4fa6e52d1fe8..9cb11c9cae53 100644 --- a/drivers/media/dvb/frontends/lgdt3305.h +++ b/drivers/media/dvb/frontends/lgdt3305.h | |||
@@ -54,13 +54,13 @@ struct lgdt3305_config { | |||
54 | u16 usref_qam256; /* default: 0x2a80 */ | 54 | u16 usref_qam256; /* default: 0x2a80 */ |
55 | 55 | ||
56 | /* disable i2c repeater - 0:repeater enabled 1:repeater disabled */ | 56 | /* disable i2c repeater - 0:repeater enabled 1:repeater disabled */ |
57 | int deny_i2c_rptr:1; | 57 | unsigned int deny_i2c_rptr:1; |
58 | 58 | ||
59 | /* spectral inversion - 0:disabled 1:enabled */ | 59 | /* spectral inversion - 0:disabled 1:enabled */ |
60 | int spectral_inversion:1; | 60 | unsigned int spectral_inversion:1; |
61 | 61 | ||
62 | /* use RF AGC loop - 0:disabled 1:enabled */ | 62 | /* use RF AGC loop - 0:disabled 1:enabled */ |
63 | int rf_agc_loop:1; | 63 | unsigned int rf_agc_loop:1; |
64 | 64 | ||
65 | enum lgdt3305_mpeg_mode mpeg_mode; | 65 | enum lgdt3305_mpeg_mode mpeg_mode; |
66 | enum lgdt3305_tp_clock_edge tpclk_edge; | 66 | enum lgdt3305_tp_clock_edge tpclk_edge; |
diff --git a/drivers/media/dvb/frontends/mb86a16.c b/drivers/media/dvb/frontends/mb86a16.c new file mode 100644 index 000000000000..d05f7500e0c5 --- /dev/null +++ b/drivers/media/dvb/frontends/mb86a16.c | |||
@@ -0,0 +1,1878 @@ | |||
1 | /* | ||
2 | Fujitsu MB86A16 DVB-S/DSS DC Receiver driver | ||
3 | |||
4 | Copyright (C) Manu Abraham (abraham.manu@gmail.com) | ||
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 | #include <linux/init.h> | ||
22 | #include <linux/kernel.h> | ||
23 | #include <linux/module.h> | ||
24 | #include <linux/moduleparam.h> | ||
25 | |||
26 | #include "dvb_frontend.h" | ||
27 | #include "mb86a16.h" | ||
28 | #include "mb86a16_priv.h" | ||
29 | |||
30 | unsigned int verbose = 5; | ||
31 | module_param(verbose, int, 0644); | ||
32 | |||
33 | #define ABS(x) ((x) < 0 ? (-x) : (x)) | ||
34 | |||
35 | struct mb86a16_state { | ||
36 | struct i2c_adapter *i2c_adap; | ||
37 | const struct mb86a16_config *config; | ||
38 | struct dvb_frontend frontend; | ||
39 | |||
40 | /* tuning parameters */ | ||
41 | int frequency; | ||
42 | int srate; | ||
43 | |||
44 | /* Internal stuff */ | ||
45 | int master_clk; | ||
46 | int deci; | ||
47 | int csel; | ||
48 | int rsel; | ||
49 | }; | ||
50 | |||
51 | #define MB86A16_ERROR 0 | ||
52 | #define MB86A16_NOTICE 1 | ||
53 | #define MB86A16_INFO 2 | ||
54 | #define MB86A16_DEBUG 3 | ||
55 | |||
56 | #define dprintk(x, y, z, format, arg...) do { \ | ||
57 | if (z) { \ | ||
58 | if ((x > MB86A16_ERROR) && (x > y)) \ | ||
59 | printk(KERN_ERR "%s: " format "\n", __func__, ##arg); \ | ||
60 | else if ((x > MB86A16_NOTICE) && (x > y)) \ | ||
61 | printk(KERN_NOTICE "%s: " format "\n", __func__, ##arg); \ | ||
62 | else if ((x > MB86A16_INFO) && (x > y)) \ | ||
63 | printk(KERN_INFO "%s: " format "\n", __func__, ##arg); \ | ||
64 | else if ((x > MB86A16_DEBUG) && (x > y)) \ | ||
65 | printk(KERN_DEBUG "%s: " format "\n", __func__, ##arg); \ | ||
66 | } else { \ | ||
67 | if (x > y) \ | ||
68 | printk(format, ##arg); \ | ||
69 | } \ | ||
70 | } while (0) | ||
71 | |||
72 | #define TRACE_IN dprintk(verbose, MB86A16_DEBUG, 1, "-->()") | ||
73 | #define TRACE_OUT dprintk(verbose, MB86A16_DEBUG, 1, "()-->") | ||
74 | |||
75 | static int mb86a16_write(struct mb86a16_state *state, u8 reg, u8 val) | ||
76 | { | ||
77 | int ret; | ||
78 | u8 buf[] = { reg, val }; | ||
79 | |||
80 | struct i2c_msg msg = { | ||
81 | .addr = state->config->demod_address, | ||
82 | .flags = 0, | ||
83 | .buf = buf, | ||
84 | .len = 2 | ||
85 | }; | ||
86 | |||
87 | dprintk(verbose, MB86A16_DEBUG, 1, | ||
88 | "writing to [0x%02x],Reg[0x%02x],Data[0x%02x]", | ||
89 | state->config->demod_address, buf[0], buf[1]); | ||
90 | |||
91 | ret = i2c_transfer(state->i2c_adap, &msg, 1); | ||
92 | |||
93 | return (ret != 1) ? -EREMOTEIO : 0; | ||
94 | } | ||
95 | |||
96 | static int mb86a16_read(struct mb86a16_state *state, u8 reg, u8 *val) | ||
97 | { | ||
98 | int ret; | ||
99 | u8 b0[] = { reg }; | ||
100 | u8 b1[] = { 0 }; | ||
101 | |||
102 | struct i2c_msg msg[] = { | ||
103 | { | ||
104 | .addr = state->config->demod_address, | ||
105 | .flags = 0, | ||
106 | .buf = b0, | ||
107 | .len = 1 | ||
108 | }, { | ||
109 | .addr = state->config->demod_address, | ||
110 | .flags = I2C_M_RD, | ||
111 | .buf = b1, | ||
112 | .len = 1 | ||
113 | } | ||
114 | }; | ||
115 | ret = i2c_transfer(state->i2c_adap, msg, 2); | ||
116 | if (ret != 2) { | ||
117 | dprintk(verbose, MB86A16_ERROR, 1, "read error(reg=0x%02x, ret=0x%i)", | ||
118 | reg, ret); | ||
119 | |||
120 | return -EREMOTEIO; | ||
121 | } | ||
122 | *val = b1[0]; | ||
123 | |||
124 | return ret; | ||
125 | } | ||
126 | |||
127 | static int CNTM_set(struct mb86a16_state *state, | ||
128 | unsigned char timint1, | ||
129 | unsigned char timint2, | ||
130 | unsigned char cnext) | ||
131 | { | ||
132 | unsigned char val; | ||
133 | |||
134 | val = (timint1 << 4) | (timint2 << 2) | cnext; | ||
135 | if (mb86a16_write(state, MB86A16_CNTMR, val) < 0) | ||
136 | goto err; | ||
137 | |||
138 | return 0; | ||
139 | |||
140 | err: | ||
141 | dprintk(verbose, MB86A16_ERROR, 1, "I2C transfer error"); | ||
142 | return -EREMOTEIO; | ||
143 | } | ||
144 | |||
145 | static int smrt_set(struct mb86a16_state *state, int rate) | ||
146 | { | ||
147 | int tmp ; | ||
148 | int m ; | ||
149 | unsigned char STOFS0, STOFS1; | ||
150 | |||
151 | m = 1 << state->deci; | ||
152 | tmp = (8192 * state->master_clk - 2 * m * rate * 8192 + state->master_clk / 2) / state->master_clk; | ||
153 | |||
154 | STOFS0 = tmp & 0x0ff; | ||
155 | STOFS1 = (tmp & 0xf00) >> 8; | ||
156 | |||
157 | if (mb86a16_write(state, MB86A16_SRATE1, (state->deci << 2) | | ||
158 | (state->csel << 1) | | ||
159 | state->rsel) < 0) | ||
160 | goto err; | ||
161 | if (mb86a16_write(state, MB86A16_SRATE2, STOFS0) < 0) | ||
162 | goto err; | ||
163 | if (mb86a16_write(state, MB86A16_SRATE3, STOFS1) < 0) | ||
164 | goto err; | ||
165 | |||
166 | return 0; | ||
167 | err: | ||
168 | dprintk(verbose, MB86A16_ERROR, 1, "I2C transfer error"); | ||
169 | return -1; | ||
170 | } | ||
171 | |||
172 | static int srst(struct mb86a16_state *state) | ||
173 | { | ||
174 | if (mb86a16_write(state, MB86A16_RESET, 0x04) < 0) | ||
175 | goto err; | ||
176 | |||
177 | return 0; | ||
178 | err: | ||
179 | dprintk(verbose, MB86A16_ERROR, 1, "I2C transfer error"); | ||
180 | return -EREMOTEIO; | ||
181 | |||
182 | } | ||
183 | |||
184 | static int afcex_data_set(struct mb86a16_state *state, | ||
185 | unsigned char AFCEX_L, | ||
186 | unsigned char AFCEX_H) | ||
187 | { | ||
188 | if (mb86a16_write(state, MB86A16_AFCEXL, AFCEX_L) < 0) | ||
189 | goto err; | ||
190 | if (mb86a16_write(state, MB86A16_AFCEXH, AFCEX_H) < 0) | ||
191 | goto err; | ||
192 | |||
193 | return 0; | ||
194 | err: | ||
195 | dprintk(verbose, MB86A16_ERROR, 1, "I2C transfer error"); | ||
196 | |||
197 | return -1; | ||
198 | } | ||
199 | |||
200 | static int afcofs_data_set(struct mb86a16_state *state, | ||
201 | unsigned char AFCEX_L, | ||
202 | unsigned char AFCEX_H) | ||
203 | { | ||
204 | if (mb86a16_write(state, 0x58, AFCEX_L) < 0) | ||
205 | goto err; | ||
206 | if (mb86a16_write(state, 0x59, AFCEX_H) < 0) | ||
207 | goto err; | ||
208 | |||
209 | return 0; | ||
210 | err: | ||
211 | dprintk(verbose, MB86A16_ERROR, 1, "I2C transfer error"); | ||
212 | return -EREMOTEIO; | ||
213 | } | ||
214 | |||
215 | static int stlp_set(struct mb86a16_state *state, | ||
216 | unsigned char STRAS, | ||
217 | unsigned char STRBS) | ||
218 | { | ||
219 | if (mb86a16_write(state, MB86A16_STRFILTCOEF1, (STRBS << 3) | (STRAS)) < 0) | ||
220 | goto err; | ||
221 | |||
222 | return 0; | ||
223 | err: | ||
224 | dprintk(verbose, MB86A16_ERROR, 1, "I2C transfer error"); | ||
225 | return -EREMOTEIO; | ||
226 | } | ||
227 | |||
228 | static int Vi_set(struct mb86a16_state *state, unsigned char ETH, unsigned char VIA) | ||
229 | { | ||
230 | if (mb86a16_write(state, MB86A16_VISET2, 0x04) < 0) | ||
231 | goto err; | ||
232 | if (mb86a16_write(state, MB86A16_VISET3, 0xf5) < 0) | ||
233 | goto err; | ||
234 | |||
235 | return 0; | ||
236 | err: | ||
237 | dprintk(verbose, MB86A16_ERROR, 1, "I2C transfer error"); | ||
238 | return -EREMOTEIO; | ||
239 | } | ||
240 | |||
241 | static int initial_set(struct mb86a16_state *state) | ||
242 | { | ||
243 | if (stlp_set(state, 5, 7)) | ||
244 | goto err; | ||
245 | |||
246 | udelay(100); | ||
247 | if (afcex_data_set(state, 0, 0)) | ||
248 | goto err; | ||
249 | |||
250 | udelay(100); | ||
251 | if (afcofs_data_set(state, 0, 0)) | ||
252 | goto err; | ||
253 | |||
254 | udelay(100); | ||
255 | if (mb86a16_write(state, MB86A16_CRLFILTCOEF1, 0x16) < 0) | ||
256 | goto err; | ||
257 | if (mb86a16_write(state, 0x2f, 0x21) < 0) | ||
258 | goto err; | ||
259 | if (mb86a16_write(state, MB86A16_VIMAG, 0x38) < 0) | ||
260 | goto err; | ||
261 | if (mb86a16_write(state, MB86A16_FAGCS1, 0x00) < 0) | ||
262 | goto err; | ||
263 | if (mb86a16_write(state, MB86A16_FAGCS2, 0x1c) < 0) | ||
264 | goto err; | ||
265 | if (mb86a16_write(state, MB86A16_FAGCS3, 0x20) < 0) | ||
266 | goto err; | ||
267 | if (mb86a16_write(state, MB86A16_FAGCS4, 0x1e) < 0) | ||
268 | goto err; | ||
269 | if (mb86a16_write(state, MB86A16_FAGCS5, 0x23) < 0) | ||
270 | goto err; | ||
271 | if (mb86a16_write(state, 0x54, 0xff) < 0) | ||
272 | goto err; | ||
273 | if (mb86a16_write(state, MB86A16_TSOUT, 0x00) < 0) | ||
274 | goto err; | ||
275 | |||
276 | return 0; | ||
277 | |||
278 | err: | ||
279 | dprintk(verbose, MB86A16_ERROR, 1, "I2C transfer error"); | ||
280 | return -EREMOTEIO; | ||
281 | } | ||
282 | |||
283 | static int S01T_set(struct mb86a16_state *state, | ||
284 | unsigned char s1t, | ||
285 | unsigned s0t) | ||
286 | { | ||
287 | if (mb86a16_write(state, 0x33, (s1t << 3) | s0t) < 0) | ||
288 | goto err; | ||
289 | |||
290 | return 0; | ||
291 | err: | ||
292 | dprintk(verbose, MB86A16_ERROR, 1, "I2C transfer error"); | ||
293 | return -EREMOTEIO; | ||
294 | } | ||
295 | |||
296 | |||
297 | static int EN_set(struct mb86a16_state *state, | ||
298 | int cren, | ||
299 | int afcen) | ||
300 | { | ||
301 | unsigned char val; | ||
302 | |||
303 | val = 0x7a | (cren << 7) | (afcen << 2); | ||
304 | if (mb86a16_write(state, 0x49, val) < 0) | ||
305 | goto err; | ||
306 | |||
307 | return 0; | ||
308 | err: | ||
309 | dprintk(verbose, MB86A16_ERROR, 1, "I2C transfer error"); | ||
310 | return -EREMOTEIO; | ||
311 | } | ||
312 | |||
313 | static int AFCEXEN_set(struct mb86a16_state *state, | ||
314 | int afcexen, | ||
315 | int smrt) | ||
316 | { | ||
317 | unsigned char AFCA ; | ||
318 | |||
319 | if (smrt > 18875) | ||
320 | AFCA = 4; | ||
321 | else if (smrt > 9375) | ||
322 | AFCA = 3; | ||
323 | else if (smrt > 2250) | ||
324 | AFCA = 2; | ||
325 | else | ||
326 | AFCA = 1; | ||
327 | |||
328 | if (mb86a16_write(state, 0x2a, 0x02 | (afcexen << 5) | (AFCA << 2)) < 0) | ||
329 | goto err; | ||
330 | |||
331 | return 0; | ||
332 | |||
333 | err: | ||
334 | dprintk(verbose, MB86A16_ERROR, 1, "I2C transfer error"); | ||
335 | return -EREMOTEIO; | ||
336 | } | ||
337 | |||
338 | static int DAGC_data_set(struct mb86a16_state *state, | ||
339 | unsigned char DAGCA, | ||
340 | unsigned char DAGCW) | ||
341 | { | ||
342 | if (mb86a16_write(state, 0x2d, (DAGCA << 3) | DAGCW) < 0) | ||
343 | goto err; | ||
344 | |||
345 | return 0; | ||
346 | |||
347 | err: | ||
348 | dprintk(verbose, MB86A16_ERROR, 1, "I2C transfer error"); | ||
349 | return -EREMOTEIO; | ||
350 | } | ||
351 | |||
352 | static void smrt_info_get(struct mb86a16_state *state, int rate) | ||
353 | { | ||
354 | if (rate >= 37501) { | ||
355 | state->deci = 0; state->csel = 0; state->rsel = 0; | ||
356 | } else if (rate >= 30001) { | ||
357 | state->deci = 0; state->csel = 0; state->rsel = 1; | ||
358 | } else if (rate >= 26251) { | ||
359 | state->deci = 0; state->csel = 1; state->rsel = 0; | ||
360 | } else if (rate >= 22501) { | ||
361 | state->deci = 0; state->csel = 1; state->rsel = 1; | ||
362 | } else if (rate >= 18751) { | ||
363 | state->deci = 1; state->csel = 0; state->rsel = 0; | ||
364 | } else if (rate >= 15001) { | ||
365 | state->deci = 1; state->csel = 0; state->rsel = 1; | ||
366 | } else if (rate >= 13126) { | ||
367 | state->deci = 1; state->csel = 1; state->rsel = 0; | ||
368 | } else if (rate >= 11251) { | ||
369 | state->deci = 1; state->csel = 1; state->rsel = 1; | ||
370 | } else if (rate >= 9376) { | ||
371 | state->deci = 2; state->csel = 0; state->rsel = 0; | ||
372 | } else if (rate >= 7501) { | ||
373 | state->deci = 2; state->csel = 0; state->rsel = 1; | ||
374 | } else if (rate >= 6563) { | ||
375 | state->deci = 2; state->csel = 1; state->rsel = 0; | ||
376 | } else if (rate >= 5626) { | ||
377 | state->deci = 2; state->csel = 1; state->rsel = 1; | ||
378 | } else if (rate >= 4688) { | ||
379 | state->deci = 3; state->csel = 0; state->rsel = 0; | ||
380 | } else if (rate >= 3751) { | ||
381 | state->deci = 3; state->csel = 0; state->rsel = 1; | ||
382 | } else if (rate >= 3282) { | ||
383 | state->deci = 3; state->csel = 1; state->rsel = 0; | ||
384 | } else if (rate >= 2814) { | ||
385 | state->deci = 3; state->csel = 1; state->rsel = 1; | ||
386 | } else if (rate >= 2344) { | ||
387 | state->deci = 4; state->csel = 0; state->rsel = 0; | ||
388 | } else if (rate >= 1876) { | ||
389 | state->deci = 4; state->csel = 0; state->rsel = 1; | ||
390 | } else if (rate >= 1641) { | ||
391 | state->deci = 4; state->csel = 1; state->rsel = 0; | ||
392 | } else if (rate >= 1407) { | ||
393 | state->deci = 4; state->csel = 1; state->rsel = 1; | ||
394 | } else if (rate >= 1172) { | ||
395 | state->deci = 5; state->csel = 0; state->rsel = 0; | ||
396 | } else if (rate >= 939) { | ||
397 | state->deci = 5; state->csel = 0; state->rsel = 1; | ||
398 | } else if (rate >= 821) { | ||
399 | state->deci = 5; state->csel = 1; state->rsel = 0; | ||
400 | } else { | ||
401 | state->deci = 5; state->csel = 1; state->rsel = 1; | ||
402 | } | ||
403 | |||
404 | if (state->csel == 0) | ||
405 | state->master_clk = 92000; | ||
406 | else | ||
407 | state->master_clk = 61333; | ||
408 | |||
409 | } | ||
410 | |||
411 | static int signal_det(struct mb86a16_state *state, | ||
412 | int smrt, | ||
413 | unsigned char *SIG) | ||
414 | { | ||
415 | |||
416 | int ret ; | ||
417 | int smrtd ; | ||
418 | int wait_sym ; | ||
419 | |||
420 | u32 wait_t; | ||
421 | unsigned char S[3] ; | ||
422 | int i ; | ||
423 | |||
424 | if (*SIG > 45) { | ||
425 | if (CNTM_set(state, 2, 1, 2) < 0) { | ||
426 | dprintk(verbose, MB86A16_ERROR, 1, "CNTM set Error"); | ||
427 | return -1; | ||
428 | } | ||
429 | wait_sym = 40000; | ||
430 | } else { | ||
431 | if (CNTM_set(state, 3, 1, 2) < 0) { | ||
432 | dprintk(verbose, MB86A16_ERROR, 1, "CNTM set Error"); | ||
433 | return -1; | ||
434 | } | ||
435 | wait_sym = 80000; | ||
436 | } | ||
437 | for (i = 0; i < 3; i++) { | ||
438 | if (i == 0) | ||
439 | smrtd = smrt * 98 / 100; | ||
440 | else if (i == 1) | ||
441 | smrtd = smrt; | ||
442 | else | ||
443 | smrtd = smrt * 102 / 100; | ||
444 | smrt_info_get(state, smrtd); | ||
445 | smrt_set(state, smrtd); | ||
446 | srst(state); | ||
447 | wait_t = (wait_sym + 99 * smrtd / 100) / smrtd; | ||
448 | if (wait_t == 0) | ||
449 | wait_t = 1; | ||
450 | msleep_interruptible(10); | ||
451 | if (mb86a16_read(state, 0x37, &(S[i])) != 2) { | ||
452 | dprintk(verbose, MB86A16_ERROR, 1, "I2C transfer error"); | ||
453 | return -EREMOTEIO; | ||
454 | } | ||
455 | } | ||
456 | if ((S[1] > S[0] * 112 / 100) && | ||
457 | (S[1] > S[2] * 112 / 100)) { | ||
458 | |||
459 | ret = 1; | ||
460 | } else { | ||
461 | ret = 0; | ||
462 | } | ||
463 | *SIG = S[1]; | ||
464 | |||
465 | if (CNTM_set(state, 0, 1, 2) < 0) { | ||
466 | dprintk(verbose, MB86A16_ERROR, 1, "CNTM set Error"); | ||
467 | return -1; | ||
468 | } | ||
469 | |||
470 | return ret; | ||
471 | } | ||
472 | |||
473 | static int rf_val_set(struct mb86a16_state *state, | ||
474 | int f, | ||
475 | int smrt, | ||
476 | unsigned char R) | ||
477 | { | ||
478 | unsigned char C, F, B; | ||
479 | int M; | ||
480 | unsigned char rf_val[5]; | ||
481 | int ack = -1; | ||
482 | |||
483 | if (smrt > 37750) | ||
484 | C = 1; | ||
485 | else if (smrt > 18875) | ||
486 | C = 2; | ||
487 | else if (smrt > 5500) | ||
488 | C = 3; | ||
489 | else | ||
490 | C = 4; | ||
491 | |||
492 | if (smrt > 30500) | ||
493 | F = 3; | ||
494 | else if (smrt > 9375) | ||
495 | F = 1; | ||
496 | else if (smrt > 4625) | ||
497 | F = 0; | ||
498 | else | ||
499 | F = 2; | ||
500 | |||
501 | if (f < 1060) | ||
502 | B = 0; | ||
503 | else if (f < 1175) | ||
504 | B = 1; | ||
505 | else if (f < 1305) | ||
506 | B = 2; | ||
507 | else if (f < 1435) | ||
508 | B = 3; | ||
509 | else if (f < 1570) | ||
510 | B = 4; | ||
511 | else if (f < 1715) | ||
512 | B = 5; | ||
513 | else if (f < 1845) | ||
514 | B = 6; | ||
515 | else if (f < 1980) | ||
516 | B = 7; | ||
517 | else if (f < 2080) | ||
518 | B = 8; | ||
519 | else | ||
520 | B = 9; | ||
521 | |||
522 | M = f * (1 << R) / 2; | ||
523 | |||
524 | rf_val[0] = 0x01 | (C << 3) | (F << 1); | ||
525 | rf_val[1] = (R << 5) | ((M & 0x1f000) >> 12); | ||
526 | rf_val[2] = (M & 0x00ff0) >> 4; | ||
527 | rf_val[3] = ((M & 0x0000f) << 4) | B; | ||
528 | |||
529 | /* Frequency Set */ | ||
530 | if (mb86a16_write(state, 0x21, rf_val[0]) < 0) | ||
531 | ack = 0; | ||
532 | if (mb86a16_write(state, 0x22, rf_val[1]) < 0) | ||
533 | ack = 0; | ||
534 | if (mb86a16_write(state, 0x23, rf_val[2]) < 0) | ||
535 | ack = 0; | ||
536 | if (mb86a16_write(state, 0x24, rf_val[3]) < 0) | ||
537 | ack = 0; | ||
538 | if (mb86a16_write(state, 0x25, 0x01) < 0) | ||
539 | ack = 0; | ||
540 | if (ack == 0) { | ||
541 | dprintk(verbose, MB86A16_ERROR, 1, "RF Setup - I2C transfer error"); | ||
542 | return -EREMOTEIO; | ||
543 | } | ||
544 | |||
545 | return 0; | ||
546 | } | ||
547 | |||
548 | static int afcerr_chk(struct mb86a16_state *state) | ||
549 | { | ||
550 | unsigned char AFCM_L, AFCM_H ; | ||
551 | int AFCM ; | ||
552 | int afcm, afcerr ; | ||
553 | |||
554 | if (mb86a16_read(state, 0x0e, &AFCM_L) != 2) | ||
555 | goto err; | ||
556 | if (mb86a16_read(state, 0x0f, &AFCM_H) != 2) | ||
557 | goto err; | ||
558 | |||
559 | AFCM = (AFCM_H << 8) + AFCM_L; | ||
560 | |||
561 | if (AFCM > 2048) | ||
562 | afcm = AFCM - 4096; | ||
563 | else | ||
564 | afcm = AFCM; | ||
565 | afcerr = afcm * state->master_clk / 8192; | ||
566 | |||
567 | return afcerr; | ||
568 | |||
569 | err: | ||
570 | dprintk(verbose, MB86A16_ERROR, 1, "I2C transfer error"); | ||
571 | return -EREMOTEIO; | ||
572 | } | ||
573 | |||
574 | static int dagcm_val_get(struct mb86a16_state *state) | ||
575 | { | ||
576 | int DAGCM; | ||
577 | unsigned char DAGCM_H, DAGCM_L; | ||
578 | |||
579 | if (mb86a16_read(state, 0x45, &DAGCM_L) != 2) | ||
580 | goto err; | ||
581 | if (mb86a16_read(state, 0x46, &DAGCM_H) != 2) | ||
582 | goto err; | ||
583 | |||
584 | DAGCM = (DAGCM_H << 8) + DAGCM_L; | ||
585 | |||
586 | return DAGCM; | ||
587 | |||
588 | err: | ||
589 | dprintk(verbose, MB86A16_ERROR, 1, "I2C transfer error"); | ||
590 | return -EREMOTEIO; | ||
591 | } | ||
592 | |||
593 | static int mb86a16_read_status(struct dvb_frontend *fe, fe_status_t *status) | ||
594 | { | ||
595 | u8 stat, stat2; | ||
596 | struct mb86a16_state *state = fe->demodulator_priv; | ||
597 | |||
598 | *status = 0; | ||
599 | |||
600 | if (mb86a16_read(state, MB86A16_SIG1, &stat) != 2) | ||
601 | goto err; | ||
602 | if (mb86a16_read(state, MB86A16_SIG2, &stat2) != 2) | ||
603 | goto err; | ||
604 | if ((stat > 25) && (stat2 > 25)) | ||
605 | *status |= FE_HAS_SIGNAL; | ||
606 | if ((stat > 45) && (stat2 > 45)) | ||
607 | *status |= FE_HAS_CARRIER; | ||
608 | |||
609 | if (mb86a16_read(state, MB86A16_STATUS, &stat) != 2) | ||
610 | goto err; | ||
611 | |||
612 | if (stat & 0x01) | ||
613 | *status |= FE_HAS_SYNC; | ||
614 | if (stat & 0x01) | ||
615 | *status |= FE_HAS_VITERBI; | ||
616 | |||
617 | if (mb86a16_read(state, MB86A16_FRAMESYNC, &stat) != 2) | ||
618 | goto err; | ||
619 | |||
620 | if ((stat & 0x0f) && (*status & FE_HAS_VITERBI)) | ||
621 | *status |= FE_HAS_LOCK; | ||
622 | |||
623 | return 0; | ||
624 | |||
625 | err: | ||
626 | dprintk(verbose, MB86A16_ERROR, 1, "I2C transfer error"); | ||
627 | return -EREMOTEIO; | ||
628 | } | ||
629 | |||
630 | static int sync_chk(struct mb86a16_state *state, | ||
631 | unsigned char *VIRM) | ||
632 | { | ||
633 | unsigned char val; | ||
634 | int sync; | ||
635 | |||
636 | if (mb86a16_read(state, 0x0d, &val) != 2) | ||
637 | goto err; | ||
638 | |||
639 | dprintk(verbose, MB86A16_INFO, 1, "Status = %02x,", val); | ||
640 | sync = val & 0x01; | ||
641 | *VIRM = (val & 0x1c) >> 2; | ||
642 | |||
643 | return sync; | ||
644 | err: | ||
645 | dprintk(verbose, MB86A16_ERROR, 1, "I2C transfer error"); | ||
646 | return -EREMOTEIO; | ||
647 | |||
648 | } | ||
649 | |||
650 | static int freqerr_chk(struct mb86a16_state *state, | ||
651 | int fTP, | ||
652 | int smrt, | ||
653 | int unit) | ||
654 | { | ||
655 | unsigned char CRM, AFCML, AFCMH; | ||
656 | unsigned char temp1, temp2, temp3; | ||
657 | int crm, afcm, AFCM; | ||
658 | int crrerr, afcerr; /* kHz */ | ||
659 | int frqerr; /* MHz */ | ||
660 | int afcen, afcexen = 0; | ||
661 | int R, M, fOSC, fOSC_OFS; | ||
662 | |||
663 | if (mb86a16_read(state, 0x43, &CRM) != 2) | ||
664 | goto err; | ||
665 | |||
666 | if (CRM > 127) | ||
667 | crm = CRM - 256; | ||
668 | else | ||
669 | crm = CRM; | ||
670 | |||
671 | crrerr = smrt * crm / 256; | ||
672 | if (mb86a16_read(state, 0x49, &temp1) != 2) | ||
673 | goto err; | ||
674 | |||
675 | afcen = (temp1 & 0x04) >> 2; | ||
676 | if (afcen == 0) { | ||
677 | if (mb86a16_read(state, 0x2a, &temp1) != 2) | ||
678 | goto err; | ||
679 | afcexen = (temp1 & 0x20) >> 5; | ||
680 | } | ||
681 | |||
682 | if (afcen == 1) { | ||
683 | if (mb86a16_read(state, 0x0e, &AFCML) != 2) | ||
684 | goto err; | ||
685 | if (mb86a16_read(state, 0x0f, &AFCMH) != 2) | ||
686 | goto err; | ||
687 | } else if (afcexen == 1) { | ||
688 | if (mb86a16_read(state, 0x2b, &AFCML) != 2) | ||
689 | goto err; | ||
690 | if (mb86a16_read(state, 0x2c, &AFCMH) != 2) | ||
691 | goto err; | ||
692 | } | ||
693 | if ((afcen == 1) || (afcexen == 1)) { | ||
694 | smrt_info_get(state, smrt); | ||
695 | AFCM = ((AFCMH & 0x01) << 8) + AFCML; | ||
696 | if (AFCM > 255) | ||
697 | afcm = AFCM - 512; | ||
698 | else | ||
699 | afcm = AFCM; | ||
700 | |||
701 | afcerr = afcm * state->master_clk / 8192; | ||
702 | } else | ||
703 | afcerr = 0; | ||
704 | |||
705 | if (mb86a16_read(state, 0x22, &temp1) != 2) | ||
706 | goto err; | ||
707 | if (mb86a16_read(state, 0x23, &temp2) != 2) | ||
708 | goto err; | ||
709 | if (mb86a16_read(state, 0x24, &temp3) != 2) | ||
710 | goto err; | ||
711 | |||
712 | R = (temp1 & 0xe0) >> 5; | ||
713 | M = ((temp1 & 0x1f) << 12) + (temp2 << 4) + (temp3 >> 4); | ||
714 | if (R == 0) | ||
715 | fOSC = 2 * M; | ||
716 | else | ||
717 | fOSC = M; | ||
718 | |||
719 | fOSC_OFS = fOSC - fTP; | ||
720 | |||
721 | if (unit == 0) { /* MHz */ | ||
722 | if (crrerr + afcerr + fOSC_OFS * 1000 >= 0) | ||
723 | frqerr = (crrerr + afcerr + fOSC_OFS * 1000 + 500) / 1000; | ||
724 | else | ||
725 | frqerr = (crrerr + afcerr + fOSC_OFS * 1000 - 500) / 1000; | ||
726 | } else { /* kHz */ | ||
727 | frqerr = crrerr + afcerr + fOSC_OFS * 1000; | ||
728 | } | ||
729 | |||
730 | return frqerr; | ||
731 | err: | ||
732 | dprintk(verbose, MB86A16_ERROR, 1, "I2C transfer error"); | ||
733 | return -EREMOTEIO; | ||
734 | } | ||
735 | |||
736 | static unsigned char vco_dev_get(struct mb86a16_state *state, int smrt) | ||
737 | { | ||
738 | unsigned char R; | ||
739 | |||
740 | if (smrt > 9375) | ||
741 | R = 0; | ||
742 | else | ||
743 | R = 1; | ||
744 | |||
745 | return R; | ||
746 | } | ||
747 | |||
748 | static void swp_info_get(struct mb86a16_state *state, | ||
749 | int fOSC_start, | ||
750 | int smrt, | ||
751 | int v, int R, | ||
752 | int swp_ofs, | ||
753 | int *fOSC, | ||
754 | int *afcex_freq, | ||
755 | unsigned char *AFCEX_L, | ||
756 | unsigned char *AFCEX_H) | ||
757 | { | ||
758 | int AFCEX ; | ||
759 | int crnt_swp_freq ; | ||
760 | |||
761 | crnt_swp_freq = fOSC_start * 1000 + v * swp_ofs; | ||
762 | |||
763 | if (R == 0) | ||
764 | *fOSC = (crnt_swp_freq + 1000) / 2000 * 2; | ||
765 | else | ||
766 | *fOSC = (crnt_swp_freq + 500) / 1000; | ||
767 | |||
768 | if (*fOSC >= crnt_swp_freq) | ||
769 | *afcex_freq = *fOSC * 1000 - crnt_swp_freq; | ||
770 | else | ||
771 | *afcex_freq = crnt_swp_freq - *fOSC * 1000; | ||
772 | |||
773 | AFCEX = *afcex_freq * 8192 / state->master_clk; | ||
774 | *AFCEX_L = AFCEX & 0x00ff; | ||
775 | *AFCEX_H = (AFCEX & 0x0f00) >> 8; | ||
776 | } | ||
777 | |||
778 | |||
779 | static int swp_freq_calcuation(struct mb86a16_state *state, int i, int v, int *V, int vmax, int vmin, | ||
780 | int SIGMIN, int fOSC, int afcex_freq, int swp_ofs, unsigned char *SIG1) | ||
781 | { | ||
782 | int swp_freq ; | ||
783 | |||
784 | if ((i % 2 == 1) && (v <= vmax)) { | ||
785 | /* positive v (case 1) */ | ||
786 | if ((v - 1 == vmin) && | ||
787 | (*(V + 30 + v) >= 0) && | ||
788 | (*(V + 30 + v - 1) >= 0) && | ||
789 | (*(V + 30 + v - 1) > *(V + 30 + v)) && | ||
790 | (*(V + 30 + v - 1) > SIGMIN)) { | ||
791 | |||
792 | swp_freq = fOSC * 1000 + afcex_freq - swp_ofs; | ||
793 | *SIG1 = *(V + 30 + v - 1); | ||
794 | } else if ((v == vmax) && | ||
795 | (*(V + 30 + v) >= 0) && | ||
796 | (*(V + 30 + v - 1) >= 0) && | ||
797 | (*(V + 30 + v) > *(V + 30 + v - 1)) && | ||
798 | (*(V + 30 + v) > SIGMIN)) { | ||
799 | /* (case 2) */ | ||
800 | swp_freq = fOSC * 1000 + afcex_freq; | ||
801 | *SIG1 = *(V + 30 + v); | ||
802 | } else if ((*(V + 30 + v) > 0) && | ||
803 | (*(V + 30 + v - 1) > 0) && | ||
804 | (*(V + 30 + v - 2) > 0) && | ||
805 | (*(V + 30 + v - 3) > 0) && | ||
806 | (*(V + 30 + v - 1) > *(V + 30 + v)) && | ||
807 | (*(V + 30 + v - 2) > *(V + 30 + v - 3)) && | ||
808 | ((*(V + 30 + v - 1) > SIGMIN) || | ||
809 | (*(V + 30 + v - 2) > SIGMIN))) { | ||
810 | /* (case 3) */ | ||
811 | if (*(V + 30 + v - 1) >= *(V + 30 + v - 2)) { | ||
812 | swp_freq = fOSC * 1000 + afcex_freq - swp_ofs; | ||
813 | *SIG1 = *(V + 30 + v - 1); | ||
814 | } else { | ||
815 | swp_freq = fOSC * 1000 + afcex_freq - swp_ofs * 2; | ||
816 | *SIG1 = *(V + 30 + v - 2); | ||
817 | } | ||
818 | } else if ((v == vmax) && | ||
819 | (*(V + 30 + v) >= 0) && | ||
820 | (*(V + 30 + v - 1) >= 0) && | ||
821 | (*(V + 30 + v - 2) >= 0) && | ||
822 | (*(V + 30 + v) > *(V + 30 + v - 2)) && | ||
823 | (*(V + 30 + v - 1) > *(V + 30 + v - 2)) && | ||
824 | ((*(V + 30 + v) > SIGMIN) || | ||
825 | (*(V + 30 + v - 1) > SIGMIN))) { | ||
826 | /* (case 4) */ | ||
827 | if (*(V + 30 + v) >= *(V + 30 + v - 1)) { | ||
828 | swp_freq = fOSC * 1000 + afcex_freq; | ||
829 | *SIG1 = *(V + 30 + v); | ||
830 | } else { | ||
831 | swp_freq = fOSC * 1000 + afcex_freq - swp_ofs; | ||
832 | *SIG1 = *(V + 30 + v - 1); | ||
833 | } | ||
834 | } else { | ||
835 | swp_freq = -1 ; | ||
836 | } | ||
837 | } else if ((i % 2 == 0) && (v >= vmin)) { | ||
838 | /* Negative v (case 1) */ | ||
839 | if ((*(V + 30 + v) > 0) && | ||
840 | (*(V + 30 + v + 1) > 0) && | ||
841 | (*(V + 30 + v + 2) > 0) && | ||
842 | (*(V + 30 + v + 1) > *(V + 30 + v)) && | ||
843 | (*(V + 30 + v + 1) > *(V + 30 + v + 2)) && | ||
844 | (*(V + 30 + v + 1) > SIGMIN)) { | ||
845 | |||
846 | swp_freq = fOSC * 1000 + afcex_freq + swp_ofs; | ||
847 | *SIG1 = *(V + 30 + v + 1); | ||
848 | } else if ((v + 1 == vmax) && | ||
849 | (*(V + 30 + v) >= 0) && | ||
850 | (*(V + 30 + v + 1) >= 0) && | ||
851 | (*(V + 30 + v + 1) > *(V + 30 + v)) && | ||
852 | (*(V + 30 + v + 1) > SIGMIN)) { | ||
853 | /* (case 2) */ | ||
854 | swp_freq = fOSC * 1000 + afcex_freq + swp_ofs; | ||
855 | *SIG1 = *(V + 30 + v); | ||
856 | } else if ((v == vmin) && | ||
857 | (*(V + 30 + v) > 0) && | ||
858 | (*(V + 30 + v + 1) > 0) && | ||
859 | (*(V + 30 + v + 2) > 0) && | ||
860 | (*(V + 30 + v) > *(V + 30 + v + 1)) && | ||
861 | (*(V + 30 + v) > *(V + 30 + v + 2)) && | ||
862 | (*(V + 30 + v) > SIGMIN)) { | ||
863 | /* (case 3) */ | ||
864 | swp_freq = fOSC * 1000 + afcex_freq; | ||
865 | *SIG1 = *(V + 30 + v); | ||
866 | } else if ((*(V + 30 + v) >= 0) && | ||
867 | (*(V + 30 + v + 1) >= 0) && | ||
868 | (*(V + 30 + v + 2) >= 0) && | ||
869 | (*(V + 30 + v + 3) >= 0) && | ||
870 | (*(V + 30 + v + 1) > *(V + 30 + v)) && | ||
871 | (*(V + 30 + v + 2) > *(V + 30 + v + 3)) && | ||
872 | ((*(V + 30 + v + 1) > SIGMIN) || | ||
873 | (*(V + 30 + v + 2) > SIGMIN))) { | ||
874 | /* (case 4) */ | ||
875 | if (*(V + 30 + v + 1) >= *(V + 30 + v + 2)) { | ||
876 | swp_freq = fOSC * 1000 + afcex_freq + swp_ofs; | ||
877 | *SIG1 = *(V + 30 + v + 1); | ||
878 | } else { | ||
879 | swp_freq = fOSC * 1000 + afcex_freq + swp_ofs * 2; | ||
880 | *SIG1 = *(V + 30 + v + 2); | ||
881 | } | ||
882 | } else if ((*(V + 30 + v) >= 0) && | ||
883 | (*(V + 30 + v + 1) >= 0) && | ||
884 | (*(V + 30 + v + 2) >= 0) && | ||
885 | (*(V + 30 + v + 3) >= 0) && | ||
886 | (*(V + 30 + v) > *(V + 30 + v + 2)) && | ||
887 | (*(V + 30 + v + 1) > *(V + 30 + v + 2)) && | ||
888 | (*(V + 30 + v) > *(V + 30 + v + 3)) && | ||
889 | (*(V + 30 + v + 1) > *(V + 30 + v + 3)) && | ||
890 | ((*(V + 30 + v) > SIGMIN) || | ||
891 | (*(V + 30 + v + 1) > SIGMIN))) { | ||
892 | /* (case 5) */ | ||
893 | if (*(V + 30 + v) >= *(V + 30 + v + 1)) { | ||
894 | swp_freq = fOSC * 1000 + afcex_freq; | ||
895 | *SIG1 = *(V + 30 + v); | ||
896 | } else { | ||
897 | swp_freq = fOSC * 1000 + afcex_freq + swp_ofs; | ||
898 | *SIG1 = *(V + 30 + v + 1); | ||
899 | } | ||
900 | } else if ((v + 2 == vmin) && | ||
901 | (*(V + 30 + v) >= 0) && | ||
902 | (*(V + 30 + v + 1) >= 0) && | ||
903 | (*(V + 30 + v + 2) >= 0) && | ||
904 | (*(V + 30 + v + 1) > *(V + 30 + v)) && | ||
905 | (*(V + 30 + v + 2) > *(V + 30 + v)) && | ||
906 | ((*(V + 30 + v + 1) > SIGMIN) || | ||
907 | (*(V + 30 + v + 2) > SIGMIN))) { | ||
908 | /* (case 6) */ | ||
909 | if (*(V + 30 + v + 1) >= *(V + 30 + v + 2)) { | ||
910 | swp_freq = fOSC * 1000 + afcex_freq + swp_ofs; | ||
911 | *SIG1 = *(V + 30 + v + 1); | ||
912 | } else { | ||
913 | swp_freq = fOSC * 1000 + afcex_freq + swp_ofs * 2; | ||
914 | *SIG1 = *(V + 30 + v + 2); | ||
915 | } | ||
916 | } else if ((vmax == 0) && (vmin == 0) && (*(V + 30 + v) > SIGMIN)) { | ||
917 | swp_freq = fOSC * 1000; | ||
918 | *SIG1 = *(V + 30 + v); | ||
919 | } else | ||
920 | swp_freq = -1; | ||
921 | } else | ||
922 | swp_freq = -1; | ||
923 | |||
924 | return swp_freq; | ||
925 | } | ||
926 | |||
927 | static void swp_info_get2(struct mb86a16_state *state, | ||
928 | int smrt, | ||
929 | int R, | ||
930 | int swp_freq, | ||
931 | int *afcex_freq, | ||
932 | int *fOSC, | ||
933 | unsigned char *AFCEX_L, | ||
934 | unsigned char *AFCEX_H) | ||
935 | { | ||
936 | int AFCEX ; | ||
937 | |||
938 | if (R == 0) | ||
939 | *fOSC = (swp_freq + 1000) / 2000 * 2; | ||
940 | else | ||
941 | *fOSC = (swp_freq + 500) / 1000; | ||
942 | |||
943 | if (*fOSC >= swp_freq) | ||
944 | *afcex_freq = *fOSC * 1000 - swp_freq; | ||
945 | else | ||
946 | *afcex_freq = swp_freq - *fOSC * 1000; | ||
947 | |||
948 | AFCEX = *afcex_freq * 8192 / state->master_clk; | ||
949 | *AFCEX_L = AFCEX & 0x00ff; | ||
950 | *AFCEX_H = (AFCEX & 0x0f00) >> 8; | ||
951 | } | ||
952 | |||
953 | static void afcex_info_get(struct mb86a16_state *state, | ||
954 | int afcex_freq, | ||
955 | unsigned char *AFCEX_L, | ||
956 | unsigned char *AFCEX_H) | ||
957 | { | ||
958 | int AFCEX ; | ||
959 | |||
960 | AFCEX = afcex_freq * 8192 / state->master_clk; | ||
961 | *AFCEX_L = AFCEX & 0x00ff; | ||
962 | *AFCEX_H = (AFCEX & 0x0f00) >> 8; | ||
963 | } | ||
964 | |||
965 | static int SEQ_set(struct mb86a16_state *state, unsigned char loop) | ||
966 | { | ||
967 | /* SLOCK0 = 0 */ | ||
968 | if (mb86a16_write(state, 0x32, 0x02 | (loop << 2)) < 0) { | ||
969 | dprintk(verbose, MB86A16_ERROR, 1, "I2C transfer error"); | ||
970 | return -EREMOTEIO; | ||
971 | } | ||
972 | |||
973 | return 0; | ||
974 | } | ||
975 | |||
976 | static int iq_vt_set(struct mb86a16_state *state, unsigned char IQINV) | ||
977 | { | ||
978 | /* Viterbi Rate, IQ Settings */ | ||
979 | if (mb86a16_write(state, 0x06, 0xdf | (IQINV << 5)) < 0) { | ||
980 | dprintk(verbose, MB86A16_ERROR, 1, "I2C transfer error"); | ||
981 | return -EREMOTEIO; | ||
982 | } | ||
983 | |||
984 | return 0; | ||
985 | } | ||
986 | |||
987 | static int FEC_srst(struct mb86a16_state *state) | ||
988 | { | ||
989 | if (mb86a16_write(state, MB86A16_RESET, 0x02) < 0) { | ||
990 | dprintk(verbose, MB86A16_ERROR, 1, "I2C transfer error"); | ||
991 | return -EREMOTEIO; | ||
992 | } | ||
993 | |||
994 | return 0; | ||
995 | } | ||
996 | |||
997 | static int S2T_set(struct mb86a16_state *state, unsigned char S2T) | ||
998 | { | ||
999 | if (mb86a16_write(state, 0x34, 0x70 | S2T) < 0) { | ||
1000 | dprintk(verbose, MB86A16_ERROR, 1, "I2C transfer error"); | ||
1001 | return -EREMOTEIO; | ||
1002 | } | ||
1003 | |||
1004 | return 0; | ||
1005 | } | ||
1006 | |||
1007 | static int S45T_set(struct mb86a16_state *state, unsigned char S4T, unsigned char S5T) | ||
1008 | { | ||
1009 | if (mb86a16_write(state, 0x35, 0x00 | (S5T << 4) | S4T) < 0) { | ||
1010 | dprintk(verbose, MB86A16_ERROR, 1, "I2C transfer error"); | ||
1011 | return -EREMOTEIO; | ||
1012 | } | ||
1013 | |||
1014 | return 0; | ||
1015 | } | ||
1016 | |||
1017 | |||
1018 | static int mb86a16_set_fe(struct mb86a16_state *state) | ||
1019 | { | ||
1020 | u8 agcval, cnmval; | ||
1021 | |||
1022 | int i, j; | ||
1023 | int fOSC = 0; | ||
1024 | int fOSC_start = 0; | ||
1025 | int wait_t; | ||
1026 | int fcp; | ||
1027 | int swp_ofs; | ||
1028 | int V[60]; | ||
1029 | u8 SIG1MIN; | ||
1030 | |||
1031 | unsigned char CREN, AFCEN, AFCEXEN; | ||
1032 | unsigned char SIG1; | ||
1033 | unsigned char TIMINT1, TIMINT2, TIMEXT; | ||
1034 | unsigned char S0T, S1T; | ||
1035 | unsigned char S2T; | ||
1036 | /* unsigned char S2T, S3T; */ | ||
1037 | unsigned char S4T, S5T; | ||
1038 | unsigned char AFCEX_L, AFCEX_H; | ||
1039 | unsigned char R; | ||
1040 | unsigned char VIRM; | ||
1041 | unsigned char ETH, VIA; | ||
1042 | unsigned char junk; | ||
1043 | |||
1044 | int loop; | ||
1045 | int ftemp; | ||
1046 | int v, vmax, vmin; | ||
1047 | int vmax_his, vmin_his; | ||
1048 | int swp_freq, prev_swp_freq[20]; | ||
1049 | int prev_freq_num; | ||
1050 | int signal_dupl; | ||
1051 | int afcex_freq; | ||
1052 | int signal; | ||
1053 | int afcerr; | ||
1054 | int temp_freq, delta_freq; | ||
1055 | int dagcm[4]; | ||
1056 | int smrt_d; | ||
1057 | /* int freq_err; */ | ||
1058 | int n; | ||
1059 | int ret = -1; | ||
1060 | int sync; | ||
1061 | |||
1062 | dprintk(verbose, MB86A16_INFO, 1, "freq=%d Mhz, symbrt=%d Ksps", state->frequency, state->srate); | ||
1063 | |||
1064 | fcp = 3000; | ||
1065 | swp_ofs = state->srate / 4; | ||
1066 | |||
1067 | for (i = 0; i < 60; i++) | ||
1068 | V[i] = -1; | ||
1069 | |||
1070 | for (i = 0; i < 20; i++) | ||
1071 | prev_swp_freq[i] = 0; | ||
1072 | |||
1073 | SIG1MIN = 25; | ||
1074 | |||
1075 | for (n = 0; ((n < 3) && (ret == -1)); n++) { | ||
1076 | SEQ_set(state, 0); | ||
1077 | iq_vt_set(state, 0); | ||
1078 | |||
1079 | CREN = 0; | ||
1080 | AFCEN = 0; | ||
1081 | AFCEXEN = 1; | ||
1082 | TIMINT1 = 0; | ||
1083 | TIMINT2 = 1; | ||
1084 | TIMEXT = 2; | ||
1085 | S1T = 0; | ||
1086 | S0T = 0; | ||
1087 | |||
1088 | if (initial_set(state) < 0) { | ||
1089 | dprintk(verbose, MB86A16_ERROR, 1, "initial set failed"); | ||
1090 | return -1; | ||
1091 | } | ||
1092 | if (DAGC_data_set(state, 3, 2) < 0) { | ||
1093 | dprintk(verbose, MB86A16_ERROR, 1, "DAGC data set error"); | ||
1094 | return -1; | ||
1095 | } | ||
1096 | if (EN_set(state, CREN, AFCEN) < 0) { | ||
1097 | dprintk(verbose, MB86A16_ERROR, 1, "EN set error"); | ||
1098 | return -1; /* (0, 0) */ | ||
1099 | } | ||
1100 | if (AFCEXEN_set(state, AFCEXEN, state->srate) < 0) { | ||
1101 | dprintk(verbose, MB86A16_ERROR, 1, "AFCEXEN set error"); | ||
1102 | return -1; /* (1, smrt) = (1, symbolrate) */ | ||
1103 | } | ||
1104 | if (CNTM_set(state, TIMINT1, TIMINT2, TIMEXT) < 0) { | ||
1105 | dprintk(verbose, MB86A16_ERROR, 1, "CNTM set error"); | ||
1106 | return -1; /* (0, 1, 2) */ | ||
1107 | } | ||
1108 | if (S01T_set(state, S1T, S0T) < 0) { | ||
1109 | dprintk(verbose, MB86A16_ERROR, 1, "S01T set error"); | ||
1110 | return -1; /* (0, 0) */ | ||
1111 | } | ||
1112 | smrt_info_get(state, state->srate); | ||
1113 | if (smrt_set(state, state->srate) < 0) { | ||
1114 | dprintk(verbose, MB86A16_ERROR, 1, "smrt info get error"); | ||
1115 | return -1; | ||
1116 | } | ||
1117 | |||
1118 | R = vco_dev_get(state, state->srate); | ||
1119 | if (R == 1) | ||
1120 | fOSC_start = state->frequency; | ||
1121 | |||
1122 | else if (R == 0) { | ||
1123 | if (state->frequency % 2 == 0) { | ||
1124 | fOSC_start = state->frequency; | ||
1125 | } else { | ||
1126 | fOSC_start = state->frequency + 1; | ||
1127 | if (fOSC_start > 2150) | ||
1128 | fOSC_start = state->frequency - 1; | ||
1129 | } | ||
1130 | } | ||
1131 | loop = 1; | ||
1132 | ftemp = fOSC_start * 1000; | ||
1133 | vmax = 0 ; | ||
1134 | while (loop == 1) { | ||
1135 | ftemp = ftemp + swp_ofs; | ||
1136 | vmax++; | ||
1137 | |||
1138 | /* Upper bound */ | ||
1139 | if (ftemp > 2150000) { | ||
1140 | loop = 0; | ||
1141 | vmax--; | ||
1142 | } else { | ||
1143 | if ((ftemp == 2150000) || | ||
1144 | (ftemp - state->frequency * 1000 >= fcp + state->srate / 4)) | ||
1145 | loop = 0; | ||
1146 | } | ||
1147 | } | ||
1148 | |||
1149 | loop = 1; | ||
1150 | ftemp = fOSC_start * 1000; | ||
1151 | vmin = 0 ; | ||
1152 | while (loop == 1) { | ||
1153 | ftemp = ftemp - swp_ofs; | ||
1154 | vmin--; | ||
1155 | |||
1156 | /* Lower bound */ | ||
1157 | if (ftemp < 950000) { | ||
1158 | loop = 0; | ||
1159 | vmin++; | ||
1160 | } else { | ||
1161 | if ((ftemp == 950000) || | ||
1162 | (state->frequency * 1000 - ftemp >= fcp + state->srate / 4)) | ||
1163 | loop = 0; | ||
1164 | } | ||
1165 | } | ||
1166 | |||
1167 | wait_t = (8000 + state->srate / 2) / state->srate; | ||
1168 | if (wait_t == 0) | ||
1169 | wait_t = 1; | ||
1170 | |||
1171 | i = 0; | ||
1172 | j = 0; | ||
1173 | prev_freq_num = 0; | ||
1174 | loop = 1; | ||
1175 | signal = 0; | ||
1176 | vmax_his = 0; | ||
1177 | vmin_his = 0; | ||
1178 | v = 0; | ||
1179 | |||
1180 | while (loop == 1) { | ||
1181 | swp_info_get(state, fOSC_start, state->srate, | ||
1182 | v, R, swp_ofs, &fOSC, | ||
1183 | &afcex_freq, &AFCEX_L, &AFCEX_H); | ||
1184 | |||
1185 | udelay(100); | ||
1186 | if (rf_val_set(state, fOSC, state->srate, R) < 0) { | ||
1187 | dprintk(verbose, MB86A16_ERROR, 1, "rf val set error"); | ||
1188 | return -1; | ||
1189 | } | ||
1190 | udelay(100); | ||
1191 | if (afcex_data_set(state, AFCEX_L, AFCEX_H) < 0) { | ||
1192 | dprintk(verbose, MB86A16_ERROR, 1, "afcex data set error"); | ||
1193 | return -1; | ||
1194 | } | ||
1195 | if (srst(state) < 0) { | ||
1196 | dprintk(verbose, MB86A16_ERROR, 1, "srst error"); | ||
1197 | return -1; | ||
1198 | } | ||
1199 | msleep_interruptible(wait_t); | ||
1200 | |||
1201 | if (mb86a16_read(state, 0x37, &SIG1) != 2) { | ||
1202 | dprintk(verbose, MB86A16_ERROR, 1, "I2C transfer error"); | ||
1203 | return -1; | ||
1204 | } | ||
1205 | V[30 + v] = SIG1 ; | ||
1206 | swp_freq = swp_freq_calcuation(state, i, v, V, vmax, vmin, | ||
1207 | SIG1MIN, fOSC, afcex_freq, | ||
1208 | swp_ofs, &SIG1); /* changed */ | ||
1209 | |||
1210 | signal_dupl = 0; | ||
1211 | for (j = 0; j < prev_freq_num; j++) { | ||
1212 | if ((ABS(prev_swp_freq[j] - swp_freq)) < (swp_ofs * 3 / 2)) { | ||
1213 | signal_dupl = 1; | ||
1214 | dprintk(verbose, MB86A16_INFO, 1, "Probably Duplicate Signal, j = %d", j); | ||
1215 | } | ||
1216 | } | ||
1217 | if ((signal_dupl == 0) && (swp_freq > 0) && (ABS(swp_freq - state->frequency * 1000) < fcp + state->srate / 6)) { | ||
1218 | dprintk(verbose, MB86A16_DEBUG, 1, "------ Signal detect ------ [swp_freq=[%07d, srate=%05d]]", swp_freq, state->srate); | ||
1219 | prev_swp_freq[prev_freq_num] = swp_freq; | ||
1220 | prev_freq_num++; | ||
1221 | swp_info_get2(state, state->srate, R, swp_freq, | ||
1222 | &afcex_freq, &fOSC, | ||
1223 | &AFCEX_L, &AFCEX_H); | ||
1224 | |||
1225 | if (rf_val_set(state, fOSC, state->srate, R) < 0) { | ||
1226 | dprintk(verbose, MB86A16_ERROR, 1, "rf val set error"); | ||
1227 | return -1; | ||
1228 | } | ||
1229 | if (afcex_data_set(state, AFCEX_L, AFCEX_H) < 0) { | ||
1230 | dprintk(verbose, MB86A16_ERROR, 1, "afcex data set error"); | ||
1231 | return -1; | ||
1232 | } | ||
1233 | signal = signal_det(state, state->srate, &SIG1); | ||
1234 | if (signal == 1) { | ||
1235 | dprintk(verbose, MB86A16_ERROR, 1, "***** Signal Found *****"); | ||
1236 | loop = 0; | ||
1237 | } else { | ||
1238 | dprintk(verbose, MB86A16_ERROR, 1, "!!!!! No signal !!!!!, try again..."); | ||
1239 | smrt_info_get(state, state->srate); | ||
1240 | if (smrt_set(state, state->srate) < 0) { | ||
1241 | dprintk(verbose, MB86A16_ERROR, 1, "smrt set error"); | ||
1242 | return -1; | ||
1243 | } | ||
1244 | } | ||
1245 | } | ||
1246 | if (v > vmax) | ||
1247 | vmax_his = 1 ; | ||
1248 | if (v < vmin) | ||
1249 | vmin_his = 1 ; | ||
1250 | i++; | ||
1251 | |||
1252 | if ((i % 2 == 1) && (vmax_his == 1)) | ||
1253 | i++; | ||
1254 | if ((i % 2 == 0) && (vmin_his == 1)) | ||
1255 | i++; | ||
1256 | |||
1257 | if (i % 2 == 1) | ||
1258 | v = (i + 1) / 2; | ||
1259 | else | ||
1260 | v = -i / 2; | ||
1261 | |||
1262 | if ((vmax_his == 1) && (vmin_his == 1)) | ||
1263 | loop = 0 ; | ||
1264 | } | ||
1265 | |||
1266 | if (signal == 1) { | ||
1267 | dprintk(verbose, MB86A16_INFO, 1, " Start Freq Error Check"); | ||
1268 | S1T = 7 ; | ||
1269 | S0T = 1 ; | ||
1270 | CREN = 0 ; | ||
1271 | AFCEN = 1 ; | ||
1272 | AFCEXEN = 0 ; | ||
1273 | |||
1274 | if (S01T_set(state, S1T, S0T) < 0) { | ||
1275 | dprintk(verbose, MB86A16_ERROR, 1, "S01T set error"); | ||
1276 | return -1; | ||
1277 | } | ||
1278 | smrt_info_get(state, state->srate); | ||
1279 | if (smrt_set(state, state->srate) < 0) { | ||
1280 | dprintk(verbose, MB86A16_ERROR, 1, "smrt set error"); | ||
1281 | return -1; | ||
1282 | } | ||
1283 | if (EN_set(state, CREN, AFCEN) < 0) { | ||
1284 | dprintk(verbose, MB86A16_ERROR, 1, "EN set error"); | ||
1285 | return -1; | ||
1286 | } | ||
1287 | if (AFCEXEN_set(state, AFCEXEN, state->srate) < 0) { | ||
1288 | dprintk(verbose, MB86A16_ERROR, 1, "AFCEXEN set error"); | ||
1289 | return -1; | ||
1290 | } | ||
1291 | afcex_info_get(state, afcex_freq, &AFCEX_L, &AFCEX_H); | ||
1292 | if (afcofs_data_set(state, AFCEX_L, AFCEX_H) < 0) { | ||
1293 | dprintk(verbose, MB86A16_ERROR, 1, "AFCOFS data set error"); | ||
1294 | return -1; | ||
1295 | } | ||
1296 | if (srst(state) < 0) { | ||
1297 | dprintk(verbose, MB86A16_ERROR, 1, "srst error"); | ||
1298 | return -1; | ||
1299 | } | ||
1300 | /* delay 4~200 */ | ||
1301 | wait_t = 200000 / state->master_clk + 200000 / state->srate; | ||
1302 | msleep(wait_t); | ||
1303 | afcerr = afcerr_chk(state); | ||
1304 | if (afcerr == -1) | ||
1305 | return -1; | ||
1306 | |||
1307 | swp_freq = fOSC * 1000 + afcerr ; | ||
1308 | AFCEXEN = 1 ; | ||
1309 | if (state->srate >= 1500) | ||
1310 | smrt_d = state->srate / 3; | ||
1311 | else | ||
1312 | smrt_d = state->srate / 2; | ||
1313 | smrt_info_get(state, smrt_d); | ||
1314 | if (smrt_set(state, smrt_d) < 0) { | ||
1315 | dprintk(verbose, MB86A16_ERROR, 1, "smrt set error"); | ||
1316 | return -1; | ||
1317 | } | ||
1318 | if (AFCEXEN_set(state, AFCEXEN, smrt_d) < 0) { | ||
1319 | dprintk(verbose, MB86A16_ERROR, 1, "AFCEXEN set error"); | ||
1320 | return -1; | ||
1321 | } | ||
1322 | R = vco_dev_get(state, smrt_d); | ||
1323 | if (DAGC_data_set(state, 2, 0) < 0) { | ||
1324 | dprintk(verbose, MB86A16_ERROR, 1, "DAGC data set error"); | ||
1325 | return -1; | ||
1326 | } | ||
1327 | for (i = 0; i < 3; i++) { | ||
1328 | temp_freq = swp_freq + (i - 1) * state->srate / 8; | ||
1329 | swp_info_get2(state, smrt_d, R, temp_freq, &afcex_freq, &fOSC, &AFCEX_L, &AFCEX_H); | ||
1330 | if (rf_val_set(state, fOSC, smrt_d, R) < 0) { | ||
1331 | dprintk(verbose, MB86A16_ERROR, 1, "rf val set error"); | ||
1332 | return -1; | ||
1333 | } | ||
1334 | if (afcex_data_set(state, AFCEX_L, AFCEX_H) < 0) { | ||
1335 | dprintk(verbose, MB86A16_ERROR, 1, "afcex data set error"); | ||
1336 | return -1; | ||
1337 | } | ||
1338 | wait_t = 200000 / state->master_clk + 40000 / smrt_d; | ||
1339 | msleep(wait_t); | ||
1340 | dagcm[i] = dagcm_val_get(state); | ||
1341 | } | ||
1342 | if ((dagcm[0] > dagcm[1]) && | ||
1343 | (dagcm[0] > dagcm[2]) && | ||
1344 | (dagcm[0] - dagcm[1] > 2 * (dagcm[2] - dagcm[1]))) { | ||
1345 | |||
1346 | temp_freq = swp_freq - 2 * state->srate / 8; | ||
1347 | swp_info_get2(state, smrt_d, R, temp_freq, &afcex_freq, &fOSC, &AFCEX_L, &AFCEX_H); | ||
1348 | if (rf_val_set(state, fOSC, smrt_d, R) < 0) { | ||
1349 | dprintk(verbose, MB86A16_ERROR, 1, "rf val set error"); | ||
1350 | return -1; | ||
1351 | } | ||
1352 | if (afcex_data_set(state, AFCEX_L, AFCEX_H) < 0) { | ||
1353 | dprintk(verbose, MB86A16_ERROR, 1, "afcex data set"); | ||
1354 | return -1; | ||
1355 | } | ||
1356 | wait_t = 200000 / state->master_clk + 40000 / smrt_d; | ||
1357 | msleep(wait_t); | ||
1358 | dagcm[3] = dagcm_val_get(state); | ||
1359 | if (dagcm[3] > dagcm[1]) | ||
1360 | delta_freq = (dagcm[2] - dagcm[0] + dagcm[1] - dagcm[3]) * state->srate / 300; | ||
1361 | else | ||
1362 | delta_freq = 0; | ||
1363 | } else if ((dagcm[2] > dagcm[1]) && | ||
1364 | (dagcm[2] > dagcm[0]) && | ||
1365 | (dagcm[2] - dagcm[1] > 2 * (dagcm[0] - dagcm[1]))) { | ||
1366 | |||
1367 | temp_freq = swp_freq + 2 * state->srate / 8; | ||
1368 | swp_info_get2(state, smrt_d, R, temp_freq, &afcex_freq, &fOSC, &AFCEX_L, &AFCEX_H); | ||
1369 | if (rf_val_set(state, fOSC, smrt_d, R) < 0) { | ||
1370 | dprintk(verbose, MB86A16_ERROR, 1, "rf val set"); | ||
1371 | return -1; | ||
1372 | } | ||
1373 | if (afcex_data_set(state, AFCEX_L, AFCEX_H) < 0) { | ||
1374 | dprintk(verbose, MB86A16_ERROR, 1, "afcex data set"); | ||
1375 | return -1; | ||
1376 | } | ||
1377 | wait_t = 200000 / state->master_clk + 40000 / smrt_d; | ||
1378 | msleep(wait_t); | ||
1379 | dagcm[3] = dagcm_val_get(state); | ||
1380 | if (dagcm[3] > dagcm[1]) | ||
1381 | delta_freq = (dagcm[2] - dagcm[0] + dagcm[3] - dagcm[1]) * state->srate / 300; | ||
1382 | else | ||
1383 | delta_freq = 0 ; | ||
1384 | |||
1385 | } else { | ||
1386 | delta_freq = 0 ; | ||
1387 | } | ||
1388 | dprintk(verbose, MB86A16_INFO, 1, "SWEEP Frequency = %d", swp_freq); | ||
1389 | swp_freq += delta_freq; | ||
1390 | dprintk(verbose, MB86A16_INFO, 1, "Adjusting .., DELTA Freq = %d, SWEEP Freq=%d", delta_freq, swp_freq); | ||
1391 | if (ABS(state->frequency * 1000 - swp_freq) > 3800) { | ||
1392 | dprintk(verbose, MB86A16_INFO, 1, "NO -- SIGNAL !"); | ||
1393 | } else { | ||
1394 | |||
1395 | S1T = 0; | ||
1396 | S0T = 3; | ||
1397 | CREN = 1; | ||
1398 | AFCEN = 0; | ||
1399 | AFCEXEN = 1; | ||
1400 | |||
1401 | if (S01T_set(state, S1T, S0T) < 0) { | ||
1402 | dprintk(verbose, MB86A16_ERROR, 1, "S01T set error"); | ||
1403 | return -1; | ||
1404 | } | ||
1405 | if (DAGC_data_set(state, 0, 0) < 0) { | ||
1406 | dprintk(verbose, MB86A16_ERROR, 1, "DAGC data set error"); | ||
1407 | return -1; | ||
1408 | } | ||
1409 | R = vco_dev_get(state, state->srate); | ||
1410 | smrt_info_get(state, state->srate); | ||
1411 | if (smrt_set(state, state->srate) < 0) { | ||
1412 | dprintk(verbose, MB86A16_ERROR, 1, "smrt set error"); | ||
1413 | return -1; | ||
1414 | } | ||
1415 | if (EN_set(state, CREN, AFCEN) < 0) { | ||
1416 | dprintk(verbose, MB86A16_ERROR, 1, "EN set error"); | ||
1417 | return -1; | ||
1418 | } | ||
1419 | if (AFCEXEN_set(state, AFCEXEN, state->srate) < 0) { | ||
1420 | dprintk(verbose, MB86A16_ERROR, 1, "AFCEXEN set error"); | ||
1421 | return -1; | ||
1422 | } | ||
1423 | swp_info_get2(state, state->srate, R, swp_freq, &afcex_freq, &fOSC, &AFCEX_L, &AFCEX_H); | ||
1424 | if (rf_val_set(state, fOSC, state->srate, R) < 0) { | ||
1425 | dprintk(verbose, MB86A16_ERROR, 1, "rf val set error"); | ||
1426 | return -1; | ||
1427 | } | ||
1428 | if (afcex_data_set(state, AFCEX_L, AFCEX_H) < 0) { | ||
1429 | dprintk(verbose, MB86A16_ERROR, 1, "afcex data set error"); | ||
1430 | return -1; | ||
1431 | } | ||
1432 | if (srst(state) < 0) { | ||
1433 | dprintk(verbose, MB86A16_ERROR, 1, "srst error"); | ||
1434 | return -1; | ||
1435 | } | ||
1436 | wait_t = 7 + (10000 + state->srate / 2) / state->srate; | ||
1437 | if (wait_t == 0) | ||
1438 | wait_t = 1; | ||
1439 | msleep_interruptible(wait_t); | ||
1440 | if (mb86a16_read(state, 0x37, &SIG1) != 2) { | ||
1441 | dprintk(verbose, MB86A16_ERROR, 1, "I2C transfer error"); | ||
1442 | return -EREMOTEIO; | ||
1443 | } | ||
1444 | |||
1445 | if (SIG1 > 110) { | ||
1446 | S2T = 4; S4T = 1; S5T = 6; ETH = 4; VIA = 6; | ||
1447 | wait_t = 7 + (917504 + state->srate / 2) / state->srate; | ||
1448 | } else if (SIG1 > 105) { | ||
1449 | S2T = 4; S4T = 2; S5T = 8; ETH = 7; VIA = 2; | ||
1450 | wait_t = 7 + (1048576 + state->srate / 2) / state->srate; | ||
1451 | } else if (SIG1 > 85) { | ||
1452 | S2T = 5; S4T = 2; S5T = 8; ETH = 7; VIA = 2; | ||
1453 | wait_t = 7 + (1310720 + state->srate / 2) / state->srate; | ||
1454 | } else if (SIG1 > 65) { | ||
1455 | S2T = 6; S4T = 2; S5T = 8; ETH = 7; VIA = 2; | ||
1456 | wait_t = 7 + (1572864 + state->srate / 2) / state->srate; | ||
1457 | } else { | ||
1458 | S2T = 7; S4T = 2; S5T = 8; ETH = 7; VIA = 2; | ||
1459 | wait_t = 7 + (2097152 + state->srate / 2) / state->srate; | ||
1460 | } | ||
1461 | wait_t *= 2; /* FOS */ | ||
1462 | S2T_set(state, S2T); | ||
1463 | S45T_set(state, S4T, S5T); | ||
1464 | Vi_set(state, ETH, VIA); | ||
1465 | srst(state); | ||
1466 | msleep_interruptible(wait_t); | ||
1467 | sync = sync_chk(state, &VIRM); | ||
1468 | dprintk(verbose, MB86A16_INFO, 1, "-------- Viterbi=[%d] SYNC=[%d] ---------", VIRM, sync); | ||
1469 | if (VIRM) { | ||
1470 | if (VIRM == 4) { | ||
1471 | /* 5/6 */ | ||
1472 | if (SIG1 > 110) | ||
1473 | wait_t = (786432 + state->srate / 2) / state->srate; | ||
1474 | else | ||
1475 | wait_t = (1572864 + state->srate / 2) / state->srate; | ||
1476 | if (state->srate < 5000) | ||
1477 | /* FIXME ! , should be a long wait ! */ | ||
1478 | msleep_interruptible(wait_t); | ||
1479 | else | ||
1480 | msleep_interruptible(wait_t); | ||
1481 | |||
1482 | if (sync_chk(state, &junk) == 0) { | ||
1483 | iq_vt_set(state, 1); | ||
1484 | FEC_srst(state); | ||
1485 | } | ||
1486 | } | ||
1487 | /* 1/2, 2/3, 3/4, 7/8 */ | ||
1488 | if (SIG1 > 110) | ||
1489 | wait_t = (786432 + state->srate / 2) / state->srate; | ||
1490 | else | ||
1491 | wait_t = (1572864 + state->srate / 2) / state->srate; | ||
1492 | msleep_interruptible(wait_t); | ||
1493 | SEQ_set(state, 1); | ||
1494 | } else { | ||
1495 | dprintk(verbose, MB86A16_INFO, 1, "NO -- SYNC"); | ||
1496 | SEQ_set(state, 1); | ||
1497 | ret = -1; | ||
1498 | } | ||
1499 | } | ||
1500 | } else { | ||
1501 | dprintk(verbose, MB86A16_INFO, 1, "NO -- SIGNAL"); | ||
1502 | ret = -1; | ||
1503 | } | ||
1504 | |||
1505 | sync = sync_chk(state, &junk); | ||
1506 | if (sync) { | ||
1507 | dprintk(verbose, MB86A16_INFO, 1, "******* SYNC *******"); | ||
1508 | freqerr_chk(state, state->frequency, state->srate, 1); | ||
1509 | ret = 0; | ||
1510 | break; | ||
1511 | } | ||
1512 | } | ||
1513 | |||
1514 | mb86a16_read(state, 0x15, &agcval); | ||
1515 | mb86a16_read(state, 0x26, &cnmval); | ||
1516 | dprintk(verbose, MB86A16_INFO, 1, "AGC = %02x CNM = %02x", agcval, cnmval); | ||
1517 | |||
1518 | return ret; | ||
1519 | } | ||
1520 | |||
1521 | static int mb86a16_send_diseqc_msg(struct dvb_frontend *fe, | ||
1522 | struct dvb_diseqc_master_cmd *cmd) | ||
1523 | { | ||
1524 | struct mb86a16_state *state = fe->demodulator_priv; | ||
1525 | int i; | ||
1526 | u8 regs; | ||
1527 | |||
1528 | if (mb86a16_write(state, MB86A16_DCC1, MB86A16_DCC1_DISTA) < 0) | ||
1529 | goto err; | ||
1530 | if (mb86a16_write(state, MB86A16_DCCOUT, 0x00) < 0) | ||
1531 | goto err; | ||
1532 | if (mb86a16_write(state, MB86A16_TONEOUT2, 0x04) < 0) | ||
1533 | goto err; | ||
1534 | |||
1535 | regs = 0x18; | ||
1536 | |||
1537 | if (cmd->msg_len > 5 || cmd->msg_len < 4) | ||
1538 | return -EINVAL; | ||
1539 | |||
1540 | for (i = 0; i < cmd->msg_len; i++) { | ||
1541 | if (mb86a16_write(state, regs, cmd->msg[i]) < 0) | ||
1542 | goto err; | ||
1543 | |||
1544 | regs++; | ||
1545 | } | ||
1546 | i += 0x90; | ||
1547 | |||
1548 | msleep_interruptible(10); | ||
1549 | |||
1550 | if (mb86a16_write(state, MB86A16_DCC1, i) < 0) | ||
1551 | goto err; | ||
1552 | if (mb86a16_write(state, MB86A16_DCCOUT, MB86A16_DCCOUT_DISEN) < 0) | ||
1553 | goto err; | ||
1554 | |||
1555 | return 0; | ||
1556 | |||
1557 | err: | ||
1558 | dprintk(verbose, MB86A16_ERROR, 1, "I2C transfer error"); | ||
1559 | return -EREMOTEIO; | ||
1560 | } | ||
1561 | |||
1562 | static int mb86a16_send_diseqc_burst(struct dvb_frontend *fe, fe_sec_mini_cmd_t burst) | ||
1563 | { | ||
1564 | struct mb86a16_state *state = fe->demodulator_priv; | ||
1565 | |||
1566 | switch (burst) { | ||
1567 | case SEC_MINI_A: | ||
1568 | if (mb86a16_write(state, MB86A16_DCC1, MB86A16_DCC1_DISTA | | ||
1569 | MB86A16_DCC1_TBEN | | ||
1570 | MB86A16_DCC1_TBO) < 0) | ||
1571 | goto err; | ||
1572 | if (mb86a16_write(state, MB86A16_DCCOUT, MB86A16_DCCOUT_DISEN) < 0) | ||
1573 | goto err; | ||
1574 | break; | ||
1575 | case SEC_MINI_B: | ||
1576 | if (mb86a16_write(state, MB86A16_DCC1, MB86A16_DCC1_DISTA | | ||
1577 | MB86A16_DCC1_TBEN) < 0) | ||
1578 | goto err; | ||
1579 | if (mb86a16_write(state, MB86A16_DCCOUT, MB86A16_DCCOUT_DISEN) < 0) | ||
1580 | goto err; | ||
1581 | break; | ||
1582 | } | ||
1583 | |||
1584 | return 0; | ||
1585 | err: | ||
1586 | dprintk(verbose, MB86A16_ERROR, 1, "I2C transfer error"); | ||
1587 | return -EREMOTEIO; | ||
1588 | } | ||
1589 | |||
1590 | static int mb86a16_set_tone(struct dvb_frontend *fe, fe_sec_tone_mode_t tone) | ||
1591 | { | ||
1592 | struct mb86a16_state *state = fe->demodulator_priv; | ||
1593 | |||
1594 | switch (tone) { | ||
1595 | case SEC_TONE_ON: | ||
1596 | if (mb86a16_write(state, MB86A16_TONEOUT2, 0x00) < 0) | ||
1597 | goto err; | ||
1598 | if (mb86a16_write(state, MB86A16_DCC1, MB86A16_DCC1_DISTA | | ||
1599 | MB86A16_DCC1_CTOE) < 0) | ||
1600 | |||
1601 | goto err; | ||
1602 | if (mb86a16_write(state, MB86A16_DCCOUT, MB86A16_DCCOUT_DISEN) < 0) | ||
1603 | goto err; | ||
1604 | break; | ||
1605 | case SEC_TONE_OFF: | ||
1606 | if (mb86a16_write(state, MB86A16_TONEOUT2, 0x04) < 0) | ||
1607 | goto err; | ||
1608 | if (mb86a16_write(state, MB86A16_DCC1, MB86A16_DCC1_DISTA) < 0) | ||
1609 | goto err; | ||
1610 | if (mb86a16_write(state, MB86A16_DCCOUT, 0x00) < 0) | ||
1611 | goto err; | ||
1612 | break; | ||
1613 | default: | ||
1614 | return -EINVAL; | ||
1615 | } | ||
1616 | return 0; | ||
1617 | |||
1618 | err: | ||
1619 | dprintk(verbose, MB86A16_ERROR, 1, "I2C transfer error"); | ||
1620 | return -EREMOTEIO; | ||
1621 | } | ||
1622 | |||
1623 | static enum dvbfe_search mb86a16_search(struct dvb_frontend *fe, | ||
1624 | struct dvb_frontend_parameters *p) | ||
1625 | { | ||
1626 | struct mb86a16_state *state = fe->demodulator_priv; | ||
1627 | |||
1628 | state->frequency = p->frequency / 1000; | ||
1629 | state->srate = p->u.qpsk.symbol_rate / 1000; | ||
1630 | |||
1631 | if (!mb86a16_set_fe(state)) { | ||
1632 | dprintk(verbose, MB86A16_ERROR, 1, "Succesfully acquired LOCK"); | ||
1633 | return DVBFE_ALGO_SEARCH_SUCCESS; | ||
1634 | } | ||
1635 | |||
1636 | dprintk(verbose, MB86A16_ERROR, 1, "Lock acquisition failed!"); | ||
1637 | return DVBFE_ALGO_SEARCH_FAILED; | ||
1638 | } | ||
1639 | |||
1640 | static void mb86a16_release(struct dvb_frontend *fe) | ||
1641 | { | ||
1642 | struct mb86a16_state *state = fe->demodulator_priv; | ||
1643 | kfree(state); | ||
1644 | } | ||
1645 | |||
1646 | static int mb86a16_init(struct dvb_frontend *fe) | ||
1647 | { | ||
1648 | return 0; | ||
1649 | } | ||
1650 | |||
1651 | static int mb86a16_sleep(struct dvb_frontend *fe) | ||
1652 | { | ||
1653 | return 0; | ||
1654 | } | ||
1655 | |||
1656 | static int mb86a16_read_ber(struct dvb_frontend *fe, u32 *ber) | ||
1657 | { | ||
1658 | u8 ber_mon, ber_tab, ber_lsb, ber_mid, ber_msb, ber_tim, ber_rst; | ||
1659 | u32 timer; | ||
1660 | |||
1661 | struct mb86a16_state *state = fe->demodulator_priv; | ||
1662 | |||
1663 | *ber = 0; | ||
1664 | if (mb86a16_read(state, MB86A16_BERMON, &ber_mon) != 2) | ||
1665 | goto err; | ||
1666 | if (mb86a16_read(state, MB86A16_BERTAB, &ber_tab) != 2) | ||
1667 | goto err; | ||
1668 | if (mb86a16_read(state, MB86A16_BERLSB, &ber_lsb) != 2) | ||
1669 | goto err; | ||
1670 | if (mb86a16_read(state, MB86A16_BERMID, &ber_mid) != 2) | ||
1671 | goto err; | ||
1672 | if (mb86a16_read(state, MB86A16_BERMSB, &ber_msb) != 2) | ||
1673 | goto err; | ||
1674 | /* BER monitor invalid when BER_EN = 0 */ | ||
1675 | if (ber_mon & 0x04) { | ||
1676 | /* coarse, fast calculation */ | ||
1677 | *ber = ber_tab & 0x1f; | ||
1678 | dprintk(verbose, MB86A16_DEBUG, 1, "BER coarse=[0x%02x]", *ber); | ||
1679 | if (ber_mon & 0x01) { | ||
1680 | /* | ||
1681 | * BER_SEL = 1, The monitored BER is the estimated | ||
1682 | * value with a Reed-Solomon decoder error amount at | ||
1683 | * the deinterleaver output. | ||
1684 | * monitored BER is expressed as a 20 bit output in total | ||
1685 | */ | ||
1686 | ber_rst = ber_mon >> 3; | ||
1687 | *ber = (((ber_msb << 8) | ber_mid) << 8) | ber_lsb; | ||
1688 | if (ber_rst == 0) | ||
1689 | timer = 12500000; | ||
1690 | if (ber_rst == 1) | ||
1691 | timer = 25000000; | ||
1692 | if (ber_rst == 2) | ||
1693 | timer = 50000000; | ||
1694 | if (ber_rst == 3) | ||
1695 | timer = 100000000; | ||
1696 | |||
1697 | *ber /= timer; | ||
1698 | dprintk(verbose, MB86A16_DEBUG, 1, "BER fine=[0x%02x]", *ber); | ||
1699 | } else { | ||
1700 | /* | ||
1701 | * BER_SEL = 0, The monitored BER is the estimated | ||
1702 | * value with a Viterbi decoder error amount at the | ||
1703 | * QPSK demodulator output. | ||
1704 | * monitored BER is expressed as a 24 bit output in total | ||
1705 | */ | ||
1706 | ber_tim = ber_mon >> 1; | ||
1707 | *ber = (((ber_msb << 8) | ber_mid) << 8) | ber_lsb; | ||
1708 | if (ber_tim == 0) | ||
1709 | timer = 16; | ||
1710 | if (ber_tim == 1) | ||
1711 | timer = 24; | ||
1712 | |||
1713 | *ber /= 2 ^ timer; | ||
1714 | dprintk(verbose, MB86A16_DEBUG, 1, "BER fine=[0x%02x]", *ber); | ||
1715 | } | ||
1716 | } | ||
1717 | return 0; | ||
1718 | err: | ||
1719 | dprintk(verbose, MB86A16_ERROR, 1, "I2C transfer error"); | ||
1720 | return -EREMOTEIO; | ||
1721 | } | ||
1722 | |||
1723 | static int mb86a16_read_signal_strength(struct dvb_frontend *fe, u16 *strength) | ||
1724 | { | ||
1725 | u8 agcm = 0; | ||
1726 | struct mb86a16_state *state = fe->demodulator_priv; | ||
1727 | |||
1728 | *strength = 0; | ||
1729 | if (mb86a16_read(state, MB86A16_AGCM, &agcm) != 2) { | ||
1730 | dprintk(verbose, MB86A16_ERROR, 1, "I2C transfer error"); | ||
1731 | return -EREMOTEIO; | ||
1732 | } | ||
1733 | |||
1734 | *strength = ((0xff - agcm) * 100) / 256; | ||
1735 | dprintk(verbose, MB86A16_DEBUG, 1, "Signal strength=[%d %%]", (u8) *strength); | ||
1736 | *strength = (0xffff - 0xff) + agcm; | ||
1737 | |||
1738 | return 0; | ||
1739 | } | ||
1740 | |||
1741 | struct cnr { | ||
1742 | u8 cn_reg; | ||
1743 | u8 cn_val; | ||
1744 | }; | ||
1745 | |||
1746 | static const struct cnr cnr_tab[] = { | ||
1747 | { 35, 2 }, | ||
1748 | { 40, 3 }, | ||
1749 | { 50, 4 }, | ||
1750 | { 60, 5 }, | ||
1751 | { 70, 6 }, | ||
1752 | { 80, 7 }, | ||
1753 | { 92, 8 }, | ||
1754 | { 103, 9 }, | ||
1755 | { 115, 10 }, | ||
1756 | { 138, 12 }, | ||
1757 | { 162, 15 }, | ||
1758 | { 180, 18 }, | ||
1759 | { 185, 19 }, | ||
1760 | { 189, 20 }, | ||
1761 | { 195, 22 }, | ||
1762 | { 199, 24 }, | ||
1763 | { 201, 25 }, | ||
1764 | { 202, 26 }, | ||
1765 | { 203, 27 }, | ||
1766 | { 205, 28 }, | ||
1767 | { 208, 30 } | ||
1768 | }; | ||
1769 | |||
1770 | static int mb86a16_read_snr(struct dvb_frontend *fe, u16 *snr) | ||
1771 | { | ||
1772 | struct mb86a16_state *state = fe->demodulator_priv; | ||
1773 | int i = 0; | ||
1774 | int low_tide = 2, high_tide = 30, q_level; | ||
1775 | u8 cn; | ||
1776 | |||
1777 | *snr = 0; | ||
1778 | if (mb86a16_read(state, 0x26, &cn) != 2) { | ||
1779 | dprintk(verbose, MB86A16_ERROR, 1, "I2C transfer error"); | ||
1780 | return -EREMOTEIO; | ||
1781 | } | ||
1782 | |||
1783 | for (i = 0; i < ARRAY_SIZE(cnr_tab); i++) { | ||
1784 | if (cn < cnr_tab[i].cn_reg) { | ||
1785 | *snr = cnr_tab[i].cn_val; | ||
1786 | break; | ||
1787 | } | ||
1788 | } | ||
1789 | q_level = (*snr * 100) / (high_tide - low_tide); | ||
1790 | dprintk(verbose, MB86A16_ERROR, 1, "SNR (Quality) = [%d dB], Level=%d %%", *snr, q_level); | ||
1791 | *snr = (0xffff - 0xff) + *snr; | ||
1792 | |||
1793 | return 0; | ||
1794 | } | ||
1795 | |||
1796 | static int mb86a16_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks) | ||
1797 | { | ||
1798 | u8 dist; | ||
1799 | struct mb86a16_state *state = fe->demodulator_priv; | ||
1800 | |||
1801 | if (mb86a16_read(state, MB86A16_DISTMON, &dist) != 2) { | ||
1802 | dprintk(verbose, MB86A16_ERROR, 1, "I2C transfer error"); | ||
1803 | return -EREMOTEIO; | ||
1804 | } | ||
1805 | *ucblocks = dist; | ||
1806 | |||
1807 | return 0; | ||
1808 | } | ||
1809 | |||
1810 | static enum dvbfe_algo mb86a16_frontend_algo(struct dvb_frontend *fe) | ||
1811 | { | ||
1812 | return DVBFE_ALGO_CUSTOM; | ||
1813 | } | ||
1814 | |||
1815 | static struct dvb_frontend_ops mb86a16_ops = { | ||
1816 | .info = { | ||
1817 | .name = "Fujitsu MB86A16 DVB-S", | ||
1818 | .type = FE_QPSK, | ||
1819 | .frequency_min = 950000, | ||
1820 | .frequency_max = 2150000, | ||
1821 | .frequency_stepsize = 3000, | ||
1822 | .frequency_tolerance = 0, | ||
1823 | .symbol_rate_min = 1000000, | ||
1824 | .symbol_rate_max = 45000000, | ||
1825 | .symbol_rate_tolerance = 500, | ||
1826 | .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | | ||
1827 | FE_CAN_FEC_3_4 | FE_CAN_FEC_5_6 | | ||
1828 | FE_CAN_FEC_7_8 | FE_CAN_QPSK | | ||
1829 | FE_CAN_FEC_AUTO | ||
1830 | }, | ||
1831 | .release = mb86a16_release, | ||
1832 | |||
1833 | .get_frontend_algo = mb86a16_frontend_algo, | ||
1834 | .search = mb86a16_search, | ||
1835 | .read_status = mb86a16_read_status, | ||
1836 | .init = mb86a16_init, | ||
1837 | .sleep = mb86a16_sleep, | ||
1838 | .read_status = mb86a16_read_status, | ||
1839 | |||
1840 | .read_ber = mb86a16_read_ber, | ||
1841 | .read_signal_strength = mb86a16_read_signal_strength, | ||
1842 | .read_snr = mb86a16_read_snr, | ||
1843 | .read_ucblocks = mb86a16_read_ucblocks, | ||
1844 | |||
1845 | .diseqc_send_master_cmd = mb86a16_send_diseqc_msg, | ||
1846 | .diseqc_send_burst = mb86a16_send_diseqc_burst, | ||
1847 | .set_tone = mb86a16_set_tone, | ||
1848 | }; | ||
1849 | |||
1850 | struct dvb_frontend *mb86a16_attach(const struct mb86a16_config *config, | ||
1851 | struct i2c_adapter *i2c_adap) | ||
1852 | { | ||
1853 | u8 dev_id = 0; | ||
1854 | struct mb86a16_state *state = NULL; | ||
1855 | |||
1856 | state = kmalloc(sizeof(struct mb86a16_state), GFP_KERNEL); | ||
1857 | if (state == NULL) | ||
1858 | goto error; | ||
1859 | |||
1860 | state->config = config; | ||
1861 | state->i2c_adap = i2c_adap; | ||
1862 | |||
1863 | mb86a16_read(state, 0x7f, &dev_id); | ||
1864 | if (dev_id != 0xfe) | ||
1865 | goto error; | ||
1866 | |||
1867 | memcpy(&state->frontend.ops, &mb86a16_ops, sizeof(struct dvb_frontend_ops)); | ||
1868 | state->frontend.demodulator_priv = state; | ||
1869 | state->frontend.ops.set_voltage = state->config->set_voltage; | ||
1870 | |||
1871 | return &state->frontend; | ||
1872 | error: | ||
1873 | kfree(state); | ||
1874 | return NULL; | ||
1875 | } | ||
1876 | EXPORT_SYMBOL(mb86a16_attach); | ||
1877 | MODULE_LICENSE("GPL"); | ||
1878 | MODULE_AUTHOR("Manu Abraham"); | ||
diff --git a/drivers/media/dvb/frontends/mb86a16.h b/drivers/media/dvb/frontends/mb86a16.h new file mode 100644 index 000000000000..6ea8c376394f --- /dev/null +++ b/drivers/media/dvb/frontends/mb86a16.h | |||
@@ -0,0 +1,52 @@ | |||
1 | /* | ||
2 | Fujitsu MB86A16 DVB-S/DSS DC Receiver driver | ||
3 | |||
4 | Copyright (C) Manu Abraham (abraham.manu@gmail.com) | ||
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 __MB86A16_H | ||
22 | #define __MB86A16_H | ||
23 | |||
24 | #include <linux/dvb/frontend.h> | ||
25 | #include "dvb_frontend.h" | ||
26 | |||
27 | |||
28 | struct mb86a16_config { | ||
29 | u8 demod_address; | ||
30 | |||
31 | int (*set_voltage)(struct dvb_frontend *fe, fe_sec_voltage_t voltage); | ||
32 | }; | ||
33 | |||
34 | |||
35 | |||
36 | #if defined(CONFIG_DVB_MB86A16) || (defined(CONFIG_DVB_MB86A16_MODULE) && defined(MODULE)) | ||
37 | |||
38 | extern struct dvb_frontend *mb86a16_attach(const struct mb86a16_config *config, | ||
39 | struct i2c_adapter *i2c_adap); | ||
40 | |||
41 | #else | ||
42 | |||
43 | static inline struct dvb_frontend *mb86a16_attach(const struct mb86a16_config *config, | ||
44 | struct i2c_adapter *i2c_adap) | ||
45 | { | ||
46 | printk(KERN_WARNING "%s: Driver disabled by Kconfig\n", __func__); | ||
47 | return NULL; | ||
48 | } | ||
49 | |||
50 | #endif /* CONFIG_DVB_MB86A16 */ | ||
51 | |||
52 | #endif /* __MB86A16_H */ | ||
diff --git a/drivers/media/dvb/frontends/mb86a16_priv.h b/drivers/media/dvb/frontends/mb86a16_priv.h new file mode 100644 index 000000000000..360a35acfe84 --- /dev/null +++ b/drivers/media/dvb/frontends/mb86a16_priv.h | |||
@@ -0,0 +1,151 @@ | |||
1 | /* | ||
2 | Fujitsu MB86A16 DVB-S/DSS DC Receiver driver | ||
3 | |||
4 | Copyright (C) Manu Abraham (abraham.manu@gmail.com) | ||
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 __MB86A16_PRIV_H | ||
22 | #define __MB86A16_PRIV_H | ||
23 | |||
24 | #define MB86A16_TSOUT 0x00 | ||
25 | #define MB86A16_TSOUT_HIZSEL (0x01 << 5) | ||
26 | #define MB86A16_TSOUT_HIZCNTI (0x01 << 4) | ||
27 | #define MB86A16_TSOUT_MODE (0x01 << 3) | ||
28 | #define MB86A16_TSOUT_ORDER (0x01 << 2) | ||
29 | #define MB86A16_TSOUT_ERROR (0x01 << 1) | ||
30 | #define Mb86A16_TSOUT_EDGE (0x01 << 0) | ||
31 | |||
32 | #define MB86A16_FEC 0x01 | ||
33 | #define MB86A16_FEC_FSYNC (0x01 << 5) | ||
34 | #define MB86A16_FEC_PCKB8 (0x01 << 4) | ||
35 | #define MB86A16_FEC_DVDS (0x01 << 3) | ||
36 | #define MB86A16_FEC_EREN (0x01 << 2) | ||
37 | #define Mb86A16_FEC_RSEN (0x01 << 1) | ||
38 | #define MB86A16_FEC_DIEN (0x01 << 0) | ||
39 | |||
40 | #define MB86A16_AGC 0x02 | ||
41 | #define MB86A16_AGC_AGMD (0x01 << 6) | ||
42 | #define MB86A16_AGC_AGCW (0x0f << 2) | ||
43 | #define MB86A16_AGC_AGCP (0x01 << 1) | ||
44 | #define MB86A16_AGC_AGCR (0x01 << 0) | ||
45 | |||
46 | #define MB86A16_SRATE1 0x03 | ||
47 | #define MB86A16_SRATE1_DECI (0x07 << 2) | ||
48 | #define MB86A16_SRATE1_CSEL (0x01 << 1) | ||
49 | #define MB86A16_SRATE1_RSEL (0x01 << 0) | ||
50 | |||
51 | #define MB86A16_SRATE2 0x04 | ||
52 | #define MB86A16_SRATE2_STOFSL (0xff << 0) | ||
53 | |||
54 | #define MB86A16_SRATE3 0x05 | ||
55 | #define MB86A16_SRATE2_STOFSH (0xff << 0) | ||
56 | |||
57 | #define MB86A16_VITERBI 0x06 | ||
58 | #define MB86A16_FRAMESYNC 0x07 | ||
59 | #define MB86A16_CRLFILTCOEF1 0x08 | ||
60 | #define MB86A16_CRLFILTCOEF2 0x09 | ||
61 | #define MB86A16_STRFILTCOEF1 0x0a | ||
62 | #define MB86A16_STRFILTCOEF2 0x0b | ||
63 | #define MB86A16_RESET 0x0c | ||
64 | #define MB86A16_STATUS 0x0d | ||
65 | #define MB86A16_AFCML 0x0e | ||
66 | #define MB86A16_AFCMH 0x0f | ||
67 | #define MB86A16_BERMON 0x10 | ||
68 | #define MB86A16_BERTAB 0x11 | ||
69 | #define MB86A16_BERLSB 0x12 | ||
70 | #define MB86A16_BERMID 0x13 | ||
71 | #define MB86A16_BERMSB 0x14 | ||
72 | #define MB86A16_AGCM 0x15 | ||
73 | |||
74 | #define MB86A16_DCC1 0x16 | ||
75 | #define MB86A16_DCC1_DISTA (0x01 << 7) | ||
76 | #define MB86A16_DCC1_PRTY (0x01 << 6) | ||
77 | #define MB86A16_DCC1_CTOE (0x01 << 5) | ||
78 | #define MB86A16_DCC1_TBEN (0x01 << 4) | ||
79 | #define MB86A16_DCC1_TBO (0x01 << 3) | ||
80 | #define MB86A16_DCC1_NUM (0x07 << 0) | ||
81 | |||
82 | #define MB86A16_DCC2 0x17 | ||
83 | #define MB86A16_DCC2_DCBST (0x01 << 0) | ||
84 | |||
85 | #define MB86A16_DCC3 0x18 | ||
86 | #define MB86A16_DCC3_CODE0 (0xff << 0) | ||
87 | |||
88 | #define MB86A16_DCC4 0x19 | ||
89 | #define MB86A16_DCC4_CODE1 (0xff << 0) | ||
90 | |||
91 | #define MB86A16_DCC5 0x1a | ||
92 | #define MB86A16_DCC5_CODE2 (0xff << 0) | ||
93 | |||
94 | #define MB86A16_DCC6 0x1b | ||
95 | #define MB86A16_DCC6_CODE3 (0xff << 0) | ||
96 | |||
97 | #define MB86A16_DCC7 0x1c | ||
98 | #define MB86A16_DCC7_CODE4 (0xff << 0) | ||
99 | |||
100 | #define MB86A16_DCC8 0x1d | ||
101 | #define MB86A16_DCC8_CODE5 (0xff << 0) | ||
102 | |||
103 | #define MB86A16_DCCOUT 0x1e | ||
104 | #define MB86A16_DCCOUT_DISEN (0x01 << 0) | ||
105 | |||
106 | #define MB86A16_TONEOUT1 0x1f | ||
107 | #define MB86A16_TONE_TDIVL (0xff << 0) | ||
108 | |||
109 | #define MB86A16_TONEOUT2 0x20 | ||
110 | #define MB86A16_TONE_TMD (0x03 << 2) | ||
111 | #define MB86A16_TONE_TDIVH (0x03 << 0) | ||
112 | |||
113 | #define MB86A16_FREQ1 0x21 | ||
114 | #define MB86A16_FREQ2 0x22 | ||
115 | #define MB86A16_FREQ3 0x23 | ||
116 | #define MB86A16_FREQ4 0x24 | ||
117 | #define MB86A16_FREQSET 0x25 | ||
118 | #define MB86A16_CNM 0x26 | ||
119 | #define MB86A16_PORT0 0x27 | ||
120 | #define MB86A16_PORT1 0x28 | ||
121 | #define MB86A16_DRCFILT 0x29 | ||
122 | #define MB86A16_AFC 0x2a | ||
123 | #define MB86A16_AFCEXL 0x2b | ||
124 | #define MB86A16_AFCEXH 0x2c | ||
125 | #define MB86A16_DAGC 0x2d | ||
126 | #define MB86A16_SEQMODE 0x32 | ||
127 | #define MB86A16_S0S1T 0x33 | ||
128 | #define MB86A16_S2S3T 0x34 | ||
129 | #define MB86A16_S4S5T 0x35 | ||
130 | #define MB86A16_CNTMR 0x36 | ||
131 | #define MB86A16_SIG1 0x37 | ||
132 | #define MB86A16_SIG2 0x38 | ||
133 | #define MB86A16_VIMAG 0x39 | ||
134 | #define MB86A16_VISET1 0x3a | ||
135 | #define MB86A16_VISET2 0x3b | ||
136 | #define MB86A16_VISET3 0x3c | ||
137 | #define MB86A16_FAGCS1 0x3d | ||
138 | #define MB86A16_FAGCS2 0x3e | ||
139 | #define MB86A16_FAGCS3 0x3f | ||
140 | #define MB86A16_FAGCS4 0x40 | ||
141 | #define MB86A16_FAGCS5 0x41 | ||
142 | #define MB86A16_FAGCS6 0x42 | ||
143 | #define MB86A16_CRM 0x43 | ||
144 | #define MB86A16_STRM 0x44 | ||
145 | #define MB86A16_DAGCML 0x45 | ||
146 | #define MB86A16_DAGCMH 0x46 | ||
147 | #define MB86A16_QPSKTST 0x49 | ||
148 | #define MB86A16_DISTMON 0x52 | ||
149 | #define MB86A16_VERSION 0x7f | ||
150 | |||
151 | #endif /* __MB86A16_PRIV_H */ | ||
diff --git a/drivers/media/dvb/frontends/tda10021.c b/drivers/media/dvb/frontends/tda10021.c index 6c1dbf9288d8..6ca533ea0f0e 100644 --- a/drivers/media/dvb/frontends/tda10021.c +++ b/drivers/media/dvb/frontends/tda10021.c | |||
@@ -426,6 +426,10 @@ struct dvb_frontend* tda10021_attach(const struct tda1002x_config* config, | |||
426 | id = tda10021_readreg(state, 0x1a); | 426 | id = tda10021_readreg(state, 0x1a); |
427 | if ((id & 0xf0) != 0x70) goto error; | 427 | if ((id & 0xf0) != 0x70) goto error; |
428 | 428 | ||
429 | /* Don't claim TDA10023 */ | ||
430 | if (id == 0x7d) | ||
431 | goto error; | ||
432 | |||
429 | printk("TDA10021: i2c-addr = 0x%02x, id = 0x%02x\n", | 433 | printk("TDA10021: i2c-addr = 0x%02x, id = 0x%02x\n", |
430 | state->config->demod_address, id); | 434 | state->config->demod_address, id); |
431 | 435 | ||
diff --git a/drivers/media/dvb/frontends/tda665x.c b/drivers/media/dvb/frontends/tda665x.c new file mode 100644 index 000000000000..87d52739c828 --- /dev/null +++ b/drivers/media/dvb/frontends/tda665x.c | |||
@@ -0,0 +1,257 @@ | |||
1 | /* | ||
2 | TDA665x tuner driver | ||
3 | Copyright (C) Manu Abraham (abraham.manu@gmail.com) | ||
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., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
18 | */ | ||
19 | |||
20 | #include <linux/init.h> | ||
21 | #include <linux/kernel.h> | ||
22 | #include <linux/module.h> | ||
23 | |||
24 | #include "dvb_frontend.h" | ||
25 | #include "tda665x.h" | ||
26 | |||
27 | struct tda665x_state { | ||
28 | struct dvb_frontend *fe; | ||
29 | struct i2c_adapter *i2c; | ||
30 | const struct tda665x_config *config; | ||
31 | |||
32 | u32 frequency; | ||
33 | u32 bandwidth; | ||
34 | }; | ||
35 | |||
36 | static int tda665x_read(struct tda665x_state *state, u8 *buf) | ||
37 | { | ||
38 | const struct tda665x_config *config = state->config; | ||
39 | int err = 0; | ||
40 | struct i2c_msg msg = { .addr = config->addr, .flags = I2C_M_RD, .buf = buf, .len = 2 }; | ||
41 | |||
42 | err = i2c_transfer(state->i2c, &msg, 1); | ||
43 | if (err != 1) | ||
44 | goto exit; | ||
45 | |||
46 | return err; | ||
47 | exit: | ||
48 | printk(KERN_ERR "%s: I/O Error err=<%d>\n", __func__, err); | ||
49 | return err; | ||
50 | } | ||
51 | |||
52 | static int tda665x_write(struct tda665x_state *state, u8 *buf, u8 length) | ||
53 | { | ||
54 | const struct tda665x_config *config = state->config; | ||
55 | int err = 0; | ||
56 | struct i2c_msg msg = { .addr = config->addr, .flags = 0, .buf = buf, .len = length }; | ||
57 | |||
58 | err = i2c_transfer(state->i2c, &msg, 1); | ||
59 | if (err != 1) | ||
60 | goto exit; | ||
61 | |||
62 | return err; | ||
63 | exit: | ||
64 | printk(KERN_ERR "%s: I/O Error err=<%d>\n", __func__, err); | ||
65 | return err; | ||
66 | } | ||
67 | |||
68 | static int tda665x_get_state(struct dvb_frontend *fe, | ||
69 | enum tuner_param param, | ||
70 | struct tuner_state *tstate) | ||
71 | { | ||
72 | struct tda665x_state *state = fe->tuner_priv; | ||
73 | int err = 0; | ||
74 | |||
75 | switch (param) { | ||
76 | case DVBFE_TUNER_FREQUENCY: | ||
77 | tstate->frequency = state->frequency; | ||
78 | break; | ||
79 | case DVBFE_TUNER_BANDWIDTH: | ||
80 | break; | ||
81 | default: | ||
82 | printk(KERN_ERR "%s: Unknown parameter (param=%d)\n", __func__, param); | ||
83 | err = -EINVAL; | ||
84 | break; | ||
85 | } | ||
86 | |||
87 | return err; | ||
88 | } | ||
89 | |||
90 | static int tda665x_get_status(struct dvb_frontend *fe, u32 *status) | ||
91 | { | ||
92 | struct tda665x_state *state = fe->tuner_priv; | ||
93 | u8 result = 0; | ||
94 | int err = 0; | ||
95 | |||
96 | *status = 0; | ||
97 | |||
98 | err = tda665x_read(state, &result); | ||
99 | if (err < 0) | ||
100 | goto exit; | ||
101 | |||
102 | if ((result >> 6) & 0x01) { | ||
103 | printk(KERN_DEBUG "%s: Tuner Phase Locked\n", __func__); | ||
104 | *status = 1; | ||
105 | } | ||
106 | |||
107 | return err; | ||
108 | exit: | ||
109 | printk(KERN_ERR "%s: I/O Error\n", __func__); | ||
110 | return err; | ||
111 | } | ||
112 | |||
113 | static int tda665x_set_state(struct dvb_frontend *fe, | ||
114 | enum tuner_param param, | ||
115 | struct tuner_state *tstate) | ||
116 | { | ||
117 | struct tda665x_state *state = fe->tuner_priv; | ||
118 | const struct tda665x_config *config = state->config; | ||
119 | u32 frequency, status = 0; | ||
120 | u8 buf[4]; | ||
121 | int err = 0; | ||
122 | |||
123 | if (param & DVBFE_TUNER_FREQUENCY) { | ||
124 | |||
125 | frequency = tstate->frequency; | ||
126 | if ((frequency < config->frequency_max) || (frequency > config->frequency_min)) { | ||
127 | printk(KERN_ERR "%s: Frequency beyond limits, frequency=%d\n", __func__, frequency); | ||
128 | return -EINVAL; | ||
129 | } | ||
130 | |||
131 | frequency += config->frequency_offst; | ||
132 | frequency *= config->ref_multiplier; | ||
133 | frequency += config->ref_divider >> 1; | ||
134 | frequency /= config->ref_divider; | ||
135 | |||
136 | buf[0] = (u8) (frequency & 0x7f00) >> 8; | ||
137 | buf[1] = (u8) (frequency & 0x00ff) >> 0; | ||
138 | buf[2] = 0x80 | 0x40 | 0x02; | ||
139 | buf[3] = 0x00; | ||
140 | |||
141 | /* restore frequency */ | ||
142 | frequency = tstate->frequency; | ||
143 | |||
144 | if (frequency < 153000000) { | ||
145 | /* VHF-L */ | ||
146 | buf[3] |= 0x01; /* fc, Low Band, 47 - 153 MHz */ | ||
147 | if (frequency < 68000000) | ||
148 | buf[3] |= 0x40; /* 83uA */ | ||
149 | if (frequency < 1040000000) | ||
150 | buf[3] |= 0x60; /* 122uA */ | ||
151 | if (frequency < 1250000000) | ||
152 | buf[3] |= 0x80; /* 163uA */ | ||
153 | else | ||
154 | buf[3] |= 0xa0; /* 254uA */ | ||
155 | } else if (frequency < 438000000) { | ||
156 | /* VHF-H */ | ||
157 | buf[3] |= 0x02; /* fc, Mid Band, 153 - 438 MHz */ | ||
158 | if (frequency < 230000000) | ||
159 | buf[3] |= 0x40; | ||
160 | if (frequency < 300000000) | ||
161 | buf[3] |= 0x60; | ||
162 | else | ||
163 | buf[3] |= 0x80; | ||
164 | } else { | ||
165 | /* UHF */ | ||
166 | buf[3] |= 0x04; /* fc, High Band, 438 - 862 MHz */ | ||
167 | if (frequency < 470000000) | ||
168 | buf[3] |= 0x60; | ||
169 | if (frequency < 526000000) | ||
170 | buf[3] |= 0x80; | ||
171 | else | ||
172 | buf[3] |= 0xa0; | ||
173 | } | ||
174 | |||
175 | /* Set params */ | ||
176 | err = tda665x_write(state, buf, 5); | ||
177 | if (err < 0) | ||
178 | goto exit; | ||
179 | |||
180 | /* sleep for some time */ | ||
181 | printk(KERN_DEBUG "%s: Waiting to Phase LOCK\n", __func__); | ||
182 | msleep(20); | ||
183 | /* check status */ | ||
184 | err = tda665x_get_status(fe, &status); | ||
185 | if (err < 0) | ||
186 | goto exit; | ||
187 | |||
188 | if (status == 1) { | ||
189 | printk(KERN_DEBUG "%s: Tuner Phase locked: status=%d\n", __func__, status); | ||
190 | state->frequency = frequency; /* cache successful state */ | ||
191 | } else { | ||
192 | printk(KERN_ERR "%s: No Phase lock: status=%d\n", __func__, status); | ||
193 | } | ||
194 | } else { | ||
195 | printk(KERN_ERR "%s: Unknown parameter (param=%d)\n", __func__, param); | ||
196 | return -EINVAL; | ||
197 | } | ||
198 | |||
199 | return 0; | ||
200 | exit: | ||
201 | printk(KERN_ERR "%s: I/O Error\n", __func__); | ||
202 | return err; | ||
203 | } | ||
204 | |||
205 | static int tda665x_release(struct dvb_frontend *fe) | ||
206 | { | ||
207 | struct tda665x_state *state = fe->tuner_priv; | ||
208 | |||
209 | fe->tuner_priv = NULL; | ||
210 | kfree(state); | ||
211 | return 0; | ||
212 | } | ||
213 | |||
214 | static struct dvb_tuner_ops tda665x_ops = { | ||
215 | |||
216 | .set_state = tda665x_set_state, | ||
217 | .get_state = tda665x_get_state, | ||
218 | .get_status = tda665x_get_status, | ||
219 | .release = tda665x_release | ||
220 | }; | ||
221 | |||
222 | struct dvb_frontend *tda665x_attach(struct dvb_frontend *fe, | ||
223 | const struct tda665x_config *config, | ||
224 | struct i2c_adapter *i2c) | ||
225 | { | ||
226 | struct tda665x_state *state = NULL; | ||
227 | struct dvb_tuner_info *info; | ||
228 | |||
229 | state = kzalloc(sizeof(struct tda665x_state), GFP_KERNEL); | ||
230 | if (state == NULL) | ||
231 | goto exit; | ||
232 | |||
233 | state->config = config; | ||
234 | state->i2c = i2c; | ||
235 | state->fe = fe; | ||
236 | fe->tuner_priv = state; | ||
237 | fe->ops.tuner_ops = tda665x_ops; | ||
238 | info = &fe->ops.tuner_ops.info; | ||
239 | |||
240 | memcpy(info->name, config->name, sizeof(config->name)); | ||
241 | info->frequency_min = config->frequency_min; | ||
242 | info->frequency_max = config->frequency_max; | ||
243 | info->frequency_step = config->frequency_offst; | ||
244 | |||
245 | printk(KERN_DEBUG "%s: Attaching TDA665x (%s) tuner\n", __func__, info->name); | ||
246 | |||
247 | return fe; | ||
248 | |||
249 | exit: | ||
250 | kfree(state); | ||
251 | return NULL; | ||
252 | } | ||
253 | EXPORT_SYMBOL(tda665x_attach); | ||
254 | |||
255 | MODULE_DESCRIPTION("TDA665x driver"); | ||
256 | MODULE_AUTHOR("Manu Abraham"); | ||
257 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/media/dvb/frontends/tda665x.h b/drivers/media/dvb/frontends/tda665x.h new file mode 100644 index 000000000000..ec7927aa75ae --- /dev/null +++ b/drivers/media/dvb/frontends/tda665x.h | |||
@@ -0,0 +1,52 @@ | |||
1 | /* | ||
2 | TDA665x tuner driver | ||
3 | Copyright (C) Manu Abraham (abraham.manu@gmail.com) | ||
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., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
18 | */ | ||
19 | |||
20 | #ifndef __TDA665x_H | ||
21 | #define __TDA665x_H | ||
22 | |||
23 | struct tda665x_config { | ||
24 | char name[128]; | ||
25 | |||
26 | u8 addr; | ||
27 | u32 frequency_min; | ||
28 | u32 frequency_max; | ||
29 | u32 frequency_offst; | ||
30 | u32 ref_multiplier; | ||
31 | u32 ref_divider; | ||
32 | }; | ||
33 | |||
34 | #if defined(CONFIG_DVB_TDA665x) || (defined(CONFIG_DVB_TDA665x_MODULE) && defined(MODULE)) | ||
35 | |||
36 | extern struct dvb_frontend *tda665x_attach(struct dvb_frontend *fe, | ||
37 | const struct tda665x_config *config, | ||
38 | struct i2c_adapter *i2c); | ||
39 | |||
40 | #else | ||
41 | |||
42 | static inline struct dvb_frontend *tda665x_attach(struct dvb_frontend *fe, | ||
43 | const struct tda665x_config *config, | ||
44 | struct i2c_adapter *i2c) | ||
45 | { | ||
46 | printk(KERN_WARNING "%s: Driver disabled by Kconfig\n", __func__); | ||
47 | return NULL; | ||
48 | } | ||
49 | |||
50 | #endif /* CONFIG_DVB_TDA665x */ | ||
51 | |||
52 | #endif /* __TDA665x_H */ | ||
diff --git a/drivers/media/dvb/mantis/Kconfig b/drivers/media/dvb/mantis/Kconfig new file mode 100644 index 000000000000..f7b72a32adf3 --- /dev/null +++ b/drivers/media/dvb/mantis/Kconfig | |||
@@ -0,0 +1,32 @@ | |||
1 | config MANTIS_CORE | ||
2 | tristate "Mantis/Hopper PCI bridge based devices" | ||
3 | depends on PCI && I2C && INPUT | ||
4 | |||
5 | help | ||
6 | Support for PCI cards based on the Mantis and Hopper PCi bridge. | ||
7 | |||
8 | Say Y if you own such a device and want to use it. | ||
9 | |||
10 | config DVB_MANTIS | ||
11 | tristate "MANTIS based cards" | ||
12 | depends on MANTIS_CORE && DVB_CORE && PCI && I2C | ||
13 | select DVB_MB86A16 | ||
14 | select DVB_ZL10353 | ||
15 | select DVB_STV0299 | ||
16 | select DVB_PLL | ||
17 | help | ||
18 | Support for PCI cards based on the Mantis PCI bridge. | ||
19 | Say Y when you have a Mantis based DVB card and want to use it. | ||
20 | |||
21 | If unsure say N. | ||
22 | |||
23 | config DVB_HOPPER | ||
24 | tristate "HOPPER based cards" | ||
25 | depends on MANTIS_CORE && DVB_CORE && PCI && I2C | ||
26 | select DVB_ZL10353 | ||
27 | select DVB_PLL | ||
28 | help | ||
29 | Support for PCI cards based on the Hopper PCI bridge. | ||
30 | Say Y when you have a Hopper based DVB card and want to use it. | ||
31 | |||
32 | If unsure say N | ||
diff --git a/drivers/media/dvb/mantis/Makefile b/drivers/media/dvb/mantis/Makefile new file mode 100644 index 000000000000..98dc5cd258ac --- /dev/null +++ b/drivers/media/dvb/mantis/Makefile | |||
@@ -0,0 +1,28 @@ | |||
1 | mantis_core-objs := mantis_ioc.o \ | ||
2 | mantis_uart.o \ | ||
3 | mantis_dma.o \ | ||
4 | mantis_pci.o \ | ||
5 | mantis_i2c.o \ | ||
6 | mantis_dvb.o \ | ||
7 | mantis_evm.o \ | ||
8 | mantis_hif.o \ | ||
9 | mantis_ca.o \ | ||
10 | mantis_pcmcia.o \ | ||
11 | mantis_input.o | ||
12 | |||
13 | mantis-objs := mantis_cards.o \ | ||
14 | mantis_vp1033.o \ | ||
15 | mantis_vp1034.o \ | ||
16 | mantis_vp1041.o \ | ||
17 | mantis_vp2033.o \ | ||
18 | mantis_vp2040.o \ | ||
19 | mantis_vp3030.o | ||
20 | |||
21 | hopper-objs := hopper_cards.o \ | ||
22 | hopper_vp3028.o | ||
23 | |||
24 | obj-$(CONFIG_MANTIS_CORE) += mantis_core.o | ||
25 | obj-$(CONFIG_DVB_MANTIS) += mantis.o | ||
26 | obj-$(CONFIG_DVB_HOPPER) += hopper.o | ||
27 | |||
28 | EXTRA_CFLAGS = -Idrivers/media/dvb/dvb-core/ -Idrivers/media/dvb/frontends/ | ||
diff --git a/drivers/media/dvb/mantis/hopper_cards.c b/drivers/media/dvb/mantis/hopper_cards.c new file mode 100644 index 000000000000..d073c61e3c0d --- /dev/null +++ b/drivers/media/dvb/mantis/hopper_cards.c | |||
@@ -0,0 +1,275 @@ | |||
1 | /* | ||
2 | Hopper PCI bridge driver | ||
3 | |||
4 | Copyright (C) Manu Abraham (abraham.manu@gmail.com) | ||
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 | #include <linux/module.h> | ||
22 | #include <linux/moduleparam.h> | ||
23 | #include <linux/kernel.h> | ||
24 | #include <linux/pci.h> | ||
25 | #include <asm/irq.h> | ||
26 | #include <linux/interrupt.h> | ||
27 | |||
28 | #include "dmxdev.h" | ||
29 | #include "dvbdev.h" | ||
30 | #include "dvb_demux.h" | ||
31 | #include "dvb_frontend.h" | ||
32 | #include "dvb_net.h" | ||
33 | |||
34 | #include "mantis_common.h" | ||
35 | #include "hopper_vp3028.h" | ||
36 | #include "mantis_dma.h" | ||
37 | #include "mantis_dvb.h" | ||
38 | #include "mantis_uart.h" | ||
39 | #include "mantis_ioc.h" | ||
40 | #include "mantis_pci.h" | ||
41 | #include "mantis_i2c.h" | ||
42 | #include "mantis_reg.h" | ||
43 | |||
44 | static unsigned int verbose; | ||
45 | module_param(verbose, int, 0644); | ||
46 | MODULE_PARM_DESC(verbose, "verbose startup messages, default is 1 (yes)"); | ||
47 | |||
48 | #define DRIVER_NAME "Hopper" | ||
49 | |||
50 | static char *label[10] = { | ||
51 | "DMA", | ||
52 | "IRQ-0", | ||
53 | "IRQ-1", | ||
54 | "OCERR", | ||
55 | "PABRT", | ||
56 | "RIPRR", | ||
57 | "PPERR", | ||
58 | "FTRGT", | ||
59 | "RISCI", | ||
60 | "RACK" | ||
61 | }; | ||
62 | |||
63 | static int devs; | ||
64 | |||
65 | static irqreturn_t hopper_irq_handler(int irq, void *dev_id) | ||
66 | { | ||
67 | u32 stat = 0, mask = 0, lstat = 0, mstat = 0; | ||
68 | u32 rst_stat = 0, rst_mask = 0; | ||
69 | |||
70 | struct mantis_pci *mantis; | ||
71 | struct mantis_ca *ca; | ||
72 | |||
73 | mantis = (struct mantis_pci *) dev_id; | ||
74 | if (unlikely(mantis == NULL)) { | ||
75 | dprintk(MANTIS_ERROR, 1, "Mantis == NULL"); | ||
76 | return IRQ_NONE; | ||
77 | } | ||
78 | ca = mantis->mantis_ca; | ||
79 | |||
80 | stat = mmread(MANTIS_INT_STAT); | ||
81 | mask = mmread(MANTIS_INT_MASK); | ||
82 | mstat = lstat = stat & ~MANTIS_INT_RISCSTAT; | ||
83 | if (!(stat & mask)) | ||
84 | return IRQ_NONE; | ||
85 | |||
86 | rst_mask = MANTIS_GPIF_WRACK | | ||
87 | MANTIS_GPIF_OTHERR | | ||
88 | MANTIS_SBUF_WSTO | | ||
89 | MANTIS_GPIF_EXTIRQ; | ||
90 | |||
91 | rst_stat = mmread(MANTIS_GPIF_STATUS); | ||
92 | rst_stat &= rst_mask; | ||
93 | mmwrite(rst_stat, MANTIS_GPIF_STATUS); | ||
94 | |||
95 | mantis->mantis_int_stat = stat; | ||
96 | mantis->mantis_int_mask = mask; | ||
97 | dprintk(MANTIS_DEBUG, 0, "\n-- Stat=<%02x> Mask=<%02x> --", stat, mask); | ||
98 | if (stat & MANTIS_INT_RISCEN) { | ||
99 | dprintk(MANTIS_DEBUG, 0, "<%s>", label[0]); | ||
100 | } | ||
101 | if (stat & MANTIS_INT_IRQ0) { | ||
102 | dprintk(MANTIS_DEBUG, 0, "<%s>", label[1]); | ||
103 | mantis->gpif_status = rst_stat; | ||
104 | wake_up(&ca->hif_write_wq); | ||
105 | schedule_work(&ca->hif_evm_work); | ||
106 | } | ||
107 | if (stat & MANTIS_INT_IRQ1) { | ||
108 | dprintk(MANTIS_DEBUG, 0, "<%s>", label[2]); | ||
109 | schedule_work(&mantis->uart_work); | ||
110 | } | ||
111 | if (stat & MANTIS_INT_OCERR) { | ||
112 | dprintk(MANTIS_DEBUG, 0, "<%s>", label[3]); | ||
113 | } | ||
114 | if (stat & MANTIS_INT_PABORT) { | ||
115 | dprintk(MANTIS_DEBUG, 0, "<%s>", label[4]); | ||
116 | } | ||
117 | if (stat & MANTIS_INT_RIPERR) { | ||
118 | dprintk(MANTIS_DEBUG, 0, "<%s>", label[5]); | ||
119 | } | ||
120 | if (stat & MANTIS_INT_PPERR) { | ||
121 | dprintk(MANTIS_DEBUG, 0, "<%s>", label[6]); | ||
122 | } | ||
123 | if (stat & MANTIS_INT_FTRGT) { | ||
124 | dprintk(MANTIS_DEBUG, 0, "<%s>", label[7]); | ||
125 | } | ||
126 | if (stat & MANTIS_INT_RISCI) { | ||
127 | dprintk(MANTIS_DEBUG, 0, "<%s>", label[8]); | ||
128 | mantis->finished_block = (stat & MANTIS_INT_RISCSTAT) >> 28; | ||
129 | tasklet_schedule(&mantis->tasklet); | ||
130 | } | ||
131 | if (stat & MANTIS_INT_I2CDONE) { | ||
132 | dprintk(MANTIS_DEBUG, 0, "<%s>", label[9]); | ||
133 | wake_up(&mantis->i2c_wq); | ||
134 | } | ||
135 | mmwrite(stat, MANTIS_INT_STAT); | ||
136 | stat &= ~(MANTIS_INT_RISCEN | MANTIS_INT_I2CDONE | | ||
137 | MANTIS_INT_I2CRACK | MANTIS_INT_PCMCIA7 | | ||
138 | MANTIS_INT_PCMCIA6 | MANTIS_INT_PCMCIA5 | | ||
139 | MANTIS_INT_PCMCIA4 | MANTIS_INT_PCMCIA3 | | ||
140 | MANTIS_INT_PCMCIA2 | MANTIS_INT_PCMCIA1 | | ||
141 | MANTIS_INT_PCMCIA0 | MANTIS_INT_IRQ1 | | ||
142 | MANTIS_INT_IRQ0 | MANTIS_INT_OCERR | | ||
143 | MANTIS_INT_PABORT | MANTIS_INT_RIPERR | | ||
144 | MANTIS_INT_PPERR | MANTIS_INT_FTRGT | | ||
145 | MANTIS_INT_RISCI); | ||
146 | |||
147 | if (stat) | ||
148 | dprintk(MANTIS_DEBUG, 0, "<Unknown> Stat=<%02x> Mask=<%02x>", stat, mask); | ||
149 | |||
150 | dprintk(MANTIS_DEBUG, 0, "\n"); | ||
151 | return IRQ_HANDLED; | ||
152 | } | ||
153 | |||
154 | static int __devinit hopper_pci_probe(struct pci_dev *pdev, const struct pci_device_id *pci_id) | ||
155 | { | ||
156 | struct mantis_pci *mantis; | ||
157 | struct mantis_hwconfig *config; | ||
158 | int err = 0; | ||
159 | |||
160 | mantis = kzalloc(sizeof(struct mantis_pci), GFP_KERNEL); | ||
161 | if (mantis == NULL) { | ||
162 | printk(KERN_ERR "%s ERROR: Out of memory\n", __func__); | ||
163 | err = -ENOMEM; | ||
164 | goto fail0; | ||
165 | } | ||
166 | |||
167 | mantis->num = devs; | ||
168 | mantis->verbose = verbose; | ||
169 | mantis->pdev = pdev; | ||
170 | config = (struct mantis_hwconfig *) pci_id->driver_data; | ||
171 | config->irq_handler = &hopper_irq_handler; | ||
172 | mantis->hwconfig = config; | ||
173 | |||
174 | err = mantis_pci_init(mantis); | ||
175 | if (err) { | ||
176 | dprintk(MANTIS_ERROR, 1, "ERROR: Mantis PCI initialization failed <%d>", err); | ||
177 | goto fail1; | ||
178 | } | ||
179 | |||
180 | err = mantis_stream_control(mantis, STREAM_TO_HIF); | ||
181 | if (err < 0) { | ||
182 | dprintk(MANTIS_ERROR, 1, "ERROR: Mantis stream control failed <%d>", err); | ||
183 | goto fail1; | ||
184 | } | ||
185 | |||
186 | err = mantis_i2c_init(mantis); | ||
187 | if (err < 0) { | ||
188 | dprintk(MANTIS_ERROR, 1, "ERROR: Mantis I2C initialization failed <%d>", err); | ||
189 | goto fail2; | ||
190 | } | ||
191 | |||
192 | err = mantis_get_mac(mantis); | ||
193 | if (err < 0) { | ||
194 | dprintk(MANTIS_ERROR, 1, "ERROR: Mantis MAC address read failed <%d>", err); | ||
195 | goto fail2; | ||
196 | } | ||
197 | |||
198 | err = mantis_dma_init(mantis); | ||
199 | if (err < 0) { | ||
200 | dprintk(MANTIS_ERROR, 1, "ERROR: Mantis DMA initialization failed <%d>", err); | ||
201 | goto fail3; | ||
202 | } | ||
203 | |||
204 | err = mantis_dvb_init(mantis); | ||
205 | if (err < 0) { | ||
206 | dprintk(MANTIS_ERROR, 1, "ERROR: Mantis DVB initialization failed <%d>", err); | ||
207 | goto fail4; | ||
208 | } | ||
209 | devs++; | ||
210 | |||
211 | return err; | ||
212 | |||
213 | fail4: | ||
214 | dprintk(MANTIS_ERROR, 1, "ERROR: Mantis DMA exit! <%d>", err); | ||
215 | mantis_dma_exit(mantis); | ||
216 | |||
217 | fail3: | ||
218 | dprintk(MANTIS_ERROR, 1, "ERROR: Mantis I2C exit! <%d>", err); | ||
219 | mantis_i2c_exit(mantis); | ||
220 | |||
221 | fail2: | ||
222 | dprintk(MANTIS_ERROR, 1, "ERROR: Mantis PCI exit! <%d>", err); | ||
223 | mantis_pci_exit(mantis); | ||
224 | |||
225 | fail1: | ||
226 | dprintk(MANTIS_ERROR, 1, "ERROR: Mantis free! <%d>", err); | ||
227 | kfree(mantis); | ||
228 | |||
229 | fail0: | ||
230 | return err; | ||
231 | } | ||
232 | |||
233 | static void __devexit hopper_pci_remove(struct pci_dev *pdev) | ||
234 | { | ||
235 | struct mantis_pci *mantis = pci_get_drvdata(pdev); | ||
236 | |||
237 | if (mantis) { | ||
238 | mantis_dvb_exit(mantis); | ||
239 | mantis_dma_exit(mantis); | ||
240 | mantis_i2c_exit(mantis); | ||
241 | mantis_pci_exit(mantis); | ||
242 | kfree(mantis); | ||
243 | } | ||
244 | return; | ||
245 | |||
246 | } | ||
247 | |||
248 | static struct pci_device_id hopper_pci_table[] = { | ||
249 | MAKE_ENTRY(TWINHAN_TECHNOLOGIES, MANTIS_VP_3028_DVB_T, &vp3028_config), | ||
250 | { } | ||
251 | }; | ||
252 | |||
253 | static struct pci_driver hopper_pci_driver = { | ||
254 | .name = DRIVER_NAME, | ||
255 | .id_table = hopper_pci_table, | ||
256 | .probe = hopper_pci_probe, | ||
257 | .remove = hopper_pci_remove, | ||
258 | }; | ||
259 | |||
260 | static int __devinit hopper_init(void) | ||
261 | { | ||
262 | return pci_register_driver(&hopper_pci_driver); | ||
263 | } | ||
264 | |||
265 | static void __devexit hopper_exit(void) | ||
266 | { | ||
267 | return pci_unregister_driver(&hopper_pci_driver); | ||
268 | } | ||
269 | |||
270 | module_init(hopper_init); | ||
271 | module_exit(hopper_exit); | ||
272 | |||
273 | MODULE_DESCRIPTION("HOPPER driver"); | ||
274 | MODULE_AUTHOR("Manu Abraham"); | ||
275 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/media/dvb/mantis/hopper_vp3028.c b/drivers/media/dvb/mantis/hopper_vp3028.c new file mode 100644 index 000000000000..96674c78e86b --- /dev/null +++ b/drivers/media/dvb/mantis/hopper_vp3028.c | |||
@@ -0,0 +1,88 @@ | |||
1 | /* | ||
2 | Hopper VP-3028 driver | ||
3 | |||
4 | Copyright (C) Manu Abraham (abraham.manu@gmail.com) | ||
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 | #include <linux/signal.h> | ||
22 | #include <linux/sched.h> | ||
23 | #include <linux/interrupt.h> | ||
24 | |||
25 | #include "dmxdev.h" | ||
26 | #include "dvbdev.h" | ||
27 | #include "dvb_demux.h" | ||
28 | #include "dvb_frontend.h" | ||
29 | #include "dvb_net.h" | ||
30 | |||
31 | #include "zl10353.h" | ||
32 | #include "mantis_common.h" | ||
33 | #include "mantis_ioc.h" | ||
34 | #include "mantis_dvb.h" | ||
35 | #include "hopper_vp3028.h" | ||
36 | |||
37 | struct zl10353_config hopper_vp3028_config = { | ||
38 | .demod_address = 0x0f, | ||
39 | }; | ||
40 | |||
41 | #define MANTIS_MODEL_NAME "VP-3028" | ||
42 | #define MANTIS_DEV_TYPE "DVB-T" | ||
43 | |||
44 | static int vp3028_frontend_init(struct mantis_pci *mantis, struct dvb_frontend *fe) | ||
45 | { | ||
46 | struct i2c_adapter *adapter = &mantis->adapter; | ||
47 | struct mantis_hwconfig *config = mantis->hwconfig; | ||
48 | int err = 0; | ||
49 | |||
50 | gpio_set_bits(mantis, config->reset, 0); | ||
51 | msleep(100); | ||
52 | err = mantis_frontend_power(mantis, POWER_ON); | ||
53 | msleep(100); | ||
54 | gpio_set_bits(mantis, config->reset, 1); | ||
55 | |||
56 | err = mantis_frontend_power(mantis, POWER_ON); | ||
57 | if (err == 0) { | ||
58 | msleep(250); | ||
59 | dprintk(MANTIS_ERROR, 1, "Probing for 10353 (DVB-T)"); | ||
60 | fe = zl10353_attach(&hopper_vp3028_config, adapter); | ||
61 | |||
62 | if (!fe) | ||
63 | return -1; | ||
64 | } else { | ||
65 | dprintk(MANTIS_ERROR, 1, "Frontend on <%s> POWER ON failed! <%d>", | ||
66 | adapter->name, | ||
67 | err); | ||
68 | |||
69 | return -EIO; | ||
70 | } | ||
71 | dprintk(MANTIS_ERROR, 1, "Done!"); | ||
72 | |||
73 | return 0; | ||
74 | } | ||
75 | |||
76 | struct mantis_hwconfig vp3028_config = { | ||
77 | .model_name = MANTIS_MODEL_NAME, | ||
78 | .dev_type = MANTIS_DEV_TYPE, | ||
79 | .ts_size = MANTIS_TS_188, | ||
80 | |||
81 | .baud_rate = MANTIS_BAUD_9600, | ||
82 | .parity = MANTIS_PARITY_NONE, | ||
83 | .bytes = 0, | ||
84 | |||
85 | .frontend_init = vp3028_frontend_init, | ||
86 | .power = GPIF_A00, | ||
87 | .reset = GPIF_A03, | ||
88 | }; | ||
diff --git a/drivers/media/dvb/mantis/hopper_vp3028.h b/drivers/media/dvb/mantis/hopper_vp3028.h new file mode 100644 index 000000000000..57239498bc87 --- /dev/null +++ b/drivers/media/dvb/mantis/hopper_vp3028.h | |||
@@ -0,0 +1,30 @@ | |||
1 | /* | ||
2 | Hopper VP-3028 driver | ||
3 | |||
4 | Copyright (C) Manu Abraham (abraham.manu@gmail.com) | ||
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 __MANTIS_VP3028_H | ||
22 | #define __MANTIS_VP3028_H | ||
23 | |||
24 | #include "mantis_common.h" | ||
25 | |||
26 | #define MANTIS_VP_3028_DVB_T 0x0028 | ||
27 | |||
28 | extern struct mantis_hwconfig vp3028_config; | ||
29 | |||
30 | #endif /* __MANTIS_VP3028_H */ | ||
diff --git a/drivers/media/dvb/mantis/mantis_ca.c b/drivers/media/dvb/mantis/mantis_ca.c new file mode 100644 index 000000000000..403ce043d00e --- /dev/null +++ b/drivers/media/dvb/mantis/mantis_ca.c | |||
@@ -0,0 +1,207 @@ | |||
1 | /* | ||
2 | Mantis PCI bridge driver | ||
3 | |||
4 | Copyright (C) Manu Abraham (abraham.manu@gmail.com) | ||
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 | #include <linux/signal.h> | ||
22 | #include <linux/sched.h> | ||
23 | #include <linux/interrupt.h> | ||
24 | |||
25 | #include "dmxdev.h" | ||
26 | #include "dvbdev.h" | ||
27 | #include "dvb_demux.h" | ||
28 | #include "dvb_frontend.h" | ||
29 | #include "dvb_net.h" | ||
30 | |||
31 | #include "mantis_common.h" | ||
32 | #include "mantis_link.h" | ||
33 | #include "mantis_hif.h" | ||
34 | #include "mantis_reg.h" | ||
35 | |||
36 | #include "mantis_ca.h" | ||
37 | |||
38 | static int mantis_ca_read_attr_mem(struct dvb_ca_en50221 *en50221, int slot, int addr) | ||
39 | { | ||
40 | struct mantis_ca *ca = en50221->data; | ||
41 | struct mantis_pci *mantis = ca->ca_priv; | ||
42 | |||
43 | dprintk(MANTIS_DEBUG, 1, "Slot(%d): Request Attribute Mem Read", slot); | ||
44 | |||
45 | if (slot != 0) | ||
46 | return -EINVAL; | ||
47 | |||
48 | return mantis_hif_read_mem(ca, addr); | ||
49 | } | ||
50 | |||
51 | static int mantis_ca_write_attr_mem(struct dvb_ca_en50221 *en50221, int slot, int addr, u8 data) | ||
52 | { | ||
53 | struct mantis_ca *ca = en50221->data; | ||
54 | struct mantis_pci *mantis = ca->ca_priv; | ||
55 | |||
56 | dprintk(MANTIS_DEBUG, 1, "Slot(%d): Request Attribute Mem Write", slot); | ||
57 | |||
58 | if (slot != 0) | ||
59 | return -EINVAL; | ||
60 | |||
61 | return mantis_hif_write_mem(ca, addr, data); | ||
62 | } | ||
63 | |||
64 | static int mantis_ca_read_cam_ctl(struct dvb_ca_en50221 *en50221, int slot, u8 addr) | ||
65 | { | ||
66 | struct mantis_ca *ca = en50221->data; | ||
67 | struct mantis_pci *mantis = ca->ca_priv; | ||
68 | |||
69 | dprintk(MANTIS_DEBUG, 1, "Slot(%d): Request CAM control Read", slot); | ||
70 | |||
71 | if (slot != 0) | ||
72 | return -EINVAL; | ||
73 | |||
74 | return mantis_hif_read_iom(ca, addr); | ||
75 | } | ||
76 | |||
77 | static int mantis_ca_write_cam_ctl(struct dvb_ca_en50221 *en50221, int slot, u8 addr, u8 data) | ||
78 | { | ||
79 | struct mantis_ca *ca = en50221->data; | ||
80 | struct mantis_pci *mantis = ca->ca_priv; | ||
81 | |||
82 | dprintk(MANTIS_DEBUG, 1, "Slot(%d): Request CAM control Write", slot); | ||
83 | |||
84 | if (slot != 0) | ||
85 | return -EINVAL; | ||
86 | |||
87 | return mantis_hif_write_iom(ca, addr, data); | ||
88 | } | ||
89 | |||
90 | static int mantis_ca_slot_reset(struct dvb_ca_en50221 *en50221, int slot) | ||
91 | { | ||
92 | struct mantis_ca *ca = en50221->data; | ||
93 | struct mantis_pci *mantis = ca->ca_priv; | ||
94 | |||
95 | dprintk(MANTIS_DEBUG, 1, "Slot(%d): Slot RESET", slot); | ||
96 | udelay(500); /* Wait.. */ | ||
97 | mmwrite(0xda, MANTIS_PCMCIA_RESET); /* Leading edge assert */ | ||
98 | udelay(500); | ||
99 | mmwrite(0x00, MANTIS_PCMCIA_RESET); /* Trailing edge deassert */ | ||
100 | msleep(1000); | ||
101 | dvb_ca_en50221_camready_irq(&ca->en50221, 0); | ||
102 | |||
103 | return 0; | ||
104 | } | ||
105 | |||
106 | static int mantis_ca_slot_shutdown(struct dvb_ca_en50221 *en50221, int slot) | ||
107 | { | ||
108 | struct mantis_ca *ca = en50221->data; | ||
109 | struct mantis_pci *mantis = ca->ca_priv; | ||
110 | |||
111 | dprintk(MANTIS_DEBUG, 1, "Slot(%d): Slot shutdown", slot); | ||
112 | |||
113 | return 0; | ||
114 | } | ||
115 | |||
116 | static int mantis_ts_control(struct dvb_ca_en50221 *en50221, int slot) | ||
117 | { | ||
118 | struct mantis_ca *ca = en50221->data; | ||
119 | struct mantis_pci *mantis = ca->ca_priv; | ||
120 | |||
121 | dprintk(MANTIS_DEBUG, 1, "Slot(%d): TS control", slot); | ||
122 | /* mantis_set_direction(mantis, 1); */ /* Enable TS through CAM */ | ||
123 | |||
124 | return 0; | ||
125 | } | ||
126 | |||
127 | static int mantis_slot_status(struct dvb_ca_en50221 *en50221, int slot, int open) | ||
128 | { | ||
129 | struct mantis_ca *ca = en50221->data; | ||
130 | struct mantis_pci *mantis = ca->ca_priv; | ||
131 | |||
132 | dprintk(MANTIS_DEBUG, 1, "Slot(%d): Poll Slot status", slot); | ||
133 | |||
134 | if (ca->slot_state == MODULE_INSERTED) { | ||
135 | dprintk(MANTIS_DEBUG, 1, "CA Module present and ready"); | ||
136 | return DVB_CA_EN50221_POLL_CAM_PRESENT | DVB_CA_EN50221_POLL_CAM_READY; | ||
137 | } else { | ||
138 | dprintk(MANTIS_DEBUG, 1, "CA Module not present or not ready"); | ||
139 | } | ||
140 | |||
141 | return 0; | ||
142 | } | ||
143 | |||
144 | int mantis_ca_init(struct mantis_pci *mantis) | ||
145 | { | ||
146 | struct dvb_adapter *dvb_adapter = &mantis->dvb_adapter; | ||
147 | struct mantis_ca *ca; | ||
148 | int ca_flags = 0, result; | ||
149 | |||
150 | dprintk(MANTIS_DEBUG, 1, "Initializing Mantis CA"); | ||
151 | ca = kzalloc(sizeof(struct mantis_ca), GFP_KERNEL); | ||
152 | if (!ca) { | ||
153 | dprintk(MANTIS_ERROR, 1, "Out of memory!, exiting .."); | ||
154 | result = -ENOMEM; | ||
155 | goto err; | ||
156 | } | ||
157 | |||
158 | ca->ca_priv = mantis; | ||
159 | mantis->mantis_ca = ca; | ||
160 | ca_flags = DVB_CA_EN50221_FLAG_IRQ_CAMCHANGE; | ||
161 | /* register CA interface */ | ||
162 | ca->en50221.owner = THIS_MODULE; | ||
163 | ca->en50221.read_attribute_mem = mantis_ca_read_attr_mem; | ||
164 | ca->en50221.write_attribute_mem = mantis_ca_write_attr_mem; | ||
165 | ca->en50221.read_cam_control = mantis_ca_read_cam_ctl; | ||
166 | ca->en50221.write_cam_control = mantis_ca_write_cam_ctl; | ||
167 | ca->en50221.slot_reset = mantis_ca_slot_reset; | ||
168 | ca->en50221.slot_shutdown = mantis_ca_slot_shutdown; | ||
169 | ca->en50221.slot_ts_enable = mantis_ts_control; | ||
170 | ca->en50221.poll_slot_status = mantis_slot_status; | ||
171 | ca->en50221.data = ca; | ||
172 | |||
173 | mutex_init(&ca->ca_lock); | ||
174 | |||
175 | init_waitqueue_head(&ca->hif_data_wq); | ||
176 | init_waitqueue_head(&ca->hif_opdone_wq); | ||
177 | init_waitqueue_head(&ca->hif_write_wq); | ||
178 | |||
179 | dprintk(MANTIS_ERROR, 1, "Registering EN50221 device"); | ||
180 | result = dvb_ca_en50221_init(dvb_adapter, &ca->en50221, ca_flags, 1); | ||
181 | if (result != 0) { | ||
182 | dprintk(MANTIS_ERROR, 1, "EN50221: Initialization failed <%d>", result); | ||
183 | goto err; | ||
184 | } | ||
185 | dprintk(MANTIS_ERROR, 1, "Registered EN50221 device"); | ||
186 | mantis_evmgr_init(ca); | ||
187 | return 0; | ||
188 | err: | ||
189 | kfree(ca); | ||
190 | return result; | ||
191 | } | ||
192 | EXPORT_SYMBOL_GPL(mantis_ca_init); | ||
193 | |||
194 | void mantis_ca_exit(struct mantis_pci *mantis) | ||
195 | { | ||
196 | struct mantis_ca *ca = mantis->mantis_ca; | ||
197 | |||
198 | dprintk(MANTIS_DEBUG, 1, "Mantis CA exit"); | ||
199 | |||
200 | mantis_evmgr_exit(ca); | ||
201 | dprintk(MANTIS_ERROR, 1, "Unregistering EN50221 device"); | ||
202 | if (ca) | ||
203 | dvb_ca_en50221_release(&ca->en50221); | ||
204 | |||
205 | kfree(ca); | ||
206 | } | ||
207 | EXPORT_SYMBOL_GPL(mantis_ca_exit); | ||
diff --git a/drivers/media/dvb/mantis/mantis_ca.h b/drivers/media/dvb/mantis/mantis_ca.h new file mode 100644 index 000000000000..dc63e55f7eca --- /dev/null +++ b/drivers/media/dvb/mantis/mantis_ca.h | |||
@@ -0,0 +1,27 @@ | |||
1 | /* | ||
2 | Mantis PCI bridge driver | ||
3 | |||
4 | Copyright (C) Manu Abraham (abraham.manu@gmail.com) | ||
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 __MANTIS_CA_H | ||
22 | #define __MANTIS_CA_H | ||
23 | |||
24 | extern int mantis_ca_init(struct mantis_pci *mantis); | ||
25 | extern void mantis_ca_exit(struct mantis_pci *mantis); | ||
26 | |||
27 | #endif /* __MANTIS_CA_H */ | ||
diff --git a/drivers/media/dvb/mantis/mantis_cards.c b/drivers/media/dvb/mantis/mantis_cards.c new file mode 100644 index 000000000000..16f1708fd3bc --- /dev/null +++ b/drivers/media/dvb/mantis/mantis_cards.c | |||
@@ -0,0 +1,305 @@ | |||
1 | /* | ||
2 | Mantis PCI bridge driver | ||
3 | |||
4 | Copyright (C) Manu Abraham (abraham.manu@gmail.com) | ||
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 | #include <linux/module.h> | ||
22 | #include <linux/moduleparam.h> | ||
23 | #include <linux/kernel.h> | ||
24 | #include <linux/pci.h> | ||
25 | #include <asm/irq.h> | ||
26 | #include <linux/interrupt.h> | ||
27 | |||
28 | #include "dmxdev.h" | ||
29 | #include "dvbdev.h" | ||
30 | #include "dvb_demux.h" | ||
31 | #include "dvb_frontend.h" | ||
32 | #include "dvb_net.h" | ||
33 | |||
34 | #include "mantis_common.h" | ||
35 | |||
36 | #include "mantis_vp1033.h" | ||
37 | #include "mantis_vp1034.h" | ||
38 | #include "mantis_vp1041.h" | ||
39 | #include "mantis_vp2033.h" | ||
40 | #include "mantis_vp2040.h" | ||
41 | #include "mantis_vp3030.h" | ||
42 | |||
43 | #include "mantis_dma.h" | ||
44 | #include "mantis_ca.h" | ||
45 | #include "mantis_dvb.h" | ||
46 | #include "mantis_uart.h" | ||
47 | #include "mantis_ioc.h" | ||
48 | #include "mantis_pci.h" | ||
49 | #include "mantis_i2c.h" | ||
50 | #include "mantis_reg.h" | ||
51 | |||
52 | static unsigned int verbose; | ||
53 | module_param(verbose, int, 0644); | ||
54 | MODULE_PARM_DESC(verbose, "verbose startup messages, default is 1 (yes)"); | ||
55 | |||
56 | static int devs; | ||
57 | |||
58 | #define DRIVER_NAME "Mantis" | ||
59 | |||
60 | static char *label[10] = { | ||
61 | "DMA", | ||
62 | "IRQ-0", | ||
63 | "IRQ-1", | ||
64 | "OCERR", | ||
65 | "PABRT", | ||
66 | "RIPRR", | ||
67 | "PPERR", | ||
68 | "FTRGT", | ||
69 | "RISCI", | ||
70 | "RACK" | ||
71 | }; | ||
72 | |||
73 | static irqreturn_t mantis_irq_handler(int irq, void *dev_id) | ||
74 | { | ||
75 | u32 stat = 0, mask = 0, lstat = 0, mstat = 0; | ||
76 | u32 rst_stat = 0, rst_mask = 0; | ||
77 | |||
78 | struct mantis_pci *mantis; | ||
79 | struct mantis_ca *ca; | ||
80 | |||
81 | mantis = (struct mantis_pci *) dev_id; | ||
82 | if (unlikely(mantis == NULL)) { | ||
83 | dprintk(MANTIS_ERROR, 1, "Mantis == NULL"); | ||
84 | return IRQ_NONE; | ||
85 | } | ||
86 | ca = mantis->mantis_ca; | ||
87 | |||
88 | stat = mmread(MANTIS_INT_STAT); | ||
89 | mask = mmread(MANTIS_INT_MASK); | ||
90 | mstat = lstat = stat & ~MANTIS_INT_RISCSTAT; | ||
91 | if (!(stat & mask)) | ||
92 | return IRQ_NONE; | ||
93 | |||
94 | rst_mask = MANTIS_GPIF_WRACK | | ||
95 | MANTIS_GPIF_OTHERR | | ||
96 | MANTIS_SBUF_WSTO | | ||
97 | MANTIS_GPIF_EXTIRQ; | ||
98 | |||
99 | rst_stat = mmread(MANTIS_GPIF_STATUS); | ||
100 | rst_stat &= rst_mask; | ||
101 | mmwrite(rst_stat, MANTIS_GPIF_STATUS); | ||
102 | |||
103 | mantis->mantis_int_stat = stat; | ||
104 | mantis->mantis_int_mask = mask; | ||
105 | dprintk(MANTIS_DEBUG, 0, "\n-- Stat=<%02x> Mask=<%02x> --", stat, mask); | ||
106 | if (stat & MANTIS_INT_RISCEN) { | ||
107 | dprintk(MANTIS_DEBUG, 0, "<%s>", label[0]); | ||
108 | } | ||
109 | if (stat & MANTIS_INT_IRQ0) { | ||
110 | dprintk(MANTIS_DEBUG, 0, "<%s>", label[1]); | ||
111 | mantis->gpif_status = rst_stat; | ||
112 | wake_up(&ca->hif_write_wq); | ||
113 | schedule_work(&ca->hif_evm_work); | ||
114 | } | ||
115 | if (stat & MANTIS_INT_IRQ1) { | ||
116 | dprintk(MANTIS_DEBUG, 0, "<%s>", label[2]); | ||
117 | schedule_work(&mantis->uart_work); | ||
118 | } | ||
119 | if (stat & MANTIS_INT_OCERR) { | ||
120 | dprintk(MANTIS_DEBUG, 0, "<%s>", label[3]); | ||
121 | } | ||
122 | if (stat & MANTIS_INT_PABORT) { | ||
123 | dprintk(MANTIS_DEBUG, 0, "<%s>", label[4]); | ||
124 | } | ||
125 | if (stat & MANTIS_INT_RIPERR) { | ||
126 | dprintk(MANTIS_DEBUG, 0, "<%s>", label[5]); | ||
127 | } | ||
128 | if (stat & MANTIS_INT_PPERR) { | ||
129 | dprintk(MANTIS_DEBUG, 0, "<%s>", label[6]); | ||
130 | } | ||
131 | if (stat & MANTIS_INT_FTRGT) { | ||
132 | dprintk(MANTIS_DEBUG, 0, "<%s>", label[7]); | ||
133 | } | ||
134 | if (stat & MANTIS_INT_RISCI) { | ||
135 | dprintk(MANTIS_DEBUG, 0, "<%s>", label[8]); | ||
136 | mantis->finished_block = (stat & MANTIS_INT_RISCSTAT) >> 28; | ||
137 | tasklet_schedule(&mantis->tasklet); | ||
138 | } | ||
139 | if (stat & MANTIS_INT_I2CDONE) { | ||
140 | dprintk(MANTIS_DEBUG, 0, "<%s>", label[9]); | ||
141 | wake_up(&mantis->i2c_wq); | ||
142 | } | ||
143 | mmwrite(stat, MANTIS_INT_STAT); | ||
144 | stat &= ~(MANTIS_INT_RISCEN | MANTIS_INT_I2CDONE | | ||
145 | MANTIS_INT_I2CRACK | MANTIS_INT_PCMCIA7 | | ||
146 | MANTIS_INT_PCMCIA6 | MANTIS_INT_PCMCIA5 | | ||
147 | MANTIS_INT_PCMCIA4 | MANTIS_INT_PCMCIA3 | | ||
148 | MANTIS_INT_PCMCIA2 | MANTIS_INT_PCMCIA1 | | ||
149 | MANTIS_INT_PCMCIA0 | MANTIS_INT_IRQ1 | | ||
150 | MANTIS_INT_IRQ0 | MANTIS_INT_OCERR | | ||
151 | MANTIS_INT_PABORT | MANTIS_INT_RIPERR | | ||
152 | MANTIS_INT_PPERR | MANTIS_INT_FTRGT | | ||
153 | MANTIS_INT_RISCI); | ||
154 | |||
155 | if (stat) | ||
156 | dprintk(MANTIS_DEBUG, 0, "<Unknown> Stat=<%02x> Mask=<%02x>", stat, mask); | ||
157 | |||
158 | dprintk(MANTIS_DEBUG, 0, "\n"); | ||
159 | return IRQ_HANDLED; | ||
160 | } | ||
161 | |||
162 | static int __devinit mantis_pci_probe(struct pci_dev *pdev, const struct pci_device_id *pci_id) | ||
163 | { | ||
164 | struct mantis_pci *mantis; | ||
165 | struct mantis_hwconfig *config; | ||
166 | int err = 0; | ||
167 | |||
168 | mantis = kzalloc(sizeof(struct mantis_pci), GFP_KERNEL); | ||
169 | if (mantis == NULL) { | ||
170 | printk(KERN_ERR "%s ERROR: Out of memory\n", __func__); | ||
171 | err = -ENOMEM; | ||
172 | goto fail0; | ||
173 | } | ||
174 | |||
175 | mantis->num = devs; | ||
176 | mantis->verbose = verbose; | ||
177 | mantis->pdev = pdev; | ||
178 | config = (struct mantis_hwconfig *) pci_id->driver_data; | ||
179 | config->irq_handler = &mantis_irq_handler; | ||
180 | mantis->hwconfig = config; | ||
181 | |||
182 | err = mantis_pci_init(mantis); | ||
183 | if (err) { | ||
184 | dprintk(MANTIS_ERROR, 1, "ERROR: Mantis PCI initialization failed <%d>", err); | ||
185 | goto fail1; | ||
186 | } | ||
187 | |||
188 | err = mantis_stream_control(mantis, STREAM_TO_HIF); | ||
189 | if (err < 0) { | ||
190 | dprintk(MANTIS_ERROR, 1, "ERROR: Mantis stream control failed <%d>", err); | ||
191 | goto fail1; | ||
192 | } | ||
193 | |||
194 | err = mantis_i2c_init(mantis); | ||
195 | if (err < 0) { | ||
196 | dprintk(MANTIS_ERROR, 1, "ERROR: Mantis I2C initialization failed <%d>", err); | ||
197 | goto fail2; | ||
198 | } | ||
199 | |||
200 | err = mantis_get_mac(mantis); | ||
201 | if (err < 0) { | ||
202 | dprintk(MANTIS_ERROR, 1, "ERROR: Mantis MAC address read failed <%d>", err); | ||
203 | goto fail2; | ||
204 | } | ||
205 | |||
206 | err = mantis_dma_init(mantis); | ||
207 | if (err < 0) { | ||
208 | dprintk(MANTIS_ERROR, 1, "ERROR: Mantis DMA initialization failed <%d>", err); | ||
209 | goto fail3; | ||
210 | } | ||
211 | |||
212 | err = mantis_dvb_init(mantis); | ||
213 | if (err < 0) { | ||
214 | dprintk(MANTIS_ERROR, 1, "ERROR: Mantis DVB initialization failed <%d>", err); | ||
215 | goto fail4; | ||
216 | } | ||
217 | err = mantis_uart_init(mantis); | ||
218 | if (err < 0) { | ||
219 | dprintk(MANTIS_ERROR, 1, "ERROR: Mantis UART initialization failed <%d>", err); | ||
220 | goto fail6; | ||
221 | } | ||
222 | |||
223 | devs++; | ||
224 | |||
225 | return err; | ||
226 | |||
227 | |||
228 | dprintk(MANTIS_ERROR, 1, "ERROR: Mantis UART exit! <%d>", err); | ||
229 | mantis_uart_exit(mantis); | ||
230 | |||
231 | fail6: | ||
232 | fail4: | ||
233 | dprintk(MANTIS_ERROR, 1, "ERROR: Mantis DMA exit! <%d>", err); | ||
234 | mantis_dma_exit(mantis); | ||
235 | |||
236 | fail3: | ||
237 | dprintk(MANTIS_ERROR, 1, "ERROR: Mantis I2C exit! <%d>", err); | ||
238 | mantis_i2c_exit(mantis); | ||
239 | |||
240 | fail2: | ||
241 | dprintk(MANTIS_ERROR, 1, "ERROR: Mantis PCI exit! <%d>", err); | ||
242 | mantis_pci_exit(mantis); | ||
243 | |||
244 | fail1: | ||
245 | dprintk(MANTIS_ERROR, 1, "ERROR: Mantis free! <%d>", err); | ||
246 | kfree(mantis); | ||
247 | |||
248 | fail0: | ||
249 | return err; | ||
250 | } | ||
251 | |||
252 | static void __devexit mantis_pci_remove(struct pci_dev *pdev) | ||
253 | { | ||
254 | struct mantis_pci *mantis = pci_get_drvdata(pdev); | ||
255 | |||
256 | if (mantis) { | ||
257 | |||
258 | mantis_uart_exit(mantis); | ||
259 | mantis_dvb_exit(mantis); | ||
260 | mantis_dma_exit(mantis); | ||
261 | mantis_i2c_exit(mantis); | ||
262 | mantis_pci_exit(mantis); | ||
263 | kfree(mantis); | ||
264 | } | ||
265 | return; | ||
266 | } | ||
267 | |||
268 | static struct pci_device_id mantis_pci_table[] = { | ||
269 | MAKE_ENTRY(TWINHAN_TECHNOLOGIES, MANTIS_VP_1033_DVB_S, &vp1033_config), | ||
270 | MAKE_ENTRY(TWINHAN_TECHNOLOGIES, MANTIS_VP_1034_DVB_S, &vp1034_config), | ||
271 | MAKE_ENTRY(TWINHAN_TECHNOLOGIES, MANTIS_VP_1041_DVB_S2, &vp1041_config), | ||
272 | MAKE_ENTRY(TECHNISAT, SKYSTAR_HD2_10, &vp1041_config), | ||
273 | MAKE_ENTRY(TECHNISAT, SKYSTAR_HD2_20, &vp1041_config), | ||
274 | MAKE_ENTRY(TERRATEC, CINERGY_S2_PCI_HD, &vp1041_config), | ||
275 | MAKE_ENTRY(TWINHAN_TECHNOLOGIES, MANTIS_VP_2033_DVB_C, &vp2033_config), | ||
276 | MAKE_ENTRY(TWINHAN_TECHNOLOGIES, MANTIS_VP_2040_DVB_C, &vp2040_config), | ||
277 | MAKE_ENTRY(TECHNISAT, CABLESTAR_HD2, &vp2040_config), | ||
278 | MAKE_ENTRY(TERRATEC, CINERGY_C, &vp2033_config), | ||
279 | MAKE_ENTRY(TWINHAN_TECHNOLOGIES, MANTIS_VP_3030_DVB_T, &vp3030_config), | ||
280 | { } | ||
281 | }; | ||
282 | |||
283 | static struct pci_driver mantis_pci_driver = { | ||
284 | .name = DRIVER_NAME, | ||
285 | .id_table = mantis_pci_table, | ||
286 | .probe = mantis_pci_probe, | ||
287 | .remove = mantis_pci_remove, | ||
288 | }; | ||
289 | |||
290 | static int __devinit mantis_init(void) | ||
291 | { | ||
292 | return pci_register_driver(&mantis_pci_driver); | ||
293 | } | ||
294 | |||
295 | static void __devexit mantis_exit(void) | ||
296 | { | ||
297 | return pci_unregister_driver(&mantis_pci_driver); | ||
298 | } | ||
299 | |||
300 | module_init(mantis_init); | ||
301 | module_exit(mantis_exit); | ||
302 | |||
303 | MODULE_DESCRIPTION("MANTIS driver"); | ||
304 | MODULE_AUTHOR("Manu Abraham"); | ||
305 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/media/dvb/mantis/mantis_common.h b/drivers/media/dvb/mantis/mantis_common.h new file mode 100644 index 000000000000..d0b645a483c9 --- /dev/null +++ b/drivers/media/dvb/mantis/mantis_common.h | |||
@@ -0,0 +1,179 @@ | |||
1 | /* | ||
2 | Mantis PCI bridge driver | ||
3 | |||
4 | Copyright (C) Manu Abraham (abraham.manu@gmail.com) | ||
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 __MANTIS_COMMON_H | ||
22 | #define __MANTIS_COMMON_H | ||
23 | |||
24 | #include <linux/mutex.h> | ||
25 | #include <linux/workqueue.h> | ||
26 | |||
27 | #include "mantis_uart.h" | ||
28 | |||
29 | #include "mantis_link.h" | ||
30 | |||
31 | #define MANTIS_ERROR 0 | ||
32 | #define MANTIS_NOTICE 1 | ||
33 | #define MANTIS_INFO 2 | ||
34 | #define MANTIS_DEBUG 3 | ||
35 | #define MANTIS_TMG 9 | ||
36 | |||
37 | #define dprintk(y, z, format, arg...) do { \ | ||
38 | if (z) { \ | ||
39 | if ((mantis->verbose > MANTIS_ERROR) && (mantis->verbose > y)) \ | ||
40 | printk(KERN_ERR "%s (%d): " format "\n" , __func__ , mantis->num , ##arg); \ | ||
41 | else if ((mantis->verbose > MANTIS_NOTICE) && (mantis->verbose > y)) \ | ||
42 | printk(KERN_NOTICE "%s (%d): " format "\n" , __func__ , mantis->num , ##arg); \ | ||
43 | else if ((mantis->verbose > MANTIS_INFO) && (mantis->verbose > y)) \ | ||
44 | printk(KERN_INFO "%s (%d): " format "\n" , __func__ , mantis->num , ##arg); \ | ||
45 | else if ((mantis->verbose > MANTIS_DEBUG) && (mantis->verbose > y)) \ | ||
46 | printk(KERN_DEBUG "%s (%d): " format "\n" , __func__ , mantis->num , ##arg); \ | ||
47 | else if ((mantis->verbose > MANTIS_TMG) && (mantis->verbose > y)) \ | ||
48 | printk(KERN_DEBUG "%s (%d): " format "\n" , __func__ , mantis->num , ##arg); \ | ||
49 | } else { \ | ||
50 | if (mantis->verbose > y) \ | ||
51 | printk(format , ##arg); \ | ||
52 | } \ | ||
53 | } while(0) | ||
54 | |||
55 | #define mwrite(dat, addr) writel((dat), addr) | ||
56 | #define mread(addr) readl(addr) | ||
57 | |||
58 | #define mmwrite(dat, addr) mwrite((dat), (mantis->mmio + (addr))) | ||
59 | #define mmread(addr) mread(mantis->mmio + (addr)) | ||
60 | |||
61 | #define MANTIS_TS_188 0 | ||
62 | #define MANTIS_TS_204 1 | ||
63 | |||
64 | #define TWINHAN_TECHNOLOGIES 0x1822 | ||
65 | #define MANTIS 0x4e35 | ||
66 | |||
67 | #define TECHNISAT 0x1ae4 | ||
68 | #define TERRATEC 0x153b | ||
69 | |||
70 | #define MAKE_ENTRY(__subven, __subdev, __configptr) { \ | ||
71 | .vendor = TWINHAN_TECHNOLOGIES, \ | ||
72 | .device = MANTIS, \ | ||
73 | .subvendor = (__subven), \ | ||
74 | .subdevice = (__subdev), \ | ||
75 | .driver_data = (unsigned long) (__configptr) \ | ||
76 | } | ||
77 | |||
78 | enum mantis_i2c_mode { | ||
79 | MANTIS_PAGE_MODE = 0, | ||
80 | MANTIS_BYTE_MODE, | ||
81 | }; | ||
82 | |||
83 | struct mantis_pci; | ||
84 | |||
85 | struct mantis_hwconfig { | ||
86 | char *model_name; | ||
87 | char *dev_type; | ||
88 | u32 ts_size; | ||
89 | |||
90 | enum mantis_baud baud_rate; | ||
91 | enum mantis_parity parity; | ||
92 | u32 bytes; | ||
93 | |||
94 | irqreturn_t (*irq_handler)(int irq, void *dev_id); | ||
95 | int (*frontend_init)(struct mantis_pci *mantis, struct dvb_frontend *fe); | ||
96 | |||
97 | u8 power; | ||
98 | u8 reset; | ||
99 | |||
100 | enum mantis_i2c_mode i2c_mode; | ||
101 | }; | ||
102 | |||
103 | struct mantis_pci { | ||
104 | unsigned int verbose; | ||
105 | |||
106 | /* PCI stuff */ | ||
107 | u16 vendor_id; | ||
108 | u16 device_id; | ||
109 | u16 subsystem_vendor; | ||
110 | u16 subsystem_device; | ||
111 | |||
112 | u8 latency; | ||
113 | |||
114 | struct pci_dev *pdev; | ||
115 | |||
116 | unsigned long mantis_addr; | ||
117 | void __iomem *mmio; | ||
118 | |||
119 | u8 irq; | ||
120 | u8 revision; | ||
121 | |||
122 | unsigned int num; | ||
123 | |||
124 | /* RISC Core */ | ||
125 | u32 finished_block; | ||
126 | u32 last_block; | ||
127 | u32 line_bytes; | ||
128 | u32 line_count; | ||
129 | u32 risc_pos; | ||
130 | u8 *buf_cpu; | ||
131 | dma_addr_t buf_dma; | ||
132 | u32 *risc_cpu; | ||
133 | dma_addr_t risc_dma; | ||
134 | |||
135 | struct tasklet_struct tasklet; | ||
136 | |||
137 | struct i2c_adapter adapter; | ||
138 | int i2c_rc; | ||
139 | wait_queue_head_t i2c_wq; | ||
140 | struct mutex i2c_lock; | ||
141 | |||
142 | /* DVB stuff */ | ||
143 | struct dvb_adapter dvb_adapter; | ||
144 | struct dvb_frontend *fe; | ||
145 | struct dvb_demux demux; | ||
146 | struct dmxdev dmxdev; | ||
147 | struct dmx_frontend fe_hw; | ||
148 | struct dmx_frontend fe_mem; | ||
149 | struct dvb_net dvbnet; | ||
150 | |||
151 | u8 feeds; | ||
152 | |||
153 | struct mantis_hwconfig *hwconfig; | ||
154 | |||
155 | u32 mantis_int_stat; | ||
156 | u32 mantis_int_mask; | ||
157 | |||
158 | /* board specific */ | ||
159 | u8 mac_address[8]; | ||
160 | u32 sub_vendor_id; | ||
161 | u32 sub_device_id; | ||
162 | |||
163 | /* A12 A13 A14 */ | ||
164 | u32 gpio_status; | ||
165 | |||
166 | u32 gpif_status; | ||
167 | |||
168 | struct mantis_ca *mantis_ca; | ||
169 | |||
170 | wait_queue_head_t uart_wq; | ||
171 | struct work_struct uart_work; | ||
172 | spinlock_t uart_lock; | ||
173 | |||
174 | struct input_dev *rc; | ||
175 | }; | ||
176 | |||
177 | #define MANTIS_HIF_STATUS (mantis->gpio_status) | ||
178 | |||
179 | #endif /* __MANTIS_COMMON_H */ | ||
diff --git a/drivers/media/dvb/mantis/mantis_core.c b/drivers/media/dvb/mantis/mantis_core.c new file mode 100644 index 000000000000..8113b23ce448 --- /dev/null +++ b/drivers/media/dvb/mantis/mantis_core.c | |||
@@ -0,0 +1,238 @@ | |||
1 | /* | ||
2 | Mantis PCI bridge driver | ||
3 | |||
4 | Copyright (C) Manu Abraham (abraham.manu@gmail.com) | ||
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 | #include "mantis_common.h" | ||
22 | #include "mantis_core.h" | ||
23 | #include "mantis_vp1033.h" | ||
24 | #include "mantis_vp1034.h" | ||
25 | #include "mantis_vp1041.h" | ||
26 | #include "mantis_vp2033.h" | ||
27 | #include "mantis_vp2040.h" | ||
28 | #include "mantis_vp3030.h" | ||
29 | |||
30 | static int read_eeprom_byte(struct mantis_pci *mantis, u8 *data, u8 length) | ||
31 | { | ||
32 | int err; | ||
33 | struct i2c_msg msg[] = { | ||
34 | { | ||
35 | .addr = 0x50, | ||
36 | .flags = 0, | ||
37 | .buf = data, | ||
38 | .len = 1 | ||
39 | }, { | ||
40 | .addr = 0x50, | ||
41 | .flags = I2C_M_RD, | ||
42 | .buf = data, | ||
43 | .len = length | ||
44 | }, | ||
45 | }; | ||
46 | |||
47 | err = i2c_transfer(&mantis->adapter, msg, 2); | ||
48 | if (err < 0) { | ||
49 | dprintk(verbose, MANTIS_ERROR, 1, | ||
50 | "ERROR: i2c read: < err=%i d0=0x%02x d1=0x%02x >", | ||
51 | err, data[0], data[1]); | ||
52 | |||
53 | return err; | ||
54 | } | ||
55 | |||
56 | return 0; | ||
57 | } | ||
58 | |||
59 | static int write_eeprom_byte(struct mantis_pci *mantis, u8 *data, u8 length) | ||
60 | { | ||
61 | int err; | ||
62 | |||
63 | struct i2c_msg msg = { | ||
64 | .addr = 0x50, | ||
65 | .flags = 0, | ||
66 | .buf = data, | ||
67 | .len = length | ||
68 | }; | ||
69 | |||
70 | err = i2c_transfer(&mantis->adapter, &msg, 1); | ||
71 | if (err < 0) { | ||
72 | dprintk(verbose, MANTIS_ERROR, 1, | ||
73 | "ERROR: i2c write: < err=%i length=0x%02x d0=0x%02x, d1=0x%02x >", | ||
74 | err, length, data[0], data[1]); | ||
75 | |||
76 | return err; | ||
77 | } | ||
78 | |||
79 | return 0; | ||
80 | } | ||
81 | |||
82 | static int get_mac_address(struct mantis_pci *mantis) | ||
83 | { | ||
84 | int err; | ||
85 | |||
86 | mantis->mac_address[0] = 0x08; | ||
87 | err = read_eeprom_byte(mantis, &mantis->mac_address[0], 6); | ||
88 | if (err < 0) { | ||
89 | dprintk(verbose, MANTIS_ERROR, 1, "Mantis EEPROM read error"); | ||
90 | |||
91 | return err; | ||
92 | } | ||
93 | dprintk(verbose, MANTIS_ERROR, 0, | ||
94 | " MAC Address=[%02x:%02x:%02x:%02x:%02x:%02x]\n", | ||
95 | mantis->mac_address[0], mantis->mac_address[1], | ||
96 | mantis->mac_address[2], mantis->mac_address[3], | ||
97 | mantis->mac_address[4], mantis->mac_address[5]); | ||
98 | |||
99 | return 0; | ||
100 | } | ||
101 | |||
102 | #define MANTIS_MODEL_UNKNOWN "UNKNOWN" | ||
103 | #define MANTIS_DEV_UNKNOWN "UNKNOWN" | ||
104 | |||
105 | struct mantis_hwconfig unknown_device = { | ||
106 | .model_name = MANTIS_MODEL_UNKNOWN, | ||
107 | .dev_type = MANTIS_DEV_UNKNOWN, | ||
108 | }; | ||
109 | |||
110 | static void mantis_load_config(struct mantis_pci *mantis) | ||
111 | { | ||
112 | switch (mantis->subsystem_device) { | ||
113 | case MANTIS_VP_1033_DVB_S: /* VP-1033 */ | ||
114 | mantis->hwconfig = &vp1033_mantis_config; | ||
115 | break; | ||
116 | case MANTIS_VP_1034_DVB_S: /* VP-1034 */ | ||
117 | mantis->hwconfig = &vp1034_mantis_config; | ||
118 | break; | ||
119 | case MANTIS_VP_1041_DVB_S2: /* VP-1041 */ | ||
120 | case TECHNISAT_SKYSTAR_HD2: | ||
121 | mantis->hwconfig = &vp1041_mantis_config; | ||
122 | break; | ||
123 | case MANTIS_VP_2033_DVB_C: /* VP-2033 */ | ||
124 | mantis->hwconfig = &vp2033_mantis_config; | ||
125 | break; | ||
126 | case MANTIS_VP_2040_DVB_C: /* VP-2040 */ | ||
127 | case TERRATEC_CINERGY_C_PCI: /* VP-2040 clone */ | ||
128 | case TECHNISAT_CABLESTAR_HD2: | ||
129 | mantis->hwconfig = &vp2040_mantis_config; | ||
130 | break; | ||
131 | case MANTIS_VP_3030_DVB_T: /* VP-3030 */ | ||
132 | mantis->hwconfig = &vp3030_mantis_config; | ||
133 | break; | ||
134 | default: | ||
135 | mantis->hwconfig = &unknown_device; | ||
136 | break; | ||
137 | } | ||
138 | } | ||
139 | |||
140 | int mantis_core_init(struct mantis_pci *mantis) | ||
141 | { | ||
142 | int err = 0; | ||
143 | |||
144 | mantis_load_config(mantis); | ||
145 | dprintk(verbose, MANTIS_ERROR, 0, "found a %s PCI %s device on (%02x:%02x.%x),\n", | ||
146 | mantis->hwconfig->model_name, mantis->hwconfig->dev_type, | ||
147 | mantis->pdev->bus->number, PCI_SLOT(mantis->pdev->devfn), PCI_FUNC(mantis->pdev->devfn)); | ||
148 | dprintk(verbose, MANTIS_ERROR, 0, " Mantis Rev %d [%04x:%04x], ", | ||
149 | mantis->revision, | ||
150 | mantis->subsystem_vendor, mantis->subsystem_device); | ||
151 | dprintk(verbose, MANTIS_ERROR, 0, | ||
152 | "irq: %d, latency: %d\n memory: 0x%lx, mmio: 0x%p\n", | ||
153 | mantis->pdev->irq, mantis->latency, | ||
154 | mantis->mantis_addr, mantis->mantis_mmio); | ||
155 | |||
156 | err = mantis_i2c_init(mantis); | ||
157 | if (err < 0) { | ||
158 | dprintk(verbose, MANTIS_ERROR, 1, "Mantis I2C init failed"); | ||
159 | return err; | ||
160 | } | ||
161 | err = get_mac_address(mantis); | ||
162 | if (err < 0) { | ||
163 | dprintk(verbose, MANTIS_ERROR, 1, "get MAC address failed"); | ||
164 | return err; | ||
165 | } | ||
166 | err = mantis_dma_init(mantis); | ||
167 | if (err < 0) { | ||
168 | dprintk(verbose, MANTIS_ERROR, 1, "Mantis DMA init failed"); | ||
169 | return err; | ||
170 | } | ||
171 | err = mantis_dvb_init(mantis); | ||
172 | if (err < 0) { | ||
173 | dprintk(verbose, MANTIS_DEBUG, 1, "Mantis DVB init failed"); | ||
174 | return err; | ||
175 | } | ||
176 | err = mantis_uart_init(mantis); | ||
177 | if (err < 0) { | ||
178 | dprintk(verbose, MANTIS_DEBUG, 1, "Mantis UART init failed"); | ||
179 | return err; | ||
180 | } | ||
181 | |||
182 | return 0; | ||
183 | } | ||
184 | |||
185 | int mantis_core_exit(struct mantis_pci *mantis) | ||
186 | { | ||
187 | mantis_dma_stop(mantis); | ||
188 | dprintk(verbose, MANTIS_ERROR, 1, "DMA engine stopping"); | ||
189 | |||
190 | mantis_uart_exit(mantis); | ||
191 | dprintk(verbose, MANTIS_ERROR, 1, "UART exit failed"); | ||
192 | |||
193 | if (mantis_dma_exit(mantis) < 0) | ||
194 | dprintk(verbose, MANTIS_ERROR, 1, "DMA exit failed"); | ||
195 | if (mantis_dvb_exit(mantis) < 0) | ||
196 | dprintk(verbose, MANTIS_ERROR, 1, "DVB exit failed"); | ||
197 | if (mantis_i2c_exit(mantis) < 0) | ||
198 | dprintk(verbose, MANTIS_ERROR, 1, "I2C adapter delete.. failed"); | ||
199 | |||
200 | return 0; | ||
201 | } | ||
202 | |||
203 | /* Turn the given bit on or off. */ | ||
204 | void gpio_set_bits(struct mantis_pci *mantis, u32 bitpos, u8 value) | ||
205 | { | ||
206 | u32 cur; | ||
207 | |||
208 | cur = mmread(MANTIS_GPIF_ADDR); | ||
209 | if (value) | ||
210 | mantis->gpio_status = cur | (1 << bitpos); | ||
211 | else | ||
212 | mantis->gpio_status = cur & (~(1 << bitpos)); | ||
213 | |||
214 | mmwrite(mantis->gpio_status, MANTIS_GPIF_ADDR); | ||
215 | mmwrite(0x00, MANTIS_GPIF_DOUT); | ||
216 | udelay(100); | ||
217 | } | ||
218 | |||
219 | /* direction = 0 , no CI passthrough ; 1 , CI passthrough */ | ||
220 | void mantis_set_direction(struct mantis_pci *mantis, int direction) | ||
221 | { | ||
222 | u32 reg; | ||
223 | |||
224 | reg = mmread(0x28); | ||
225 | dprintk(verbose, MANTIS_DEBUG, 1, "TS direction setup"); | ||
226 | if (direction == 0x01) { | ||
227 | /* to CI */ | ||
228 | reg |= 0x04; | ||
229 | mmwrite(reg, 0x28); | ||
230 | reg &= 0xff - 0x04; | ||
231 | mmwrite(reg, 0x28); | ||
232 | } else { | ||
233 | reg &= 0xff - 0x04; | ||
234 | mmwrite(reg, 0x28); | ||
235 | reg |= 0x04; | ||
236 | mmwrite(reg, 0x28); | ||
237 | } | ||
238 | } | ||
diff --git a/drivers/media/dvb/mantis/mantis_core.h b/drivers/media/dvb/mantis/mantis_core.h new file mode 100644 index 000000000000..833ee42e694e --- /dev/null +++ b/drivers/media/dvb/mantis/mantis_core.h | |||
@@ -0,0 +1,57 @@ | |||
1 | /* | ||
2 | Mantis PCI bridge driver | ||
3 | |||
4 | Copyright (C) Manu Abraham (abraham.manu@gmail.com) | ||
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 __MANTIS_CORE_H | ||
22 | #define __MANTIS_CORE_H | ||
23 | |||
24 | #include "mantis_common.h" | ||
25 | |||
26 | |||
27 | #define FE_TYPE_SAT 0 | ||
28 | #define FE_TYPE_CAB 1 | ||
29 | #define FE_TYPE_TER 2 | ||
30 | |||
31 | #define FE_TYPE_TS204 0 | ||
32 | #define FE_TYPE_TS188 1 | ||
33 | |||
34 | |||
35 | struct vendorname { | ||
36 | u8 *sub_vendor_name; | ||
37 | u32 sub_vendor_id; | ||
38 | }; | ||
39 | |||
40 | struct devicetype { | ||
41 | u8 *sub_device_name; | ||
42 | u32 sub_device_id; | ||
43 | u8 device_type; | ||
44 | u32 type_flags; | ||
45 | }; | ||
46 | |||
47 | |||
48 | extern int mantis_dma_init(struct mantis_pci *mantis); | ||
49 | extern int mantis_dma_exit(struct mantis_pci *mantis); | ||
50 | extern void mantis_dma_start(struct mantis_pci *mantis); | ||
51 | extern void mantis_dma_stop(struct mantis_pci *mantis); | ||
52 | extern int mantis_i2c_init(struct mantis_pci *mantis); | ||
53 | extern int mantis_i2c_exit(struct mantis_pci *mantis); | ||
54 | extern int mantis_core_init(struct mantis_pci *mantis); | ||
55 | extern int mantis_core_exit(struct mantis_pci *mantis); | ||
56 | |||
57 | #endif /* __MANTIS_CORE_H */ | ||
diff --git a/drivers/media/dvb/mantis/mantis_dma.c b/drivers/media/dvb/mantis/mantis_dma.c new file mode 100644 index 000000000000..46202a4012aa --- /dev/null +++ b/drivers/media/dvb/mantis/mantis_dma.c | |||
@@ -0,0 +1,256 @@ | |||
1 | /* | ||
2 | Mantis PCI bridge driver | ||
3 | |||
4 | Copyright (C) Manu Abraham (abraham.manu@gmail.com) | ||
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 | #include <linux/kernel.h> | ||
22 | #include <asm/page.h> | ||
23 | #include <linux/vmalloc.h> | ||
24 | #include <linux/pci.h> | ||
25 | |||
26 | #include <asm/irq.h> | ||
27 | #include <linux/signal.h> | ||
28 | #include <linux/sched.h> | ||
29 | #include <linux/interrupt.h> | ||
30 | |||
31 | #include "dmxdev.h" | ||
32 | #include "dvbdev.h" | ||
33 | #include "dvb_demux.h" | ||
34 | #include "dvb_frontend.h" | ||
35 | #include "dvb_net.h" | ||
36 | |||
37 | #include "mantis_common.h" | ||
38 | #include "mantis_reg.h" | ||
39 | #include "mantis_dma.h" | ||
40 | |||
41 | #define RISC_WRITE (0x01 << 28) | ||
42 | #define RISC_JUMP (0x07 << 28) | ||
43 | #define RISC_IRQ (0x01 << 24) | ||
44 | |||
45 | #define RISC_STATUS(status) ((((~status) & 0x0f) << 20) | ((status & 0x0f) << 16)) | ||
46 | #define RISC_FLUSH() (mantis->risc_pos = 0) | ||
47 | #define RISC_INSTR(opcode) (mantis->risc_cpu[mantis->risc_pos++] = cpu_to_le32(opcode)) | ||
48 | |||
49 | #define MANTIS_BUF_SIZE (64 * 1024) | ||
50 | #define MANTIS_BLOCK_BYTES (MANTIS_BUF_SIZE >> 4) | ||
51 | #define MANTIS_BLOCK_COUNT (1 << 4) | ||
52 | #define MANTIS_RISC_SIZE PAGE_SIZE | ||
53 | |||
54 | int mantis_dma_exit(struct mantis_pci *mantis) | ||
55 | { | ||
56 | if (mantis->buf_cpu) { | ||
57 | dprintk(MANTIS_ERROR, 1, | ||
58 | "DMA=0x%lx cpu=0x%p size=%d", | ||
59 | (unsigned long) mantis->buf_dma, | ||
60 | mantis->buf_cpu, | ||
61 | MANTIS_BUF_SIZE); | ||
62 | |||
63 | pci_free_consistent(mantis->pdev, MANTIS_BUF_SIZE, | ||
64 | mantis->buf_cpu, mantis->buf_dma); | ||
65 | |||
66 | mantis->buf_cpu = NULL; | ||
67 | } | ||
68 | if (mantis->risc_cpu) { | ||
69 | dprintk(MANTIS_ERROR, 1, | ||
70 | "RISC=0x%lx cpu=0x%p size=%lx", | ||
71 | (unsigned long) mantis->risc_dma, | ||
72 | mantis->risc_cpu, | ||
73 | MANTIS_RISC_SIZE); | ||
74 | |||
75 | pci_free_consistent(mantis->pdev, MANTIS_RISC_SIZE, | ||
76 | mantis->risc_cpu, mantis->risc_dma); | ||
77 | |||
78 | mantis->risc_cpu = NULL; | ||
79 | } | ||
80 | |||
81 | return 0; | ||
82 | } | ||
83 | EXPORT_SYMBOL_GPL(mantis_dma_exit); | ||
84 | |||
85 | static inline int mantis_alloc_buffers(struct mantis_pci *mantis) | ||
86 | { | ||
87 | if (!mantis->buf_cpu) { | ||
88 | mantis->buf_cpu = pci_alloc_consistent(mantis->pdev, | ||
89 | MANTIS_BUF_SIZE, | ||
90 | &mantis->buf_dma); | ||
91 | if (!mantis->buf_cpu) { | ||
92 | dprintk(MANTIS_ERROR, 1, | ||
93 | "DMA buffer allocation failed"); | ||
94 | |||
95 | goto err; | ||
96 | } | ||
97 | dprintk(MANTIS_ERROR, 1, | ||
98 | "DMA=0x%lx cpu=0x%p size=%d", | ||
99 | (unsigned long) mantis->buf_dma, | ||
100 | mantis->buf_cpu, MANTIS_BUF_SIZE); | ||
101 | } | ||
102 | if (!mantis->risc_cpu) { | ||
103 | mantis->risc_cpu = pci_alloc_consistent(mantis->pdev, | ||
104 | MANTIS_RISC_SIZE, | ||
105 | &mantis->risc_dma); | ||
106 | |||
107 | if (!mantis->risc_cpu) { | ||
108 | dprintk(MANTIS_ERROR, 1, | ||
109 | "RISC program allocation failed"); | ||
110 | |||
111 | mantis_dma_exit(mantis); | ||
112 | |||
113 | goto err; | ||
114 | } | ||
115 | dprintk(MANTIS_ERROR, 1, | ||
116 | "RISC=0x%lx cpu=0x%p size=%lx", | ||
117 | (unsigned long) mantis->risc_dma, | ||
118 | mantis->risc_cpu, MANTIS_RISC_SIZE); | ||
119 | } | ||
120 | |||
121 | return 0; | ||
122 | err: | ||
123 | dprintk(MANTIS_ERROR, 1, "Out of memory (?) ....."); | ||
124 | return -ENOMEM; | ||
125 | } | ||
126 | |||
127 | static inline int mantis_calc_lines(struct mantis_pci *mantis) | ||
128 | { | ||
129 | mantis->line_bytes = MANTIS_BLOCK_BYTES; | ||
130 | mantis->line_count = MANTIS_BLOCK_COUNT; | ||
131 | |||
132 | while (mantis->line_bytes > 4095) { | ||
133 | mantis->line_bytes >>= 1; | ||
134 | mantis->line_count <<= 1; | ||
135 | } | ||
136 | |||
137 | dprintk(MANTIS_DEBUG, 1, "Mantis RISC block bytes=[%d], line bytes=[%d], line count=[%d]", | ||
138 | MANTIS_BLOCK_BYTES, mantis->line_bytes, mantis->line_count); | ||
139 | |||
140 | if (mantis->line_count > 255) { | ||
141 | dprintk(MANTIS_ERROR, 1, "Buffer size error"); | ||
142 | return -EINVAL; | ||
143 | } | ||
144 | |||
145 | return 0; | ||
146 | } | ||
147 | |||
148 | int mantis_dma_init(struct mantis_pci *mantis) | ||
149 | { | ||
150 | int err = 0; | ||
151 | |||
152 | dprintk(MANTIS_DEBUG, 1, "Mantis DMA init"); | ||
153 | if (mantis_alloc_buffers(mantis) < 0) { | ||
154 | dprintk(MANTIS_ERROR, 1, "Error allocating DMA buffer"); | ||
155 | |||
156 | /* Stop RISC Engine */ | ||
157 | mmwrite(0, MANTIS_DMA_CTL); | ||
158 | |||
159 | goto err; | ||
160 | } | ||
161 | err = mantis_calc_lines(mantis); | ||
162 | if (err < 0) { | ||
163 | dprintk(MANTIS_ERROR, 1, "Mantis calc lines failed"); | ||
164 | |||
165 | goto err; | ||
166 | } | ||
167 | |||
168 | return 0; | ||
169 | err: | ||
170 | return err; | ||
171 | } | ||
172 | EXPORT_SYMBOL_GPL(mantis_dma_init); | ||
173 | |||
174 | static inline void mantis_risc_program(struct mantis_pci *mantis) | ||
175 | { | ||
176 | u32 buf_pos = 0; | ||
177 | u32 line; | ||
178 | |||
179 | dprintk(MANTIS_DEBUG, 1, "Mantis create RISC program"); | ||
180 | RISC_FLUSH(); | ||
181 | |||
182 | dprintk(MANTIS_DEBUG, 1, "risc len lines %u, bytes per line %u", | ||
183 | mantis->line_count, mantis->line_bytes); | ||
184 | |||
185 | for (line = 0; line < mantis->line_count; line++) { | ||
186 | dprintk(MANTIS_DEBUG, 1, "RISC PROG line=[%d]", line); | ||
187 | if (!(buf_pos % MANTIS_BLOCK_BYTES)) { | ||
188 | RISC_INSTR(RISC_WRITE | | ||
189 | RISC_IRQ | | ||
190 | RISC_STATUS(((buf_pos / MANTIS_BLOCK_BYTES) + | ||
191 | (MANTIS_BLOCK_COUNT - 1)) % | ||
192 | MANTIS_BLOCK_COUNT) | | ||
193 | mantis->line_bytes); | ||
194 | } else { | ||
195 | RISC_INSTR(RISC_WRITE | mantis->line_bytes); | ||
196 | } | ||
197 | RISC_INSTR(mantis->buf_dma + buf_pos); | ||
198 | buf_pos += mantis->line_bytes; | ||
199 | } | ||
200 | RISC_INSTR(RISC_JUMP); | ||
201 | RISC_INSTR(mantis->risc_dma); | ||
202 | } | ||
203 | |||
204 | void mantis_dma_start(struct mantis_pci *mantis) | ||
205 | { | ||
206 | dprintk(MANTIS_DEBUG, 1, "Mantis Start DMA engine"); | ||
207 | |||
208 | mantis_risc_program(mantis); | ||
209 | mmwrite(mantis->risc_dma, MANTIS_RISC_START); | ||
210 | mmwrite(mmread(MANTIS_GPIF_ADDR) | MANTIS_GPIF_HIFRDWRN, MANTIS_GPIF_ADDR); | ||
211 | |||
212 | mmwrite(0, MANTIS_DMA_CTL); | ||
213 | mantis->last_block = mantis->finished_block = 0; | ||
214 | |||
215 | mmwrite(mmread(MANTIS_INT_MASK) | MANTIS_INT_RISCI, MANTIS_INT_MASK); | ||
216 | |||
217 | mmwrite(MANTIS_FIFO_EN | MANTIS_DCAP_EN | ||
218 | | MANTIS_RISC_EN, MANTIS_DMA_CTL); | ||
219 | |||
220 | } | ||
221 | |||
222 | void mantis_dma_stop(struct mantis_pci *mantis) | ||
223 | { | ||
224 | u32 stat = 0, mask = 0; | ||
225 | |||
226 | stat = mmread(MANTIS_INT_STAT); | ||
227 | mask = mmread(MANTIS_INT_MASK); | ||
228 | dprintk(MANTIS_DEBUG, 1, "Mantis Stop DMA engine"); | ||
229 | |||
230 | mmwrite((mmread(MANTIS_GPIF_ADDR) & (~(MANTIS_GPIF_HIFRDWRN))), MANTIS_GPIF_ADDR); | ||
231 | |||
232 | mmwrite((mmread(MANTIS_DMA_CTL) & ~(MANTIS_FIFO_EN | | ||
233 | MANTIS_DCAP_EN | | ||
234 | MANTIS_RISC_EN)), MANTIS_DMA_CTL); | ||
235 | |||
236 | mmwrite(mmread(MANTIS_INT_STAT), MANTIS_INT_STAT); | ||
237 | |||
238 | mmwrite(mmread(MANTIS_INT_MASK) & ~(MANTIS_INT_RISCI | | ||
239 | MANTIS_INT_RISCEN), MANTIS_INT_MASK); | ||
240 | } | ||
241 | |||
242 | |||
243 | void mantis_dma_xfer(unsigned long data) | ||
244 | { | ||
245 | struct mantis_pci *mantis = (struct mantis_pci *) data; | ||
246 | struct mantis_hwconfig *config = mantis->hwconfig; | ||
247 | |||
248 | while (mantis->last_block != mantis->finished_block) { | ||
249 | dprintk(MANTIS_DEBUG, 1, "last block=[%d] finished block=[%d]", | ||
250 | mantis->last_block, mantis->finished_block); | ||
251 | |||
252 | (config->ts_size ? dvb_dmx_swfilter_204 : dvb_dmx_swfilter) | ||
253 | (&mantis->demux, &mantis->buf_cpu[mantis->last_block * MANTIS_BLOCK_BYTES], MANTIS_BLOCK_BYTES); | ||
254 | mantis->last_block = (mantis->last_block + 1) % MANTIS_BLOCK_COUNT; | ||
255 | } | ||
256 | } | ||
diff --git a/drivers/media/dvb/mantis/mantis_dma.h b/drivers/media/dvb/mantis/mantis_dma.h new file mode 100644 index 000000000000..6be00fa82094 --- /dev/null +++ b/drivers/media/dvb/mantis/mantis_dma.h | |||
@@ -0,0 +1,30 @@ | |||
1 | /* | ||
2 | Mantis PCI bridge driver | ||
3 | |||
4 | Copyright (C) Manu Abraham (abraham.manu@gmail.com) | ||
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 __MANTIS_DMA_H | ||
22 | #define __MANTIS_DMA_H | ||
23 | |||
24 | extern int mantis_dma_init(struct mantis_pci *mantis); | ||
25 | extern int mantis_dma_exit(struct mantis_pci *mantis); | ||
26 | extern void mantis_dma_start(struct mantis_pci *mantis); | ||
27 | extern void mantis_dma_stop(struct mantis_pci *mantis); | ||
28 | extern void mantis_dma_xfer(unsigned long data); | ||
29 | |||
30 | #endif /* __MANTIS_DMA_H */ | ||
diff --git a/drivers/media/dvb/mantis/mantis_dvb.c b/drivers/media/dvb/mantis/mantis_dvb.c new file mode 100644 index 000000000000..99d82eec3b03 --- /dev/null +++ b/drivers/media/dvb/mantis/mantis_dvb.c | |||
@@ -0,0 +1,296 @@ | |||
1 | /* | ||
2 | Mantis PCI bridge driver | ||
3 | Copyright (C) Manu Abraham (abraham.manu@gmail.com) | ||
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., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
18 | */ | ||
19 | |||
20 | #include <linux/kernel.h> | ||
21 | #include <linux/bitops.h> | ||
22 | |||
23 | #include <linux/signal.h> | ||
24 | #include <linux/sched.h> | ||
25 | #include <linux/interrupt.h> | ||
26 | #include <linux/pci.h> | ||
27 | #include <linux/i2c.h> | ||
28 | |||
29 | #include "dmxdev.h" | ||
30 | #include "dvbdev.h" | ||
31 | #include "dvb_demux.h" | ||
32 | #include "dvb_frontend.h" | ||
33 | #include "dvb_net.h" | ||
34 | |||
35 | #include "mantis_common.h" | ||
36 | #include "mantis_dma.h" | ||
37 | #include "mantis_ca.h" | ||
38 | #include "mantis_ioc.h" | ||
39 | #include "mantis_dvb.h" | ||
40 | |||
41 | DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); | ||
42 | |||
43 | int mantis_frontend_power(struct mantis_pci *mantis, enum mantis_power power) | ||
44 | { | ||
45 | struct mantis_hwconfig *config = mantis->hwconfig; | ||
46 | |||
47 | switch (power) { | ||
48 | case POWER_ON: | ||
49 | dprintk(MANTIS_DEBUG, 1, "Power ON"); | ||
50 | gpio_set_bits(mantis, config->power, POWER_ON); | ||
51 | msleep(100); | ||
52 | gpio_set_bits(mantis, config->power, POWER_ON); | ||
53 | msleep(100); | ||
54 | break; | ||
55 | |||
56 | case POWER_OFF: | ||
57 | dprintk(MANTIS_DEBUG, 1, "Power OFF"); | ||
58 | gpio_set_bits(mantis, config->power, POWER_OFF); | ||
59 | msleep(100); | ||
60 | break; | ||
61 | |||
62 | default: | ||
63 | dprintk(MANTIS_DEBUG, 1, "Unknown state <%02x>", power); | ||
64 | return -1; | ||
65 | } | ||
66 | |||
67 | return 0; | ||
68 | } | ||
69 | EXPORT_SYMBOL_GPL(mantis_frontend_power); | ||
70 | |||
71 | void mantis_frontend_soft_reset(struct mantis_pci *mantis) | ||
72 | { | ||
73 | struct mantis_hwconfig *config = mantis->hwconfig; | ||
74 | |||
75 | dprintk(MANTIS_DEBUG, 1, "Frontend RESET"); | ||
76 | gpio_set_bits(mantis, config->reset, 0); | ||
77 | msleep(100); | ||
78 | gpio_set_bits(mantis, config->reset, 0); | ||
79 | msleep(100); | ||
80 | gpio_set_bits(mantis, config->reset, 1); | ||
81 | msleep(100); | ||
82 | gpio_set_bits(mantis, config->reset, 1); | ||
83 | msleep(100); | ||
84 | |||
85 | return; | ||
86 | } | ||
87 | EXPORT_SYMBOL_GPL(mantis_frontend_soft_reset); | ||
88 | |||
89 | static int mantis_frontend_shutdown(struct mantis_pci *mantis) | ||
90 | { | ||
91 | int err; | ||
92 | |||
93 | mantis_frontend_soft_reset(mantis); | ||
94 | err = mantis_frontend_power(mantis, POWER_OFF); | ||
95 | if (err != 0) { | ||
96 | dprintk(MANTIS_ERROR, 1, "Frontend POWER OFF failed! <%d>", err); | ||
97 | return 1; | ||
98 | } | ||
99 | |||
100 | return 0; | ||
101 | } | ||
102 | |||
103 | static int mantis_dvb_start_feed(struct dvb_demux_feed *dvbdmxfeed) | ||
104 | { | ||
105 | struct dvb_demux *dvbdmx = dvbdmxfeed->demux; | ||
106 | struct mantis_pci *mantis = dvbdmx->priv; | ||
107 | |||
108 | dprintk(MANTIS_DEBUG, 1, "Mantis DVB Start feed"); | ||
109 | if (!dvbdmx->dmx.frontend) { | ||
110 | dprintk(MANTIS_DEBUG, 1, "no frontend ?"); | ||
111 | return -EINVAL; | ||
112 | } | ||
113 | |||
114 | mantis->feeds++; | ||
115 | dprintk(MANTIS_DEBUG, 1, "mantis start feed, feeds=%d", mantis->feeds); | ||
116 | |||
117 | if (mantis->feeds == 1) { | ||
118 | dprintk(MANTIS_DEBUG, 1, "mantis start feed & dma"); | ||
119 | mantis_dma_start(mantis); | ||
120 | } | ||
121 | |||
122 | return mantis->feeds; | ||
123 | } | ||
124 | |||
125 | static int mantis_dvb_stop_feed(struct dvb_demux_feed *dvbdmxfeed) | ||
126 | { | ||
127 | struct dvb_demux *dvbdmx = dvbdmxfeed->demux; | ||
128 | struct mantis_pci *mantis = dvbdmx->priv; | ||
129 | |||
130 | dprintk(MANTIS_DEBUG, 1, "Mantis DVB Stop feed"); | ||
131 | if (!dvbdmx->dmx.frontend) { | ||
132 | dprintk(MANTIS_DEBUG, 1, "no frontend ?"); | ||
133 | return -EINVAL; | ||
134 | } | ||
135 | |||
136 | mantis->feeds--; | ||
137 | if (mantis->feeds == 0) { | ||
138 | dprintk(MANTIS_DEBUG, 1, "mantis stop feed and dma"); | ||
139 | mantis_dma_stop(mantis); | ||
140 | } | ||
141 | |||
142 | return 0; | ||
143 | } | ||
144 | |||
145 | int __devinit mantis_dvb_init(struct mantis_pci *mantis) | ||
146 | { | ||
147 | struct mantis_hwconfig *config = mantis->hwconfig; | ||
148 | int result = -1; | ||
149 | |||
150 | dprintk(MANTIS_DEBUG, 1, "dvb_register_adapter"); | ||
151 | |||
152 | result = dvb_register_adapter(&mantis->dvb_adapter, | ||
153 | "Mantis DVB adapter", | ||
154 | THIS_MODULE, | ||
155 | &mantis->pdev->dev, | ||
156 | adapter_nr); | ||
157 | |||
158 | if (result < 0) { | ||
159 | |||
160 | dprintk(MANTIS_ERROR, 1, "Error registering adapter"); | ||
161 | return -ENODEV; | ||
162 | } | ||
163 | |||
164 | mantis->dvb_adapter.priv = mantis; | ||
165 | mantis->demux.dmx.capabilities = DMX_TS_FILTERING | | ||
166 | DMX_SECTION_FILTERING | | ||
167 | DMX_MEMORY_BASED_FILTERING; | ||
168 | |||
169 | mantis->demux.priv = mantis; | ||
170 | mantis->demux.filternum = 256; | ||
171 | mantis->demux.feednum = 256; | ||
172 | mantis->demux.start_feed = mantis_dvb_start_feed; | ||
173 | mantis->demux.stop_feed = mantis_dvb_stop_feed; | ||
174 | mantis->demux.write_to_decoder = NULL; | ||
175 | |||
176 | dprintk(MANTIS_DEBUG, 1, "dvb_dmx_init"); | ||
177 | result = dvb_dmx_init(&mantis->demux); | ||
178 | if (result < 0) { | ||
179 | dprintk(MANTIS_ERROR, 1, "dvb_dmx_init failed, ERROR=%d", result); | ||
180 | |||
181 | goto err0; | ||
182 | } | ||
183 | |||
184 | mantis->dmxdev.filternum = 256; | ||
185 | mantis->dmxdev.demux = &mantis->demux.dmx; | ||
186 | mantis->dmxdev.capabilities = 0; | ||
187 | dprintk(MANTIS_DEBUG, 1, "dvb_dmxdev_init"); | ||
188 | |||
189 | result = dvb_dmxdev_init(&mantis->dmxdev, &mantis->dvb_adapter); | ||
190 | if (result < 0) { | ||
191 | |||
192 | dprintk(MANTIS_ERROR, 1, "dvb_dmxdev_init failed, ERROR=%d", result); | ||
193 | goto err1; | ||
194 | } | ||
195 | |||
196 | mantis->fe_hw.source = DMX_FRONTEND_0; | ||
197 | result = mantis->demux.dmx.add_frontend(&mantis->demux.dmx, &mantis->fe_hw); | ||
198 | if (result < 0) { | ||
199 | |||
200 | dprintk(MANTIS_ERROR, 1, "dvb_dmx_init failed, ERROR=%d", result); | ||
201 | goto err2; | ||
202 | } | ||
203 | |||
204 | mantis->fe_mem.source = DMX_MEMORY_FE; | ||
205 | result = mantis->demux.dmx.add_frontend(&mantis->demux.dmx, &mantis->fe_mem); | ||
206 | if (result < 0) { | ||
207 | dprintk(MANTIS_ERROR, 1, "dvb_dmx_init failed, ERROR=%d", result); | ||
208 | goto err3; | ||
209 | } | ||
210 | |||
211 | result = mantis->demux.dmx.connect_frontend(&mantis->demux.dmx, &mantis->fe_hw); | ||
212 | if (result < 0) { | ||
213 | dprintk(MANTIS_ERROR, 1, "dvb_dmx_init failed, ERROR=%d", result); | ||
214 | goto err4; | ||
215 | } | ||
216 | |||
217 | dvb_net_init(&mantis->dvb_adapter, &mantis->dvbnet, &mantis->demux.dmx); | ||
218 | tasklet_init(&mantis->tasklet, mantis_dma_xfer, (unsigned long) mantis); | ||
219 | if (mantis->hwconfig) { | ||
220 | result = config->frontend_init(mantis, mantis->fe); | ||
221 | if (result < 0) { | ||
222 | dprintk(MANTIS_ERROR, 1, "!!! NO Frontends found !!!"); | ||
223 | goto err5; | ||
224 | } else { | ||
225 | if (mantis->fe == NULL) { | ||
226 | dprintk(MANTIS_ERROR, 1, "FE <NULL>"); | ||
227 | goto err5; | ||
228 | } | ||
229 | |||
230 | if (dvb_register_frontend(&mantis->dvb_adapter, mantis->fe)) { | ||
231 | dprintk(MANTIS_ERROR, 1, "ERROR: Frontend registration failed"); | ||
232 | |||
233 | if (mantis->fe->ops.release) | ||
234 | mantis->fe->ops.release(mantis->fe); | ||
235 | |||
236 | mantis->fe = NULL; | ||
237 | goto err5; | ||
238 | } | ||
239 | } | ||
240 | } | ||
241 | |||
242 | return 0; | ||
243 | |||
244 | /* Error conditions .. */ | ||
245 | err5: | ||
246 | tasklet_kill(&mantis->tasklet); | ||
247 | dvb_net_release(&mantis->dvbnet); | ||
248 | dvb_unregister_frontend(mantis->fe); | ||
249 | dvb_frontend_detach(mantis->fe); | ||
250 | err4: | ||
251 | mantis->demux.dmx.remove_frontend(&mantis->demux.dmx, &mantis->fe_mem); | ||
252 | |||
253 | err3: | ||
254 | mantis->demux.dmx.remove_frontend(&mantis->demux.dmx, &mantis->fe_hw); | ||
255 | |||
256 | err2: | ||
257 | dvb_dmxdev_release(&mantis->dmxdev); | ||
258 | |||
259 | err1: | ||
260 | dvb_dmx_release(&mantis->demux); | ||
261 | |||
262 | err0: | ||
263 | dvb_unregister_adapter(&mantis->dvb_adapter); | ||
264 | |||
265 | return result; | ||
266 | } | ||
267 | EXPORT_SYMBOL_GPL(mantis_dvb_init); | ||
268 | |||
269 | int __devexit mantis_dvb_exit(struct mantis_pci *mantis) | ||
270 | { | ||
271 | int err; | ||
272 | |||
273 | if (mantis->fe) { | ||
274 | /* mantis_ca_exit(mantis); */ | ||
275 | err = mantis_frontend_shutdown(mantis); | ||
276 | if (err != 0) | ||
277 | dprintk(MANTIS_ERROR, 1, "Frontend exit while POWER ON! <%d>", err); | ||
278 | dvb_unregister_frontend(mantis->fe); | ||
279 | dvb_frontend_detach(mantis->fe); | ||
280 | } | ||
281 | |||
282 | tasklet_kill(&mantis->tasklet); | ||
283 | dvb_net_release(&mantis->dvbnet); | ||
284 | |||
285 | mantis->demux.dmx.remove_frontend(&mantis->demux.dmx, &mantis->fe_mem); | ||
286 | mantis->demux.dmx.remove_frontend(&mantis->demux.dmx, &mantis->fe_hw); | ||
287 | |||
288 | dvb_dmxdev_release(&mantis->dmxdev); | ||
289 | dvb_dmx_release(&mantis->demux); | ||
290 | |||
291 | dprintk(MANTIS_DEBUG, 1, "dvb_unregister_adapter"); | ||
292 | dvb_unregister_adapter(&mantis->dvb_adapter); | ||
293 | |||
294 | return 0; | ||
295 | } | ||
296 | EXPORT_SYMBOL_GPL(mantis_dvb_exit); | ||
diff --git a/drivers/media/dvb/mantis/mantis_dvb.h b/drivers/media/dvb/mantis/mantis_dvb.h new file mode 100644 index 000000000000..464199db304e --- /dev/null +++ b/drivers/media/dvb/mantis/mantis_dvb.h | |||
@@ -0,0 +1,35 @@ | |||
1 | /* | ||
2 | Mantis PCI bridge driver | ||
3 | |||
4 | Copyright (C) Manu Abraham (abraham.manu@gmail.com) | ||
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 __MANTIS_DVB_H | ||
22 | #define __MANTIS_DVB_H | ||
23 | |||
24 | enum mantis_power { | ||
25 | POWER_OFF = 0, | ||
26 | POWER_ON = 1 | ||
27 | }; | ||
28 | |||
29 | extern int mantis_frontend_power(struct mantis_pci *mantis, enum mantis_power power); | ||
30 | extern void mantis_frontend_soft_reset(struct mantis_pci *mantis); | ||
31 | |||
32 | extern int mantis_dvb_init(struct mantis_pci *mantis); | ||
33 | extern int mantis_dvb_exit(struct mantis_pci *mantis); | ||
34 | |||
35 | #endif /* __MANTIS_DVB_H */ | ||
diff --git a/drivers/media/dvb/mantis/mantis_evm.c b/drivers/media/dvb/mantis/mantis_evm.c new file mode 100644 index 000000000000..a7b369a439d6 --- /dev/null +++ b/drivers/media/dvb/mantis/mantis_evm.c | |||
@@ -0,0 +1,117 @@ | |||
1 | /* | ||
2 | Mantis PCI bridge driver | ||
3 | |||
4 | Copyright (C) Manu Abraham (abraham.manu@gmail.com) | ||
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 | #include <linux/kernel.h> | ||
22 | |||
23 | #include <linux/signal.h> | ||
24 | #include <linux/sched.h> | ||
25 | #include <linux/interrupt.h> | ||
26 | |||
27 | #include "dmxdev.h" | ||
28 | #include "dvbdev.h" | ||
29 | #include "dvb_demux.h" | ||
30 | #include "dvb_frontend.h" | ||
31 | #include "dvb_net.h" | ||
32 | |||
33 | #include "mantis_common.h" | ||
34 | #include "mantis_link.h" | ||
35 | #include "mantis_hif.h" | ||
36 | #include "mantis_reg.h" | ||
37 | |||
38 | static void mantis_hifevm_work(struct work_struct *work) | ||
39 | { | ||
40 | struct mantis_ca *ca = container_of(work, struct mantis_ca, hif_evm_work); | ||
41 | struct mantis_pci *mantis = ca->ca_priv; | ||
42 | |||
43 | u32 gpif_stat, gpif_mask; | ||
44 | |||
45 | gpif_stat = mmread(MANTIS_GPIF_STATUS); | ||
46 | gpif_mask = mmread(MANTIS_GPIF_IRQCFG); | ||
47 | |||
48 | if (gpif_stat & MANTIS_GPIF_DETSTAT) { | ||
49 | if (gpif_stat & MANTIS_CARD_PLUGIN) { | ||
50 | dprintk(MANTIS_DEBUG, 1, "Event Mgr: Adapter(%d) Slot(0): CAM Plugin", mantis->num); | ||
51 | mmwrite(0xdada0000, MANTIS_CARD_RESET); | ||
52 | mantis_event_cam_plugin(ca); | ||
53 | dvb_ca_en50221_camchange_irq(&ca->en50221, | ||
54 | 0, | ||
55 | DVB_CA_EN50221_CAMCHANGE_INSERTED); | ||
56 | } | ||
57 | } else { | ||
58 | if (gpif_stat & MANTIS_CARD_PLUGOUT) { | ||
59 | dprintk(MANTIS_DEBUG, 1, "Event Mgr: Adapter(%d) Slot(0): CAM Unplug", mantis->num); | ||
60 | mmwrite(0xdada0000, MANTIS_CARD_RESET); | ||
61 | mantis_event_cam_unplug(ca); | ||
62 | dvb_ca_en50221_camchange_irq(&ca->en50221, | ||
63 | 0, | ||
64 | DVB_CA_EN50221_CAMCHANGE_REMOVED); | ||
65 | } | ||
66 | } | ||
67 | |||
68 | if (mantis->gpif_status & MANTIS_GPIF_EXTIRQ) | ||
69 | dprintk(MANTIS_DEBUG, 1, "Event Mgr: Adapter(%d) Slot(0): Ext IRQ", mantis->num); | ||
70 | |||
71 | if (mantis->gpif_status & MANTIS_SBUF_WSTO) | ||
72 | dprintk(MANTIS_DEBUG, 1, "Event Mgr: Adapter(%d) Slot(0): Smart Buffer Timeout", mantis->num); | ||
73 | |||
74 | if (mantis->gpif_status & MANTIS_GPIF_OTHERR) | ||
75 | dprintk(MANTIS_DEBUG, 1, "Event Mgr: Adapter(%d) Slot(0): Alignment Error", mantis->num); | ||
76 | |||
77 | if (gpif_stat & MANTIS_SBUF_OVFLW) | ||
78 | dprintk(MANTIS_DEBUG, 1, "Event Mgr: Adapter(%d) Slot(0): Smart Buffer Overflow", mantis->num); | ||
79 | |||
80 | if (gpif_stat & MANTIS_GPIF_BRRDY) | ||
81 | dprintk(MANTIS_DEBUG, 1, "Event Mgr: Adapter(%d) Slot(0): Smart Buffer Read Ready", mantis->num); | ||
82 | |||
83 | if (gpif_stat & MANTIS_GPIF_INTSTAT) | ||
84 | dprintk(MANTIS_DEBUG, 1, "Event Mgr: Adapter(%d) Slot(0): GPIF IRQ", mantis->num); | ||
85 | |||
86 | if (gpif_stat & MANTIS_SBUF_EMPTY) | ||
87 | dprintk(MANTIS_DEBUG, 1, "Event Mgr: Adapter(%d) Slot(0): Smart Buffer Empty", mantis->num); | ||
88 | |||
89 | if (gpif_stat & MANTIS_SBUF_OPDONE) { | ||
90 | dprintk(MANTIS_DEBUG, 1, "Event Mgr: Adapter(%d) Slot(0): Smart Buffer operation complete", mantis->num); | ||
91 | ca->sbuf_status = MANTIS_SBUF_DATA_AVAIL; | ||
92 | ca->hif_event = MANTIS_SBUF_OPDONE; | ||
93 | wake_up(&ca->hif_opdone_wq); | ||
94 | } | ||
95 | } | ||
96 | |||
97 | int mantis_evmgr_init(struct mantis_ca *ca) | ||
98 | { | ||
99 | struct mantis_pci *mantis = ca->ca_priv; | ||
100 | |||
101 | dprintk(MANTIS_DEBUG, 1, "Initializing Mantis Host I/F Event manager"); | ||
102 | INIT_WORK(&ca->hif_evm_work, mantis_hifevm_work); | ||
103 | mantis_pcmcia_init(ca); | ||
104 | schedule_work(&ca->hif_evm_work); | ||
105 | mantis_hif_init(ca); | ||
106 | return 0; | ||
107 | } | ||
108 | |||
109 | void mantis_evmgr_exit(struct mantis_ca *ca) | ||
110 | { | ||
111 | struct mantis_pci *mantis = ca->ca_priv; | ||
112 | |||
113 | dprintk(MANTIS_DEBUG, 1, "Mantis Host I/F Event manager exiting"); | ||
114 | flush_scheduled_work(); | ||
115 | mantis_hif_exit(ca); | ||
116 | mantis_pcmcia_exit(ca); | ||
117 | } | ||
diff --git a/drivers/media/dvb/mantis/mantis_hif.c b/drivers/media/dvb/mantis/mantis_hif.c new file mode 100644 index 000000000000..7477dac628b4 --- /dev/null +++ b/drivers/media/dvb/mantis/mantis_hif.c | |||
@@ -0,0 +1,240 @@ | |||
1 | /* | ||
2 | Mantis PCI bridge driver | ||
3 | |||
4 | Copyright (C) Manu Abraham (abraham.manu@gmail.com) | ||
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 | #include <linux/kernel.h> | ||
22 | #include <linux/signal.h> | ||
23 | #include <linux/sched.h> | ||
24 | |||
25 | #include <linux/signal.h> | ||
26 | #include <linux/sched.h> | ||
27 | #include <linux/interrupt.h> | ||
28 | |||
29 | #include "dmxdev.h" | ||
30 | #include "dvbdev.h" | ||
31 | #include "dvb_demux.h" | ||
32 | #include "dvb_frontend.h" | ||
33 | #include "dvb_net.h" | ||
34 | |||
35 | #include "mantis_common.h" | ||
36 | |||
37 | #include "mantis_hif.h" | ||
38 | #include "mantis_link.h" /* temporary due to physical layer stuff */ | ||
39 | |||
40 | #include "mantis_reg.h" | ||
41 | |||
42 | |||
43 | static int mantis_hif_sbuf_opdone_wait(struct mantis_ca *ca) | ||
44 | { | ||
45 | struct mantis_pci *mantis = ca->ca_priv; | ||
46 | int rc = 0; | ||
47 | |||
48 | if (wait_event_timeout(ca->hif_opdone_wq, | ||
49 | ca->hif_event & MANTIS_SBUF_OPDONE, | ||
50 | msecs_to_jiffies(500)) == -ERESTARTSYS) { | ||
51 | |||
52 | dprintk(MANTIS_ERROR, 1, "Adapter(%d) Slot(0): Smart buffer operation timeout !", mantis->num); | ||
53 | rc = -EREMOTEIO; | ||
54 | } | ||
55 | dprintk(MANTIS_DEBUG, 1, "Smart Buffer Operation complete"); | ||
56 | ca->hif_event &= ~MANTIS_SBUF_OPDONE; | ||
57 | return rc; | ||
58 | } | ||
59 | |||
60 | static int mantis_hif_write_wait(struct mantis_ca *ca) | ||
61 | { | ||
62 | struct mantis_pci *mantis = ca->ca_priv; | ||
63 | u32 opdone = 0, timeout = 0; | ||
64 | int rc = 0; | ||
65 | |||
66 | if (wait_event_timeout(ca->hif_write_wq, | ||
67 | mantis->gpif_status & MANTIS_GPIF_WRACK, | ||
68 | msecs_to_jiffies(500)) == -ERESTARTSYS) { | ||
69 | |||
70 | dprintk(MANTIS_ERROR, 1, "Adapter(%d) Slot(0): Write ACK timed out !", mantis->num); | ||
71 | rc = -EREMOTEIO; | ||
72 | } | ||
73 | dprintk(MANTIS_DEBUG, 1, "Write Acknowledged"); | ||
74 | mantis->gpif_status &= ~MANTIS_GPIF_WRACK; | ||
75 | while (!opdone) { | ||
76 | opdone = (mmread(MANTIS_GPIF_STATUS) & MANTIS_SBUF_OPDONE); | ||
77 | udelay(500); | ||
78 | timeout++; | ||
79 | if (timeout > 100) { | ||
80 | dprintk(MANTIS_ERROR, 1, "Adater(%d) Slot(0): Write operation timed out!", mantis->num); | ||
81 | rc = -ETIMEDOUT; | ||
82 | break; | ||
83 | } | ||
84 | } | ||
85 | dprintk(MANTIS_DEBUG, 1, "HIF Write success"); | ||
86 | return rc; | ||
87 | } | ||
88 | |||
89 | |||
90 | int mantis_hif_read_mem(struct mantis_ca *ca, u32 addr) | ||
91 | { | ||
92 | struct mantis_pci *mantis = ca->ca_priv; | ||
93 | u32 hif_addr = 0, data, count = 4; | ||
94 | |||
95 | dprintk(MANTIS_DEBUG, 1, "Adapter(%d) Slot(0): Request HIF Mem Read", mantis->num); | ||
96 | mutex_lock(&ca->ca_lock); | ||
97 | hif_addr &= ~MANTIS_GPIF_PCMCIAREG; | ||
98 | hif_addr &= ~MANTIS_GPIF_PCMCIAIOM; | ||
99 | hif_addr |= MANTIS_HIF_STATUS; | ||
100 | hif_addr |= addr; | ||
101 | |||
102 | mmwrite(hif_addr, MANTIS_GPIF_BRADDR); | ||
103 | mmwrite(count, MANTIS_GPIF_BRBYTES); | ||
104 | udelay(20); | ||
105 | mmwrite(hif_addr | MANTIS_GPIF_HIFRDWRN, MANTIS_GPIF_ADDR); | ||
106 | |||
107 | if (mantis_hif_sbuf_opdone_wait(ca) != 0) { | ||
108 | dprintk(MANTIS_ERROR, 1, "Adapter(%d) Slot(0): GPIF Smart Buffer operation failed", mantis->num); | ||
109 | mutex_unlock(&ca->ca_lock); | ||
110 | return -EREMOTEIO; | ||
111 | } | ||
112 | data = mmread(MANTIS_GPIF_DIN); | ||
113 | mutex_unlock(&ca->ca_lock); | ||
114 | dprintk(MANTIS_DEBUG, 1, "Mem Read: 0x%02x", data); | ||
115 | return (data >> 24) & 0xff; | ||
116 | } | ||
117 | |||
118 | int mantis_hif_write_mem(struct mantis_ca *ca, u32 addr, u8 data) | ||
119 | { | ||
120 | struct mantis_slot *slot = ca->slot; | ||
121 | struct mantis_pci *mantis = ca->ca_priv; | ||
122 | u32 hif_addr = 0; | ||
123 | |||
124 | dprintk(MANTIS_DEBUG, 1, "Adapter(%d) Slot(0): Request HIF Mem Write", mantis->num); | ||
125 | mutex_lock(&ca->ca_lock); | ||
126 | hif_addr &= ~MANTIS_GPIF_HIFRDWRN; | ||
127 | hif_addr &= ~MANTIS_GPIF_PCMCIAREG; | ||
128 | hif_addr &= ~MANTIS_GPIF_PCMCIAIOM; | ||
129 | hif_addr |= MANTIS_HIF_STATUS; | ||
130 | hif_addr |= addr; | ||
131 | |||
132 | mmwrite(slot->slave_cfg, MANTIS_GPIF_CFGSLA); /* Slot0 alone for now */ | ||
133 | mmwrite(hif_addr, MANTIS_GPIF_ADDR); | ||
134 | mmwrite(data, MANTIS_GPIF_DOUT); | ||
135 | |||
136 | if (mantis_hif_write_wait(ca) != 0) { | ||
137 | dprintk(MANTIS_ERROR, 1, "Adapter(%d) Slot(0): HIF Smart Buffer operation failed", mantis->num); | ||
138 | mutex_unlock(&ca->ca_lock); | ||
139 | return -EREMOTEIO; | ||
140 | } | ||
141 | dprintk(MANTIS_DEBUG, 1, "Mem Write: (0x%02x to 0x%02x)", data, addr); | ||
142 | mutex_unlock(&ca->ca_lock); | ||
143 | |||
144 | return 0; | ||
145 | } | ||
146 | |||
147 | int mantis_hif_read_iom(struct mantis_ca *ca, u32 addr) | ||
148 | { | ||
149 | struct mantis_pci *mantis = ca->ca_priv; | ||
150 | u32 data, hif_addr = 0; | ||
151 | |||
152 | dprintk(MANTIS_DEBUG, 1, "Adapter(%d) Slot(0): Request HIF I/O Read", mantis->num); | ||
153 | mutex_lock(&ca->ca_lock); | ||
154 | hif_addr &= ~MANTIS_GPIF_PCMCIAREG; | ||
155 | hif_addr |= MANTIS_GPIF_PCMCIAIOM; | ||
156 | hif_addr |= MANTIS_HIF_STATUS; | ||
157 | hif_addr |= addr; | ||
158 | |||
159 | mmwrite(hif_addr, MANTIS_GPIF_BRADDR); | ||
160 | mmwrite(1, MANTIS_GPIF_BRBYTES); | ||
161 | udelay(20); | ||
162 | mmwrite(hif_addr | MANTIS_GPIF_HIFRDWRN, MANTIS_GPIF_ADDR); | ||
163 | |||
164 | if (mantis_hif_sbuf_opdone_wait(ca) != 0) { | ||
165 | dprintk(MANTIS_ERROR, 1, "Adapter(%d) Slot(0): HIF Smart Buffer operation failed", mantis->num); | ||
166 | mutex_unlock(&ca->ca_lock); | ||
167 | return -EREMOTEIO; | ||
168 | } | ||
169 | data = mmread(MANTIS_GPIF_DIN); | ||
170 | dprintk(MANTIS_DEBUG, 1, "I/O Read: 0x%02x", data); | ||
171 | udelay(50); | ||
172 | mutex_unlock(&ca->ca_lock); | ||
173 | |||
174 | return (u8) data; | ||
175 | } | ||
176 | |||
177 | int mantis_hif_write_iom(struct mantis_ca *ca, u32 addr, u8 data) | ||
178 | { | ||
179 | struct mantis_pci *mantis = ca->ca_priv; | ||
180 | u32 hif_addr = 0; | ||
181 | |||
182 | dprintk(MANTIS_DEBUG, 1, "Adapter(%d) Slot(0): Request HIF I/O Write", mantis->num); | ||
183 | mutex_lock(&ca->ca_lock); | ||
184 | hif_addr &= ~MANTIS_GPIF_PCMCIAREG; | ||
185 | hif_addr &= ~MANTIS_GPIF_HIFRDWRN; | ||
186 | hif_addr |= MANTIS_GPIF_PCMCIAIOM; | ||
187 | hif_addr |= MANTIS_HIF_STATUS; | ||
188 | hif_addr |= addr; | ||
189 | |||
190 | mmwrite(hif_addr, MANTIS_GPIF_ADDR); | ||
191 | mmwrite(data, MANTIS_GPIF_DOUT); | ||
192 | |||
193 | if (mantis_hif_write_wait(ca) != 0) { | ||
194 | dprintk(MANTIS_ERROR, 1, "Adapter(%d) Slot(0): HIF Smart Buffer operation failed", mantis->num); | ||
195 | mutex_unlock(&ca->ca_lock); | ||
196 | return -EREMOTEIO; | ||
197 | } | ||
198 | dprintk(MANTIS_DEBUG, 1, "I/O Write: (0x%02x to 0x%02x)", data, addr); | ||
199 | mutex_unlock(&ca->ca_lock); | ||
200 | udelay(50); | ||
201 | |||
202 | return 0; | ||
203 | } | ||
204 | |||
205 | int mantis_hif_init(struct mantis_ca *ca) | ||
206 | { | ||
207 | struct mantis_slot *slot = ca->slot; | ||
208 | struct mantis_pci *mantis = ca->ca_priv; | ||
209 | u32 irqcfg; | ||
210 | |||
211 | slot[0].slave_cfg = 0x70773028; | ||
212 | dprintk(MANTIS_ERROR, 1, "Adapter(%d) Initializing Mantis Host Interface", mantis->num); | ||
213 | |||
214 | mutex_lock(&ca->ca_lock); | ||
215 | irqcfg = mmread(MANTIS_GPIF_IRQCFG); | ||
216 | irqcfg = MANTIS_MASK_BRRDY | | ||
217 | MANTIS_MASK_WRACK | | ||
218 | MANTIS_MASK_EXTIRQ | | ||
219 | MANTIS_MASK_WSTO | | ||
220 | MANTIS_MASK_OTHERR | | ||
221 | MANTIS_MASK_OVFLW; | ||
222 | |||
223 | mmwrite(irqcfg, MANTIS_GPIF_IRQCFG); | ||
224 | mutex_unlock(&ca->ca_lock); | ||
225 | |||
226 | return 0; | ||
227 | } | ||
228 | |||
229 | void mantis_hif_exit(struct mantis_ca *ca) | ||
230 | { | ||
231 | struct mantis_pci *mantis = ca->ca_priv; | ||
232 | u32 irqcfg; | ||
233 | |||
234 | dprintk(MANTIS_ERROR, 1, "Adapter(%d) Exiting Mantis Host Interface", mantis->num); | ||
235 | mutex_lock(&ca->ca_lock); | ||
236 | irqcfg = mmread(MANTIS_GPIF_IRQCFG); | ||
237 | irqcfg &= ~MANTIS_MASK_BRRDY; | ||
238 | mmwrite(irqcfg, MANTIS_GPIF_IRQCFG); | ||
239 | mutex_unlock(&ca->ca_lock); | ||
240 | } | ||
diff --git a/drivers/media/dvb/mantis/mantis_hif.h b/drivers/media/dvb/mantis/mantis_hif.h new file mode 100644 index 000000000000..9094f9ed2362 --- /dev/null +++ b/drivers/media/dvb/mantis/mantis_hif.h | |||
@@ -0,0 +1,29 @@ | |||
1 | /* | ||
2 | Mantis PCI bridge driver | ||
3 | |||
4 | Copyright (C) Manu Abraham (abraham.manu@gmail.com) | ||
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 __MANTIS_HIF_H | ||
22 | #define __MANTIS_HIF_H | ||
23 | |||
24 | #define MANTIS_HIF_MEMRD 1 | ||
25 | #define MANTIS_HIF_MEMWR 2 | ||
26 | #define MANTIS_HIF_IOMRD 3 | ||
27 | #define MANTIS_HIF_IOMWR 4 | ||
28 | |||
29 | #endif /* __MANTIS_HIF_H */ | ||
diff --git a/drivers/media/dvb/mantis/mantis_i2c.c b/drivers/media/dvb/mantis/mantis_i2c.c new file mode 100644 index 000000000000..7870bcf9689a --- /dev/null +++ b/drivers/media/dvb/mantis/mantis_i2c.c | |||
@@ -0,0 +1,267 @@ | |||
1 | /* | ||
2 | Mantis PCI bridge driver | ||
3 | |||
4 | Copyright (C) Manu Abraham (abraham.manu@gmail.com) | ||
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 | #include <asm/io.h> | ||
22 | #include <linux/ioport.h> | ||
23 | #include <linux/pci.h> | ||
24 | #include <linux/i2c.h> | ||
25 | |||
26 | #include "dmxdev.h" | ||
27 | #include "dvbdev.h" | ||
28 | #include "dvb_demux.h" | ||
29 | #include "dvb_frontend.h" | ||
30 | #include "dvb_net.h" | ||
31 | |||
32 | #include "mantis_common.h" | ||
33 | #include "mantis_reg.h" | ||
34 | #include "mantis_i2c.h" | ||
35 | |||
36 | #define TRIALS 10000 | ||
37 | |||
38 | static int mantis_i2c_read(struct mantis_pci *mantis, const struct i2c_msg *msg) | ||
39 | { | ||
40 | u32 rxd, i, stat, trials; | ||
41 | |||
42 | dprintk(MANTIS_INFO, 0, " %s: Address=[0x%02x] <R>[ ", | ||
43 | __func__, msg->addr); | ||
44 | |||
45 | for (i = 0; i < msg->len; i++) { | ||
46 | rxd = (msg->addr << 25) | (1 << 24) | ||
47 | | MANTIS_I2C_RATE_3 | ||
48 | | MANTIS_I2C_STOP | ||
49 | | MANTIS_I2C_PGMODE; | ||
50 | |||
51 | if (i == (msg->len - 1)) | ||
52 | rxd &= ~MANTIS_I2C_STOP; | ||
53 | |||
54 | mmwrite(MANTIS_INT_I2CDONE, MANTIS_INT_STAT); | ||
55 | mmwrite(rxd, MANTIS_I2CDATA_CTL); | ||
56 | |||
57 | /* wait for xfer completion */ | ||
58 | for (trials = 0; trials < TRIALS; trials++) { | ||
59 | stat = mmread(MANTIS_INT_STAT); | ||
60 | if (stat & MANTIS_INT_I2CDONE) | ||
61 | break; | ||
62 | } | ||
63 | |||
64 | dprintk(MANTIS_TMG, 0, "I2CDONE: trials=%d\n", trials); | ||
65 | |||
66 | /* wait for xfer completion */ | ||
67 | for (trials = 0; trials < TRIALS; trials++) { | ||
68 | stat = mmread(MANTIS_INT_STAT); | ||
69 | if (stat & MANTIS_INT_I2CRACK) | ||
70 | break; | ||
71 | } | ||
72 | |||
73 | dprintk(MANTIS_TMG, 0, "I2CRACK: trials=%d\n", trials); | ||
74 | |||
75 | rxd = mmread(MANTIS_I2CDATA_CTL); | ||
76 | msg->buf[i] = (u8)((rxd >> 8) & 0xFF); | ||
77 | dprintk(MANTIS_INFO, 0, "%02x ", msg->buf[i]); | ||
78 | } | ||
79 | dprintk(MANTIS_INFO, 0, "]\n"); | ||
80 | |||
81 | return 0; | ||
82 | } | ||
83 | |||
84 | static int mantis_i2c_write(struct mantis_pci *mantis, const struct i2c_msg *msg) | ||
85 | { | ||
86 | int i; | ||
87 | u32 txd = 0, stat, trials; | ||
88 | |||
89 | dprintk(MANTIS_INFO, 0, " %s: Address=[0x%02x] <W>[ ", | ||
90 | __func__, msg->addr); | ||
91 | |||
92 | for (i = 0; i < msg->len; i++) { | ||
93 | dprintk(MANTIS_INFO, 0, "%02x ", msg->buf[i]); | ||
94 | txd = (msg->addr << 25) | (msg->buf[i] << 8) | ||
95 | | MANTIS_I2C_RATE_3 | ||
96 | | MANTIS_I2C_STOP | ||
97 | | MANTIS_I2C_PGMODE; | ||
98 | |||
99 | if (i == (msg->len - 1)) | ||
100 | txd &= ~MANTIS_I2C_STOP; | ||
101 | |||
102 | mmwrite(MANTIS_INT_I2CDONE, MANTIS_INT_STAT); | ||
103 | mmwrite(txd, MANTIS_I2CDATA_CTL); | ||
104 | |||
105 | /* wait for xfer completion */ | ||
106 | for (trials = 0; trials < TRIALS; trials++) { | ||
107 | stat = mmread(MANTIS_INT_STAT); | ||
108 | if (stat & MANTIS_INT_I2CDONE) | ||
109 | break; | ||
110 | } | ||
111 | |||
112 | dprintk(MANTIS_TMG, 0, "I2CDONE: trials=%d\n", trials); | ||
113 | |||
114 | /* wait for xfer completion */ | ||
115 | for (trials = 0; trials < TRIALS; trials++) { | ||
116 | stat = mmread(MANTIS_INT_STAT); | ||
117 | if (stat & MANTIS_INT_I2CRACK) | ||
118 | break; | ||
119 | } | ||
120 | |||
121 | dprintk(MANTIS_TMG, 0, "I2CRACK: trials=%d\n", trials); | ||
122 | } | ||
123 | dprintk(MANTIS_INFO, 0, "]\n"); | ||
124 | |||
125 | return 0; | ||
126 | } | ||
127 | |||
128 | static int mantis_i2c_xfer(struct i2c_adapter *adapter, struct i2c_msg *msgs, int num) | ||
129 | { | ||
130 | int ret = 0, i = 0, trials; | ||
131 | u32 stat, data, txd; | ||
132 | struct mantis_pci *mantis; | ||
133 | struct mantis_hwconfig *config; | ||
134 | |||
135 | mantis = i2c_get_adapdata(adapter); | ||
136 | BUG_ON(!mantis); | ||
137 | config = mantis->hwconfig; | ||
138 | BUG_ON(!config); | ||
139 | |||
140 | dprintk(MANTIS_DEBUG, 1, "Messages:%d", num); | ||
141 | mutex_lock(&mantis->i2c_lock); | ||
142 | |||
143 | while (i < num) { | ||
144 | /* Byte MODE */ | ||
145 | if ((config->i2c_mode & MANTIS_BYTE_MODE) && | ||
146 | ((i + 1) < num) && | ||
147 | (msgs[i].len < 2) && | ||
148 | (msgs[i + 1].len < 2) && | ||
149 | (msgs[i + 1].flags & I2C_M_RD)) { | ||
150 | |||
151 | dprintk(MANTIS_DEBUG, 0, " Byte MODE:\n"); | ||
152 | |||
153 | /* Read operation */ | ||
154 | txd = msgs[i].addr << 25 | (0x1 << 24) | ||
155 | | (msgs[i].buf[0] << 16) | ||
156 | | MANTIS_I2C_RATE_3; | ||
157 | |||
158 | mmwrite(txd, MANTIS_I2CDATA_CTL); | ||
159 | /* wait for xfer completion */ | ||
160 | for (trials = 0; trials < TRIALS; trials++) { | ||
161 | stat = mmread(MANTIS_INT_STAT); | ||
162 | if (stat & MANTIS_INT_I2CDONE) | ||
163 | break; | ||
164 | } | ||
165 | |||
166 | /* check for xfer completion */ | ||
167 | if (stat & MANTIS_INT_I2CDONE) { | ||
168 | /* check xfer was acknowledged */ | ||
169 | if (stat & MANTIS_INT_I2CRACK) { | ||
170 | data = mmread(MANTIS_I2CDATA_CTL); | ||
171 | msgs[i + 1].buf[0] = (data >> 8) & 0xff; | ||
172 | dprintk(MANTIS_DEBUG, 0, " Byte <%d> RXD=0x%02x [%02x]\n", 0x0, data, msgs[i + 1].buf[0]); | ||
173 | } else { | ||
174 | /* I/O error */ | ||
175 | dprintk(MANTIS_ERROR, 1, " I/O error, LINE:%d", __LINE__); | ||
176 | ret = -EIO; | ||
177 | break; | ||
178 | } | ||
179 | } else { | ||
180 | /* I/O error */ | ||
181 | dprintk(MANTIS_ERROR, 1, " I/O error, LINE:%d", __LINE__); | ||
182 | ret = -EIO; | ||
183 | break; | ||
184 | } | ||
185 | i += 2; /* Write/Read operation in one go */ | ||
186 | } | ||
187 | |||
188 | if (i < num) { | ||
189 | if (msgs[i].flags & I2C_M_RD) | ||
190 | ret = mantis_i2c_read(mantis, &msgs[i]); | ||
191 | else | ||
192 | ret = mantis_i2c_write(mantis, &msgs[i]); | ||
193 | |||
194 | i++; | ||
195 | if (ret < 0) | ||
196 | goto bail_out; | ||
197 | } | ||
198 | |||
199 | } | ||
200 | |||
201 | mutex_unlock(&mantis->i2c_lock); | ||
202 | |||
203 | return num; | ||
204 | |||
205 | bail_out: | ||
206 | mutex_unlock(&mantis->i2c_lock); | ||
207 | return ret; | ||
208 | } | ||
209 | |||
210 | static u32 mantis_i2c_func(struct i2c_adapter *adapter) | ||
211 | { | ||
212 | return I2C_FUNC_SMBUS_EMUL; | ||
213 | } | ||
214 | |||
215 | static struct i2c_algorithm mantis_algo = { | ||
216 | .master_xfer = mantis_i2c_xfer, | ||
217 | .functionality = mantis_i2c_func, | ||
218 | }; | ||
219 | |||
220 | int __devinit mantis_i2c_init(struct mantis_pci *mantis) | ||
221 | { | ||
222 | u32 intstat, intmask; | ||
223 | struct i2c_adapter *i2c_adapter = &mantis->adapter; | ||
224 | struct pci_dev *pdev = mantis->pdev; | ||
225 | |||
226 | init_waitqueue_head(&mantis->i2c_wq); | ||
227 | mutex_init(&mantis->i2c_lock); | ||
228 | strncpy(i2c_adapter->name, "Mantis I2C", sizeof(i2c_adapter->name)); | ||
229 | i2c_set_adapdata(i2c_adapter, mantis); | ||
230 | |||
231 | i2c_adapter->owner = THIS_MODULE; | ||
232 | i2c_adapter->class = I2C_CLASS_TV_DIGITAL; | ||
233 | i2c_adapter->algo = &mantis_algo; | ||
234 | i2c_adapter->algo_data = NULL; | ||
235 | i2c_adapter->timeout = 500; | ||
236 | i2c_adapter->retries = 3; | ||
237 | i2c_adapter->dev.parent = &pdev->dev; | ||
238 | |||
239 | mantis->i2c_rc = i2c_add_adapter(i2c_adapter); | ||
240 | if (mantis->i2c_rc < 0) | ||
241 | return mantis->i2c_rc; | ||
242 | |||
243 | dprintk(MANTIS_DEBUG, 1, "Initializing I2C .."); | ||
244 | |||
245 | intstat = mmread(MANTIS_INT_STAT); | ||
246 | intmask = mmread(MANTIS_INT_MASK); | ||
247 | mmwrite(intstat, MANTIS_INT_STAT); | ||
248 | dprintk(MANTIS_DEBUG, 1, "Disabling I2C interrupt"); | ||
249 | intmask = mmread(MANTIS_INT_MASK); | ||
250 | mmwrite((intmask & ~MANTIS_INT_I2CDONE), MANTIS_INT_MASK); | ||
251 | |||
252 | return 0; | ||
253 | } | ||
254 | EXPORT_SYMBOL_GPL(mantis_i2c_init); | ||
255 | |||
256 | int mantis_i2c_exit(struct mantis_pci *mantis) | ||
257 | { | ||
258 | u32 intmask; | ||
259 | |||
260 | dprintk(MANTIS_DEBUG, 1, "Disabling I2C interrupt"); | ||
261 | intmask = mmread(MANTIS_INT_MASK); | ||
262 | mmwrite((intmask & ~MANTIS_INT_I2CDONE), MANTIS_INT_MASK); | ||
263 | |||
264 | dprintk(MANTIS_DEBUG, 1, "Removing I2C adapter"); | ||
265 | return i2c_del_adapter(&mantis->adapter); | ||
266 | } | ||
267 | EXPORT_SYMBOL_GPL(mantis_i2c_exit); | ||
diff --git a/drivers/media/dvb/mantis/mantis_i2c.h b/drivers/media/dvb/mantis/mantis_i2c.h new file mode 100644 index 000000000000..1342df2faed8 --- /dev/null +++ b/drivers/media/dvb/mantis/mantis_i2c.h | |||
@@ -0,0 +1,30 @@ | |||
1 | /* | ||
2 | Mantis PCI bridge driver | ||
3 | |||
4 | Copyright (C) Manu Abraham (abraham.manu@gmail.com) | ||
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 __MANTIS_I2C_H | ||
22 | #define __MANTIS_I2C_H | ||
23 | |||
24 | #define I2C_STOP (1 << 0) | ||
25 | #define I2C_READ (1 << 1) | ||
26 | |||
27 | extern int mantis_i2c_init(struct mantis_pci *mantis); | ||
28 | extern int mantis_i2c_exit(struct mantis_pci *mantis); | ||
29 | |||
30 | #endif /* __MANTIS_I2C_H */ | ||
diff --git a/drivers/media/dvb/mantis/mantis_input.c b/drivers/media/dvb/mantis/mantis_input.c new file mode 100644 index 000000000000..6a9df779441f --- /dev/null +++ b/drivers/media/dvb/mantis/mantis_input.c | |||
@@ -0,0 +1,148 @@ | |||
1 | /* | ||
2 | Mantis PCI bridge driver | ||
3 | |||
4 | Copyright (C) Manu Abraham (abraham.manu@gmail.com) | ||
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 | #include <linux/input.h> | ||
22 | #include <media/ir-common.h> | ||
23 | #include <linux/pci.h> | ||
24 | |||
25 | #include "dmxdev.h" | ||
26 | #include "dvbdev.h" | ||
27 | #include "dvb_demux.h" | ||
28 | #include "dvb_frontend.h" | ||
29 | #include "dvb_net.h" | ||
30 | |||
31 | #include "mantis_common.h" | ||
32 | #include "mantis_reg.h" | ||
33 | #include "mantis_uart.h" | ||
34 | |||
35 | static struct ir_scancode mantis_ir_table[] = { | ||
36 | { 0x29, KEY_POWER }, | ||
37 | { 0x28, KEY_FAVORITES }, | ||
38 | { 0x30, KEY_TEXT }, | ||
39 | { 0x17, KEY_INFO }, /* Preview */ | ||
40 | { 0x23, KEY_EPG }, | ||
41 | { 0x3b, KEY_F22 }, /* Record List */ | ||
42 | { 0x3c, KEY_1 }, | ||
43 | { 0x3e, KEY_2 }, | ||
44 | { 0x39, KEY_3 }, | ||
45 | { 0x36, KEY_4 }, | ||
46 | { 0x22, KEY_5 }, | ||
47 | { 0x20, KEY_6 }, | ||
48 | { 0x32, KEY_7 }, | ||
49 | { 0x26, KEY_8 }, | ||
50 | { 0x24, KEY_9 }, | ||
51 | { 0x2a, KEY_0 }, | ||
52 | |||
53 | { 0x33, KEY_CANCEL }, | ||
54 | { 0x2c, KEY_BACK }, | ||
55 | { 0x15, KEY_CLEAR }, | ||
56 | { 0x3f, KEY_TAB }, | ||
57 | { 0x10, KEY_ENTER }, | ||
58 | { 0x14, KEY_UP }, | ||
59 | { 0x0d, KEY_RIGHT }, | ||
60 | { 0x0e, KEY_DOWN }, | ||
61 | { 0x11, KEY_LEFT }, | ||
62 | |||
63 | { 0x21, KEY_VOLUMEUP }, | ||
64 | { 0x35, KEY_VOLUMEDOWN }, | ||
65 | { 0x3d, KEY_CHANNELDOWN }, | ||
66 | { 0x3a, KEY_CHANNELUP }, | ||
67 | { 0x2e, KEY_RECORD }, | ||
68 | { 0x2b, KEY_PLAY }, | ||
69 | { 0x13, KEY_PAUSE }, | ||
70 | { 0x25, KEY_STOP }, | ||
71 | |||
72 | { 0x1f, KEY_REWIND }, | ||
73 | { 0x2d, KEY_FASTFORWARD }, | ||
74 | { 0x1e, KEY_PREVIOUS }, /* Replay |< */ | ||
75 | { 0x1d, KEY_NEXT }, /* Skip >| */ | ||
76 | |||
77 | { 0x0b, KEY_CAMERA }, /* Capture */ | ||
78 | { 0x0f, KEY_LANGUAGE }, /* SAP */ | ||
79 | { 0x18, KEY_MODE }, /* PIP */ | ||
80 | { 0x12, KEY_ZOOM }, /* Full screen */ | ||
81 | { 0x1c, KEY_SUBTITLE }, | ||
82 | { 0x2f, KEY_MUTE }, | ||
83 | { 0x16, KEY_F20 }, /* L/R */ | ||
84 | { 0x38, KEY_F21 }, /* Hibernate */ | ||
85 | |||
86 | { 0x37, KEY_SWITCHVIDEOMODE }, /* A/V */ | ||
87 | { 0x31, KEY_AGAIN }, /* Recall */ | ||
88 | { 0x1a, KEY_KPPLUS }, /* Zoom+ */ | ||
89 | { 0x19, KEY_KPMINUS }, /* Zoom- */ | ||
90 | { 0x27, KEY_RED }, | ||
91 | { 0x0C, KEY_GREEN }, | ||
92 | { 0x01, KEY_YELLOW }, | ||
93 | { 0x00, KEY_BLUE }, | ||
94 | }; | ||
95 | |||
96 | struct ir_scancode_table ir_mantis = { | ||
97 | .scan = mantis_ir_table, | ||
98 | .size = ARRAY_SIZE(mantis_ir_table), | ||
99 | }; | ||
100 | EXPORT_SYMBOL_GPL(ir_mantis); | ||
101 | |||
102 | int mantis_input_init(struct mantis_pci *mantis) | ||
103 | { | ||
104 | struct input_dev *rc; | ||
105 | struct ir_input_state rc_state; | ||
106 | char name[80], dev[80]; | ||
107 | int err; | ||
108 | |||
109 | rc = input_allocate_device(); | ||
110 | if (!rc) { | ||
111 | dprintk(MANTIS_ERROR, 1, "Input device allocate failed"); | ||
112 | return -ENOMEM; | ||
113 | } | ||
114 | |||
115 | sprintf(name, "Mantis %s IR receiver", mantis->hwconfig->model_name); | ||
116 | sprintf(dev, "pci-%s/ir0", pci_name(mantis->pdev)); | ||
117 | |||
118 | rc->name = name; | ||
119 | rc->phys = dev; | ||
120 | |||
121 | ir_input_init(rc, &rc_state, IR_TYPE_OTHER); | ||
122 | |||
123 | rc->id.bustype = BUS_PCI; | ||
124 | rc->id.vendor = mantis->vendor_id; | ||
125 | rc->id.product = mantis->device_id; | ||
126 | rc->id.version = 1; | ||
127 | rc->dev = mantis->pdev->dev; | ||
128 | |||
129 | err = ir_input_register(rc, &ir_mantis); | ||
130 | if (err) { | ||
131 | dprintk(MANTIS_ERROR, 1, "IR device registration failed, ret = %d", err); | ||
132 | input_free_device(rc); | ||
133 | return -ENODEV; | ||
134 | } | ||
135 | |||
136 | mantis->rc = rc; | ||
137 | |||
138 | return 0; | ||
139 | } | ||
140 | |||
141 | int mantis_exit(struct mantis_pci *mantis) | ||
142 | { | ||
143 | struct input_dev *rc = mantis->rc; | ||
144 | |||
145 | ir_input_unregister(rc); | ||
146 | |||
147 | return 0; | ||
148 | } | ||
diff --git a/drivers/media/dvb/mantis/mantis_ioc.c b/drivers/media/dvb/mantis/mantis_ioc.c new file mode 100644 index 000000000000..de148ded52d8 --- /dev/null +++ b/drivers/media/dvb/mantis/mantis_ioc.c | |||
@@ -0,0 +1,130 @@ | |||
1 | /* | ||
2 | Mantis PCI bridge driver | ||
3 | |||
4 | Copyright (C) Manu Abraham (abraham.manu@gmail.com) | ||
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 | #include <linux/kernel.h> | ||
22 | #include <linux/i2c.h> | ||
23 | |||
24 | #include <linux/signal.h> | ||
25 | #include <linux/sched.h> | ||
26 | #include <linux/interrupt.h> | ||
27 | |||
28 | #include "dmxdev.h" | ||
29 | #include "dvbdev.h" | ||
30 | #include "dvb_demux.h" | ||
31 | #include "dvb_frontend.h" | ||
32 | #include "dvb_net.h" | ||
33 | |||
34 | #include "mantis_common.h" | ||
35 | #include "mantis_reg.h" | ||
36 | #include "mantis_ioc.h" | ||
37 | |||
38 | static int read_eeprom_bytes(struct mantis_pci *mantis, u8 reg, u8 *data, u8 length) | ||
39 | { | ||
40 | struct i2c_adapter *adapter = &mantis->adapter; | ||
41 | int err; | ||
42 | u8 buf = reg; | ||
43 | |||
44 | struct i2c_msg msg[] = { | ||
45 | { .addr = 0x50, .flags = 0, .buf = &buf, .len = 1 }, | ||
46 | { .addr = 0x50, .flags = I2C_M_RD, .buf = data, .len = length }, | ||
47 | }; | ||
48 | |||
49 | err = i2c_transfer(adapter, msg, 2); | ||
50 | if (err < 0) { | ||
51 | dprintk(MANTIS_ERROR, 1, "ERROR: i2c read: < err=%i d0=0x%02x d1=0x%02x >", | ||
52 | err, data[0], data[1]); | ||
53 | |||
54 | return err; | ||
55 | } | ||
56 | |||
57 | return 0; | ||
58 | } | ||
59 | int mantis_get_mac(struct mantis_pci *mantis) | ||
60 | { | ||
61 | int err; | ||
62 | u8 mac_addr[6] = {0}; | ||
63 | |||
64 | err = read_eeprom_bytes(mantis, 0x08, mac_addr, 6); | ||
65 | if (err < 0) { | ||
66 | dprintk(MANTIS_ERROR, 1, "ERROR: Mantis EEPROM read error <%d>", err); | ||
67 | |||
68 | return err; | ||
69 | } | ||
70 | |||
71 | dprintk(MANTIS_ERROR, 0, | ||
72 | " MAC Address=[%02x:%02x:%02x:%02x:%02x:%02x]\n", | ||
73 | mac_addr[0], | ||
74 | mac_addr[1], | ||
75 | mac_addr[2], | ||
76 | mac_addr[3], | ||
77 | mac_addr[4], | ||
78 | mac_addr[5]); | ||
79 | |||
80 | return 0; | ||
81 | } | ||
82 | EXPORT_SYMBOL_GPL(mantis_get_mac); | ||
83 | |||
84 | /* Turn the given bit on or off. */ | ||
85 | void gpio_set_bits(struct mantis_pci *mantis, u32 bitpos, u8 value) | ||
86 | { | ||
87 | u32 cur; | ||
88 | |||
89 | dprintk(MANTIS_DEBUG, 1, "Set Bit <%d> to <%d>", bitpos, value); | ||
90 | cur = mmread(MANTIS_GPIF_ADDR); | ||
91 | if (value) | ||
92 | mantis->gpio_status = cur | (1 << bitpos); | ||
93 | else | ||
94 | mantis->gpio_status = cur & (~(1 << bitpos)); | ||
95 | |||
96 | dprintk(MANTIS_DEBUG, 1, "GPIO Value <%02x>", mantis->gpio_status); | ||
97 | mmwrite(mantis->gpio_status, MANTIS_GPIF_ADDR); | ||
98 | mmwrite(0x00, MANTIS_GPIF_DOUT); | ||
99 | } | ||
100 | EXPORT_SYMBOL_GPL(gpio_set_bits); | ||
101 | |||
102 | int mantis_stream_control(struct mantis_pci *mantis, enum mantis_stream_control stream_ctl) | ||
103 | { | ||
104 | u32 reg; | ||
105 | |||
106 | reg = mmread(MANTIS_CONTROL); | ||
107 | switch (stream_ctl) { | ||
108 | case STREAM_TO_HIF: | ||
109 | dprintk(MANTIS_DEBUG, 1, "Set stream to HIF"); | ||
110 | reg &= 0xff - MANTIS_BYPASS; | ||
111 | mmwrite(reg, MANTIS_CONTROL); | ||
112 | reg |= MANTIS_BYPASS; | ||
113 | mmwrite(reg, MANTIS_CONTROL); | ||
114 | break; | ||
115 | |||
116 | case STREAM_TO_CAM: | ||
117 | dprintk(MANTIS_DEBUG, 1, "Set stream to CAM"); | ||
118 | reg |= MANTIS_BYPASS; | ||
119 | mmwrite(reg, MANTIS_CONTROL); | ||
120 | reg &= 0xff - MANTIS_BYPASS; | ||
121 | mmwrite(reg, MANTIS_CONTROL); | ||
122 | break; | ||
123 | default: | ||
124 | dprintk(MANTIS_ERROR, 1, "Unknown MODE <%02x>", stream_ctl); | ||
125 | return -1; | ||
126 | } | ||
127 | |||
128 | return 0; | ||
129 | } | ||
130 | EXPORT_SYMBOL_GPL(mantis_stream_control); | ||
diff --git a/drivers/media/dvb/mantis/mantis_ioc.h b/drivers/media/dvb/mantis/mantis_ioc.h new file mode 100644 index 000000000000..188fe5a81614 --- /dev/null +++ b/drivers/media/dvb/mantis/mantis_ioc.h | |||
@@ -0,0 +1,51 @@ | |||
1 | /* | ||
2 | Mantis PCI bridge driver | ||
3 | |||
4 | Copyright (C) Manu Abraham (abraham.manu@gmail.com) | ||
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 __MANTIS_IOC_H | ||
22 | #define __MANTIS_IOC_H | ||
23 | |||
24 | #define GPIF_A00 0x00 | ||
25 | #define GPIF_A01 0x01 | ||
26 | #define GPIF_A02 0x02 | ||
27 | #define GPIF_A03 0x03 | ||
28 | #define GPIF_A04 0x04 | ||
29 | #define GPIF_A05 0x05 | ||
30 | #define GPIF_A06 0x06 | ||
31 | #define GPIF_A07 0x07 | ||
32 | #define GPIF_A08 0x08 | ||
33 | #define GPIF_A09 0x09 | ||
34 | #define GPIF_A10 0x0a | ||
35 | #define GPIF_A11 0x0b | ||
36 | |||
37 | #define GPIF_A12 0x0c | ||
38 | #define GPIF_A13 0x0d | ||
39 | #define GPIF_A14 0x0e | ||
40 | |||
41 | enum mantis_stream_control { | ||
42 | STREAM_TO_HIF = 0, | ||
43 | STREAM_TO_CAM | ||
44 | }; | ||
45 | |||
46 | extern int mantis_get_mac(struct mantis_pci *mantis); | ||
47 | extern void gpio_set_bits(struct mantis_pci *mantis, u32 bitpos, u8 value); | ||
48 | |||
49 | extern int mantis_stream_control(struct mantis_pci *mantis, enum mantis_stream_control stream_ctl); | ||
50 | |||
51 | #endif /* __MANTIS_IOC_H */ | ||
diff --git a/drivers/media/dvb/mantis/mantis_link.h b/drivers/media/dvb/mantis/mantis_link.h new file mode 100644 index 000000000000..2a814774a001 --- /dev/null +++ b/drivers/media/dvb/mantis/mantis_link.h | |||
@@ -0,0 +1,83 @@ | |||
1 | /* | ||
2 | Mantis PCI bridge driver | ||
3 | |||
4 | Copyright (C) Manu Abraham (abraham.manu@gmail.com) | ||
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 __MANTIS_LINK_H | ||
22 | #define __MANTIS_LINK_H | ||
23 | |||
24 | #include <linux/mutex.h> | ||
25 | #include <linux/workqueue.h> | ||
26 | #include "dvb_ca_en50221.h" | ||
27 | |||
28 | enum mantis_sbuf_status { | ||
29 | MANTIS_SBUF_DATA_AVAIL = 1, | ||
30 | MANTIS_SBUF_DATA_EMPTY = 2, | ||
31 | MANTIS_SBUF_DATA_OVFLW = 3 | ||
32 | }; | ||
33 | |||
34 | struct mantis_slot { | ||
35 | u32 timeout; | ||
36 | u32 slave_cfg; | ||
37 | u32 bar; | ||
38 | }; | ||
39 | |||
40 | /* Physical layer */ | ||
41 | enum mantis_slot_state { | ||
42 | MODULE_INSERTED = 3, | ||
43 | MODULE_XTRACTED = 4 | ||
44 | }; | ||
45 | |||
46 | struct mantis_ca { | ||
47 | struct mantis_slot slot[4]; | ||
48 | |||
49 | struct work_struct hif_evm_work; | ||
50 | |||
51 | u32 hif_event; | ||
52 | wait_queue_head_t hif_opdone_wq; | ||
53 | wait_queue_head_t hif_brrdyw_wq; | ||
54 | wait_queue_head_t hif_data_wq; | ||
55 | wait_queue_head_t hif_write_wq; /* HIF Write op */ | ||
56 | |||
57 | enum mantis_sbuf_status sbuf_status; | ||
58 | |||
59 | enum mantis_slot_state slot_state; | ||
60 | |||
61 | void *ca_priv; | ||
62 | |||
63 | struct dvb_ca_en50221 en50221; | ||
64 | struct mutex ca_lock; | ||
65 | }; | ||
66 | |||
67 | /* CA */ | ||
68 | extern void mantis_event_cam_plugin(struct mantis_ca *ca); | ||
69 | extern void mantis_event_cam_unplug(struct mantis_ca *ca); | ||
70 | extern int mantis_pcmcia_init(struct mantis_ca *ca); | ||
71 | extern void mantis_pcmcia_exit(struct mantis_ca *ca); | ||
72 | extern int mantis_evmgr_init(struct mantis_ca *ca); | ||
73 | extern void mantis_evmgr_exit(struct mantis_ca *ca); | ||
74 | |||
75 | /* HIF */ | ||
76 | extern int mantis_hif_init(struct mantis_ca *ca); | ||
77 | extern void mantis_hif_exit(struct mantis_ca *ca); | ||
78 | extern int mantis_hif_read_mem(struct mantis_ca *ca, u32 addr); | ||
79 | extern int mantis_hif_write_mem(struct mantis_ca *ca, u32 addr, u8 data); | ||
80 | extern int mantis_hif_read_iom(struct mantis_ca *ca, u32 addr); | ||
81 | extern int mantis_hif_write_iom(struct mantis_ca *ca, u32 addr, u8 data); | ||
82 | |||
83 | #endif /* __MANTIS_LINK_H */ | ||
diff --git a/drivers/media/dvb/mantis/mantis_pci.c b/drivers/media/dvb/mantis/mantis_pci.c new file mode 100644 index 000000000000..6c7534af6b44 --- /dev/null +++ b/drivers/media/dvb/mantis/mantis_pci.c | |||
@@ -0,0 +1,177 @@ | |||
1 | /* | ||
2 | Mantis PCI bridge driver | ||
3 | |||
4 | Copyright (C) Manu Abraham (abraham.manu@gmail.com) | ||
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 | #include <linux/module.h> | ||
22 | #include <linux/moduleparam.h> | ||
23 | #include <linux/kernel.h> | ||
24 | #include <asm/io.h> | ||
25 | #include <asm/pgtable.h> | ||
26 | #include <asm/page.h> | ||
27 | #include <linux/kmod.h> | ||
28 | #include <linux/vmalloc.h> | ||
29 | #include <linux/init.h> | ||
30 | #include <linux/device.h> | ||
31 | #include <linux/pci.h> | ||
32 | |||
33 | #include <asm/irq.h> | ||
34 | #include <linux/signal.h> | ||
35 | #include <linux/sched.h> | ||
36 | #include <linux/interrupt.h> | ||
37 | |||
38 | #include "dmxdev.h" | ||
39 | #include "dvbdev.h" | ||
40 | #include "dvb_demux.h" | ||
41 | #include "dvb_frontend.h" | ||
42 | #include "dvb_net.h" | ||
43 | |||
44 | #include <asm/irq.h> | ||
45 | #include <linux/signal.h> | ||
46 | #include <linux/sched.h> | ||
47 | #include <linux/interrupt.h> | ||
48 | |||
49 | #include "mantis_common.h" | ||
50 | #include "mantis_reg.h" | ||
51 | #include "mantis_pci.h" | ||
52 | |||
53 | #define DRIVER_NAME "Mantis Core" | ||
54 | |||
55 | int __devinit mantis_pci_init(struct mantis_pci *mantis) | ||
56 | { | ||
57 | u8 revision, latency; | ||
58 | struct mantis_hwconfig *config = mantis->hwconfig; | ||
59 | struct pci_dev *pdev = mantis->pdev; | ||
60 | int err, ret = 0; | ||
61 | |||
62 | dprintk(MANTIS_ERROR, 0, "found a %s PCI %s device on (%02x:%02x.%x),\n", | ||
63 | config->model_name, | ||
64 | config->dev_type, | ||
65 | mantis->pdev->bus->number, | ||
66 | PCI_SLOT(mantis->pdev->devfn), | ||
67 | PCI_FUNC(mantis->pdev->devfn)); | ||
68 | |||
69 | err = pci_enable_device(pdev); | ||
70 | if (err != 0) { | ||
71 | ret = -ENODEV; | ||
72 | dprintk(MANTIS_ERROR, 1, "ERROR: PCI enable failed <%i>", err); | ||
73 | goto fail0; | ||
74 | } | ||
75 | |||
76 | err = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32)); | ||
77 | if (err != 0) { | ||
78 | dprintk(MANTIS_ERROR, 1, "ERROR: Unable to obtain 32 bit DMA <%i>", err); | ||
79 | ret = -ENOMEM; | ||
80 | goto fail1; | ||
81 | } | ||
82 | |||
83 | pci_set_master(pdev); | ||
84 | |||
85 | if (!request_mem_region(pci_resource_start(pdev, 0), | ||
86 | pci_resource_len(pdev, 0), | ||
87 | DRIVER_NAME)) { | ||
88 | |||
89 | dprintk(MANTIS_ERROR, 1, "ERROR: BAR0 Request failed !"); | ||
90 | ret = -ENODEV; | ||
91 | goto fail1; | ||
92 | } | ||
93 | |||
94 | mantis->mmio = ioremap(pci_resource_start(pdev, 0), | ||
95 | pci_resource_len(pdev, 0)); | ||
96 | |||
97 | if (!mantis->mmio) { | ||
98 | dprintk(MANTIS_ERROR, 1, "ERROR: BAR0 remap failed !"); | ||
99 | ret = -ENODEV; | ||
100 | goto fail2; | ||
101 | } | ||
102 | |||
103 | pci_read_config_byte(pdev, PCI_LATENCY_TIMER, &latency); | ||
104 | pci_read_config_byte(pdev, PCI_CLASS_REVISION, &revision); | ||
105 | mantis->latency = latency; | ||
106 | mantis->revision = revision; | ||
107 | |||
108 | dprintk(MANTIS_ERROR, 0, " Mantis Rev %d [%04x:%04x], ", | ||
109 | mantis->revision, | ||
110 | mantis->pdev->subsystem_vendor, | ||
111 | mantis->pdev->subsystem_device); | ||
112 | |||
113 | dprintk(MANTIS_ERROR, 0, | ||
114 | "irq: %d, latency: %d\n memory: 0x%lx, mmio: 0x%p\n", | ||
115 | mantis->pdev->irq, | ||
116 | mantis->latency, | ||
117 | mantis->mantis_addr, | ||
118 | mantis->mmio); | ||
119 | |||
120 | err = request_irq(pdev->irq, | ||
121 | config->irq_handler, | ||
122 | IRQF_SHARED, | ||
123 | DRIVER_NAME, | ||
124 | mantis); | ||
125 | |||
126 | if (err != 0) { | ||
127 | |||
128 | dprintk(MANTIS_ERROR, 1, "ERROR: IRQ registration failed ! <%d>", err); | ||
129 | ret = -ENODEV; | ||
130 | goto fail3; | ||
131 | } | ||
132 | |||
133 | pci_set_drvdata(pdev, mantis); | ||
134 | return ret; | ||
135 | |||
136 | /* Error conditions */ | ||
137 | fail3: | ||
138 | dprintk(MANTIS_ERROR, 1, "ERROR: <%d> I/O unmap", ret); | ||
139 | if (mantis->mmio) | ||
140 | iounmap(mantis->mmio); | ||
141 | |||
142 | fail2: | ||
143 | dprintk(MANTIS_ERROR, 1, "ERROR: <%d> releasing regions", ret); | ||
144 | release_mem_region(pci_resource_start(pdev, 0), | ||
145 | pci_resource_len(pdev, 0)); | ||
146 | |||
147 | fail1: | ||
148 | dprintk(MANTIS_ERROR, 1, "ERROR: <%d> disabling device", ret); | ||
149 | pci_disable_device(pdev); | ||
150 | |||
151 | fail0: | ||
152 | dprintk(MANTIS_ERROR, 1, "ERROR: <%d> exiting", ret); | ||
153 | pci_set_drvdata(pdev, NULL); | ||
154 | return ret; | ||
155 | } | ||
156 | EXPORT_SYMBOL_GPL(mantis_pci_init); | ||
157 | |||
158 | void mantis_pci_exit(struct mantis_pci *mantis) | ||
159 | { | ||
160 | struct pci_dev *pdev = mantis->pdev; | ||
161 | |||
162 | dprintk(MANTIS_NOTICE, 1, " mem: 0x%p", mantis->mmio); | ||
163 | free_irq(pdev->irq, mantis); | ||
164 | if (mantis->mmio) { | ||
165 | iounmap(mantis->mmio); | ||
166 | release_mem_region(pci_resource_start(pdev, 0), | ||
167 | pci_resource_len(pdev, 0)); | ||
168 | } | ||
169 | |||
170 | pci_disable_device(pdev); | ||
171 | pci_set_drvdata(pdev, NULL); | ||
172 | } | ||
173 | EXPORT_SYMBOL_GPL(mantis_pci_exit); | ||
174 | |||
175 | MODULE_DESCRIPTION("Mantis PCI DTV bridge driver"); | ||
176 | MODULE_AUTHOR("Manu Abraham"); | ||
177 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/media/dvb/mantis/mantis_pci.h b/drivers/media/dvb/mantis/mantis_pci.h new file mode 100644 index 000000000000..65f004519086 --- /dev/null +++ b/drivers/media/dvb/mantis/mantis_pci.h | |||
@@ -0,0 +1,27 @@ | |||
1 | /* | ||
2 | Mantis PCI bridge driver | ||
3 | |||
4 | Copyright (C) Manu Abraham (abraham.manu@gmail.com) | ||
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 __MANTIS_PCI_H | ||
22 | #define __MANTIS_PCI_H | ||
23 | |||
24 | extern int mantis_pci_init(struct mantis_pci *mantis); | ||
25 | extern void mantis_pci_exit(struct mantis_pci *mantis); | ||
26 | |||
27 | #endif /* __MANTIS_PCI_H */ | ||
diff --git a/drivers/media/dvb/mantis/mantis_pcmcia.c b/drivers/media/dvb/mantis/mantis_pcmcia.c new file mode 100644 index 000000000000..5cb545b913f6 --- /dev/null +++ b/drivers/media/dvb/mantis/mantis_pcmcia.c | |||
@@ -0,0 +1,120 @@ | |||
1 | /* | ||
2 | Mantis PCI bridge driver | ||
3 | |||
4 | Copyright (C) Manu Abraham (abraham.manu@gmail.com) | ||
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 | #include <linux/kernel.h> | ||
22 | |||
23 | #include <linux/signal.h> | ||
24 | #include <linux/sched.h> | ||
25 | #include <linux/interrupt.h> | ||
26 | |||
27 | #include "dmxdev.h" | ||
28 | #include "dvbdev.h" | ||
29 | #include "dvb_demux.h" | ||
30 | #include "dvb_frontend.h" | ||
31 | #include "dvb_net.h" | ||
32 | |||
33 | #include "mantis_common.h" | ||
34 | #include "mantis_link.h" /* temporary due to physical layer stuff */ | ||
35 | #include "mantis_reg.h" | ||
36 | |||
37 | /* | ||
38 | * If Slot state is already PLUG_IN event and we are called | ||
39 | * again, definitely it is jitter alone | ||
40 | */ | ||
41 | void mantis_event_cam_plugin(struct mantis_ca *ca) | ||
42 | { | ||
43 | struct mantis_pci *mantis = ca->ca_priv; | ||
44 | |||
45 | u32 gpif_irqcfg; | ||
46 | |||
47 | if (ca->slot_state == MODULE_XTRACTED) { | ||
48 | dprintk(MANTIS_DEBUG, 1, "Event: CAM Plugged IN: Adapter(%d) Slot(0)", mantis->num); | ||
49 | udelay(50); | ||
50 | mmwrite(0xda000000, MANTIS_CARD_RESET); | ||
51 | gpif_irqcfg = mmread(MANTIS_GPIF_IRQCFG); | ||
52 | gpif_irqcfg |= MANTIS_MASK_PLUGOUT; | ||
53 | gpif_irqcfg &= ~MANTIS_MASK_PLUGIN; | ||
54 | mmwrite(gpif_irqcfg, MANTIS_GPIF_IRQCFG); | ||
55 | udelay(500); | ||
56 | ca->slot_state = MODULE_INSERTED; | ||
57 | } | ||
58 | udelay(100); | ||
59 | } | ||
60 | |||
61 | /* | ||
62 | * If Slot state is already UN_PLUG event and we are called | ||
63 | * again, definitely it is jitter alone | ||
64 | */ | ||
65 | void mantis_event_cam_unplug(struct mantis_ca *ca) | ||
66 | { | ||
67 | struct mantis_pci *mantis = ca->ca_priv; | ||
68 | |||
69 | u32 gpif_irqcfg; | ||
70 | |||
71 | if (ca->slot_state == MODULE_INSERTED) { | ||
72 | dprintk(MANTIS_DEBUG, 1, "Event: CAM Unplugged: Adapter(%d) Slot(0)", mantis->num); | ||
73 | udelay(50); | ||
74 | mmwrite(0x00da0000, MANTIS_CARD_RESET); | ||
75 | gpif_irqcfg = mmread(MANTIS_GPIF_IRQCFG); | ||
76 | gpif_irqcfg |= MANTIS_MASK_PLUGIN; | ||
77 | gpif_irqcfg &= ~MANTIS_MASK_PLUGOUT; | ||
78 | mmwrite(gpif_irqcfg, MANTIS_GPIF_IRQCFG); | ||
79 | udelay(500); | ||
80 | ca->slot_state = MODULE_XTRACTED; | ||
81 | } | ||
82 | udelay(100); | ||
83 | } | ||
84 | |||
85 | int mantis_pcmcia_init(struct mantis_ca *ca) | ||
86 | { | ||
87 | struct mantis_pci *mantis = ca->ca_priv; | ||
88 | |||
89 | u32 gpif_stat, card_stat; | ||
90 | |||
91 | mmwrite(mmread(MANTIS_INT_MASK) | MANTIS_INT_IRQ0, MANTIS_INT_MASK); | ||
92 | gpif_stat = mmread(MANTIS_GPIF_STATUS); | ||
93 | card_stat = mmread(MANTIS_GPIF_IRQCFG); | ||
94 | |||
95 | if (gpif_stat & MANTIS_GPIF_DETSTAT) { | ||
96 | dprintk(MANTIS_DEBUG, 1, "CAM found on Adapter(%d) Slot(0)", mantis->num); | ||
97 | mmwrite(card_stat | MANTIS_MASK_PLUGOUT, MANTIS_GPIF_IRQCFG); | ||
98 | ca->slot_state = MODULE_INSERTED; | ||
99 | dvb_ca_en50221_camchange_irq(&ca->en50221, | ||
100 | 0, | ||
101 | DVB_CA_EN50221_CAMCHANGE_INSERTED); | ||
102 | } else { | ||
103 | dprintk(MANTIS_DEBUG, 1, "Empty Slot on Adapter(%d) Slot(0)", mantis->num); | ||
104 | mmwrite(card_stat | MANTIS_MASK_PLUGIN, MANTIS_GPIF_IRQCFG); | ||
105 | ca->slot_state = MODULE_XTRACTED; | ||
106 | dvb_ca_en50221_camchange_irq(&ca->en50221, | ||
107 | 0, | ||
108 | DVB_CA_EN50221_CAMCHANGE_REMOVED); | ||
109 | } | ||
110 | |||
111 | return 0; | ||
112 | } | ||
113 | |||
114 | void mantis_pcmcia_exit(struct mantis_ca *ca) | ||
115 | { | ||
116 | struct mantis_pci *mantis = ca->ca_priv; | ||
117 | |||
118 | mmwrite(mmread(MANTIS_GPIF_STATUS) & (~MANTIS_CARD_PLUGOUT | ~MANTIS_CARD_PLUGIN), MANTIS_GPIF_STATUS); | ||
119 | mmwrite(mmread(MANTIS_INT_MASK) & ~MANTIS_INT_IRQ0, MANTIS_INT_MASK); | ||
120 | } | ||
diff --git a/drivers/media/dvb/mantis/mantis_reg.h b/drivers/media/dvb/mantis/mantis_reg.h new file mode 100644 index 000000000000..7761f9dc7fe0 --- /dev/null +++ b/drivers/media/dvb/mantis/mantis_reg.h | |||
@@ -0,0 +1,197 @@ | |||
1 | /* | ||
2 | Mantis PCI bridge driver | ||
3 | |||
4 | Copyright (C) Manu Abraham (abraham.manu@gmail.com) | ||
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 __MANTIS_REG_H | ||
22 | #define __MANTIS_REG_H | ||
23 | |||
24 | /* Interrupts */ | ||
25 | #define MANTIS_INT_STAT 0x00 | ||
26 | #define MANTIS_INT_MASK 0x04 | ||
27 | |||
28 | #define MANTIS_INT_RISCSTAT (0x0f << 28) | ||
29 | #define MANTIS_INT_RISCEN (0x01 << 27) | ||
30 | #define MANTIS_INT_I2CRACK (0x01 << 26) | ||
31 | |||
32 | /* #define MANTIS_INT_GPIF (0xff << 12) */ | ||
33 | |||
34 | #define MANTIS_INT_PCMCIA7 (0x01 << 19) | ||
35 | #define MANTIS_INT_PCMCIA6 (0x01 << 18) | ||
36 | #define MANTIS_INT_PCMCIA5 (0x01 << 17) | ||
37 | #define MANTIS_INT_PCMCIA4 (0x01 << 16) | ||
38 | #define MANTIS_INT_PCMCIA3 (0x01 << 15) | ||
39 | #define MANTIS_INT_PCMCIA2 (0x01 << 14) | ||
40 | #define MANTIS_INT_PCMCIA1 (0x01 << 13) | ||
41 | #define MANTIS_INT_PCMCIA0 (0x01 << 12) | ||
42 | #define MANTIS_INT_IRQ1 (0x01 << 11) | ||
43 | #define MANTIS_INT_IRQ0 (0x01 << 10) | ||
44 | #define MANTIS_INT_OCERR (0x01 << 8) | ||
45 | #define MANTIS_INT_PABORT (0x01 << 7) | ||
46 | #define MANTIS_INT_RIPERR (0x01 << 6) | ||
47 | #define MANTIS_INT_PPERR (0x01 << 5) | ||
48 | #define MANTIS_INT_FTRGT (0x01 << 3) | ||
49 | #define MANTIS_INT_RISCI (0x01 << 1) | ||
50 | #define MANTIS_INT_I2CDONE (0x01 << 0) | ||
51 | |||
52 | /* DMA */ | ||
53 | #define MANTIS_DMA_CTL 0x08 | ||
54 | #define MANTIS_GPIF_RD (0xff << 24) | ||
55 | #define MANTIS_GPIF_WR (0xff << 16) | ||
56 | #define MANTIS_CPU_DO (0x01 << 10) | ||
57 | #define MANTIS_DRV_DO (0x01 << 9) | ||
58 | #define MANTIS_I2C_RD (0x01 << 7) | ||
59 | #define MANTIS_I2C_WR (0x01 << 6) | ||
60 | #define MANTIS_DCAP_MODE (0x01 << 5) | ||
61 | #define MANTIS_FIFO_TP_4 (0x00 << 3) | ||
62 | #define MANTIS_FIFO_TP_8 (0x01 << 3) | ||
63 | #define MANTIS_FIFO_TP_16 (0x02 << 3) | ||
64 | #define MANTIS_FIFO_EN (0x01 << 2) | ||
65 | #define MANTIS_DCAP_EN (0x01 << 1) | ||
66 | #define MANTIS_RISC_EN (0x01 << 0) | ||
67 | |||
68 | /* DEBUG */ | ||
69 | #define MANTIS_DEBUGREG 0x0c | ||
70 | #define MANTIS_DATINV (0x0e << 7) | ||
71 | #define MANTIS_TOP_DEBUGSEL (0x07 << 4) | ||
72 | #define MANTIS_PCMCIA_DEBUGSEL (0x0f << 0) | ||
73 | |||
74 | #define MANTIS_RISC_START 0x10 | ||
75 | #define MANTIS_RISC_PC 0x14 | ||
76 | |||
77 | /* I2C */ | ||
78 | #define MANTIS_I2CDATA_CTL 0x18 | ||
79 | #define MANTIS_I2C_RATE_1 (0x00 << 6) | ||
80 | #define MANTIS_I2C_RATE_2 (0x01 << 6) | ||
81 | #define MANTIS_I2C_RATE_3 (0x02 << 6) | ||
82 | #define MANTIS_I2C_RATE_4 (0x03 << 6) | ||
83 | #define MANTIS_I2C_STOP (0x01 << 5) | ||
84 | #define MANTIS_I2C_PGMODE (0x01 << 3) | ||
85 | |||
86 | /* DATA */ | ||
87 | #define MANTIS_CMD_DATA_R1 0x20 | ||
88 | #define MANTIS_CMD_DATA_3 (0xff << 24) | ||
89 | #define MANTIS_CMD_DATA_2 (0xff << 16) | ||
90 | #define MANTIS_CMD_DATA_1 (0xff << 8) | ||
91 | #define MANTIS_CMD_DATA_0 (0xff << 0) | ||
92 | |||
93 | #define MANTIS_CMD_DATA_R2 0x24 | ||
94 | #define MANTIS_CMD_DATA_7 (0xff << 24) | ||
95 | #define MANTIS_CMD_DATA_6 (0xff << 16) | ||
96 | #define MANTIS_CMD_DATA_5 (0xff << 8) | ||
97 | #define MANTIS_CMD_DATA_4 (0xff << 0) | ||
98 | |||
99 | #define MANTIS_CONTROL 0x28 | ||
100 | #define MANTIS_DET (0x01 << 7) | ||
101 | #define MANTIS_DAT_CF_EN (0x01 << 6) | ||
102 | #define MANTIS_ACS (0x03 << 4) | ||
103 | #define MANTIS_VCCEN (0x01 << 3) | ||
104 | #define MANTIS_BYPASS (0x01 << 2) | ||
105 | #define MANTIS_MRST (0x01 << 1) | ||
106 | #define MANTIS_CRST_INT (0x01 << 0) | ||
107 | |||
108 | #define MANTIS_GPIF_CFGSLA 0x84 | ||
109 | #define MANTIS_GPIF_WAITSMPL (0x07 << 28) | ||
110 | #define MANTIS_GPIF_BYTEADDRSUB (0x01 << 25) | ||
111 | #define MANTIS_GPIF_WAITPOL (0x01 << 24) | ||
112 | #define MANTIS_GPIF_NCDELAY (0x07 << 20) | ||
113 | #define MANTIS_GPIF_RW2CSDELAY (0x07 << 16) | ||
114 | #define MANTIS_GPIF_SLFTIMEDMODE (0x01 << 15) | ||
115 | #define MANTIS_GPIF_SLFTIMEDDELY (0x7f << 8) | ||
116 | #define MANTIS_GPIF_DEVTYPE (0x07 << 4) | ||
117 | #define MANTIS_GPIF_BIGENDIAN (0x01 << 3) | ||
118 | #define MANTIS_GPIF_FETCHCMD (0x03 << 1) | ||
119 | #define MANTIS_GPIF_HWORDDEV (0x01 << 0) | ||
120 | |||
121 | #define MANTIS_GPIF_WSTOPER 0x90 | ||
122 | #define MANTIS_GPIF_WSTOPERWREN3 (0x01 << 31) | ||
123 | #define MANTIS_GPIF_PARBOOTN (0x01 << 29) | ||
124 | #define MANTIS_GPIF_WSTOPERSLID3 (0x1f << 24) | ||
125 | #define MANTIS_GPIF_WSTOPERWREN2 (0x01 << 23) | ||
126 | #define MANTIS_GPIF_WSTOPERSLID2 (0x1f << 16) | ||
127 | #define MANTIS_GPIF_WSTOPERWREN1 (0x01 << 15) | ||
128 | #define MANTIS_GPIF_WSTOPERSLID1 (0x1f << 8) | ||
129 | #define MANTIS_GPIF_WSTOPERWREN0 (0x01 << 7) | ||
130 | #define MANTIS_GPIF_WSTOPERSLID0 (0x1f << 0) | ||
131 | |||
132 | #define MANTIS_GPIF_CS2RW 0x94 | ||
133 | #define MANTIS_GPIF_CS2RWWREN3 (0x01 << 31) | ||
134 | #define MANTIS_GPIF_CS2RWDELY3 (0x3f << 24) | ||
135 | #define MANTIS_GPIF_CS2RWWREN2 (0x01 << 23) | ||
136 | #define MANTIS_GPIF_CS2RWDELY2 (0x3f << 16) | ||
137 | #define MANTIS_GPIF_CS2RWWREN1 (0x01 << 15) | ||
138 | #define MANTIS_GPIF_CS2RWDELY1 (0x3f << 8) | ||
139 | #define MANTIS_GPIF_CS2RWWREN0 (0x01 << 7) | ||
140 | #define MANTIS_GPIF_CS2RWDELY0 (0x3f << 0) | ||
141 | |||
142 | #define MANTIS_GPIF_IRQCFG 0x98 | ||
143 | #define MANTIS_GPIF_IRQPOL (0x01 << 8) | ||
144 | #define MANTIS_MASK_WRACK (0x01 << 7) | ||
145 | #define MANTIS_MASK_BRRDY (0x01 << 6) | ||
146 | #define MANTIS_MASK_OVFLW (0x01 << 5) | ||
147 | #define MANTIS_MASK_OTHERR (0x01 << 4) | ||
148 | #define MANTIS_MASK_WSTO (0x01 << 3) | ||
149 | #define MANTIS_MASK_EXTIRQ (0x01 << 2) | ||
150 | #define MANTIS_MASK_PLUGIN (0x01 << 1) | ||
151 | #define MANTIS_MASK_PLUGOUT (0x01 << 0) | ||
152 | |||
153 | #define MANTIS_GPIF_STATUS 0x9c | ||
154 | #define MANTIS_SBUF_KILLOP (0x01 << 15) | ||
155 | #define MANTIS_SBUF_OPDONE (0x01 << 14) | ||
156 | #define MANTIS_SBUF_EMPTY (0x01 << 13) | ||
157 | #define MANTIS_GPIF_DETSTAT (0x01 << 9) | ||
158 | #define MANTIS_GPIF_INTSTAT (0x01 << 8) | ||
159 | #define MANTIS_GPIF_WRACK (0x01 << 7) | ||
160 | #define MANTIS_GPIF_BRRDY (0x01 << 6) | ||
161 | #define MANTIS_SBUF_OVFLW (0x01 << 5) | ||
162 | #define MANTIS_GPIF_OTHERR (0x01 << 4) | ||
163 | #define MANTIS_SBUF_WSTO (0x01 << 3) | ||
164 | #define MANTIS_GPIF_EXTIRQ (0x01 << 2) | ||
165 | #define MANTIS_CARD_PLUGIN (0x01 << 1) | ||
166 | #define MANTIS_CARD_PLUGOUT (0x01 << 0) | ||
167 | |||
168 | #define MANTIS_GPIF_BRADDR 0xa0 | ||
169 | #define MANTIS_GPIF_PCMCIAREG (0x01 << 27) | ||
170 | #define MANTIS_GPIF_PCMCIAIOM (0x01 << 26) | ||
171 | #define MANTIS_GPIF_BR_ADDR (0xfffffff << 0) | ||
172 | |||
173 | #define MANTIS_GPIF_BRBYTES 0xa4 | ||
174 | #define MANTIS_GPIF_BRCNT (0xfff << 0) | ||
175 | |||
176 | #define MANTIS_PCMCIA_RESET 0xa8 | ||
177 | #define MANTIS_PCMCIA_RSTVAL (0xff << 0) | ||
178 | |||
179 | #define MANTIS_CARD_RESET 0xac | ||
180 | |||
181 | #define MANTIS_GPIF_ADDR 0xb0 | ||
182 | #define MANTIS_GPIF_HIFRDWRN (0x01 << 31) | ||
183 | #define MANTIS_GPIF_PCMCIAREG (0x01 << 27) | ||
184 | #define MANTIS_GPIF_PCMCIAIOM (0x01 << 26) | ||
185 | #define MANTIS_GPIF_HIFADDR (0xfffffff << 0) | ||
186 | |||
187 | #define MANTIS_GPIF_DOUT 0xb4 | ||
188 | #define MANTIS_GPIF_HIFDOUT (0xfffffff << 0) | ||
189 | |||
190 | #define MANTIS_GPIF_DIN 0xb8 | ||
191 | #define MANTIS_GPIF_HIFDIN (0xfffffff << 0) | ||
192 | |||
193 | #define MANTIS_GPIF_SPARE 0xbc | ||
194 | #define MANTIS_GPIF_LOGICRD (0xffff << 16) | ||
195 | #define MANTIS_GPIF_LOGICRW (0xffff << 0) | ||
196 | |||
197 | #endif /* __MANTIS_REG_H */ | ||
diff --git a/drivers/media/dvb/mantis/mantis_uart.c b/drivers/media/dvb/mantis/mantis_uart.c new file mode 100644 index 000000000000..7d2f2398fa8b --- /dev/null +++ b/drivers/media/dvb/mantis/mantis_uart.c | |||
@@ -0,0 +1,186 @@ | |||
1 | /* | ||
2 | Mantis PCI bridge driver | ||
3 | |||
4 | Copyright (C) Manu Abraham (abraham.manu@gmail.com) | ||
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 | #include <linux/kernel.h> | ||
22 | #include <linux/spinlock.h> | ||
23 | |||
24 | #include <linux/signal.h> | ||
25 | #include <linux/sched.h> | ||
26 | #include <linux/interrupt.h> | ||
27 | |||
28 | #include "dmxdev.h" | ||
29 | #include "dvbdev.h" | ||
30 | #include "dvb_demux.h" | ||
31 | #include "dvb_frontend.h" | ||
32 | #include "dvb_net.h" | ||
33 | |||
34 | #include "mantis_common.h" | ||
35 | #include "mantis_reg.h" | ||
36 | #include "mantis_uart.h" | ||
37 | |||
38 | struct mantis_uart_params { | ||
39 | enum mantis_baud baud_rate; | ||
40 | enum mantis_parity parity; | ||
41 | }; | ||
42 | |||
43 | static struct { | ||
44 | char string[7]; | ||
45 | } rates[5] = { | ||
46 | { "9600" }, | ||
47 | { "19200" }, | ||
48 | { "38400" }, | ||
49 | { "57600" }, | ||
50 | { "115200" } | ||
51 | }; | ||
52 | |||
53 | static struct { | ||
54 | char string[5]; | ||
55 | } parity[3] = { | ||
56 | { "NONE" }, | ||
57 | { "ODD" }, | ||
58 | { "EVEN" } | ||
59 | }; | ||
60 | |||
61 | #define UART_MAX_BUF 16 | ||
62 | |||
63 | int mantis_uart_read(struct mantis_pci *mantis, u8 *data) | ||
64 | { | ||
65 | struct mantis_hwconfig *config = mantis->hwconfig; | ||
66 | u32 stat = 0, i; | ||
67 | |||
68 | /* get data */ | ||
69 | for (i = 0; i < (config->bytes + 1); i++) { | ||
70 | |||
71 | stat = mmread(MANTIS_UART_STAT); | ||
72 | |||
73 | if (stat & MANTIS_UART_RXFIFO_FULL) { | ||
74 | dprintk(MANTIS_ERROR, 1, "RX Fifo FULL"); | ||
75 | } | ||
76 | data[i] = mmread(MANTIS_UART_RXD) & 0x3f; | ||
77 | |||
78 | dprintk(MANTIS_DEBUG, 1, "Reading ... <%02x>", data[i] & 0x3f); | ||
79 | |||
80 | if (data[i] & (1 << 7)) { | ||
81 | dprintk(MANTIS_ERROR, 1, "UART framing error"); | ||
82 | return -EINVAL; | ||
83 | } | ||
84 | if (data[i] & (1 << 6)) { | ||
85 | dprintk(MANTIS_ERROR, 1, "UART parity error"); | ||
86 | return -EINVAL; | ||
87 | } | ||
88 | } | ||
89 | |||
90 | return 0; | ||
91 | } | ||
92 | |||
93 | static void mantis_uart_work(struct work_struct *work) | ||
94 | { | ||
95 | struct mantis_pci *mantis = container_of(work, struct mantis_pci, uart_work); | ||
96 | struct mantis_hwconfig *config = mantis->hwconfig; | ||
97 | u8 buf[16]; | ||
98 | int i; | ||
99 | |||
100 | mantis_uart_read(mantis, buf); | ||
101 | |||
102 | for (i = 0; i < (config->bytes + 1); i++) | ||
103 | dprintk(MANTIS_INFO, 1, "UART BUF:%d <%02x> ", i, buf[i]); | ||
104 | |||
105 | dprintk(MANTIS_DEBUG, 0, "\n"); | ||
106 | } | ||
107 | |||
108 | static int mantis_uart_setup(struct mantis_pci *mantis, | ||
109 | struct mantis_uart_params *params) | ||
110 | { | ||
111 | u32 reg; | ||
112 | |||
113 | mmwrite((mmread(MANTIS_UART_CTL) | (params->parity & 0x3)), MANTIS_UART_CTL); | ||
114 | |||
115 | reg = mmread(MANTIS_UART_BAUD); | ||
116 | |||
117 | switch (params->baud_rate) { | ||
118 | case MANTIS_BAUD_9600: | ||
119 | reg |= 0xd8; | ||
120 | break; | ||
121 | case MANTIS_BAUD_19200: | ||
122 | reg |= 0x6c; | ||
123 | break; | ||
124 | case MANTIS_BAUD_38400: | ||
125 | reg |= 0x36; | ||
126 | break; | ||
127 | case MANTIS_BAUD_57600: | ||
128 | reg |= 0x23; | ||
129 | break; | ||
130 | case MANTIS_BAUD_115200: | ||
131 | reg |= 0x11; | ||
132 | break; | ||
133 | default: | ||
134 | return -EINVAL; | ||
135 | } | ||
136 | |||
137 | mmwrite(reg, MANTIS_UART_BAUD); | ||
138 | |||
139 | return 0; | ||
140 | } | ||
141 | |||
142 | int mantis_uart_init(struct mantis_pci *mantis) | ||
143 | { | ||
144 | struct mantis_hwconfig *config = mantis->hwconfig; | ||
145 | struct mantis_uart_params params; | ||
146 | |||
147 | /* default parity: */ | ||
148 | params.baud_rate = config->baud_rate; | ||
149 | params.parity = config->parity; | ||
150 | dprintk(MANTIS_INFO, 1, "Initializing UART @ %sbps parity:%s", | ||
151 | rates[params.baud_rate].string, | ||
152 | parity[params.parity].string); | ||
153 | |||
154 | init_waitqueue_head(&mantis->uart_wq); | ||
155 | spin_lock_init(&mantis->uart_lock); | ||
156 | |||
157 | INIT_WORK(&mantis->uart_work, mantis_uart_work); | ||
158 | |||
159 | /* disable interrupt */ | ||
160 | mmwrite(mmread(MANTIS_UART_CTL) & 0xffef, MANTIS_UART_CTL); | ||
161 | |||
162 | mantis_uart_setup(mantis, ¶ms); | ||
163 | |||
164 | /* default 1 byte */ | ||
165 | mmwrite((mmread(MANTIS_UART_BAUD) | (config->bytes << 8)), MANTIS_UART_BAUD); | ||
166 | |||
167 | /* flush buffer */ | ||
168 | mmwrite((mmread(MANTIS_UART_CTL) | MANTIS_UART_RXFLUSH), MANTIS_UART_CTL); | ||
169 | |||
170 | /* enable interrupt */ | ||
171 | mmwrite(mmread(MANTIS_INT_MASK) | 0x800, MANTIS_INT_MASK); | ||
172 | mmwrite(mmread(MANTIS_UART_CTL) | MANTIS_UART_RXINT, MANTIS_UART_CTL); | ||
173 | |||
174 | schedule_work(&mantis->uart_work); | ||
175 | dprintk(MANTIS_DEBUG, 1, "UART succesfully initialized"); | ||
176 | |||
177 | return 0; | ||
178 | } | ||
179 | EXPORT_SYMBOL_GPL(mantis_uart_init); | ||
180 | |||
181 | void mantis_uart_exit(struct mantis_pci *mantis) | ||
182 | { | ||
183 | /* disable interrupt */ | ||
184 | mmwrite(mmread(MANTIS_UART_CTL) & 0xffef, MANTIS_UART_CTL); | ||
185 | } | ||
186 | EXPORT_SYMBOL_GPL(mantis_uart_exit); | ||
diff --git a/drivers/media/dvb/mantis/mantis_uart.h b/drivers/media/dvb/mantis/mantis_uart.h new file mode 100644 index 000000000000..ffb62a0a5a13 --- /dev/null +++ b/drivers/media/dvb/mantis/mantis_uart.h | |||
@@ -0,0 +1,58 @@ | |||
1 | /* | ||
2 | Mantis PCI bridge driver | ||
3 | |||
4 | Copyright (C) Manu Abraham (abraham.manu@gmail.com) | ||
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 __MANTIS_UART_H | ||
22 | #define __MANTIS_UART_H | ||
23 | |||
24 | #define MANTIS_UART_CTL 0xe0 | ||
25 | #define MANTIS_UART_RXINT (1 << 4) | ||
26 | #define MANTIS_UART_RXFLUSH (1 << 2) | ||
27 | |||
28 | #define MANTIS_UART_RXD 0xe8 | ||
29 | #define MANTIS_UART_BAUD 0xec | ||
30 | |||
31 | #define MANTIS_UART_STAT 0xf0 | ||
32 | #define MANTIS_UART_RXFIFO_DATA (1 << 7) | ||
33 | #define MANTIS_UART_RXFIFO_EMPTY (1 << 6) | ||
34 | #define MANTIS_UART_RXFIFO_FULL (1 << 3) | ||
35 | #define MANTIS_UART_FRAME_ERR (1 << 2) | ||
36 | #define MANTIS_UART_PARITY_ERR (1 << 1) | ||
37 | #define MANTIS_UART_RXTHRESH_INT (1 << 0) | ||
38 | |||
39 | enum mantis_baud { | ||
40 | MANTIS_BAUD_9600 = 0, | ||
41 | MANTIS_BAUD_19200, | ||
42 | MANTIS_BAUD_38400, | ||
43 | MANTIS_BAUD_57600, | ||
44 | MANTIS_BAUD_115200 | ||
45 | }; | ||
46 | |||
47 | enum mantis_parity { | ||
48 | MANTIS_PARITY_NONE = 0, | ||
49 | MANTIS_PARITY_EVEN, | ||
50 | MANTIS_PARITY_ODD, | ||
51 | }; | ||
52 | |||
53 | struct mantis_pci; | ||
54 | |||
55 | extern int mantis_uart_init(struct mantis_pci *mantis); | ||
56 | extern void mantis_uart_exit(struct mantis_pci *mantis); | ||
57 | |||
58 | #endif /* __MANTIS_UART_H */ | ||
diff --git a/drivers/media/dvb/mantis/mantis_vp1033.c b/drivers/media/dvb/mantis/mantis_vp1033.c new file mode 100644 index 000000000000..4a723bda0031 --- /dev/null +++ b/drivers/media/dvb/mantis/mantis_vp1033.c | |||
@@ -0,0 +1,212 @@ | |||
1 | /* | ||
2 | Mantis VP-1033 driver | ||
3 | |||
4 | Copyright (C) Manu Abraham (abraham.manu@gmail.com) | ||
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 | #include <linux/signal.h> | ||
22 | #include <linux/sched.h> | ||
23 | #include <linux/interrupt.h> | ||
24 | |||
25 | #include "dmxdev.h" | ||
26 | #include "dvbdev.h" | ||
27 | #include "dvb_demux.h" | ||
28 | #include "dvb_frontend.h" | ||
29 | #include "dvb_net.h" | ||
30 | |||
31 | #include "stv0299.h" | ||
32 | #include "mantis_common.h" | ||
33 | #include "mantis_ioc.h" | ||
34 | #include "mantis_dvb.h" | ||
35 | #include "mantis_vp1033.h" | ||
36 | #include "mantis_reg.h" | ||
37 | |||
38 | u8 lgtdqcs001f_inittab[] = { | ||
39 | 0x01, 0x15, | ||
40 | 0x02, 0x00, | ||
41 | 0x03, 0x00, | ||
42 | 0x04, 0x2a, | ||
43 | 0x05, 0x85, | ||
44 | 0x06, 0x02, | ||
45 | 0x07, 0x00, | ||
46 | 0x08, 0x00, | ||
47 | 0x0c, 0x01, | ||
48 | 0x0d, 0x81, | ||
49 | 0x0e, 0x44, | ||
50 | 0x0f, 0x94, | ||
51 | 0x10, 0x3c, | ||
52 | 0x11, 0x84, | ||
53 | 0x12, 0xb9, | ||
54 | 0x13, 0xb5, | ||
55 | 0x14, 0x4f, | ||
56 | 0x15, 0xc9, | ||
57 | 0x16, 0x80, | ||
58 | 0x17, 0x36, | ||
59 | 0x18, 0xfb, | ||
60 | 0x19, 0xcf, | ||
61 | 0x1a, 0xbc, | ||
62 | 0x1c, 0x2b, | ||
63 | 0x1d, 0x27, | ||
64 | 0x1e, 0x00, | ||
65 | 0x1f, 0x0b, | ||
66 | 0x20, 0xa1, | ||
67 | 0x21, 0x60, | ||
68 | 0x22, 0x00, | ||
69 | 0x23, 0x00, | ||
70 | 0x28, 0x00, | ||
71 | 0x29, 0x28, | ||
72 | 0x2a, 0x14, | ||
73 | 0x2b, 0x0f, | ||
74 | 0x2c, 0x09, | ||
75 | 0x2d, 0x05, | ||
76 | 0x31, 0x1f, | ||
77 | 0x32, 0x19, | ||
78 | 0x33, 0xfc, | ||
79 | 0x34, 0x13, | ||
80 | 0xff, 0xff, | ||
81 | }; | ||
82 | |||
83 | #define MANTIS_MODEL_NAME "VP-1033" | ||
84 | #define MANTIS_DEV_TYPE "DVB-S/DSS" | ||
85 | |||
86 | int lgtdqcs001f_tuner_set(struct dvb_frontend *fe, | ||
87 | struct dvb_frontend_parameters *params) | ||
88 | { | ||
89 | struct mantis_pci *mantis = fe->dvb->priv; | ||
90 | struct i2c_adapter *adapter = &mantis->adapter; | ||
91 | |||
92 | u8 buf[4]; | ||
93 | u32 div; | ||
94 | |||
95 | |||
96 | struct i2c_msg msg = {.addr = 0x61, .flags = 0, .buf = buf, .len = sizeof(buf)}; | ||
97 | |||
98 | div = params->frequency / 250; | ||
99 | |||
100 | buf[0] = (div >> 8) & 0x7f; | ||
101 | buf[1] = div & 0xff; | ||
102 | buf[2] = 0x83; | ||
103 | buf[3] = 0xc0; | ||
104 | |||
105 | if (params->frequency < 1531000) | ||
106 | buf[3] |= 0x04; | ||
107 | else | ||
108 | buf[3] &= ~0x04; | ||
109 | if (i2c_transfer(adapter, &msg, 1) < 0) { | ||
110 | dprintk(MANTIS_ERROR, 1, "Write: I2C Transfer failed"); | ||
111 | return -EIO; | ||
112 | } | ||
113 | msleep_interruptible(100); | ||
114 | |||
115 | return 0; | ||
116 | } | ||
117 | |||
118 | int lgtdqcs001f_set_symbol_rate(struct dvb_frontend *fe, | ||
119 | u32 srate, u32 ratio) | ||
120 | { | ||
121 | u8 aclk = 0; | ||
122 | u8 bclk = 0; | ||
123 | |||
124 | if (srate < 1500000) { | ||
125 | aclk = 0xb7; | ||
126 | bclk = 0x47; | ||
127 | } else if (srate < 3000000) { | ||
128 | aclk = 0xb7; | ||
129 | bclk = 0x4b; | ||
130 | } else if (srate < 7000000) { | ||
131 | aclk = 0xb7; | ||
132 | bclk = 0x4f; | ||
133 | } else if (srate < 14000000) { | ||
134 | aclk = 0xb7; | ||
135 | bclk = 0x53; | ||
136 | } else if (srate < 30000000) { | ||
137 | aclk = 0xb6; | ||
138 | bclk = 0x53; | ||
139 | } else if (srate < 45000000) { | ||
140 | aclk = 0xb4; | ||
141 | bclk = 0x51; | ||
142 | } | ||
143 | stv0299_writereg(fe, 0x13, aclk); | ||
144 | stv0299_writereg(fe, 0x14, bclk); | ||
145 | |||
146 | stv0299_writereg(fe, 0x1f, (ratio >> 16) & 0xff); | ||
147 | stv0299_writereg(fe, 0x20, (ratio >> 8) & 0xff); | ||
148 | stv0299_writereg(fe, 0x21, ratio & 0xf0); | ||
149 | |||
150 | return 0; | ||
151 | } | ||
152 | |||
153 | struct stv0299_config lgtdqcs001f_config = { | ||
154 | .demod_address = 0x68, | ||
155 | .inittab = lgtdqcs001f_inittab, | ||
156 | .mclk = 88000000UL, | ||
157 | .invert = 0, | ||
158 | .skip_reinit = 0, | ||
159 | .volt13_op0_op1 = STV0299_VOLT13_OP0, | ||
160 | .min_delay_ms = 100, | ||
161 | .set_symbol_rate = lgtdqcs001f_set_symbol_rate, | ||
162 | }; | ||
163 | |||
164 | static int vp1033_frontend_init(struct mantis_pci *mantis, struct dvb_frontend *fe) | ||
165 | { | ||
166 | struct i2c_adapter *adapter = &mantis->adapter; | ||
167 | |||
168 | int err = 0; | ||
169 | |||
170 | err = mantis_frontend_power(mantis, POWER_ON); | ||
171 | if (err == 0) { | ||
172 | mantis_frontend_soft_reset(mantis); | ||
173 | msleep(250); | ||
174 | |||
175 | dprintk(MANTIS_ERROR, 1, "Probing for STV0299 (DVB-S)"); | ||
176 | fe = stv0299_attach(&lgtdqcs001f_config, adapter); | ||
177 | |||
178 | if (fe) { | ||
179 | fe->ops.tuner_ops.set_params = lgtdqcs001f_tuner_set; | ||
180 | dprintk(MANTIS_ERROR, 1, "found STV0299 DVB-S frontend @ 0x%02x", | ||
181 | lgtdqcs001f_config.demod_address); | ||
182 | |||
183 | dprintk(MANTIS_ERROR, 1, "Mantis DVB-S STV0299 frontend attach success"); | ||
184 | } else { | ||
185 | return -1; | ||
186 | } | ||
187 | } else { | ||
188 | dprintk(MANTIS_ERROR, 1, "Frontend on <%s> POWER ON failed! <%d>", | ||
189 | adapter->name, | ||
190 | err); | ||
191 | |||
192 | return -EIO; | ||
193 | } | ||
194 | mantis->fe = fe; | ||
195 | dprintk(MANTIS_ERROR, 1, "Done!"); | ||
196 | |||
197 | return 0; | ||
198 | } | ||
199 | |||
200 | struct mantis_hwconfig vp1033_config = { | ||
201 | .model_name = MANTIS_MODEL_NAME, | ||
202 | .dev_type = MANTIS_DEV_TYPE, | ||
203 | .ts_size = MANTIS_TS_204, | ||
204 | |||
205 | .baud_rate = MANTIS_BAUD_9600, | ||
206 | .parity = MANTIS_PARITY_NONE, | ||
207 | .bytes = 0, | ||
208 | |||
209 | .frontend_init = vp1033_frontend_init, | ||
210 | .power = GPIF_A12, | ||
211 | .reset = GPIF_A13, | ||
212 | }; | ||
diff --git a/drivers/media/dvb/mantis/mantis_vp1033.h b/drivers/media/dvb/mantis/mantis_vp1033.h new file mode 100644 index 000000000000..7daaa1bf127d --- /dev/null +++ b/drivers/media/dvb/mantis/mantis_vp1033.h | |||
@@ -0,0 +1,30 @@ | |||
1 | /* | ||
2 | Mantis VP-1033 driver | ||
3 | |||
4 | Copyright (C) Manu Abraham (abraham.manu@gmail.com) | ||
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 __MANTIS_VP1033_H | ||
22 | #define __MANTIS_VP1033_H | ||
23 | |||
24 | #include "mantis_common.h" | ||
25 | |||
26 | #define MANTIS_VP_1033_DVB_S 0x0016 | ||
27 | |||
28 | extern struct mantis_hwconfig vp1033_config; | ||
29 | |||
30 | #endif /* __MANTIS_VP1033_H */ | ||
diff --git a/drivers/media/dvb/mantis/mantis_vp1034.c b/drivers/media/dvb/mantis/mantis_vp1034.c new file mode 100644 index 000000000000..8e6ae558ee57 --- /dev/null +++ b/drivers/media/dvb/mantis/mantis_vp1034.c | |||
@@ -0,0 +1,119 @@ | |||
1 | /* | ||
2 | Mantis VP-1034 driver | ||
3 | |||
4 | Copyright (C) Manu Abraham (abraham.manu@gmail.com) | ||
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 | #include <linux/signal.h> | ||
22 | #include <linux/sched.h> | ||
23 | #include <linux/interrupt.h> | ||
24 | |||
25 | #include "dmxdev.h" | ||
26 | #include "dvbdev.h" | ||
27 | #include "dvb_demux.h" | ||
28 | #include "dvb_frontend.h" | ||
29 | #include "dvb_net.h" | ||
30 | |||
31 | #include "mb86a16.h" | ||
32 | #include "mantis_common.h" | ||
33 | #include "mantis_ioc.h" | ||
34 | #include "mantis_dvb.h" | ||
35 | #include "mantis_vp1034.h" | ||
36 | #include "mantis_reg.h" | ||
37 | |||
38 | struct mb86a16_config vp1034_mb86a16_config = { | ||
39 | .demod_address = 0x08, | ||
40 | .set_voltage = vp1034_set_voltage, | ||
41 | }; | ||
42 | |||
43 | #define MANTIS_MODEL_NAME "VP-1034" | ||
44 | #define MANTIS_DEV_TYPE "DVB-S/DSS" | ||
45 | |||
46 | int vp1034_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage) | ||
47 | { | ||
48 | struct mantis_pci *mantis = fe->dvb->priv; | ||
49 | |||
50 | switch (voltage) { | ||
51 | case SEC_VOLTAGE_13: | ||
52 | dprintk(MANTIS_ERROR, 1, "Polarization=[13V]"); | ||
53 | gpio_set_bits(mantis, 13, 1); | ||
54 | gpio_set_bits(mantis, 14, 0); | ||
55 | break; | ||
56 | case SEC_VOLTAGE_18: | ||
57 | dprintk(MANTIS_ERROR, 1, "Polarization=[18V]"); | ||
58 | gpio_set_bits(mantis, 13, 1); | ||
59 | gpio_set_bits(mantis, 14, 1); | ||
60 | break; | ||
61 | case SEC_VOLTAGE_OFF: | ||
62 | dprintk(MANTIS_ERROR, 1, "Frontend (dummy) POWERDOWN"); | ||
63 | break; | ||
64 | default: | ||
65 | dprintk(MANTIS_ERROR, 1, "Invalid = (%d)", (u32) voltage); | ||
66 | return -EINVAL; | ||
67 | } | ||
68 | mmwrite(0x00, MANTIS_GPIF_DOUT); | ||
69 | |||
70 | return 0; | ||
71 | } | ||
72 | |||
73 | static int vp1034_frontend_init(struct mantis_pci *mantis, struct dvb_frontend *fe) | ||
74 | { | ||
75 | struct i2c_adapter *adapter = &mantis->adapter; | ||
76 | |||
77 | int err = 0; | ||
78 | |||
79 | err = mantis_frontend_power(mantis, POWER_ON); | ||
80 | if (err == 0) { | ||
81 | mantis_frontend_soft_reset(mantis); | ||
82 | msleep(250); | ||
83 | |||
84 | dprintk(MANTIS_ERROR, 1, "Probing for MB86A16 (DVB-S/DSS)"); | ||
85 | fe = mb86a16_attach(&vp1034_mb86a16_config, adapter); | ||
86 | if (fe) { | ||
87 | dprintk(MANTIS_ERROR, 1, | ||
88 | "found MB86A16 DVB-S/DSS frontend @0x%02x", | ||
89 | vp1034_mb86a16_config.demod_address); | ||
90 | |||
91 | } else { | ||
92 | return -1; | ||
93 | } | ||
94 | } else { | ||
95 | dprintk(MANTIS_ERROR, 1, "Frontend on <%s> POWER ON failed! <%d>", | ||
96 | adapter->name, | ||
97 | err); | ||
98 | |||
99 | return -EIO; | ||
100 | } | ||
101 | mantis->fe = fe; | ||
102 | dprintk(MANTIS_ERROR, 1, "Done!"); | ||
103 | |||
104 | return 0; | ||
105 | } | ||
106 | |||
107 | struct mantis_hwconfig vp1034_config = { | ||
108 | .model_name = MANTIS_MODEL_NAME, | ||
109 | .dev_type = MANTIS_DEV_TYPE, | ||
110 | .ts_size = MANTIS_TS_204, | ||
111 | |||
112 | .baud_rate = MANTIS_BAUD_9600, | ||
113 | .parity = MANTIS_PARITY_NONE, | ||
114 | .bytes = 0, | ||
115 | |||
116 | .frontend_init = vp1034_frontend_init, | ||
117 | .power = GPIF_A12, | ||
118 | .reset = GPIF_A13, | ||
119 | }; | ||
diff --git a/drivers/media/dvb/mantis/mantis_vp1034.h b/drivers/media/dvb/mantis/mantis_vp1034.h new file mode 100644 index 000000000000..323f38ef8e3d --- /dev/null +++ b/drivers/media/dvb/mantis/mantis_vp1034.h | |||
@@ -0,0 +1,33 @@ | |||
1 | /* | ||
2 | Mantis VP-1034 driver | ||
3 | |||
4 | Copyright (C) Manu Abraham (abraham.manu@gmail.com) | ||
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 __MANTIS_VP1034_H | ||
22 | #define __MANTIS_VP1034_H | ||
23 | |||
24 | #include "dvb_frontend.h" | ||
25 | #include "mantis_common.h" | ||
26 | |||
27 | |||
28 | #define MANTIS_VP_1034_DVB_S 0x0014 | ||
29 | |||
30 | extern struct mantis_hwconfig vp1034_config; | ||
31 | extern int vp1034_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage); | ||
32 | |||
33 | #endif /* __MANTIS_VP1034_H */ | ||
diff --git a/drivers/media/dvb/mantis/mantis_vp1041.c b/drivers/media/dvb/mantis/mantis_vp1041.c new file mode 100644 index 000000000000..515346dd31d0 --- /dev/null +++ b/drivers/media/dvb/mantis/mantis_vp1041.c | |||
@@ -0,0 +1,358 @@ | |||
1 | /* | ||
2 | Mantis VP-1041 driver | ||
3 | |||
4 | Copyright (C) Manu Abraham (abraham.manu@gmail.com) | ||
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 | #include <linux/signal.h> | ||
22 | #include <linux/sched.h> | ||
23 | #include <linux/interrupt.h> | ||
24 | |||
25 | #include "dmxdev.h" | ||
26 | #include "dvbdev.h" | ||
27 | #include "dvb_demux.h" | ||
28 | #include "dvb_frontend.h" | ||
29 | #include "dvb_net.h" | ||
30 | |||
31 | #include "mantis_common.h" | ||
32 | #include "mantis_ioc.h" | ||
33 | #include "mantis_dvb.h" | ||
34 | #include "mantis_vp1041.h" | ||
35 | #include "stb0899_reg.h" | ||
36 | #include "stb0899_drv.h" | ||
37 | #include "stb0899_cfg.h" | ||
38 | #include "stb6100_cfg.h" | ||
39 | #include "stb6100.h" | ||
40 | #include "lnbp21.h" | ||
41 | |||
42 | #define MANTIS_MODEL_NAME "VP-1041" | ||
43 | #define MANTIS_DEV_TYPE "DSS/DVB-S/DVB-S2" | ||
44 | |||
45 | static const struct stb0899_s1_reg vp1041_stb0899_s1_init_1[] = { | ||
46 | |||
47 | /* 0x0000000b, *//* SYSREG */ | ||
48 | { STB0899_DEV_ID , 0x30 }, | ||
49 | { STB0899_DISCNTRL1 , 0x32 }, | ||
50 | { STB0899_DISCNTRL2 , 0x80 }, | ||
51 | { STB0899_DISRX_ST0 , 0x04 }, | ||
52 | { STB0899_DISRX_ST1 , 0x00 }, | ||
53 | { STB0899_DISPARITY , 0x00 }, | ||
54 | { STB0899_DISFIFO , 0x00 }, | ||
55 | { STB0899_DISSTATUS , 0x20 }, | ||
56 | { STB0899_DISF22 , 0x99 }, | ||
57 | { STB0899_DISF22RX , 0xa8 }, | ||
58 | /* SYSREG ? */ | ||
59 | { STB0899_ACRPRESC , 0x11 }, | ||
60 | { STB0899_ACRDIV1 , 0x0a }, | ||
61 | { STB0899_ACRDIV2 , 0x05 }, | ||
62 | { STB0899_DACR1 , 0x00 }, | ||
63 | { STB0899_DACR2 , 0x00 }, | ||
64 | { STB0899_OUTCFG , 0x00 }, | ||
65 | { STB0899_MODECFG , 0x00 }, | ||
66 | { STB0899_IRQSTATUS_3 , 0xfe }, | ||
67 | { STB0899_IRQSTATUS_2 , 0x03 }, | ||
68 | { STB0899_IRQSTATUS_1 , 0x7c }, | ||
69 | { STB0899_IRQSTATUS_0 , 0xf4 }, | ||
70 | { STB0899_IRQMSK_3 , 0xf3 }, | ||
71 | { STB0899_IRQMSK_2 , 0xfc }, | ||
72 | { STB0899_IRQMSK_1 , 0xff }, | ||
73 | { STB0899_IRQMSK_0 , 0xff }, | ||
74 | { STB0899_IRQCFG , 0x00 }, | ||
75 | { STB0899_I2CCFG , 0x88 }, | ||
76 | { STB0899_I2CRPT , 0x58 }, | ||
77 | { STB0899_IOPVALUE5 , 0x00 }, | ||
78 | { STB0899_IOPVALUE4 , 0x33 }, | ||
79 | { STB0899_IOPVALUE3 , 0x6d }, | ||
80 | { STB0899_IOPVALUE2 , 0x90 }, | ||
81 | { STB0899_IOPVALUE1 , 0x60 }, | ||
82 | { STB0899_IOPVALUE0 , 0x00 }, | ||
83 | { STB0899_GPIO00CFG , 0x82 }, | ||
84 | { STB0899_GPIO01CFG , 0x82 }, | ||
85 | { STB0899_GPIO02CFG , 0x82 }, | ||
86 | { STB0899_GPIO03CFG , 0x82 }, | ||
87 | { STB0899_GPIO04CFG , 0x82 }, | ||
88 | { STB0899_GPIO05CFG , 0x82 }, | ||
89 | { STB0899_GPIO06CFG , 0x82 }, | ||
90 | { STB0899_GPIO07CFG , 0x82 }, | ||
91 | { STB0899_GPIO08CFG , 0x82 }, | ||
92 | { STB0899_GPIO09CFG , 0x82 }, | ||
93 | { STB0899_GPIO10CFG , 0x82 }, | ||
94 | { STB0899_GPIO11CFG , 0x82 }, | ||
95 | { STB0899_GPIO12CFG , 0x82 }, | ||
96 | { STB0899_GPIO13CFG , 0x82 }, | ||
97 | { STB0899_GPIO14CFG , 0x82 }, | ||
98 | { STB0899_GPIO15CFG , 0x82 }, | ||
99 | { STB0899_GPIO16CFG , 0x82 }, | ||
100 | { STB0899_GPIO17CFG , 0x82 }, | ||
101 | { STB0899_GPIO18CFG , 0x82 }, | ||
102 | { STB0899_GPIO19CFG , 0x82 }, | ||
103 | { STB0899_GPIO20CFG , 0x82 }, | ||
104 | { STB0899_SDATCFG , 0xb8 }, | ||
105 | { STB0899_SCLTCFG , 0xba }, | ||
106 | { STB0899_AGCRFCFG , 0x1c }, /* 0x11 */ | ||
107 | { STB0899_GPIO22 , 0x82 }, /* AGCBB2CFG */ | ||
108 | { STB0899_GPIO21 , 0x91 }, /* AGCBB1CFG */ | ||
109 | { STB0899_DIRCLKCFG , 0x82 }, | ||
110 | { STB0899_CLKOUT27CFG , 0x7e }, | ||
111 | { STB0899_STDBYCFG , 0x82 }, | ||
112 | { STB0899_CS0CFG , 0x82 }, | ||
113 | { STB0899_CS1CFG , 0x82 }, | ||
114 | { STB0899_DISEQCOCFG , 0x20 }, | ||
115 | { STB0899_GPIO32CFG , 0x82 }, | ||
116 | { STB0899_GPIO33CFG , 0x82 }, | ||
117 | { STB0899_GPIO34CFG , 0x82 }, | ||
118 | { STB0899_GPIO35CFG , 0x82 }, | ||
119 | { STB0899_GPIO36CFG , 0x82 }, | ||
120 | { STB0899_GPIO37CFG , 0x82 }, | ||
121 | { STB0899_GPIO38CFG , 0x82 }, | ||
122 | { STB0899_GPIO39CFG , 0x82 }, | ||
123 | { STB0899_NCOARSE , 0x17 }, /* 0x15 = 27 Mhz Clock, F/3 = 198MHz, F/6 = 99MHz */ | ||
124 | { STB0899_SYNTCTRL , 0x02 }, /* 0x00 = CLK from CLKI, 0x02 = CLK from XTALI */ | ||
125 | { STB0899_FILTCTRL , 0x00 }, | ||
126 | { STB0899_SYSCTRL , 0x01 }, | ||
127 | { STB0899_STOPCLK1 , 0x20 }, | ||
128 | { STB0899_STOPCLK2 , 0x00 }, | ||
129 | { STB0899_INTBUFSTATUS , 0x00 }, | ||
130 | { STB0899_INTBUFCTRL , 0x0a }, | ||
131 | { 0xffff , 0xff }, | ||
132 | }; | ||
133 | |||
134 | static const struct stb0899_s1_reg vp1041_stb0899_s1_init_3[] = { | ||
135 | { STB0899_DEMOD , 0x00 }, | ||
136 | { STB0899_RCOMPC , 0xc9 }, | ||
137 | { STB0899_AGC1CN , 0x01 }, | ||
138 | { STB0899_AGC1REF , 0x10 }, | ||
139 | { STB0899_RTC , 0x23 }, | ||
140 | { STB0899_TMGCFG , 0x4e }, | ||
141 | { STB0899_AGC2REF , 0x34 }, | ||
142 | { STB0899_TLSR , 0x84 }, | ||
143 | { STB0899_CFD , 0xf7 }, | ||
144 | { STB0899_ACLC , 0x87 }, | ||
145 | { STB0899_BCLC , 0x94 }, | ||
146 | { STB0899_EQON , 0x41 }, | ||
147 | { STB0899_LDT , 0xf1 }, | ||
148 | { STB0899_LDT2 , 0xe3 }, | ||
149 | { STB0899_EQUALREF , 0xb4 }, | ||
150 | { STB0899_TMGRAMP , 0x10 }, | ||
151 | { STB0899_TMGTHD , 0x30 }, | ||
152 | { STB0899_IDCCOMP , 0xfd }, | ||
153 | { STB0899_QDCCOMP , 0xff }, | ||
154 | { STB0899_POWERI , 0x0c }, | ||
155 | { STB0899_POWERQ , 0x0f }, | ||
156 | { STB0899_RCOMP , 0x6c }, | ||
157 | { STB0899_AGCIQIN , 0x80 }, | ||
158 | { STB0899_AGC2I1 , 0x06 }, | ||
159 | { STB0899_AGC2I2 , 0x00 }, | ||
160 | { STB0899_TLIR , 0x30 }, | ||
161 | { STB0899_RTF , 0x7f }, | ||
162 | { STB0899_DSTATUS , 0x00 }, | ||
163 | { STB0899_LDI , 0xbc }, | ||
164 | { STB0899_CFRM , 0xea }, | ||
165 | { STB0899_CFRL , 0x31 }, | ||
166 | { STB0899_NIRM , 0x2b }, | ||
167 | { STB0899_NIRL , 0x80 }, | ||
168 | { STB0899_ISYMB , 0x1d }, | ||
169 | { STB0899_QSYMB , 0xa6 }, | ||
170 | { STB0899_SFRH , 0x2f }, | ||
171 | { STB0899_SFRM , 0x68 }, | ||
172 | { STB0899_SFRL , 0x40 }, | ||
173 | { STB0899_SFRUPH , 0x2f }, | ||
174 | { STB0899_SFRUPM , 0x68 }, | ||
175 | { STB0899_SFRUPL , 0x40 }, | ||
176 | { STB0899_EQUAI1 , 0x02 }, | ||
177 | { STB0899_EQUAQ1 , 0xff }, | ||
178 | { STB0899_EQUAI2 , 0x04 }, | ||
179 | { STB0899_EQUAQ2 , 0x05 }, | ||
180 | { STB0899_EQUAI3 , 0x02 }, | ||
181 | { STB0899_EQUAQ3 , 0xfd }, | ||
182 | { STB0899_EQUAI4 , 0x03 }, | ||
183 | { STB0899_EQUAQ4 , 0x07 }, | ||
184 | { STB0899_EQUAI5 , 0x08 }, | ||
185 | { STB0899_EQUAQ5 , 0xf5 }, | ||
186 | { STB0899_DSTATUS2 , 0x00 }, | ||
187 | { STB0899_VSTATUS , 0x00 }, | ||
188 | { STB0899_VERROR , 0x86 }, | ||
189 | { STB0899_IQSWAP , 0x2a }, | ||
190 | { STB0899_ECNT1M , 0x00 }, | ||
191 | { STB0899_ECNT1L , 0x00 }, | ||
192 | { STB0899_ECNT2M , 0x00 }, | ||
193 | { STB0899_ECNT2L , 0x00 }, | ||
194 | { STB0899_ECNT3M , 0x0a }, | ||
195 | { STB0899_ECNT3L , 0xad }, | ||
196 | { STB0899_FECAUTO1 , 0x06 }, | ||
197 | { STB0899_FECM , 0x01 }, | ||
198 | { STB0899_VTH12 , 0xb0 }, | ||
199 | { STB0899_VTH23 , 0x7a }, | ||
200 | { STB0899_VTH34 , 0x58 }, | ||
201 | { STB0899_VTH56 , 0x38 }, | ||
202 | { STB0899_VTH67 , 0x34 }, | ||
203 | { STB0899_VTH78 , 0x24 }, | ||
204 | { STB0899_PRVIT , 0xff }, | ||
205 | { STB0899_VITSYNC , 0x19 }, | ||
206 | { STB0899_RSULC , 0xb1 }, /* DVB = 0xb1, DSS = 0xa1 */ | ||
207 | { STB0899_TSULC , 0x42 }, | ||
208 | { STB0899_RSLLC , 0x41 }, | ||
209 | { STB0899_TSLPL , 0x12 }, | ||
210 | { STB0899_TSCFGH , 0x0c }, | ||
211 | { STB0899_TSCFGM , 0x00 }, | ||
212 | { STB0899_TSCFGL , 0x00 }, | ||
213 | { STB0899_TSOUT , 0x69 }, /* 0x0d for CAM */ | ||
214 | { STB0899_RSSYNCDEL , 0x00 }, | ||
215 | { STB0899_TSINHDELH , 0x02 }, | ||
216 | { STB0899_TSINHDELM , 0x00 }, | ||
217 | { STB0899_TSINHDELL , 0x00 }, | ||
218 | { STB0899_TSLLSTKM , 0x1b }, | ||
219 | { STB0899_TSLLSTKL , 0xb3 }, | ||
220 | { STB0899_TSULSTKM , 0x00 }, | ||
221 | { STB0899_TSULSTKL , 0x00 }, | ||
222 | { STB0899_PCKLENUL , 0xbc }, | ||
223 | { STB0899_PCKLENLL , 0xcc }, | ||
224 | { STB0899_RSPCKLEN , 0xbd }, | ||
225 | { STB0899_TSSTATUS , 0x90 }, | ||
226 | { STB0899_ERRCTRL1 , 0xb6 }, | ||
227 | { STB0899_ERRCTRL2 , 0x95 }, | ||
228 | { STB0899_ERRCTRL3 , 0x8d }, | ||
229 | { STB0899_DMONMSK1 , 0x27 }, | ||
230 | { STB0899_DMONMSK0 , 0x03 }, | ||
231 | { STB0899_DEMAPVIT , 0x5c }, | ||
232 | { STB0899_PLPARM , 0x19 }, | ||
233 | { STB0899_PDELCTRL , 0x48 }, | ||
234 | { STB0899_PDELCTRL2 , 0x00 }, | ||
235 | { STB0899_BBHCTRL1 , 0x00 }, | ||
236 | { STB0899_BBHCTRL2 , 0x00 }, | ||
237 | { STB0899_HYSTTHRESH , 0x77 }, | ||
238 | { STB0899_MATCSTM , 0x00 }, | ||
239 | { STB0899_MATCSTL , 0x00 }, | ||
240 | { STB0899_UPLCSTM , 0x00 }, | ||
241 | { STB0899_UPLCSTL , 0x00 }, | ||
242 | { STB0899_DFLCSTM , 0x00 }, | ||
243 | { STB0899_DFLCSTL , 0x00 }, | ||
244 | { STB0899_SYNCCST , 0x00 }, | ||
245 | { STB0899_SYNCDCSTM , 0x00 }, | ||
246 | { STB0899_SYNCDCSTL , 0x00 }, | ||
247 | { STB0899_ISI_ENTRY , 0x00 }, | ||
248 | { STB0899_ISI_BIT_EN , 0x00 }, | ||
249 | { STB0899_MATSTRM , 0xf0 }, | ||
250 | { STB0899_MATSTRL , 0x02 }, | ||
251 | { STB0899_UPLSTRM , 0x45 }, | ||
252 | { STB0899_UPLSTRL , 0x60 }, | ||
253 | { STB0899_DFLSTRM , 0xe3 }, | ||
254 | { STB0899_DFLSTRL , 0x00 }, | ||
255 | { STB0899_SYNCSTR , 0x47 }, | ||
256 | { STB0899_SYNCDSTRM , 0x05 }, | ||
257 | { STB0899_SYNCDSTRL , 0x18 }, | ||
258 | { STB0899_CFGPDELSTATUS1 , 0x19 }, | ||
259 | { STB0899_CFGPDELSTATUS2 , 0x2b }, | ||
260 | { STB0899_BBFERRORM , 0x00 }, | ||
261 | { STB0899_BBFERRORL , 0x01 }, | ||
262 | { STB0899_UPKTERRORM , 0x00 }, | ||
263 | { STB0899_UPKTERRORL , 0x00 }, | ||
264 | { 0xffff , 0xff }, | ||
265 | }; | ||
266 | |||
267 | struct stb0899_config vp1041_stb0899_config = { | ||
268 | .init_dev = vp1041_stb0899_s1_init_1, | ||
269 | .init_s2_demod = stb0899_s2_init_2, | ||
270 | .init_s1_demod = vp1041_stb0899_s1_init_3, | ||
271 | .init_s2_fec = stb0899_s2_init_4, | ||
272 | .init_tst = stb0899_s1_init_5, | ||
273 | |||
274 | .demod_address = 0x68, /* 0xd0 >> 1 */ | ||
275 | |||
276 | .xtal_freq = 27000000, | ||
277 | .inversion = IQ_SWAP_ON, /* 1 */ | ||
278 | |||
279 | .lo_clk = 76500000, | ||
280 | .hi_clk = 99000000, | ||
281 | |||
282 | .esno_ave = STB0899_DVBS2_ESNO_AVE, | ||
283 | .esno_quant = STB0899_DVBS2_ESNO_QUANT, | ||
284 | .avframes_coarse = STB0899_DVBS2_AVFRAMES_COARSE, | ||
285 | .avframes_fine = STB0899_DVBS2_AVFRAMES_FINE, | ||
286 | .miss_threshold = STB0899_DVBS2_MISS_THRESHOLD, | ||
287 | .uwp_threshold_acq = STB0899_DVBS2_UWP_THRESHOLD_ACQ, | ||
288 | .uwp_threshold_track = STB0899_DVBS2_UWP_THRESHOLD_TRACK, | ||
289 | .uwp_threshold_sof = STB0899_DVBS2_UWP_THRESHOLD_SOF, | ||
290 | .sof_search_timeout = STB0899_DVBS2_SOF_SEARCH_TIMEOUT, | ||
291 | |||
292 | .btr_nco_bits = STB0899_DVBS2_BTR_NCO_BITS, | ||
293 | .btr_gain_shift_offset = STB0899_DVBS2_BTR_GAIN_SHIFT_OFFSET, | ||
294 | .crl_nco_bits = STB0899_DVBS2_CRL_NCO_BITS, | ||
295 | .ldpc_max_iter = STB0899_DVBS2_LDPC_MAX_ITER, | ||
296 | |||
297 | .tuner_get_frequency = stb6100_get_frequency, | ||
298 | .tuner_set_frequency = stb6100_set_frequency, | ||
299 | .tuner_set_bandwidth = stb6100_set_bandwidth, | ||
300 | .tuner_get_bandwidth = stb6100_get_bandwidth, | ||
301 | .tuner_set_rfsiggain = NULL, | ||
302 | }; | ||
303 | |||
304 | struct stb6100_config vp1041_stb6100_config = { | ||
305 | .tuner_address = 0x60, | ||
306 | .refclock = 27000000, | ||
307 | }; | ||
308 | |||
309 | static int vp1041_frontend_init(struct mantis_pci *mantis, struct dvb_frontend *fe) | ||
310 | { | ||
311 | struct i2c_adapter *adapter = &mantis->adapter; | ||
312 | |||
313 | int err = 0; | ||
314 | |||
315 | err = mantis_frontend_power(mantis, POWER_ON); | ||
316 | if (err == 0) { | ||
317 | mantis_frontend_soft_reset(mantis); | ||
318 | msleep(250); | ||
319 | mantis->fe = stb0899_attach(&vp1041_stb0899_config, adapter); | ||
320 | if (mantis->fe) { | ||
321 | dprintk(MANTIS_ERROR, 1, | ||
322 | "found STB0899 DVB-S/DVB-S2 frontend @0x%02x", | ||
323 | vp1041_stb0899_config.demod_address); | ||
324 | |||
325 | if (stb6100_attach(mantis->fe, &vp1041_stb6100_config, adapter)) { | ||
326 | if (!lnbp21_attach(mantis->fe, adapter, 0, 0)) | ||
327 | dprintk(MANTIS_ERROR, 1, "No LNBP21 found!"); | ||
328 | } | ||
329 | } else { | ||
330 | return -EREMOTEIO; | ||
331 | } | ||
332 | } else { | ||
333 | dprintk(MANTIS_ERROR, 1, "Frontend on <%s> POWER ON failed! <%d>", | ||
334 | adapter->name, | ||
335 | err); | ||
336 | |||
337 | return -EIO; | ||
338 | } | ||
339 | |||
340 | |||
341 | dprintk(MANTIS_ERROR, 1, "Done!"); | ||
342 | |||
343 | return 0; | ||
344 | } | ||
345 | |||
346 | struct mantis_hwconfig vp1041_config = { | ||
347 | .model_name = MANTIS_MODEL_NAME, | ||
348 | .dev_type = MANTIS_DEV_TYPE, | ||
349 | .ts_size = MANTIS_TS_188, | ||
350 | |||
351 | .baud_rate = MANTIS_BAUD_9600, | ||
352 | .parity = MANTIS_PARITY_NONE, | ||
353 | .bytes = 0, | ||
354 | |||
355 | .frontend_init = vp1041_frontend_init, | ||
356 | .power = GPIF_A12, | ||
357 | .reset = GPIF_A13, | ||
358 | }; | ||
diff --git a/drivers/media/dvb/mantis/mantis_vp1041.h b/drivers/media/dvb/mantis/mantis_vp1041.h new file mode 100644 index 000000000000..1ae5b3de8081 --- /dev/null +++ b/drivers/media/dvb/mantis/mantis_vp1041.h | |||
@@ -0,0 +1,33 @@ | |||
1 | /* | ||
2 | Mantis VP-1041 driver | ||
3 | |||
4 | Copyright (C) Manu Abraham (abraham.manu@gmail.com) | ||
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 __MANTIS_VP1041_H | ||
22 | #define __MANTIS_VP1041_H | ||
23 | |||
24 | #include "mantis_common.h" | ||
25 | |||
26 | #define MANTIS_VP_1041_DVB_S2 0x0031 | ||
27 | #define SKYSTAR_HD2_10 0x0001 | ||
28 | #define SKYSTAR_HD2_20 0x0003 | ||
29 | #define CINERGY_S2_PCI_HD 0x1179 | ||
30 | |||
31 | extern struct mantis_hwconfig vp1041_config; | ||
32 | |||
33 | #endif /* __MANTIS_VP1041_H */ | ||
diff --git a/drivers/media/dvb/mantis/mantis_vp2033.c b/drivers/media/dvb/mantis/mantis_vp2033.c new file mode 100644 index 000000000000..10ce81790a8c --- /dev/null +++ b/drivers/media/dvb/mantis/mantis_vp2033.c | |||
@@ -0,0 +1,187 @@ | |||
1 | /* | ||
2 | Mantis VP-2033 driver | ||
3 | |||
4 | Copyright (C) Manu Abraham (abraham.manu@gmail.com) | ||
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 | #include <linux/signal.h> | ||
22 | #include <linux/sched.h> | ||
23 | #include <linux/interrupt.h> | ||
24 | |||
25 | #include "dmxdev.h" | ||
26 | #include "dvbdev.h" | ||
27 | #include "dvb_demux.h" | ||
28 | #include "dvb_frontend.h" | ||
29 | #include "dvb_net.h" | ||
30 | |||
31 | #include "tda1002x.h" | ||
32 | #include "mantis_common.h" | ||
33 | #include "mantis_ioc.h" | ||
34 | #include "mantis_dvb.h" | ||
35 | #include "mantis_vp2033.h" | ||
36 | |||
37 | #define MANTIS_MODEL_NAME "VP-2033" | ||
38 | #define MANTIS_DEV_TYPE "DVB-C" | ||
39 | |||
40 | struct tda1002x_config vp2033_tda1002x_cu1216_config = { | ||
41 | .demod_address = 0x18 >> 1, | ||
42 | .invert = 1, | ||
43 | }; | ||
44 | |||
45 | struct tda10023_config vp2033_tda10023_cu1216_config = { | ||
46 | .demod_address = 0x18 >> 1, | ||
47 | .invert = 1, | ||
48 | }; | ||
49 | |||
50 | static u8 read_pwm(struct mantis_pci *mantis) | ||
51 | { | ||
52 | struct i2c_adapter *adapter = &mantis->adapter; | ||
53 | |||
54 | u8 b = 0xff; | ||
55 | u8 pwm; | ||
56 | struct i2c_msg msg[] = { | ||
57 | {.addr = 0x50, .flags = 0, .buf = &b, .len = 1}, | ||
58 | {.addr = 0x50, .flags = I2C_M_RD, .buf = &pwm, .len = 1} | ||
59 | }; | ||
60 | |||
61 | if ((i2c_transfer(adapter, msg, 2) != 2) | ||
62 | || (pwm == 0xff)) | ||
63 | pwm = 0x48; | ||
64 | |||
65 | return pwm; | ||
66 | } | ||
67 | |||
68 | static int tda1002x_cu1216_tuner_set(struct dvb_frontend *fe, struct dvb_frontend_parameters *params) | ||
69 | { | ||
70 | struct mantis_pci *mantis = fe->dvb->priv; | ||
71 | struct i2c_adapter *adapter = &mantis->adapter; | ||
72 | |||
73 | u8 buf[6]; | ||
74 | struct i2c_msg msg = {.addr = 0x60, .flags = 0, .buf = buf, .len = sizeof(buf)}; | ||
75 | int i; | ||
76 | |||
77 | #define CU1216_IF 36125000 | ||
78 | #define TUNER_MUL 62500 | ||
79 | |||
80 | u32 div = (params->frequency + CU1216_IF + TUNER_MUL / 2) / TUNER_MUL; | ||
81 | |||
82 | buf[0] = (div >> 8) & 0x7f; | ||
83 | buf[1] = div & 0xff; | ||
84 | buf[2] = 0xce; | ||
85 | buf[3] = (params->frequency < 150000000 ? 0x01 : | ||
86 | params->frequency < 445000000 ? 0x02 : 0x04); | ||
87 | buf[4] = 0xde; | ||
88 | buf[5] = 0x20; | ||
89 | |||
90 | if (fe->ops.i2c_gate_ctrl) | ||
91 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
92 | |||
93 | if (i2c_transfer(adapter, &msg, 1) != 1) | ||
94 | return -EIO; | ||
95 | |||
96 | /* wait for the pll lock */ | ||
97 | msg.flags = I2C_M_RD; | ||
98 | msg.len = 1; | ||
99 | for (i = 0; i < 20; i++) { | ||
100 | if (fe->ops.i2c_gate_ctrl) | ||
101 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
102 | |||
103 | if (i2c_transfer(adapter, &msg, 1) == 1 && (buf[0] & 0x40)) | ||
104 | break; | ||
105 | |||
106 | msleep(10); | ||
107 | } | ||
108 | |||
109 | /* switch the charge pump to the lower current */ | ||
110 | msg.flags = 0; | ||
111 | msg.len = 2; | ||
112 | msg.buf = &buf[2]; | ||
113 | buf[2] &= ~0x40; | ||
114 | if (fe->ops.i2c_gate_ctrl) | ||
115 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
116 | |||
117 | if (i2c_transfer(adapter, &msg, 1) != 1) | ||
118 | return -EIO; | ||
119 | |||
120 | return 0; | ||
121 | } | ||
122 | |||
123 | static int vp2033_frontend_init(struct mantis_pci *mantis, struct dvb_frontend *fe) | ||
124 | { | ||
125 | struct i2c_adapter *adapter = &mantis->adapter; | ||
126 | |||
127 | int err = 0; | ||
128 | |||
129 | err = mantis_frontend_power(mantis, POWER_ON); | ||
130 | if (err == 0) { | ||
131 | mantis_frontend_soft_reset(mantis); | ||
132 | msleep(250); | ||
133 | |||
134 | dprintk(MANTIS_ERROR, 1, "Probing for CU1216 (DVB-C)"); | ||
135 | fe = tda10021_attach(&vp2033_tda1002x_cu1216_config, | ||
136 | adapter, | ||
137 | read_pwm(mantis)); | ||
138 | |||
139 | if (fe) { | ||
140 | dprintk(MANTIS_ERROR, 1, | ||
141 | "found Philips CU1216 DVB-C frontend (TDA10021) @ 0x%02x", | ||
142 | vp2033_tda1002x_cu1216_config.demod_address); | ||
143 | } else { | ||
144 | fe = tda10023_attach(&vp2033_tda10023_cu1216_config, | ||
145 | adapter, | ||
146 | read_pwm(mantis)); | ||
147 | |||
148 | if (fe) { | ||
149 | dprintk(MANTIS_ERROR, 1, | ||
150 | "found Philips CU1216 DVB-C frontend (TDA10023) @ 0x%02x", | ||
151 | vp2033_tda1002x_cu1216_config.demod_address); | ||
152 | } | ||
153 | } | ||
154 | |||
155 | if (fe) { | ||
156 | fe->ops.tuner_ops.set_params = tda1002x_cu1216_tuner_set; | ||
157 | dprintk(MANTIS_ERROR, 1, "Mantis DVB-C Philips CU1216 frontend attach success"); | ||
158 | } else { | ||
159 | return -1; | ||
160 | } | ||
161 | } else { | ||
162 | dprintk(MANTIS_ERROR, 1, "Frontend on <%s> POWER ON failed! <%d>", | ||
163 | adapter->name, | ||
164 | err); | ||
165 | |||
166 | return -EIO; | ||
167 | } | ||
168 | |||
169 | mantis->fe = fe; | ||
170 | dprintk(MANTIS_DEBUG, 1, "Done!"); | ||
171 | |||
172 | return 0; | ||
173 | } | ||
174 | |||
175 | struct mantis_hwconfig vp2033_config = { | ||
176 | .model_name = MANTIS_MODEL_NAME, | ||
177 | .dev_type = MANTIS_DEV_TYPE, | ||
178 | .ts_size = MANTIS_TS_204, | ||
179 | |||
180 | .baud_rate = MANTIS_BAUD_9600, | ||
181 | .parity = MANTIS_PARITY_NONE, | ||
182 | .bytes = 0, | ||
183 | |||
184 | .frontend_init = vp2033_frontend_init, | ||
185 | .power = GPIF_A12, | ||
186 | .reset = GPIF_A13, | ||
187 | }; | ||
diff --git a/drivers/media/dvb/mantis/mantis_vp2033.h b/drivers/media/dvb/mantis/mantis_vp2033.h new file mode 100644 index 000000000000..c55242b79d54 --- /dev/null +++ b/drivers/media/dvb/mantis/mantis_vp2033.h | |||
@@ -0,0 +1,30 @@ | |||
1 | /* | ||
2 | Mantis VP-2033 driver | ||
3 | |||
4 | Copyright (C) Manu Abraham (abraham.manu@gmail.com) | ||
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 __MANTIS_VP2033_H | ||
22 | #define __MANTIS_VP2033_H | ||
23 | |||
24 | #include "mantis_common.h" | ||
25 | |||
26 | #define MANTIS_VP_2033_DVB_C 0x0008 | ||
27 | |||
28 | extern struct mantis_hwconfig vp2033_config; | ||
29 | |||
30 | #endif /* __MANTIS_VP2033_H */ | ||
diff --git a/drivers/media/dvb/mantis/mantis_vp2040.c b/drivers/media/dvb/mantis/mantis_vp2040.c new file mode 100644 index 000000000000..a7ca233e800b --- /dev/null +++ b/drivers/media/dvb/mantis/mantis_vp2040.c | |||
@@ -0,0 +1,186 @@ | |||
1 | /* | ||
2 | Mantis VP-2040 driver | ||
3 | |||
4 | Copyright (C) Manu Abraham (abraham.manu@gmail.com) | ||
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 | #include <linux/signal.h> | ||
22 | #include <linux/sched.h> | ||
23 | #include <linux/interrupt.h> | ||
24 | |||
25 | #include "dmxdev.h" | ||
26 | #include "dvbdev.h" | ||
27 | #include "dvb_demux.h" | ||
28 | #include "dvb_frontend.h" | ||
29 | #include "dvb_net.h" | ||
30 | |||
31 | #include "tda1002x.h" | ||
32 | #include "mantis_common.h" | ||
33 | #include "mantis_ioc.h" | ||
34 | #include "mantis_dvb.h" | ||
35 | #include "mantis_vp2040.h" | ||
36 | |||
37 | #define MANTIS_MODEL_NAME "VP-2040" | ||
38 | #define MANTIS_DEV_TYPE "DVB-C" | ||
39 | |||
40 | struct tda1002x_config vp2040_tda1002x_cu1216_config = { | ||
41 | .demod_address = 0x18 >> 1, | ||
42 | .invert = 1, | ||
43 | }; | ||
44 | |||
45 | struct tda10023_config vp2040_tda10023_cu1216_config = { | ||
46 | .demod_address = 0x18 >> 1, | ||
47 | .invert = 1, | ||
48 | }; | ||
49 | |||
50 | static int tda1002x_cu1216_tuner_set(struct dvb_frontend *fe, struct dvb_frontend_parameters *params) | ||
51 | { | ||
52 | struct mantis_pci *mantis = fe->dvb->priv; | ||
53 | struct i2c_adapter *adapter = &mantis->adapter; | ||
54 | |||
55 | u8 buf[6]; | ||
56 | struct i2c_msg msg = {.addr = 0x60, .flags = 0, .buf = buf, .len = sizeof(buf)}; | ||
57 | int i; | ||
58 | |||
59 | #define CU1216_IF 36125000 | ||
60 | #define TUNER_MUL 62500 | ||
61 | |||
62 | u32 div = (params->frequency + CU1216_IF + TUNER_MUL / 2) / TUNER_MUL; | ||
63 | |||
64 | buf[0] = (div >> 8) & 0x7f; | ||
65 | buf[1] = div & 0xff; | ||
66 | buf[2] = 0xce; | ||
67 | buf[3] = (params->frequency < 150000000 ? 0x01 : | ||
68 | params->frequency < 445000000 ? 0x02 : 0x04); | ||
69 | buf[4] = 0xde; | ||
70 | buf[5] = 0x20; | ||
71 | |||
72 | if (fe->ops.i2c_gate_ctrl) | ||
73 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
74 | |||
75 | if (i2c_transfer(adapter, &msg, 1) != 1) | ||
76 | return -EIO; | ||
77 | |||
78 | /* wait for the pll lock */ | ||
79 | msg.flags = I2C_M_RD; | ||
80 | msg.len = 1; | ||
81 | for (i = 0; i < 20; i++) { | ||
82 | if (fe->ops.i2c_gate_ctrl) | ||
83 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
84 | |||
85 | if (i2c_transfer(adapter, &msg, 1) == 1 && (buf[0] & 0x40)) | ||
86 | break; | ||
87 | |||
88 | msleep(10); | ||
89 | } | ||
90 | |||
91 | /* switch the charge pump to the lower current */ | ||
92 | msg.flags = 0; | ||
93 | msg.len = 2; | ||
94 | msg.buf = &buf[2]; | ||
95 | buf[2] &= ~0x40; | ||
96 | if (fe->ops.i2c_gate_ctrl) | ||
97 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
98 | |||
99 | if (i2c_transfer(adapter, &msg, 1) != 1) | ||
100 | return -EIO; | ||
101 | |||
102 | return 0; | ||
103 | } | ||
104 | |||
105 | static u8 read_pwm(struct mantis_pci *mantis) | ||
106 | { | ||
107 | struct i2c_adapter *adapter = &mantis->adapter; | ||
108 | |||
109 | u8 b = 0xff; | ||
110 | u8 pwm; | ||
111 | struct i2c_msg msg[] = { | ||
112 | {.addr = 0x50, .flags = 0, .buf = &b, .len = 1}, | ||
113 | {.addr = 0x50, .flags = I2C_M_RD, .buf = &pwm, .len = 1} | ||
114 | }; | ||
115 | |||
116 | if ((i2c_transfer(adapter, msg, 2) != 2) | ||
117 | || (pwm == 0xff)) | ||
118 | pwm = 0x48; | ||
119 | |||
120 | return pwm; | ||
121 | } | ||
122 | |||
123 | static int vp2040_frontend_init(struct mantis_pci *mantis, struct dvb_frontend *fe) | ||
124 | { | ||
125 | struct i2c_adapter *adapter = &mantis->adapter; | ||
126 | |||
127 | int err = 0; | ||
128 | |||
129 | err = mantis_frontend_power(mantis, POWER_ON); | ||
130 | if (err == 0) { | ||
131 | mantis_frontend_soft_reset(mantis); | ||
132 | msleep(250); | ||
133 | |||
134 | dprintk(MANTIS_ERROR, 1, "Probing for CU1216 (DVB-C)"); | ||
135 | fe = tda10021_attach(&vp2040_tda1002x_cu1216_config, | ||
136 | adapter, | ||
137 | read_pwm(mantis)); | ||
138 | |||
139 | if (fe) { | ||
140 | dprintk(MANTIS_ERROR, 1, | ||
141 | "found Philips CU1216 DVB-C frontend (TDA10021) @ 0x%02x", | ||
142 | vp2040_tda1002x_cu1216_config.demod_address); | ||
143 | } else { | ||
144 | fe = tda10023_attach(&vp2040_tda10023_cu1216_config, | ||
145 | adapter, | ||
146 | read_pwm(mantis)); | ||
147 | |||
148 | if (fe) { | ||
149 | dprintk(MANTIS_ERROR, 1, | ||
150 | "found Philips CU1216 DVB-C frontend (TDA10023) @ 0x%02x", | ||
151 | vp2040_tda1002x_cu1216_config.demod_address); | ||
152 | } | ||
153 | } | ||
154 | |||
155 | if (fe) { | ||
156 | fe->ops.tuner_ops.set_params = tda1002x_cu1216_tuner_set; | ||
157 | dprintk(MANTIS_ERROR, 1, "Mantis DVB-C Philips CU1216 frontend attach success"); | ||
158 | } else { | ||
159 | return -1; | ||
160 | } | ||
161 | } else { | ||
162 | dprintk(MANTIS_ERROR, 1, "Frontend on <%s> POWER ON failed! <%d>", | ||
163 | adapter->name, | ||
164 | err); | ||
165 | |||
166 | return -EIO; | ||
167 | } | ||
168 | mantis->fe = fe; | ||
169 | dprintk(MANTIS_DEBUG, 1, "Done!"); | ||
170 | |||
171 | return 0; | ||
172 | } | ||
173 | |||
174 | struct mantis_hwconfig vp2040_config = { | ||
175 | .model_name = MANTIS_MODEL_NAME, | ||
176 | .dev_type = MANTIS_DEV_TYPE, | ||
177 | .ts_size = MANTIS_TS_204, | ||
178 | |||
179 | .baud_rate = MANTIS_BAUD_9600, | ||
180 | .parity = MANTIS_PARITY_NONE, | ||
181 | .bytes = 0, | ||
182 | |||
183 | .frontend_init = vp2040_frontend_init, | ||
184 | .power = GPIF_A12, | ||
185 | .reset = GPIF_A13, | ||
186 | }; | ||
diff --git a/drivers/media/dvb/mantis/mantis_vp2040.h b/drivers/media/dvb/mantis/mantis_vp2040.h new file mode 100644 index 000000000000..d125e219b685 --- /dev/null +++ b/drivers/media/dvb/mantis/mantis_vp2040.h | |||
@@ -0,0 +1,32 @@ | |||
1 | /* | ||
2 | Mantis VP-2040 driver | ||
3 | |||
4 | Copyright (C) Manu Abraham (abraham.manu@gmail.com) | ||
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 __MANTIS_VP2040_H | ||
22 | #define __MANTIS_VP2040_H | ||
23 | |||
24 | #include "mantis_common.h" | ||
25 | |||
26 | #define MANTIS_VP_2040_DVB_C 0x0043 | ||
27 | #define CINERGY_C 0x1178 | ||
28 | #define CABLESTAR_HD2 0x0002 | ||
29 | |||
30 | extern struct mantis_hwconfig vp2040_config; | ||
31 | |||
32 | #endif /* __MANTIS_VP2040_H */ | ||
diff --git a/drivers/media/dvb/mantis/mantis_vp3028.c b/drivers/media/dvb/mantis/mantis_vp3028.c new file mode 100644 index 000000000000..4155c838a18a --- /dev/null +++ b/drivers/media/dvb/mantis/mantis_vp3028.c | |||
@@ -0,0 +1,38 @@ | |||
1 | /* | ||
2 | Mantis VP-3028 driver | ||
3 | |||
4 | Copyright (C) Manu Abraham (abraham.manu@gmail.com) | ||
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 | #include "mantis_common.h" | ||
22 | #include "mantis_vp3028.h" | ||
23 | |||
24 | struct zl10353_config mantis_vp3028_config = { | ||
25 | .demod_address = 0x0f, | ||
26 | }; | ||
27 | |||
28 | #define MANTIS_MODEL_NAME "VP-3028" | ||
29 | #define MANTIS_DEV_TYPE "DVB-T" | ||
30 | |||
31 | struct mantis_hwconfig vp3028_mantis_config = { | ||
32 | .model_name = MANTIS_MODEL_NAME, | ||
33 | .dev_type = MANTIS_DEV_TYPE, | ||
34 | .ts_size = MANTIS_TS_188, | ||
35 | .baud_rate = MANTIS_BAUD_9600, | ||
36 | .parity = MANTIS_PARITY_NONE, | ||
37 | .bytes = 0, | ||
38 | }; | ||
diff --git a/drivers/media/dvb/mantis/mantis_vp3028.h b/drivers/media/dvb/mantis/mantis_vp3028.h new file mode 100644 index 000000000000..b07be6adc522 --- /dev/null +++ b/drivers/media/dvb/mantis/mantis_vp3028.h | |||
@@ -0,0 +1,33 @@ | |||
1 | /* | ||
2 | Mantis VP-3028 driver | ||
3 | |||
4 | Copyright (C) Manu Abraham (abraham.manu@gmail.com) | ||
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 __MANTIS_VP3028_H | ||
22 | #define __MANTIS_VP3028_H | ||
23 | |||
24 | #include "dvb_frontend.h" | ||
25 | #include "mantis_common.h" | ||
26 | #include "zl10353.h" | ||
27 | |||
28 | #define MANTIS_VP_3028_DVB_T 0x0028 | ||
29 | |||
30 | extern struct zl10353_config mantis_vp3028_config; | ||
31 | extern struct mantis_hwconfig vp3028_mantis_config; | ||
32 | |||
33 | #endif /* __MANTIS_VP3028_H */ | ||
diff --git a/drivers/media/dvb/mantis/mantis_vp3030.c b/drivers/media/dvb/mantis/mantis_vp3030.c new file mode 100644 index 000000000000..1f4334214953 --- /dev/null +++ b/drivers/media/dvb/mantis/mantis_vp3030.c | |||
@@ -0,0 +1,105 @@ | |||
1 | /* | ||
2 | Mantis VP-3030 driver | ||
3 | |||
4 | Copyright (C) Manu Abraham (abraham.manu@gmail.com) | ||
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 | #include <linux/signal.h> | ||
22 | #include <linux/sched.h> | ||
23 | #include <linux/interrupt.h> | ||
24 | |||
25 | #include "dmxdev.h" | ||
26 | #include "dvbdev.h" | ||
27 | #include "dvb_demux.h" | ||
28 | #include "dvb_frontend.h" | ||
29 | #include "dvb_net.h" | ||
30 | |||
31 | #include "zl10353.h" | ||
32 | #include "tda665x.h" | ||
33 | #include "mantis_common.h" | ||
34 | #include "mantis_ioc.h" | ||
35 | #include "mantis_dvb.h" | ||
36 | #include "mantis_vp3030.h" | ||
37 | |||
38 | struct zl10353_config mantis_vp3030_config = { | ||
39 | .demod_address = 0x0f, | ||
40 | }; | ||
41 | |||
42 | struct tda665x_config env57h12d5_config = { | ||
43 | .name = "ENV57H12D5 (ET-50DT)", | ||
44 | .addr = 0x60, | ||
45 | .frequency_min = 47000000, | ||
46 | .frequency_max = 862000000, | ||
47 | .frequency_offst = 3616667, | ||
48 | .ref_multiplier = 6, /* 1/6 MHz */ | ||
49 | .ref_divider = 100000, /* 1/6 MHz */ | ||
50 | }; | ||
51 | |||
52 | #define MANTIS_MODEL_NAME "VP-3030" | ||
53 | #define MANTIS_DEV_TYPE "DVB-T" | ||
54 | |||
55 | |||
56 | static int vp3030_frontend_init(struct mantis_pci *mantis, struct dvb_frontend *fe) | ||
57 | { | ||
58 | struct i2c_adapter *adapter = &mantis->adapter; | ||
59 | struct mantis_hwconfig *config = mantis->hwconfig; | ||
60 | int err = 0; | ||
61 | |||
62 | gpio_set_bits(mantis, config->reset, 0); | ||
63 | msleep(100); | ||
64 | err = mantis_frontend_power(mantis, POWER_ON); | ||
65 | msleep(100); | ||
66 | gpio_set_bits(mantis, config->reset, 1); | ||
67 | |||
68 | if (err == 0) { | ||
69 | msleep(250); | ||
70 | dprintk(MANTIS_ERROR, 1, "Probing for 10353 (DVB-T)"); | ||
71 | fe = zl10353_attach(&mantis_vp3030_config, adapter); | ||
72 | |||
73 | if (!fe) | ||
74 | return -1; | ||
75 | |||
76 | tda665x_attach(fe, &env57h12d5_config, adapter); | ||
77 | } else { | ||
78 | dprintk(MANTIS_ERROR, 1, "Frontend on <%s> POWER ON failed! <%d>", | ||
79 | adapter->name, | ||
80 | err); | ||
81 | |||
82 | return -EIO; | ||
83 | |||
84 | } | ||
85 | mantis->fe = fe; | ||
86 | dprintk(MANTIS_ERROR, 1, "Done!"); | ||
87 | |||
88 | return 0; | ||
89 | } | ||
90 | |||
91 | struct mantis_hwconfig vp3030_config = { | ||
92 | .model_name = MANTIS_MODEL_NAME, | ||
93 | .dev_type = MANTIS_DEV_TYPE, | ||
94 | .ts_size = MANTIS_TS_188, | ||
95 | |||
96 | .baud_rate = MANTIS_BAUD_9600, | ||
97 | .parity = MANTIS_PARITY_NONE, | ||
98 | .bytes = 0, | ||
99 | |||
100 | .frontend_init = vp3030_frontend_init, | ||
101 | .power = GPIF_A12, | ||
102 | .reset = GPIF_A13, | ||
103 | |||
104 | .i2c_mode = MANTIS_BYTE_MODE | ||
105 | }; | ||
diff --git a/drivers/media/dvb/mantis/mantis_vp3030.h b/drivers/media/dvb/mantis/mantis_vp3030.h new file mode 100644 index 000000000000..5f12c4266277 --- /dev/null +++ b/drivers/media/dvb/mantis/mantis_vp3030.h | |||
@@ -0,0 +1,30 @@ | |||
1 | /* | ||
2 | Mantis VP-3030 driver | ||
3 | |||
4 | Copyright (C) Manu Abraham (abraham.manu@gmail.com) | ||
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 __MANTIS_VP3030_H | ||
22 | #define __MANTIS_VP3030_H | ||
23 | |||
24 | #include "mantis_common.h" | ||
25 | |||
26 | #define MANTIS_VP_3030_DVB_T 0x0024 | ||
27 | |||
28 | extern struct mantis_hwconfig vp3030_config; | ||
29 | |||
30 | #endif /* __MANTIS_VP3030_H */ | ||
diff --git a/drivers/media/video/gspca/gspca.c b/drivers/media/video/gspca/gspca.c index e930a67d526b..bd6214d4ab3b 100644 --- a/drivers/media/video/gspca/gspca.c +++ b/drivers/media/video/gspca/gspca.c | |||
@@ -1815,6 +1815,8 @@ static int vidioc_qbuf(struct file *file, void *priv, | |||
1815 | /* put the buffer in the 'queued' queue */ | 1815 | /* put the buffer in the 'queued' queue */ |
1816 | i = gspca_dev->fr_q; | 1816 | i = gspca_dev->fr_q; |
1817 | gspca_dev->fr_queue[i] = index; | 1817 | gspca_dev->fr_queue[i] = index; |
1818 | if (gspca_dev->fr_i == i) | ||
1819 | gspca_dev->cur_frame = frame; | ||
1818 | gspca_dev->fr_q = (i + 1) % gspca_dev->nframes; | 1820 | gspca_dev->fr_q = (i + 1) % gspca_dev->nframes; |
1819 | PDEBUG(D_FRAM, "qbuf q:%d i:%d o:%d", | 1821 | PDEBUG(D_FRAM, "qbuf q:%d i:%d o:%d", |
1820 | gspca_dev->fr_q, | 1822 | gspca_dev->fr_q, |
diff --git a/drivers/media/video/gspca/m5602/m5602_s5k4aa.c b/drivers/media/video/gspca/m5602/m5602_s5k4aa.c index aa2f3c7e2cb5..1b536f7d30cf 100644 --- a/drivers/media/video/gspca/m5602/m5602_s5k4aa.c +++ b/drivers/media/video/gspca/m5602/m5602_s5k4aa.c | |||
@@ -48,6 +48,12 @@ static | |||
48 | DMI_MATCH(DMI_PRODUCT_NAME, "AMILO Xa 2528") | 48 | DMI_MATCH(DMI_PRODUCT_NAME, "AMILO Xa 2528") |
49 | } | 49 | } |
50 | }, { | 50 | }, { |
51 | .ident = "Fujitsu-Siemens Amilo Xi 2428", | ||
52 | .matches = { | ||
53 | DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"), | ||
54 | DMI_MATCH(DMI_PRODUCT_NAME, "AMILO Xi 2428") | ||
55 | } | ||
56 | }, { | ||
51 | .ident = "Fujitsu-Siemens Amilo Xi 2528", | 57 | .ident = "Fujitsu-Siemens Amilo Xi 2528", |
52 | .matches = { | 58 | .matches = { |
53 | DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"), | 59 | DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"), |
diff --git a/drivers/media/video/gspca/ov534.c b/drivers/media/video/gspca/ov534.c index 4dbb882c83dc..0a6b8f07a69d 100644 --- a/drivers/media/video/gspca/ov534.c +++ b/drivers/media/video/gspca/ov534.c | |||
@@ -1533,7 +1533,7 @@ static void setexposure_96(struct gspca_dev *gspca_dev) | |||
1533 | static void setsharpness_96(struct gspca_dev *gspca_dev) | 1533 | static void setsharpness_96(struct gspca_dev *gspca_dev) |
1534 | { | 1534 | { |
1535 | struct sd *sd = (struct sd *) gspca_dev; | 1535 | struct sd *sd = (struct sd *) gspca_dev; |
1536 | u8 val; | 1536 | s8 val; |
1537 | 1537 | ||
1538 | val = sd->sharpness; | 1538 | val = sd->sharpness; |
1539 | if (val < 0) { /* auto */ | 1539 | if (val < 0) { /* auto */ |
diff --git a/drivers/media/video/gspca/sn9c20x.c b/drivers/media/video/gspca/sn9c20x.c index 4cff8035614f..0ca1c06652b1 100644 --- a/drivers/media/video/gspca/sn9c20x.c +++ b/drivers/media/video/gspca/sn9c20x.c | |||
@@ -2319,7 +2319,7 @@ static void do_autogain(struct gspca_dev *gspca_dev, u16 avg_lum) | |||
2319 | } | 2319 | } |
2320 | } | 2320 | } |
2321 | if (avg_lum > MAX_AVG_LUM) { | 2321 | if (avg_lum > MAX_AVG_LUM) { |
2322 | if (sd->gain - 1 >= 0) { | 2322 | if (sd->gain >= 1) { |
2323 | sd->gain--; | 2323 | sd->gain--; |
2324 | set_gain(gspca_dev); | 2324 | set_gain(gspca_dev); |
2325 | } | 2325 | } |
diff --git a/drivers/media/video/gspca/stv06xx/stv06xx_vv6410.h b/drivers/media/video/gspca/stv06xx/stv06xx_vv6410.h index 487d40555343..96c61926d372 100644 --- a/drivers/media/video/gspca/stv06xx/stv06xx_vv6410.h +++ b/drivers/media/video/gspca/stv06xx/stv06xx_vv6410.h | |||
@@ -228,6 +228,7 @@ static const struct stv_init stv_bridge_init[] = { | |||
228 | /* This reg is written twice. Some kind of reset? */ | 228 | /* This reg is written twice. Some kind of reset? */ |
229 | {NULL, 0x1620, 0x80}, | 229 | {NULL, 0x1620, 0x80}, |
230 | {NULL, 0x1620, 0x00}, | 230 | {NULL, 0x1620, 0x00}, |
231 | {NULL, 0x1443, 0x00}, | ||
231 | {NULL, 0x1423, 0x04}, | 232 | {NULL, 0x1423, 0x04}, |
232 | {x1500, 0x1500, ARRAY_SIZE(x1500)}, | 233 | {x1500, 0x1500, ARRAY_SIZE(x1500)}, |
233 | {x1536, 0x1536, ARRAY_SIZE(x1536)}, | 234 | {x1536, 0x1536, ARRAY_SIZE(x1536)}, |
diff --git a/drivers/media/video/gspca/sunplus.c b/drivers/media/video/gspca/sunplus.c index 716df6b15fc5..306b7d75b4aa 100644 --- a/drivers/media/video/gspca/sunplus.c +++ b/drivers/media/video/gspca/sunplus.c | |||
@@ -709,7 +709,7 @@ static void spca504B_SetSizeType(struct gspca_dev *gspca_dev) | |||
709 | spca504B_PollingDataReady(gspca_dev); | 709 | spca504B_PollingDataReady(gspca_dev); |
710 | 710 | ||
711 | /* Init the cam width height with some values get on init ? */ | 711 | /* Init the cam width height with some values get on init ? */ |
712 | reg_w_riv(gspca_dev, 0x31, 0, 0x04); | 712 | reg_w_riv(gspca_dev, 0x31, 0x0004, 0x00); |
713 | spca504B_WaitCmdStatus(gspca_dev); | 713 | spca504B_WaitCmdStatus(gspca_dev); |
714 | spca504B_PollingDataReady(gspca_dev); | 714 | spca504B_PollingDataReady(gspca_dev); |
715 | break; | 715 | break; |
@@ -807,14 +807,14 @@ static void init_ctl_reg(struct gspca_dev *gspca_dev) | |||
807 | default: | 807 | default: |
808 | /* case BRIDGE_SPCA533: */ | 808 | /* case BRIDGE_SPCA533: */ |
809 | /* case BRIDGE_SPCA504B: */ | 809 | /* case BRIDGE_SPCA504B: */ |
810 | reg_w_riv(gspca_dev, 0, 0x00, 0x21ad); /* hue */ | 810 | reg_w_riv(gspca_dev, 0, 0x21ad, 0x00); /* hue */ |
811 | reg_w_riv(gspca_dev, 0, 0x01, 0x21ac); /* sat/hue */ | 811 | reg_w_riv(gspca_dev, 0, 0x21ac, 0x01); /* sat/hue */ |
812 | reg_w_riv(gspca_dev, 0, 0x00, 0x21a3); /* gamma */ | 812 | reg_w_riv(gspca_dev, 0, 0x21a3, 0x00); /* gamma */ |
813 | break; | 813 | break; |
814 | case BRIDGE_SPCA536: | 814 | case BRIDGE_SPCA536: |
815 | reg_w_riv(gspca_dev, 0, 0x40, 0x20f5); | 815 | reg_w_riv(gspca_dev, 0, 0x20f5, 0x40); |
816 | reg_w_riv(gspca_dev, 0, 0x01, 0x20f4); | 816 | reg_w_riv(gspca_dev, 0, 0x20f4, 0x01); |
817 | reg_w_riv(gspca_dev, 0, 0x00, 0x2089); | 817 | reg_w_riv(gspca_dev, 0, 0x2089, 0x00); |
818 | break; | 818 | break; |
819 | } | 819 | } |
820 | if (pollreg) | 820 | if (pollreg) |
@@ -887,11 +887,11 @@ static int sd_init(struct gspca_dev *gspca_dev) | |||
887 | switch (sd->bridge) { | 887 | switch (sd->bridge) { |
888 | case BRIDGE_SPCA504B: | 888 | case BRIDGE_SPCA504B: |
889 | reg_w_riv(gspca_dev, 0x1d, 0x00, 0); | 889 | reg_w_riv(gspca_dev, 0x1d, 0x00, 0); |
890 | reg_w_riv(gspca_dev, 0, 0x01, 0x2306); | 890 | reg_w_riv(gspca_dev, 0x00, 0x2306, 0x01); |
891 | reg_w_riv(gspca_dev, 0, 0x00, 0x0d04); | 891 | reg_w_riv(gspca_dev, 0x00, 0x0d04, 0x00); |
892 | reg_w_riv(gspca_dev, 0, 0x00, 0x2000); | 892 | reg_w_riv(gspca_dev, 0x00, 0x2000, 0x00); |
893 | reg_w_riv(gspca_dev, 0, 0x13, 0x2301); | 893 | reg_w_riv(gspca_dev, 0x00, 0x2301, 0x13); |
894 | reg_w_riv(gspca_dev, 0, 0x00, 0x2306); | 894 | reg_w_riv(gspca_dev, 0x00, 0x2306, 0x00); |
895 | /* fall thru */ | 895 | /* fall thru */ |
896 | case BRIDGE_SPCA533: | 896 | case BRIDGE_SPCA533: |
897 | spca504B_PollingDataReady(gspca_dev); | 897 | spca504B_PollingDataReady(gspca_dev); |
@@ -1000,7 +1000,7 @@ static int sd_start(struct gspca_dev *gspca_dev) | |||
1000 | spca504B_WaitCmdStatus(gspca_dev); | 1000 | spca504B_WaitCmdStatus(gspca_dev); |
1001 | break; | 1001 | break; |
1002 | default: | 1002 | default: |
1003 | reg_w_riv(gspca_dev, 0x31, 0, 0x04); | 1003 | reg_w_riv(gspca_dev, 0x31, 0x0004, 0x00); |
1004 | spca504B_WaitCmdStatus(gspca_dev); | 1004 | spca504B_WaitCmdStatus(gspca_dev); |
1005 | spca504B_PollingDataReady(gspca_dev); | 1005 | spca504B_PollingDataReady(gspca_dev); |
1006 | break; | 1006 | break; |
diff --git a/drivers/media/video/gspca/vc032x.c b/drivers/media/video/gspca/vc032x.c index c090efcd8045..71921c878424 100644 --- a/drivers/media/video/gspca/vc032x.c +++ b/drivers/media/video/gspca/vc032x.c | |||
@@ -3009,6 +3009,10 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, | |||
3009 | int l; | 3009 | int l; |
3010 | 3010 | ||
3011 | frame = gspca_get_i_frame(gspca_dev); | 3011 | frame = gspca_get_i_frame(gspca_dev); |
3012 | if (frame == NULL) { | ||
3013 | gspca_dev->last_packet_type = DISCARD_PACKET; | ||
3014 | return; | ||
3015 | } | ||
3012 | l = frame->data_end - frame->data; | 3016 | l = frame->data_end - frame->data; |
3013 | if (len > frame->v4l2_buf.length - l) | 3017 | if (len > frame->v4l2_buf.length - l) |
3014 | len = frame->v4l2_buf.length - l; | 3018 | len = frame->v4l2_buf.length - l; |
diff --git a/drivers/media/video/mx1_camera.c b/drivers/media/video/mx1_camera.c index 2ba14fb5b031..c167cc3de492 100644 --- a/drivers/media/video/mx1_camera.c +++ b/drivers/media/video/mx1_camera.c | |||
@@ -718,7 +718,7 @@ static int __init mx1_camera_probe(struct platform_device *pdev) | |||
718 | 718 | ||
719 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 719 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
720 | irq = platform_get_irq(pdev, 0); | 720 | irq = platform_get_irq(pdev, 0); |
721 | if (!res || !irq) { | 721 | if (!res || (int)irq <= 0) { |
722 | err = -ENODEV; | 722 | err = -ENODEV; |
723 | goto exit; | 723 | goto exit; |
724 | } | 724 | } |
diff --git a/drivers/media/video/rj54n1cb0c.c b/drivers/media/video/rj54n1cb0c.c index 7e42989ce0e4..805226e0d9c1 100644 --- a/drivers/media/video/rj54n1cb0c.c +++ b/drivers/media/video/rj54n1cb0c.c | |||
@@ -563,7 +563,7 @@ static int rj54n1_s_crop(struct v4l2_subdev *sd, struct v4l2_crop *a) | |||
563 | struct i2c_client *client = sd->priv; | 563 | struct i2c_client *client = sd->priv; |
564 | struct rj54n1 *rj54n1 = to_rj54n1(client); | 564 | struct rj54n1 *rj54n1 = to_rj54n1(client); |
565 | struct v4l2_rect *rect = &a->c; | 565 | struct v4l2_rect *rect = &a->c; |
566 | unsigned int dummy, output_w, output_h, | 566 | unsigned int dummy = 0, output_w, output_h, |
567 | input_w = rect->width, input_h = rect->height; | 567 | input_w = rect->width, input_h = rect->height; |
568 | int ret; | 568 | int ret; |
569 | 569 | ||
diff --git a/drivers/media/video/saa7134/saa7134-core.c b/drivers/media/video/saa7134/saa7134-core.c index 9f85e917f9f3..a7ad7810fddc 100644 --- a/drivers/media/video/saa7134/saa7134-core.c +++ b/drivers/media/video/saa7134/saa7134-core.c | |||
@@ -420,19 +420,6 @@ int saa7134_set_dmabits(struct saa7134_dev *dev) | |||
420 | ctrl |= SAA7134_MAIN_CTRL_TE5; | 420 | ctrl |= SAA7134_MAIN_CTRL_TE5; |
421 | irq |= SAA7134_IRQ1_INTE_RA2_1 | | 421 | irq |= SAA7134_IRQ1_INTE_RA2_1 | |
422 | SAA7134_IRQ1_INTE_RA2_0; | 422 | SAA7134_IRQ1_INTE_RA2_0; |
423 | |||
424 | /* dma: setup channel 5 (= TS) */ | ||
425 | |||
426 | saa_writeb(SAA7134_TS_DMA0, (dev->ts.nr_packets - 1) & 0xff); | ||
427 | saa_writeb(SAA7134_TS_DMA1, | ||
428 | ((dev->ts.nr_packets - 1) >> 8) & 0xff); | ||
429 | /* TSNOPIT=0, TSCOLAP=0 */ | ||
430 | saa_writeb(SAA7134_TS_DMA2, | ||
431 | (((dev->ts.nr_packets - 1) >> 16) & 0x3f) | 0x00); | ||
432 | saa_writel(SAA7134_RS_PITCH(5), TS_PACKET_SIZE); | ||
433 | saa_writel(SAA7134_RS_CONTROL(5), SAA7134_RS_CONTROL_BURST_16 | | ||
434 | SAA7134_RS_CONTROL_ME | | ||
435 | (dev->ts.pt_ts.dma >> 12)); | ||
436 | } | 423 | } |
437 | 424 | ||
438 | /* set task conditions + field handling */ | 425 | /* set task conditions + field handling */ |
diff --git a/drivers/media/video/saa7134/saa7134-ts.c b/drivers/media/video/saa7134/saa7134-ts.c index 03488ba4c99c..b9817d74943f 100644 --- a/drivers/media/video/saa7134/saa7134-ts.c +++ b/drivers/media/video/saa7134/saa7134-ts.c | |||
@@ -250,6 +250,19 @@ int saa7134_ts_start(struct saa7134_dev *dev) | |||
250 | 250 | ||
251 | BUG_ON(dev->ts_started); | 251 | BUG_ON(dev->ts_started); |
252 | 252 | ||
253 | /* dma: setup channel 5 (= TS) */ | ||
254 | saa_writeb(SAA7134_TS_DMA0, (dev->ts.nr_packets - 1) & 0xff); | ||
255 | saa_writeb(SAA7134_TS_DMA1, | ||
256 | ((dev->ts.nr_packets - 1) >> 8) & 0xff); | ||
257 | /* TSNOPIT=0, TSCOLAP=0 */ | ||
258 | saa_writeb(SAA7134_TS_DMA2, | ||
259 | (((dev->ts.nr_packets - 1) >> 16) & 0x3f) | 0x00); | ||
260 | saa_writel(SAA7134_RS_PITCH(5), TS_PACKET_SIZE); | ||
261 | saa_writel(SAA7134_RS_CONTROL(5), SAA7134_RS_CONTROL_BURST_16 | | ||
262 | SAA7134_RS_CONTROL_ME | | ||
263 | (dev->ts.pt_ts.dma >> 12)); | ||
264 | |||
265 | /* reset hardware TS buffers */ | ||
253 | saa_writeb(SAA7134_TS_SERIAL1, 0x00); | 266 | saa_writeb(SAA7134_TS_SERIAL1, 0x00); |
254 | saa_writeb(SAA7134_TS_SERIAL1, 0x03); | 267 | saa_writeb(SAA7134_TS_SERIAL1, 0x03); |
255 | saa_writeb(SAA7134_TS_SERIAL1, 0x00); | 268 | saa_writeb(SAA7134_TS_SERIAL1, 0x00); |
diff --git a/drivers/media/video/sh_mobile_ceu_camera.c b/drivers/media/video/sh_mobile_ceu_camera.c index d69363f0d8c9..f09c7140d6b2 100644 --- a/drivers/media/video/sh_mobile_ceu_camera.c +++ b/drivers/media/video/sh_mobile_ceu_camera.c | |||
@@ -1827,7 +1827,7 @@ static int __devinit sh_mobile_ceu_probe(struct platform_device *pdev) | |||
1827 | 1827 | ||
1828 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 1828 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
1829 | irq = platform_get_irq(pdev, 0); | 1829 | irq = platform_get_irq(pdev, 0); |
1830 | if (!res || !irq) { | 1830 | if (!res || (int)irq <= 0) { |
1831 | dev_err(&pdev->dev, "Not enough CEU platform resources.\n"); | 1831 | dev_err(&pdev->dev, "Not enough CEU platform resources.\n"); |
1832 | err = -ENODEV; | 1832 | err = -ENODEV; |
1833 | goto exit; | 1833 | goto exit; |
diff --git a/drivers/media/video/uvc/uvc_ctrl.c b/drivers/media/video/uvc/uvc_ctrl.c index 0469d7a876a8..ec8ef8c5560a 100644 --- a/drivers/media/video/uvc/uvc_ctrl.c +++ b/drivers/media/video/uvc/uvc_ctrl.c | |||
@@ -1393,7 +1393,7 @@ uvc_ctrl_prune_entity(struct uvc_device *dev, struct uvc_entity *entity) | |||
1393 | size = entity->processing.bControlSize; | 1393 | size = entity->processing.bControlSize; |
1394 | 1394 | ||
1395 | for (i = 0; i < ARRAY_SIZE(blacklist); ++i) { | 1395 | for (i = 0; i < ARRAY_SIZE(blacklist); ++i) { |
1396 | if (!usb_match_id(dev->intf, &blacklist[i].id)) | 1396 | if (!usb_match_one_id(dev->intf, &blacklist[i].id)) |
1397 | continue; | 1397 | continue; |
1398 | 1398 | ||
1399 | if (blacklist[i].index >= 8 * size || | 1399 | if (blacklist[i].index >= 8 * size || |
diff --git a/drivers/media/video/uvc/uvc_queue.c b/drivers/media/video/uvc/uvc_queue.c index f854698c4061..ea11839cba4a 100644 --- a/drivers/media/video/uvc/uvc_queue.c +++ b/drivers/media/video/uvc/uvc_queue.c | |||
@@ -59,9 +59,9 @@ | |||
59 | * returns immediately. | 59 | * returns immediately. |
60 | * | 60 | * |
61 | * When the buffer is full, the completion handler removes it from the irq | 61 | * When the buffer is full, the completion handler removes it from the irq |
62 | * queue, marks it as ready (UVC_BUF_STATE_DONE) and wakes its wait queue. | 62 | * queue, marks it as done (UVC_BUF_STATE_DONE) and wakes its wait queue. |
63 | * At that point, any process waiting on the buffer will be woken up. If a | 63 | * At that point, any process waiting on the buffer will be woken up. If a |
64 | * process tries to dequeue a buffer after it has been marked ready, the | 64 | * process tries to dequeue a buffer after it has been marked done, the |
65 | * dequeing will succeed immediately. | 65 | * dequeing will succeed immediately. |
66 | * | 66 | * |
67 | * 2. Buffers are queued, user is waiting on a buffer and the device gets | 67 | * 2. Buffers are queued, user is waiting on a buffer and the device gets |
@@ -201,6 +201,7 @@ static void __uvc_query_buffer(struct uvc_buffer *buf, | |||
201 | break; | 201 | break; |
202 | case UVC_BUF_STATE_QUEUED: | 202 | case UVC_BUF_STATE_QUEUED: |
203 | case UVC_BUF_STATE_ACTIVE: | 203 | case UVC_BUF_STATE_ACTIVE: |
204 | case UVC_BUF_STATE_READY: | ||
204 | v4l2_buf->flags |= V4L2_BUF_FLAG_QUEUED; | 205 | v4l2_buf->flags |= V4L2_BUF_FLAG_QUEUED; |
205 | break; | 206 | break; |
206 | case UVC_BUF_STATE_IDLE: | 207 | case UVC_BUF_STATE_IDLE: |
@@ -295,13 +296,15 @@ static int uvc_queue_waiton(struct uvc_buffer *buf, int nonblocking) | |||
295 | { | 296 | { |
296 | if (nonblocking) { | 297 | if (nonblocking) { |
297 | return (buf->state != UVC_BUF_STATE_QUEUED && | 298 | return (buf->state != UVC_BUF_STATE_QUEUED && |
298 | buf->state != UVC_BUF_STATE_ACTIVE) | 299 | buf->state != UVC_BUF_STATE_ACTIVE && |
300 | buf->state != UVC_BUF_STATE_READY) | ||
299 | ? 0 : -EAGAIN; | 301 | ? 0 : -EAGAIN; |
300 | } | 302 | } |
301 | 303 | ||
302 | return wait_event_interruptible(buf->wait, | 304 | return wait_event_interruptible(buf->wait, |
303 | buf->state != UVC_BUF_STATE_QUEUED && | 305 | buf->state != UVC_BUF_STATE_QUEUED && |
304 | buf->state != UVC_BUF_STATE_ACTIVE); | 306 | buf->state != UVC_BUF_STATE_ACTIVE && |
307 | buf->state != UVC_BUF_STATE_READY); | ||
305 | } | 308 | } |
306 | 309 | ||
307 | /* | 310 | /* |
@@ -348,6 +351,7 @@ int uvc_dequeue_buffer(struct uvc_video_queue *queue, | |||
348 | case UVC_BUF_STATE_IDLE: | 351 | case UVC_BUF_STATE_IDLE: |
349 | case UVC_BUF_STATE_QUEUED: | 352 | case UVC_BUF_STATE_QUEUED: |
350 | case UVC_BUF_STATE_ACTIVE: | 353 | case UVC_BUF_STATE_ACTIVE: |
354 | case UVC_BUF_STATE_READY: | ||
351 | default: | 355 | default: |
352 | uvc_trace(UVC_TRACE_CAPTURE, "[E] Invalid buffer state %u " | 356 | uvc_trace(UVC_TRACE_CAPTURE, "[E] Invalid buffer state %u " |
353 | "(driver bug?).\n", buf->state); | 357 | "(driver bug?).\n", buf->state); |
@@ -489,6 +493,7 @@ struct uvc_buffer *uvc_queue_next_buffer(struct uvc_video_queue *queue, | |||
489 | 493 | ||
490 | spin_lock_irqsave(&queue->irqlock, flags); | 494 | spin_lock_irqsave(&queue->irqlock, flags); |
491 | list_del(&buf->queue); | 495 | list_del(&buf->queue); |
496 | buf->state = UVC_BUF_STATE_DONE; | ||
492 | if (!list_empty(&queue->irqqueue)) | 497 | if (!list_empty(&queue->irqqueue)) |
493 | nextbuf = list_first_entry(&queue->irqqueue, struct uvc_buffer, | 498 | nextbuf = list_first_entry(&queue->irqqueue, struct uvc_buffer, |
494 | queue); | 499 | queue); |
diff --git a/drivers/media/video/uvc/uvc_video.c b/drivers/media/video/uvc/uvc_video.c index 9a9802830d41..7dcf534a0cf3 100644 --- a/drivers/media/video/uvc/uvc_video.c +++ b/drivers/media/video/uvc/uvc_video.c | |||
@@ -441,7 +441,7 @@ static int uvc_video_decode_start(struct uvc_streaming *stream, | |||
441 | if (fid != stream->last_fid && buf->buf.bytesused != 0) { | 441 | if (fid != stream->last_fid && buf->buf.bytesused != 0) { |
442 | uvc_trace(UVC_TRACE_FRAME, "Frame complete (FID bit " | 442 | uvc_trace(UVC_TRACE_FRAME, "Frame complete (FID bit " |
443 | "toggled).\n"); | 443 | "toggled).\n"); |
444 | buf->state = UVC_BUF_STATE_DONE; | 444 | buf->state = UVC_BUF_STATE_READY; |
445 | return -EAGAIN; | 445 | return -EAGAIN; |
446 | } | 446 | } |
447 | 447 | ||
@@ -470,7 +470,7 @@ static void uvc_video_decode_data(struct uvc_streaming *stream, | |||
470 | /* Complete the current frame if the buffer size was exceeded. */ | 470 | /* Complete the current frame if the buffer size was exceeded. */ |
471 | if (len > maxlen) { | 471 | if (len > maxlen) { |
472 | uvc_trace(UVC_TRACE_FRAME, "Frame complete (overflow).\n"); | 472 | uvc_trace(UVC_TRACE_FRAME, "Frame complete (overflow).\n"); |
473 | buf->state = UVC_BUF_STATE_DONE; | 473 | buf->state = UVC_BUF_STATE_READY; |
474 | } | 474 | } |
475 | } | 475 | } |
476 | 476 | ||
@@ -482,7 +482,7 @@ static void uvc_video_decode_end(struct uvc_streaming *stream, | |||
482 | uvc_trace(UVC_TRACE_FRAME, "Frame complete (EOF found).\n"); | 482 | uvc_trace(UVC_TRACE_FRAME, "Frame complete (EOF found).\n"); |
483 | if (data[0] == len) | 483 | if (data[0] == len) |
484 | uvc_trace(UVC_TRACE_FRAME, "EOF in empty payload.\n"); | 484 | uvc_trace(UVC_TRACE_FRAME, "EOF in empty payload.\n"); |
485 | buf->state = UVC_BUF_STATE_DONE; | 485 | buf->state = UVC_BUF_STATE_READY; |
486 | if (stream->dev->quirks & UVC_QUIRK_STREAM_NO_FID) | 486 | if (stream->dev->quirks & UVC_QUIRK_STREAM_NO_FID) |
487 | stream->last_fid ^= UVC_STREAM_FID; | 487 | stream->last_fid ^= UVC_STREAM_FID; |
488 | } | 488 | } |
@@ -568,8 +568,7 @@ static void uvc_video_decode_isoc(struct urb *urb, struct uvc_streaming *stream, | |||
568 | uvc_video_decode_end(stream, buf, mem, | 568 | uvc_video_decode_end(stream, buf, mem, |
569 | urb->iso_frame_desc[i].actual_length); | 569 | urb->iso_frame_desc[i].actual_length); |
570 | 570 | ||
571 | if (buf->state == UVC_BUF_STATE_DONE || | 571 | if (buf->state == UVC_BUF_STATE_READY) |
572 | buf->state == UVC_BUF_STATE_ERROR) | ||
573 | buf = uvc_queue_next_buffer(&stream->queue, buf); | 572 | buf = uvc_queue_next_buffer(&stream->queue, buf); |
574 | } | 573 | } |
575 | } | 574 | } |
@@ -627,8 +626,7 @@ static void uvc_video_decode_bulk(struct urb *urb, struct uvc_streaming *stream, | |||
627 | if (!stream->bulk.skip_payload && buf != NULL) { | 626 | if (!stream->bulk.skip_payload && buf != NULL) { |
628 | uvc_video_decode_end(stream, buf, stream->bulk.header, | 627 | uvc_video_decode_end(stream, buf, stream->bulk.header, |
629 | stream->bulk.payload_size); | 628 | stream->bulk.payload_size); |
630 | if (buf->state == UVC_BUF_STATE_DONE || | 629 | if (buf->state == UVC_BUF_STATE_READY) |
631 | buf->state == UVC_BUF_STATE_ERROR) | ||
632 | buf = uvc_queue_next_buffer(&stream->queue, | 630 | buf = uvc_queue_next_buffer(&stream->queue, |
633 | buf); | 631 | buf); |
634 | } | 632 | } |
@@ -669,7 +667,7 @@ static void uvc_video_encode_bulk(struct urb *urb, struct uvc_streaming *stream, | |||
669 | stream->bulk.payload_size == stream->bulk.max_payload_size) { | 667 | stream->bulk.payload_size == stream->bulk.max_payload_size) { |
670 | if (buf->buf.bytesused == stream->queue.buf_used) { | 668 | if (buf->buf.bytesused == stream->queue.buf_used) { |
671 | stream->queue.buf_used = 0; | 669 | stream->queue.buf_used = 0; |
672 | buf->state = UVC_BUF_STATE_DONE; | 670 | buf->state = UVC_BUF_STATE_READY; |
673 | uvc_queue_next_buffer(&stream->queue, buf); | 671 | uvc_queue_next_buffer(&stream->queue, buf); |
674 | stream->last_fid ^= UVC_STREAM_FID; | 672 | stream->last_fid ^= UVC_STREAM_FID; |
675 | } | 673 | } |
@@ -924,10 +922,8 @@ static int uvc_init_video_bulk(struct uvc_streaming *stream, | |||
924 | static int uvc_init_video(struct uvc_streaming *stream, gfp_t gfp_flags) | 922 | static int uvc_init_video(struct uvc_streaming *stream, gfp_t gfp_flags) |
925 | { | 923 | { |
926 | struct usb_interface *intf = stream->intf; | 924 | struct usb_interface *intf = stream->intf; |
927 | struct usb_host_interface *alts; | 925 | struct usb_host_endpoint *ep; |
928 | struct usb_host_endpoint *ep = NULL; | 926 | unsigned int i; |
929 | int intfnum = stream->intfnum; | ||
930 | unsigned int bandwidth, psize, i; | ||
931 | int ret; | 927 | int ret; |
932 | 928 | ||
933 | stream->last_fid = -1; | 929 | stream->last_fid = -1; |
@@ -936,6 +932,12 @@ static int uvc_init_video(struct uvc_streaming *stream, gfp_t gfp_flags) | |||
936 | stream->bulk.payload_size = 0; | 932 | stream->bulk.payload_size = 0; |
937 | 933 | ||
938 | if (intf->num_altsetting > 1) { | 934 | if (intf->num_altsetting > 1) { |
935 | struct usb_host_endpoint *best_ep = NULL; | ||
936 | unsigned int best_psize = 3 * 1024; | ||
937 | unsigned int bandwidth; | ||
938 | unsigned int uninitialized_var(altsetting); | ||
939 | int intfnum = stream->intfnum; | ||
940 | |||
939 | /* Isochronous endpoint, select the alternate setting. */ | 941 | /* Isochronous endpoint, select the alternate setting. */ |
940 | bandwidth = stream->ctrl.dwMaxPayloadTransferSize; | 942 | bandwidth = stream->ctrl.dwMaxPayloadTransferSize; |
941 | 943 | ||
@@ -949,6 +951,9 @@ static int uvc_init_video(struct uvc_streaming *stream, gfp_t gfp_flags) | |||
949 | } | 951 | } |
950 | 952 | ||
951 | for (i = 0; i < intf->num_altsetting; ++i) { | 953 | for (i = 0; i < intf->num_altsetting; ++i) { |
954 | struct usb_host_interface *alts; | ||
955 | unsigned int psize; | ||
956 | |||
952 | alts = &intf->altsetting[i]; | 957 | alts = &intf->altsetting[i]; |
953 | ep = uvc_find_endpoint(alts, | 958 | ep = uvc_find_endpoint(alts, |
954 | stream->header.bEndpointAddress); | 959 | stream->header.bEndpointAddress); |
@@ -958,21 +963,27 @@ static int uvc_init_video(struct uvc_streaming *stream, gfp_t gfp_flags) | |||
958 | /* Check if the bandwidth is high enough. */ | 963 | /* Check if the bandwidth is high enough. */ |
959 | psize = le16_to_cpu(ep->desc.wMaxPacketSize); | 964 | psize = le16_to_cpu(ep->desc.wMaxPacketSize); |
960 | psize = (psize & 0x07ff) * (1 + ((psize >> 11) & 3)); | 965 | psize = (psize & 0x07ff) * (1 + ((psize >> 11) & 3)); |
961 | if (psize >= bandwidth) | 966 | if (psize >= bandwidth && psize <= best_psize) { |
962 | break; | 967 | altsetting = i; |
968 | best_psize = psize; | ||
969 | best_ep = ep; | ||
970 | } | ||
963 | } | 971 | } |
964 | 972 | ||
965 | if (i >= intf->num_altsetting) { | 973 | if (best_ep == NULL) { |
966 | uvc_trace(UVC_TRACE_VIDEO, "No fast enough alt setting " | 974 | uvc_trace(UVC_TRACE_VIDEO, "No fast enough alt setting " |
967 | "for requested bandwidth.\n"); | 975 | "for requested bandwidth.\n"); |
968 | return -EIO; | 976 | return -EIO; |
969 | } | 977 | } |
970 | 978 | ||
971 | ret = usb_set_interface(stream->dev->udev, intfnum, i); | 979 | uvc_trace(UVC_TRACE_VIDEO, "Selecting alternate setting %u " |
980 | "(%u B/frame bandwidth).\n", altsetting, best_psize); | ||
981 | |||
982 | ret = usb_set_interface(stream->dev->udev, intfnum, altsetting); | ||
972 | if (ret < 0) | 983 | if (ret < 0) |
973 | return ret; | 984 | return ret; |
974 | 985 | ||
975 | ret = uvc_init_video_isoc(stream, ep, gfp_flags); | 986 | ret = uvc_init_video_isoc(stream, best_ep, gfp_flags); |
976 | } else { | 987 | } else { |
977 | /* Bulk endpoint, proceed to URB initialization. */ | 988 | /* Bulk endpoint, proceed to URB initialization. */ |
978 | ep = uvc_find_endpoint(&intf->altsetting[0], | 989 | ep = uvc_find_endpoint(&intf->altsetting[0], |
diff --git a/drivers/media/video/uvc/uvcvideo.h b/drivers/media/video/uvc/uvcvideo.h index 7ec9a04ced50..2337585001ea 100644 --- a/drivers/media/video/uvc/uvcvideo.h +++ b/drivers/media/video/uvc/uvcvideo.h | |||
@@ -365,8 +365,9 @@ enum uvc_buffer_state { | |||
365 | UVC_BUF_STATE_IDLE = 0, | 365 | UVC_BUF_STATE_IDLE = 0, |
366 | UVC_BUF_STATE_QUEUED = 1, | 366 | UVC_BUF_STATE_QUEUED = 1, |
367 | UVC_BUF_STATE_ACTIVE = 2, | 367 | UVC_BUF_STATE_ACTIVE = 2, |
368 | UVC_BUF_STATE_DONE = 3, | 368 | UVC_BUF_STATE_READY = 3, |
369 | UVC_BUF_STATE_ERROR = 4, | 369 | UVC_BUF_STATE_DONE = 4, |
370 | UVC_BUF_STATE_ERROR = 5, | ||
370 | }; | 371 | }; |
371 | 372 | ||
372 | struct uvc_buffer { | 373 | struct uvc_buffer { |
diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile index ca2f2c4ff05e..8f0d18409ede 100644 --- a/drivers/mfd/Makefile +++ b/drivers/mfd/Makefile | |||
@@ -11,9 +11,9 @@ obj-$(CONFIG_HTC_PASIC3) += htc-pasic3.o | |||
11 | 11 | ||
12 | obj-$(CONFIG_MFD_DM355EVM_MSP) += dm355evm_msp.o | 12 | obj-$(CONFIG_MFD_DM355EVM_MSP) += dm355evm_msp.o |
13 | 13 | ||
14 | obj-$(CONFIG_MFD_T7L66XB) += t7l66xb.o | 14 | obj-$(CONFIG_MFD_T7L66XB) += t7l66xb.o tmio_core.o |
15 | obj-$(CONFIG_MFD_TC6387XB) += tc6387xb.o | 15 | obj-$(CONFIG_MFD_TC6387XB) += tc6387xb.o tmio_core.o |
16 | obj-$(CONFIG_MFD_TC6393XB) += tc6393xb.o | 16 | obj-$(CONFIG_MFD_TC6393XB) += tc6393xb.o tmio_core.o |
17 | 17 | ||
18 | obj-$(CONFIG_MFD_WM8400) += wm8400-core.o | 18 | obj-$(CONFIG_MFD_WM8400) += wm8400-core.o |
19 | wm831x-objs := wm831x-core.o wm831x-irq.o wm831x-otp.o | 19 | wm831x-objs := wm831x-core.o wm831x-irq.o wm831x-otp.o |
diff --git a/drivers/mfd/asic3.c b/drivers/mfd/asic3.c index e22128c3e9a8..95c1e6bd1729 100644 --- a/drivers/mfd/asic3.c +++ b/drivers/mfd/asic3.c | |||
@@ -80,6 +80,7 @@ struct asic3 { | |||
80 | u16 irq_bothedge[4]; | 80 | u16 irq_bothedge[4]; |
81 | struct gpio_chip gpio; | 81 | struct gpio_chip gpio; |
82 | struct device *dev; | 82 | struct device *dev; |
83 | void __iomem *tmio_cnf; | ||
83 | 84 | ||
84 | struct asic3_clk clocks[ARRAY_SIZE(asic3_clk_init)]; | 85 | struct asic3_clk clocks[ARRAY_SIZE(asic3_clk_init)]; |
85 | }; | 86 | }; |
@@ -685,8 +686,24 @@ static struct mfd_cell asic3_cell_ds1wm = { | |||
685 | .resources = ds1wm_resources, | 686 | .resources = ds1wm_resources, |
686 | }; | 687 | }; |
687 | 688 | ||
689 | static void asic3_mmc_pwr(struct platform_device *pdev, int state) | ||
690 | { | ||
691 | struct asic3 *asic = dev_get_drvdata(pdev->dev.parent); | ||
692 | |||
693 | tmio_core_mmc_pwr(asic->tmio_cnf, 1 - asic->bus_shift, state); | ||
694 | } | ||
695 | |||
696 | static void asic3_mmc_clk_div(struct platform_device *pdev, int state) | ||
697 | { | ||
698 | struct asic3 *asic = dev_get_drvdata(pdev->dev.parent); | ||
699 | |||
700 | tmio_core_mmc_clk_div(asic->tmio_cnf, 1 - asic->bus_shift, state); | ||
701 | } | ||
702 | |||
688 | static struct tmio_mmc_data asic3_mmc_data = { | 703 | static struct tmio_mmc_data asic3_mmc_data = { |
689 | .hclk = 24576000, | 704 | .hclk = 24576000, |
705 | .set_pwr = asic3_mmc_pwr, | ||
706 | .set_clk_div = asic3_mmc_clk_div, | ||
690 | }; | 707 | }; |
691 | 708 | ||
692 | static struct resource asic3_mmc_resources[] = { | 709 | static struct resource asic3_mmc_resources[] = { |
@@ -696,11 +713,6 @@ static struct resource asic3_mmc_resources[] = { | |||
696 | .flags = IORESOURCE_MEM, | 713 | .flags = IORESOURCE_MEM, |
697 | }, | 714 | }, |
698 | { | 715 | { |
699 | .start = ASIC3_SD_CONFIG_BASE, | ||
700 | .end = ASIC3_SD_CONFIG_BASE + 0x1ff, | ||
701 | .flags = IORESOURCE_MEM, | ||
702 | }, | ||
703 | { | ||
704 | .start = 0, | 716 | .start = 0, |
705 | .end = 0, | 717 | .end = 0, |
706 | .flags = IORESOURCE_IRQ, | 718 | .flags = IORESOURCE_IRQ, |
@@ -743,6 +755,10 @@ static int asic3_mmc_enable(struct platform_device *pdev) | |||
743 | asic3_set_register(asic, ASIC3_OFFSET(SDHWCTRL, SDCONF), | 755 | asic3_set_register(asic, ASIC3_OFFSET(SDHWCTRL, SDCONF), |
744 | ASIC3_SDHWCTRL_SDPWR, 1); | 756 | ASIC3_SDHWCTRL_SDPWR, 1); |
745 | 757 | ||
758 | /* ASIC3_SD_CTRL_BASE assumes 32-bit addressing, TMIO is 16-bit */ | ||
759 | tmio_core_mmc_enable(asic->tmio_cnf, 1 - asic->bus_shift, | ||
760 | ASIC3_SD_CTRL_BASE >> 1); | ||
761 | |||
746 | return 0; | 762 | return 0; |
747 | } | 763 | } |
748 | 764 | ||
@@ -797,10 +813,15 @@ static int __init asic3_mfd_probe(struct platform_device *pdev, | |||
797 | asic3_cell_ds1wm.data_size = sizeof(asic3_cell_ds1wm); | 813 | asic3_cell_ds1wm.data_size = sizeof(asic3_cell_ds1wm); |
798 | 814 | ||
799 | /* MMC */ | 815 | /* MMC */ |
816 | asic->tmio_cnf = ioremap((ASIC3_SD_CONFIG_BASE >> asic->bus_shift) + | ||
817 | mem_sdio->start, 0x400 >> asic->bus_shift); | ||
818 | if (!asic->tmio_cnf) { | ||
819 | ret = -ENOMEM; | ||
820 | dev_dbg(asic->dev, "Couldn't ioremap SD_CONFIG\n"); | ||
821 | goto out; | ||
822 | } | ||
800 | asic3_mmc_resources[0].start >>= asic->bus_shift; | 823 | asic3_mmc_resources[0].start >>= asic->bus_shift; |
801 | asic3_mmc_resources[0].end >>= asic->bus_shift; | 824 | asic3_mmc_resources[0].end >>= asic->bus_shift; |
802 | asic3_mmc_resources[1].start >>= asic->bus_shift; | ||
803 | asic3_mmc_resources[1].end >>= asic->bus_shift; | ||
804 | 825 | ||
805 | asic3_cell_mmc.platform_data = &asic3_cell_mmc; | 826 | asic3_cell_mmc.platform_data = &asic3_cell_mmc; |
806 | asic3_cell_mmc.data_size = sizeof(asic3_cell_mmc); | 827 | asic3_cell_mmc.data_size = sizeof(asic3_cell_mmc); |
@@ -820,7 +841,10 @@ static int __init asic3_mfd_probe(struct platform_device *pdev, | |||
820 | 841 | ||
821 | static void asic3_mfd_remove(struct platform_device *pdev) | 842 | static void asic3_mfd_remove(struct platform_device *pdev) |
822 | { | 843 | { |
844 | struct asic3 *asic = platform_get_drvdata(pdev); | ||
845 | |||
823 | mfd_remove_devices(&pdev->dev); | 846 | mfd_remove_devices(&pdev->dev); |
847 | iounmap(asic->tmio_cnf); | ||
824 | } | 848 | } |
825 | 849 | ||
826 | /* Core */ | 850 | /* Core */ |
diff --git a/drivers/mfd/mc13783-core.c b/drivers/mfd/mc13783-core.c index a1ade2324ea9..735c8a4d164f 100644 --- a/drivers/mfd/mc13783-core.c +++ b/drivers/mfd/mc13783-core.c | |||
@@ -619,6 +619,8 @@ err_revision: | |||
619 | } | 619 | } |
620 | /* This should go away (END) */ | 620 | /* This should go away (END) */ |
621 | 621 | ||
622 | mc13783_unlock(mc13783); | ||
623 | |||
622 | if (pdata->flags & MC13783_USE_ADC) | 624 | if (pdata->flags & MC13783_USE_ADC) |
623 | mc13783_add_subdevice(mc13783, "mc13783-adc"); | 625 | mc13783_add_subdevice(mc13783, "mc13783-adc"); |
624 | 626 | ||
@@ -641,8 +643,6 @@ err_revision: | |||
641 | if (pdata->flags & MC13783_USE_TOUCHSCREEN) | 643 | if (pdata->flags & MC13783_USE_TOUCHSCREEN) |
642 | mc13783_add_subdevice(mc13783, "mc13783-ts"); | 644 | mc13783_add_subdevice(mc13783, "mc13783-ts"); |
643 | 645 | ||
644 | mc13783_unlock(mc13783); | ||
645 | |||
646 | return 0; | 646 | return 0; |
647 | } | 647 | } |
648 | 648 | ||
diff --git a/drivers/mfd/t7l66xb.c b/drivers/mfd/t7l66xb.c index 0a255c1f1ce7..bcf4687d4af5 100644 --- a/drivers/mfd/t7l66xb.c +++ b/drivers/mfd/t7l66xb.c | |||
@@ -38,6 +38,19 @@ enum { | |||
38 | T7L66XB_CELL_MMC, | 38 | T7L66XB_CELL_MMC, |
39 | }; | 39 | }; |
40 | 40 | ||
41 | static const struct resource t7l66xb_mmc_resources[] = { | ||
42 | { | ||
43 | .start = 0x800, | ||
44 | .end = 0x9ff, | ||
45 | .flags = IORESOURCE_MEM, | ||
46 | }, | ||
47 | { | ||
48 | .start = IRQ_T7L66XB_MMC, | ||
49 | .end = IRQ_T7L66XB_MMC, | ||
50 | .flags = IORESOURCE_IRQ, | ||
51 | }, | ||
52 | }; | ||
53 | |||
41 | #define SCR_REVID 0x08 /* b Revision ID */ | 54 | #define SCR_REVID 0x08 /* b Revision ID */ |
42 | #define SCR_IMR 0x42 /* b Interrupt Mask */ | 55 | #define SCR_IMR 0x42 /* b Interrupt Mask */ |
43 | #define SCR_DEV_CTL 0xe0 /* b Device control */ | 56 | #define SCR_DEV_CTL 0xe0 /* b Device control */ |
@@ -83,6 +96,9 @@ static int t7l66xb_mmc_enable(struct platform_device *mmc) | |||
83 | 96 | ||
84 | spin_unlock_irqrestore(&t7l66xb->lock, flags); | 97 | spin_unlock_irqrestore(&t7l66xb->lock, flags); |
85 | 98 | ||
99 | tmio_core_mmc_enable(t7l66xb->scr + 0x200, 0, | ||
100 | t7l66xb_mmc_resources[0].start & 0xfffe); | ||
101 | |||
86 | return 0; | 102 | return 0; |
87 | } | 103 | } |
88 | 104 | ||
@@ -106,28 +122,28 @@ static int t7l66xb_mmc_disable(struct platform_device *mmc) | |||
106 | return 0; | 122 | return 0; |
107 | } | 123 | } |
108 | 124 | ||
125 | static void t7l66xb_mmc_pwr(struct platform_device *mmc, int state) | ||
126 | { | ||
127 | struct platform_device *dev = to_platform_device(mmc->dev.parent); | ||
128 | struct t7l66xb *t7l66xb = platform_get_drvdata(dev); | ||
129 | |||
130 | tmio_core_mmc_pwr(t7l66xb->scr + 0x200, 0, state); | ||
131 | } | ||
132 | |||
133 | static void t7l66xb_mmc_clk_div(struct platform_device *mmc, int state) | ||
134 | { | ||
135 | struct platform_device *dev = to_platform_device(mmc->dev.parent); | ||
136 | struct t7l66xb *t7l66xb = platform_get_drvdata(dev); | ||
137 | |||
138 | tmio_core_mmc_clk_div(t7l66xb->scr + 0x200, 0, state); | ||
139 | } | ||
140 | |||
109 | /*--------------------------------------------------------------------------*/ | 141 | /*--------------------------------------------------------------------------*/ |
110 | 142 | ||
111 | static struct tmio_mmc_data t7166xb_mmc_data = { | 143 | static struct tmio_mmc_data t7166xb_mmc_data = { |
112 | .hclk = 24000000, | 144 | .hclk = 24000000, |
113 | }; | 145 | .set_pwr = t7l66xb_mmc_pwr, |
114 | 146 | .set_clk_div = t7l66xb_mmc_clk_div, | |
115 | static const struct resource t7l66xb_mmc_resources[] = { | ||
116 | { | ||
117 | .start = 0x800, | ||
118 | .end = 0x9ff, | ||
119 | .flags = IORESOURCE_MEM, | ||
120 | }, | ||
121 | { | ||
122 | .start = 0x200, | ||
123 | .end = 0x2ff, | ||
124 | .flags = IORESOURCE_MEM, | ||
125 | }, | ||
126 | { | ||
127 | .start = IRQ_T7L66XB_MMC, | ||
128 | .end = IRQ_T7L66XB_MMC, | ||
129 | .flags = IORESOURCE_IRQ, | ||
130 | }, | ||
131 | }; | 147 | }; |
132 | 148 | ||
133 | static const struct resource t7l66xb_nand_resources[] = { | 149 | static const struct resource t7l66xb_nand_resources[] = { |
@@ -282,6 +298,9 @@ static int t7l66xb_resume(struct platform_device *dev) | |||
282 | if (pdata && pdata->resume) | 298 | if (pdata && pdata->resume) |
283 | pdata->resume(dev); | 299 | pdata->resume(dev); |
284 | 300 | ||
301 | tmio_core_mmc_enable(t7l66xb->scr + 0x200, 0, | ||
302 | t7l66xb_mmc_resources[0].start & 0xfffe); | ||
303 | |||
285 | return 0; | 304 | return 0; |
286 | } | 305 | } |
287 | #else | 306 | #else |
diff --git a/drivers/mfd/tc6387xb.c b/drivers/mfd/tc6387xb.c index 3280ab33f88a..5c7f04343d5c 100644 --- a/drivers/mfd/tc6387xb.c +++ b/drivers/mfd/tc6387xb.c | |||
@@ -22,28 +22,52 @@ enum { | |||
22 | TC6387XB_CELL_MMC, | 22 | TC6387XB_CELL_MMC, |
23 | }; | 23 | }; |
24 | 24 | ||
25 | struct tc6387xb { | ||
26 | void __iomem *scr; | ||
27 | struct clk *clk32k; | ||
28 | struct resource rscr; | ||
29 | }; | ||
30 | |||
31 | static struct resource tc6387xb_mmc_resources[] = { | ||
32 | { | ||
33 | .start = 0x800, | ||
34 | .end = 0x9ff, | ||
35 | .flags = IORESOURCE_MEM, | ||
36 | }, | ||
37 | { | ||
38 | .start = 0, | ||
39 | .end = 0, | ||
40 | .flags = IORESOURCE_IRQ, | ||
41 | }, | ||
42 | }; | ||
43 | |||
44 | /*--------------------------------------------------------------------------*/ | ||
45 | |||
25 | #ifdef CONFIG_PM | 46 | #ifdef CONFIG_PM |
26 | static int tc6387xb_suspend(struct platform_device *dev, pm_message_t state) | 47 | static int tc6387xb_suspend(struct platform_device *dev, pm_message_t state) |
27 | { | 48 | { |
28 | struct clk *clk32k = platform_get_drvdata(dev); | 49 | struct tc6387xb *tc6387xb = platform_get_drvdata(dev); |
29 | struct tc6387xb_platform_data *pdata = dev->dev.platform_data; | 50 | struct tc6387xb_platform_data *pdata = dev->dev.platform_data; |
30 | 51 | ||
31 | if (pdata && pdata->suspend) | 52 | if (pdata && pdata->suspend) |
32 | pdata->suspend(dev); | 53 | pdata->suspend(dev); |
33 | clk_disable(clk32k); | 54 | clk_disable(tc6387xb->clk32k); |
34 | 55 | ||
35 | return 0; | 56 | return 0; |
36 | } | 57 | } |
37 | 58 | ||
38 | static int tc6387xb_resume(struct platform_device *dev) | 59 | static int tc6387xb_resume(struct platform_device *dev) |
39 | { | 60 | { |
40 | struct clk *clk32k = platform_get_drvdata(dev); | 61 | struct tc6387xb *tc6387xb = platform_get_drvdata(dev); |
41 | struct tc6387xb_platform_data *pdata = dev->dev.platform_data; | 62 | struct tc6387xb_platform_data *pdata = dev->dev.platform_data; |
42 | 63 | ||
43 | clk_enable(clk32k); | 64 | clk_enable(tc6387xb->clk32k); |
44 | if (pdata && pdata->resume) | 65 | if (pdata && pdata->resume) |
45 | pdata->resume(dev); | 66 | pdata->resume(dev); |
46 | 67 | ||
68 | tmio_core_mmc_resume(tc6387xb->scr + 0x200, 0, | ||
69 | tc6387xb_mmc_resources[0].start & 0xfffe); | ||
70 | |||
47 | return 0; | 71 | return 0; |
48 | } | 72 | } |
49 | #else | 73 | #else |
@@ -53,12 +77,32 @@ static int tc6387xb_resume(struct platform_device *dev) | |||
53 | 77 | ||
54 | /*--------------------------------------------------------------------------*/ | 78 | /*--------------------------------------------------------------------------*/ |
55 | 79 | ||
80 | static void tc6387xb_mmc_pwr(struct platform_device *mmc, int state) | ||
81 | { | ||
82 | struct platform_device *dev = to_platform_device(mmc->dev.parent); | ||
83 | struct tc6387xb *tc6387xb = platform_get_drvdata(dev); | ||
84 | |||
85 | tmio_core_mmc_pwr(tc6387xb->scr + 0x200, 0, state); | ||
86 | } | ||
87 | |||
88 | static void tc6387xb_mmc_clk_div(struct platform_device *mmc, int state) | ||
89 | { | ||
90 | struct platform_device *dev = to_platform_device(mmc->dev.parent); | ||
91 | struct tc6387xb *tc6387xb = platform_get_drvdata(dev); | ||
92 | |||
93 | tmio_core_mmc_clk_div(tc6387xb->scr + 0x200, 0, state); | ||
94 | } | ||
95 | |||
96 | |||
56 | static int tc6387xb_mmc_enable(struct platform_device *mmc) | 97 | static int tc6387xb_mmc_enable(struct platform_device *mmc) |
57 | { | 98 | { |
58 | struct platform_device *dev = to_platform_device(mmc->dev.parent); | 99 | struct platform_device *dev = to_platform_device(mmc->dev.parent); |
59 | struct clk *clk32k = platform_get_drvdata(dev); | 100 | struct tc6387xb *tc6387xb = platform_get_drvdata(dev); |
60 | 101 | ||
61 | clk_enable(clk32k); | 102 | clk_enable(tc6387xb->clk32k); |
103 | |||
104 | tmio_core_mmc_enable(tc6387xb->scr + 0x200, 0, | ||
105 | tc6387xb_mmc_resources[0].start & 0xfffe); | ||
62 | 106 | ||
63 | return 0; | 107 | return 0; |
64 | } | 108 | } |
@@ -66,36 +110,20 @@ static int tc6387xb_mmc_enable(struct platform_device *mmc) | |||
66 | static int tc6387xb_mmc_disable(struct platform_device *mmc) | 110 | static int tc6387xb_mmc_disable(struct platform_device *mmc) |
67 | { | 111 | { |
68 | struct platform_device *dev = to_platform_device(mmc->dev.parent); | 112 | struct platform_device *dev = to_platform_device(mmc->dev.parent); |
69 | struct clk *clk32k = platform_get_drvdata(dev); | 113 | struct tc6387xb *tc6387xb = platform_get_drvdata(dev); |
70 | 114 | ||
71 | clk_disable(clk32k); | 115 | clk_disable(tc6387xb->clk32k); |
72 | 116 | ||
73 | return 0; | 117 | return 0; |
74 | } | 118 | } |
75 | 119 | ||
76 | /*--------------------------------------------------------------------------*/ | ||
77 | |||
78 | static struct tmio_mmc_data tc6387xb_mmc_data = { | 120 | static struct tmio_mmc_data tc6387xb_mmc_data = { |
79 | .hclk = 24000000, | 121 | .hclk = 24000000, |
122 | .set_pwr = tc6387xb_mmc_pwr, | ||
123 | .set_clk_div = tc6387xb_mmc_clk_div, | ||
80 | }; | 124 | }; |
81 | 125 | ||
82 | static struct resource tc6387xb_mmc_resources[] = { | 126 | /*--------------------------------------------------------------------------*/ |
83 | { | ||
84 | .start = 0x800, | ||
85 | .end = 0x9ff, | ||
86 | .flags = IORESOURCE_MEM, | ||
87 | }, | ||
88 | { | ||
89 | .start = 0x200, | ||
90 | .end = 0x2ff, | ||
91 | .flags = IORESOURCE_MEM, | ||
92 | }, | ||
93 | { | ||
94 | .start = 0, | ||
95 | .end = 0, | ||
96 | .flags = IORESOURCE_IRQ, | ||
97 | }, | ||
98 | }; | ||
99 | 127 | ||
100 | static struct mfd_cell tc6387xb_cells[] = { | 128 | static struct mfd_cell tc6387xb_cells[] = { |
101 | [TC6387XB_CELL_MMC] = { | 129 | [TC6387XB_CELL_MMC] = { |
@@ -111,8 +139,9 @@ static struct mfd_cell tc6387xb_cells[] = { | |||
111 | static int tc6387xb_probe(struct platform_device *dev) | 139 | static int tc6387xb_probe(struct platform_device *dev) |
112 | { | 140 | { |
113 | struct tc6387xb_platform_data *pdata = dev->dev.platform_data; | 141 | struct tc6387xb_platform_data *pdata = dev->dev.platform_data; |
114 | struct resource *iomem; | 142 | struct resource *iomem, *rscr; |
115 | struct clk *clk32k; | 143 | struct clk *clk32k; |
144 | struct tc6387xb *tc6387xb; | ||
116 | int irq, ret; | 145 | int irq, ret; |
117 | 146 | ||
118 | iomem = platform_get_resource(dev, IORESOURCE_MEM, 0); | 147 | iomem = platform_get_resource(dev, IORESOURCE_MEM, 0); |
@@ -120,18 +149,40 @@ static int tc6387xb_probe(struct platform_device *dev) | |||
120 | return -EINVAL; | 149 | return -EINVAL; |
121 | } | 150 | } |
122 | 151 | ||
152 | tc6387xb = kzalloc(sizeof *tc6387xb, GFP_KERNEL); | ||
153 | if (!tc6387xb) | ||
154 | return -ENOMEM; | ||
155 | |||
123 | ret = platform_get_irq(dev, 0); | 156 | ret = platform_get_irq(dev, 0); |
124 | if (ret >= 0) | 157 | if (ret >= 0) |
125 | irq = ret; | 158 | irq = ret; |
126 | else | 159 | else |
127 | goto err_resource; | 160 | goto err_no_irq; |
128 | 161 | ||
129 | clk32k = clk_get(&dev->dev, "CLK_CK32K"); | 162 | clk32k = clk_get(&dev->dev, "CLK_CK32K"); |
130 | if (IS_ERR(clk32k)) { | 163 | if (IS_ERR(clk32k)) { |
131 | ret = PTR_ERR(clk32k); | 164 | ret = PTR_ERR(clk32k); |
165 | goto err_no_clk; | ||
166 | } | ||
167 | |||
168 | rscr = &tc6387xb->rscr; | ||
169 | rscr->name = "tc6387xb-core"; | ||
170 | rscr->start = iomem->start; | ||
171 | rscr->end = iomem->start + 0xff; | ||
172 | rscr->flags = IORESOURCE_MEM; | ||
173 | |||
174 | ret = request_resource(iomem, rscr); | ||
175 | if (ret) | ||
132 | goto err_resource; | 176 | goto err_resource; |
177 | |||
178 | tc6387xb->scr = ioremap(rscr->start, rscr->end - rscr->start + 1); | ||
179 | if (!tc6387xb->scr) { | ||
180 | ret = -ENOMEM; | ||
181 | goto err_ioremap; | ||
133 | } | 182 | } |
134 | platform_set_drvdata(dev, clk32k); | 183 | |
184 | tc6387xb->clk32k = clk32k; | ||
185 | platform_set_drvdata(dev, tc6387xb); | ||
135 | 186 | ||
136 | if (pdata && pdata->enable) | 187 | if (pdata && pdata->enable) |
137 | pdata->enable(dev); | 188 | pdata->enable(dev); |
@@ -149,8 +200,13 @@ static int tc6387xb_probe(struct platform_device *dev) | |||
149 | if (!ret) | 200 | if (!ret) |
150 | return 0; | 201 | return 0; |
151 | 202 | ||
152 | clk_put(clk32k); | 203 | err_ioremap: |
204 | release_resource(&tc6387xb->rscr); | ||
153 | err_resource: | 205 | err_resource: |
206 | clk_put(clk32k); | ||
207 | err_no_clk: | ||
208 | err_no_irq: | ||
209 | kfree(tc6387xb); | ||
154 | return ret; | 210 | return ret; |
155 | } | 211 | } |
156 | 212 | ||
@@ -195,3 +251,4 @@ MODULE_DESCRIPTION("Toshiba TC6387XB core driver"); | |||
195 | MODULE_LICENSE("GPL v2"); | 251 | MODULE_LICENSE("GPL v2"); |
196 | MODULE_AUTHOR("Ian Molton"); | 252 | MODULE_AUTHOR("Ian Molton"); |
197 | MODULE_ALIAS("platform:tc6387xb"); | 253 | MODULE_ALIAS("platform:tc6387xb"); |
254 | |||
diff --git a/drivers/mfd/tc6393xb.c b/drivers/mfd/tc6393xb.c index 1429a7341a9a..4bc5a08a2b09 100644 --- a/drivers/mfd/tc6393xb.c +++ b/drivers/mfd/tc6393xb.c | |||
@@ -136,10 +136,6 @@ static int tc6393xb_nand_enable(struct platform_device *nand) | |||
136 | return 0; | 136 | return 0; |
137 | } | 137 | } |
138 | 138 | ||
139 | static struct tmio_mmc_data tc6393xb_mmc_data = { | ||
140 | .hclk = 24000000, | ||
141 | }; | ||
142 | |||
143 | static struct resource __devinitdata tc6393xb_nand_resources[] = { | 139 | static struct resource __devinitdata tc6393xb_nand_resources[] = { |
144 | { | 140 | { |
145 | .start = 0x1000, | 141 | .start = 0x1000, |
@@ -165,11 +161,6 @@ static struct resource __devinitdata tc6393xb_mmc_resources[] = { | |||
165 | .flags = IORESOURCE_MEM, | 161 | .flags = IORESOURCE_MEM, |
166 | }, | 162 | }, |
167 | { | 163 | { |
168 | .start = 0x200, | ||
169 | .end = 0x2ff, | ||
170 | .flags = IORESOURCE_MEM, | ||
171 | }, | ||
172 | { | ||
173 | .start = IRQ_TC6393_MMC, | 164 | .start = IRQ_TC6393_MMC, |
174 | .end = IRQ_TC6393_MMC, | 165 | .end = IRQ_TC6393_MMC, |
175 | .flags = IORESOURCE_IRQ, | 166 | .flags = IORESOURCE_IRQ, |
@@ -346,6 +337,50 @@ int tc6393xb_lcd_mode(struct platform_device *fb, | |||
346 | } | 337 | } |
347 | EXPORT_SYMBOL(tc6393xb_lcd_mode); | 338 | EXPORT_SYMBOL(tc6393xb_lcd_mode); |
348 | 339 | ||
340 | static int tc6393xb_mmc_enable(struct platform_device *mmc) | ||
341 | { | ||
342 | struct platform_device *dev = to_platform_device(mmc->dev.parent); | ||
343 | struct tc6393xb *tc6393xb = platform_get_drvdata(dev); | ||
344 | |||
345 | tmio_core_mmc_enable(tc6393xb->scr + 0x200, 0, | ||
346 | tc6393xb_mmc_resources[0].start & 0xfffe); | ||
347 | |||
348 | return 0; | ||
349 | } | ||
350 | |||
351 | static int tc6393xb_mmc_resume(struct platform_device *mmc) | ||
352 | { | ||
353 | struct platform_device *dev = to_platform_device(mmc->dev.parent); | ||
354 | struct tc6393xb *tc6393xb = platform_get_drvdata(dev); | ||
355 | |||
356 | tmio_core_mmc_resume(tc6393xb->scr + 0x200, 0, | ||
357 | tc6393xb_mmc_resources[0].start & 0xfffe); | ||
358 | |||
359 | return 0; | ||
360 | } | ||
361 | |||
362 | static void tc6393xb_mmc_pwr(struct platform_device *mmc, int state) | ||
363 | { | ||
364 | struct platform_device *dev = to_platform_device(mmc->dev.parent); | ||
365 | struct tc6393xb *tc6393xb = platform_get_drvdata(dev); | ||
366 | |||
367 | tmio_core_mmc_pwr(tc6393xb->scr + 0x200, 0, state); | ||
368 | } | ||
369 | |||
370 | static void tc6393xb_mmc_clk_div(struct platform_device *mmc, int state) | ||
371 | { | ||
372 | struct platform_device *dev = to_platform_device(mmc->dev.parent); | ||
373 | struct tc6393xb *tc6393xb = platform_get_drvdata(dev); | ||
374 | |||
375 | tmio_core_mmc_clk_div(tc6393xb->scr + 0x200, 0, state); | ||
376 | } | ||
377 | |||
378 | static struct tmio_mmc_data tc6393xb_mmc_data = { | ||
379 | .hclk = 24000000, | ||
380 | .set_pwr = tc6393xb_mmc_pwr, | ||
381 | .set_clk_div = tc6393xb_mmc_clk_div, | ||
382 | }; | ||
383 | |||
349 | static struct mfd_cell __devinitdata tc6393xb_cells[] = { | 384 | static struct mfd_cell __devinitdata tc6393xb_cells[] = { |
350 | [TC6393XB_CELL_NAND] = { | 385 | [TC6393XB_CELL_NAND] = { |
351 | .name = "tmio-nand", | 386 | .name = "tmio-nand", |
@@ -355,6 +390,8 @@ static struct mfd_cell __devinitdata tc6393xb_cells[] = { | |||
355 | }, | 390 | }, |
356 | [TC6393XB_CELL_MMC] = { | 391 | [TC6393XB_CELL_MMC] = { |
357 | .name = "tmio-mmc", | 392 | .name = "tmio-mmc", |
393 | .enable = tc6393xb_mmc_enable, | ||
394 | .resume = tc6393xb_mmc_resume, | ||
358 | .driver_data = &tc6393xb_mmc_data, | 395 | .driver_data = &tc6393xb_mmc_data, |
359 | .num_resources = ARRAY_SIZE(tc6393xb_mmc_resources), | 396 | .num_resources = ARRAY_SIZE(tc6393xb_mmc_resources), |
360 | .resources = tc6393xb_mmc_resources, | 397 | .resources = tc6393xb_mmc_resources, |
@@ -836,3 +873,4 @@ MODULE_LICENSE("GPL v2"); | |||
836 | MODULE_AUTHOR("Ian Molton, Dmitry Baryshkov and Dirk Opfer"); | 873 | MODULE_AUTHOR("Ian Molton, Dmitry Baryshkov and Dirk Opfer"); |
837 | MODULE_DESCRIPTION("tc6393xb Toshiba Mobile IO Controller"); | 874 | MODULE_DESCRIPTION("tc6393xb Toshiba Mobile IO Controller"); |
838 | MODULE_ALIAS("platform:tc6393xb"); | 875 | MODULE_ALIAS("platform:tc6393xb"); |
876 | |||
diff --git a/drivers/mfd/tmio_core.c b/drivers/mfd/tmio_core.c new file mode 100644 index 000000000000..eddc19ae464b --- /dev/null +++ b/drivers/mfd/tmio_core.c | |||
@@ -0,0 +1,52 @@ | |||
1 | /* | ||
2 | * Copyright(c) 2009 Ian Molton <spyro@f2s.com> | ||
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 version 2 as | ||
6 | * published by the Free Software Foundation. | ||
7 | */ | ||
8 | |||
9 | #include <linux/mfd/tmio.h> | ||
10 | |||
11 | int tmio_core_mmc_enable(void __iomem *cnf, int shift, unsigned long base) | ||
12 | { | ||
13 | /* Enable the MMC/SD Control registers */ | ||
14 | sd_config_write16(cnf, shift, CNF_CMD, SDCREN); | ||
15 | sd_config_write32(cnf, shift, CNF_CTL_BASE, base & 0xfffe); | ||
16 | |||
17 | /* Disable SD power during suspend */ | ||
18 | sd_config_write8(cnf, shift, CNF_PWR_CTL_3, 0x01); | ||
19 | |||
20 | /* The below is required but why? FIXME */ | ||
21 | sd_config_write8(cnf, shift, CNF_STOP_CLK_CTL, 0x1f); | ||
22 | |||
23 | /* Power down SD bus */ | ||
24 | sd_config_write8(cnf, shift, CNF_PWR_CTL_2, 0x00); | ||
25 | |||
26 | return 0; | ||
27 | } | ||
28 | EXPORT_SYMBOL(tmio_core_mmc_enable); | ||
29 | |||
30 | int tmio_core_mmc_resume(void __iomem *cnf, int shift, unsigned long base) | ||
31 | { | ||
32 | |||
33 | /* Enable the MMC/SD Control registers */ | ||
34 | sd_config_write16(cnf, shift, CNF_CMD, SDCREN); | ||
35 | sd_config_write32(cnf, shift, CNF_CTL_BASE, base & 0xfffe); | ||
36 | |||
37 | return 0; | ||
38 | } | ||
39 | EXPORT_SYMBOL(tmio_core_mmc_resume); | ||
40 | |||
41 | void tmio_core_mmc_pwr(void __iomem *cnf, int shift, int state) | ||
42 | { | ||
43 | sd_config_write8(cnf, shift, CNF_PWR_CTL_2, state ? 0x02 : 0x00); | ||
44 | } | ||
45 | EXPORT_SYMBOL(tmio_core_mmc_pwr); | ||
46 | |||
47 | void tmio_core_mmc_clk_div(void __iomem *cnf, int shift, int state) | ||
48 | { | ||
49 | sd_config_write8(cnf, shift, CNF_SD_CLK_MODE, state ? 1 : 0); | ||
50 | } | ||
51 | EXPORT_SYMBOL(tmio_core_mmc_clk_div); | ||
52 | |||
diff --git a/drivers/mfd/wm8350-core.c b/drivers/mfd/wm8350-core.c index 8485a7018060..9a970bd68775 100644 --- a/drivers/mfd/wm8350-core.c +++ b/drivers/mfd/wm8350-core.c | |||
@@ -134,8 +134,7 @@ static inline int is_reg_locked(struct wm8350 *wm8350, u8 reg) | |||
134 | wm8350->reg_cache[WM8350_SECURITY] == WM8350_UNLOCK_KEY) | 134 | wm8350->reg_cache[WM8350_SECURITY] == WM8350_UNLOCK_KEY) |
135 | return 0; | 135 | return 0; |
136 | 136 | ||
137 | if ((reg == WM8350_GPIO_CONFIGURATION_I_O) || | 137 | if ((reg >= WM8350_GPIO_FUNCTION_SELECT_1 && |
138 | (reg >= WM8350_GPIO_FUNCTION_SELECT_1 && | ||
139 | reg <= WM8350_GPIO_FUNCTION_SELECT_4) || | 138 | reg <= WM8350_GPIO_FUNCTION_SELECT_4) || |
140 | (reg >= WM8350_BATTERY_CHARGER_CONTROL_1 && | 139 | (reg >= WM8350_BATTERY_CHARGER_CONTROL_1 && |
141 | reg <= WM8350_BATTERY_CHARGER_CONTROL_3)) | 140 | reg <= WM8350_BATTERY_CHARGER_CONTROL_3)) |
diff --git a/drivers/mfd/wm8350-irq.c b/drivers/mfd/wm8350-irq.c index c8df547c4747..9025f29e2707 100644 --- a/drivers/mfd/wm8350-irq.c +++ b/drivers/mfd/wm8350-irq.c | |||
@@ -434,7 +434,7 @@ int wm8350_register_irq(struct wm8350 *wm8350, int irq, | |||
434 | irq_handler_t handler, unsigned long flags, | 434 | irq_handler_t handler, unsigned long flags, |
435 | const char *name, void *data) | 435 | const char *name, void *data) |
436 | { | 436 | { |
437 | if (irq < 0 || irq > WM8350_NUM_IRQ || !handler) | 437 | if (irq < 0 || irq >= WM8350_NUM_IRQ || !handler) |
438 | return -EINVAL; | 438 | return -EINVAL; |
439 | 439 | ||
440 | if (wm8350->irq[irq].handler) | 440 | if (wm8350->irq[irq].handler) |
@@ -453,7 +453,7 @@ EXPORT_SYMBOL_GPL(wm8350_register_irq); | |||
453 | 453 | ||
454 | int wm8350_free_irq(struct wm8350 *wm8350, int irq) | 454 | int wm8350_free_irq(struct wm8350 *wm8350, int irq) |
455 | { | 455 | { |
456 | if (irq < 0 || irq > WM8350_NUM_IRQ) | 456 | if (irq < 0 || irq >= WM8350_NUM_IRQ) |
457 | return -EINVAL; | 457 | return -EINVAL; |
458 | 458 | ||
459 | wm8350_mask_irq(wm8350, irq); | 459 | wm8350_mask_irq(wm8350, irq); |
diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c index 85f0e8cd875b..1f552c6e7579 100644 --- a/drivers/mmc/card/block.c +++ b/drivers/mmc/card/block.c | |||
@@ -85,7 +85,14 @@ static void mmc_blk_put(struct mmc_blk_data *md) | |||
85 | mutex_lock(&open_lock); | 85 | mutex_lock(&open_lock); |
86 | md->usage--; | 86 | md->usage--; |
87 | if (md->usage == 0) { | 87 | if (md->usage == 0) { |
88 | int devmaj = MAJOR(disk_devt(md->disk)); | ||
88 | int devidx = MINOR(disk_devt(md->disk)) >> MMC_SHIFT; | 89 | int devidx = MINOR(disk_devt(md->disk)) >> MMC_SHIFT; |
90 | |||
91 | if (!devmaj) | ||
92 | devidx = md->disk->first_minor >> MMC_SHIFT; | ||
93 | |||
94 | blk_cleanup_queue(md->queue.queue); | ||
95 | |||
89 | __clear_bit(devidx, dev_use); | 96 | __clear_bit(devidx, dev_use); |
90 | 97 | ||
91 | put_disk(md->disk); | 98 | put_disk(md->disk); |
@@ -613,6 +620,7 @@ static int mmc_blk_probe(struct mmc_card *card) | |||
613 | return 0; | 620 | return 0; |
614 | 621 | ||
615 | out: | 622 | out: |
623 | mmc_cleanup_queue(&md->queue); | ||
616 | mmc_blk_put(md); | 624 | mmc_blk_put(md); |
617 | 625 | ||
618 | return err; | 626 | return err; |
diff --git a/drivers/mmc/card/queue.c b/drivers/mmc/card/queue.c index 49e582356c65..c5a7a855f4b1 100644 --- a/drivers/mmc/card/queue.c +++ b/drivers/mmc/card/queue.c | |||
@@ -90,9 +90,10 @@ static void mmc_request(struct request_queue *q) | |||
90 | struct request *req; | 90 | struct request *req; |
91 | 91 | ||
92 | if (!mq) { | 92 | if (!mq) { |
93 | printk(KERN_ERR "MMC: killing requests for dead queue\n"); | 93 | while ((req = blk_fetch_request(q)) != NULL) { |
94 | while ((req = blk_fetch_request(q)) != NULL) | 94 | req->cmd_flags |= REQ_QUIET; |
95 | __blk_end_request_all(req, -EIO); | 95 | __blk_end_request_all(req, -EIO); |
96 | } | ||
96 | return; | 97 | return; |
97 | } | 98 | } |
98 | 99 | ||
@@ -223,17 +224,18 @@ void mmc_cleanup_queue(struct mmc_queue *mq) | |||
223 | struct request_queue *q = mq->queue; | 224 | struct request_queue *q = mq->queue; |
224 | unsigned long flags; | 225 | unsigned long flags; |
225 | 226 | ||
226 | /* Mark that we should start throwing out stragglers */ | ||
227 | spin_lock_irqsave(q->queue_lock, flags); | ||
228 | q->queuedata = NULL; | ||
229 | spin_unlock_irqrestore(q->queue_lock, flags); | ||
230 | |||
231 | /* Make sure the queue isn't suspended, as that will deadlock */ | 227 | /* Make sure the queue isn't suspended, as that will deadlock */ |
232 | mmc_queue_resume(mq); | 228 | mmc_queue_resume(mq); |
233 | 229 | ||
234 | /* Then terminate our worker thread */ | 230 | /* Then terminate our worker thread */ |
235 | kthread_stop(mq->thread); | 231 | kthread_stop(mq->thread); |
236 | 232 | ||
233 | /* Empty the queue */ | ||
234 | spin_lock_irqsave(q->queue_lock, flags); | ||
235 | q->queuedata = NULL; | ||
236 | blk_start_queue(q); | ||
237 | spin_unlock_irqrestore(q->queue_lock, flags); | ||
238 | |||
237 | if (mq->bounce_sg) | 239 | if (mq->bounce_sg) |
238 | kfree(mq->bounce_sg); | 240 | kfree(mq->bounce_sg); |
239 | mq->bounce_sg = NULL; | 241 | mq->bounce_sg = NULL; |
@@ -245,8 +247,6 @@ void mmc_cleanup_queue(struct mmc_queue *mq) | |||
245 | kfree(mq->bounce_buf); | 247 | kfree(mq->bounce_buf); |
246 | mq->bounce_buf = NULL; | 248 | mq->bounce_buf = NULL; |
247 | 249 | ||
248 | blk_cleanup_queue(mq->queue); | ||
249 | |||
250 | mq->card = NULL; | 250 | mq->card = NULL; |
251 | } | 251 | } |
252 | EXPORT_SYMBOL(mmc_cleanup_queue); | 252 | EXPORT_SYMBOL(mmc_cleanup_queue); |
diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c index c11189446a1f..0eac6c814904 100644 --- a/drivers/mmc/core/mmc.c +++ b/drivers/mmc/core/mmc.c | |||
@@ -207,7 +207,7 @@ static int mmc_read_ext_csd(struct mmc_card *card) | |||
207 | } | 207 | } |
208 | 208 | ||
209 | card->ext_csd.rev = ext_csd[EXT_CSD_REV]; | 209 | card->ext_csd.rev = ext_csd[EXT_CSD_REV]; |
210 | if (card->ext_csd.rev > 3) { | 210 | if (card->ext_csd.rev > 5) { |
211 | printk(KERN_ERR "%s: unrecognised EXT_CSD structure " | 211 | printk(KERN_ERR "%s: unrecognised EXT_CSD structure " |
212 | "version %d\n", mmc_hostname(card->host), | 212 | "version %d\n", mmc_hostname(card->host), |
213 | card->ext_csd.rev); | 213 | card->ext_csd.rev); |
diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c index 90d168ad03b6..84c103a7ee13 100644 --- a/drivers/mmc/host/mmci.c +++ b/drivers/mmc/host/mmci.c | |||
@@ -2,6 +2,7 @@ | |||
2 | * linux/drivers/mmc/host/mmci.c - ARM PrimeCell MMCI PL180/1 driver | 2 | * linux/drivers/mmc/host/mmci.c - ARM PrimeCell MMCI PL180/1 driver |
3 | * | 3 | * |
4 | * Copyright (C) 2003 Deep Blue Solutions, Ltd, All Rights Reserved. | 4 | * Copyright (C) 2003 Deep Blue Solutions, Ltd, All Rights Reserved. |
5 | * Copyright (C) 2010 ST-Ericsson AB. | ||
5 | * | 6 | * |
6 | * This program is free software; you can redistribute it and/or modify | 7 | * This program is free software; you can redistribute it and/or modify |
7 | * it under the terms of the GNU General Public License version 2 as | 8 | * it under the terms of the GNU General Public License version 2 as |
@@ -34,9 +35,6 @@ | |||
34 | 35 | ||
35 | #define DRIVER_NAME "mmci-pl18x" | 36 | #define DRIVER_NAME "mmci-pl18x" |
36 | 37 | ||
37 | #define DBG(host,fmt,args...) \ | ||
38 | pr_debug("%s: %s: " fmt, mmc_hostname(host->mmc), __func__ , args) | ||
39 | |||
40 | static unsigned int fmax = 515633; | 38 | static unsigned int fmax = 515633; |
41 | 39 | ||
42 | /* | 40 | /* |
@@ -105,8 +103,8 @@ static void mmci_start_data(struct mmci_host *host, struct mmc_data *data) | |||
105 | void __iomem *base; | 103 | void __iomem *base; |
106 | int blksz_bits; | 104 | int blksz_bits; |
107 | 105 | ||
108 | DBG(host, "blksz %04x blks %04x flags %08x\n", | 106 | dev_dbg(mmc_dev(host->mmc), "blksz %04x blks %04x flags %08x\n", |
109 | data->blksz, data->blocks, data->flags); | 107 | data->blksz, data->blocks, data->flags); |
110 | 108 | ||
111 | host->data = data; | 109 | host->data = data; |
112 | host->size = data->blksz; | 110 | host->size = data->blksz; |
@@ -155,7 +153,7 @@ mmci_start_command(struct mmci_host *host, struct mmc_command *cmd, u32 c) | |||
155 | { | 153 | { |
156 | void __iomem *base = host->base; | 154 | void __iomem *base = host->base; |
157 | 155 | ||
158 | DBG(host, "op %02x arg %08x flags %08x\n", | 156 | dev_dbg(mmc_dev(host->mmc), "op %02x arg %08x flags %08x\n", |
159 | cmd->opcode, cmd->arg, cmd->flags); | 157 | cmd->opcode, cmd->arg, cmd->flags); |
160 | 158 | ||
161 | if (readl(base + MMCICOMMAND) & MCI_CPSM_ENABLE) { | 159 | if (readl(base + MMCICOMMAND) & MCI_CPSM_ENABLE) { |
@@ -184,8 +182,20 @@ mmci_data_irq(struct mmci_host *host, struct mmc_data *data, | |||
184 | { | 182 | { |
185 | if (status & MCI_DATABLOCKEND) { | 183 | if (status & MCI_DATABLOCKEND) { |
186 | host->data_xfered += data->blksz; | 184 | host->data_xfered += data->blksz; |
185 | #ifdef CONFIG_ARCH_U300 | ||
186 | /* | ||
187 | * On the U300 some signal or other is | ||
188 | * badly routed so that a data write does | ||
189 | * not properly terminate with a MCI_DATAEND | ||
190 | * status flag. This quirk will make writes | ||
191 | * work again. | ||
192 | */ | ||
193 | if (data->flags & MMC_DATA_WRITE) | ||
194 | status |= MCI_DATAEND; | ||
195 | #endif | ||
187 | } | 196 | } |
188 | if (status & (MCI_DATACRCFAIL|MCI_DATATIMEOUT|MCI_TXUNDERRUN|MCI_RXOVERRUN)) { | 197 | if (status & (MCI_DATACRCFAIL|MCI_DATATIMEOUT|MCI_TXUNDERRUN|MCI_RXOVERRUN)) { |
198 | dev_dbg(mmc_dev(host->mmc), "MCI ERROR IRQ (status %08x)\n", status); | ||
189 | if (status & MCI_DATACRCFAIL) | 199 | if (status & MCI_DATACRCFAIL) |
190 | data->error = -EILSEQ; | 200 | data->error = -EILSEQ; |
191 | else if (status & MCI_DATATIMEOUT) | 201 | else if (status & MCI_DATATIMEOUT) |
@@ -307,7 +317,7 @@ static irqreturn_t mmci_pio_irq(int irq, void *dev_id) | |||
307 | 317 | ||
308 | status = readl(base + MMCISTATUS); | 318 | status = readl(base + MMCISTATUS); |
309 | 319 | ||
310 | DBG(host, "irq1 %08x\n", status); | 320 | dev_dbg(mmc_dev(host->mmc), "irq1 (pio) %08x\n", status); |
311 | 321 | ||
312 | do { | 322 | do { |
313 | unsigned long flags; | 323 | unsigned long flags; |
@@ -401,7 +411,7 @@ static irqreturn_t mmci_irq(int irq, void *dev_id) | |||
401 | status &= readl(host->base + MMCIMASK0); | 411 | status &= readl(host->base + MMCIMASK0); |
402 | writel(status, host->base + MMCICLEAR); | 412 | writel(status, host->base + MMCICLEAR); |
403 | 413 | ||
404 | DBG(host, "irq0 %08x\n", status); | 414 | dev_dbg(mmc_dev(host->mmc), "irq0 (data+cmd) %08x\n", status); |
405 | 415 | ||
406 | data = host->data; | 416 | data = host->data; |
407 | if (status & (MCI_DATACRCFAIL|MCI_DATATIMEOUT|MCI_TXUNDERRUN| | 417 | if (status & (MCI_DATACRCFAIL|MCI_DATATIMEOUT|MCI_TXUNDERRUN| |
@@ -428,8 +438,8 @@ static void mmci_request(struct mmc_host *mmc, struct mmc_request *mrq) | |||
428 | WARN_ON(host->mrq != NULL); | 438 | WARN_ON(host->mrq != NULL); |
429 | 439 | ||
430 | if (mrq->data && !is_power_of_2(mrq->data->blksz)) { | 440 | if (mrq->data && !is_power_of_2(mrq->data->blksz)) { |
431 | printk(KERN_ERR "%s: Unsupported block size (%d bytes)\n", | 441 | dev_err(mmc_dev(mmc), "unsupported block size (%d bytes)\n", |
432 | mmc_hostname(mmc), mrq->data->blksz); | 442 | mrq->data->blksz); |
433 | mrq->cmd->error = -EINVAL; | 443 | mrq->cmd->error = -EINVAL; |
434 | mmc_request_done(mmc, mrq); | 444 | mmc_request_done(mmc, mrq); |
435 | return; | 445 | return; |
@@ -582,8 +592,8 @@ static int __devinit mmci_probe(struct amba_device *dev, struct amba_id *id) | |||
582 | 592 | ||
583 | host->hw_designer = amba_manf(dev); | 593 | host->hw_designer = amba_manf(dev); |
584 | host->hw_revision = amba_rev(dev); | 594 | host->hw_revision = amba_rev(dev); |
585 | DBG(host, "designer ID = 0x%02x\n", host->hw_designer); | 595 | dev_dbg(mmc_dev(mmc), "designer ID = 0x%02x\n", host->hw_designer); |
586 | DBG(host, "revision = 0x%01x\n", host->hw_revision); | 596 | dev_dbg(mmc_dev(mmc), "revision = 0x%01x\n", host->hw_revision); |
587 | 597 | ||
588 | host->clk = clk_get(&dev->dev, NULL); | 598 | host->clk = clk_get(&dev->dev, NULL); |
589 | if (IS_ERR(host->clk)) { | 599 | if (IS_ERR(host->clk)) { |
@@ -608,7 +618,8 @@ static int __devinit mmci_probe(struct amba_device *dev, struct amba_id *id) | |||
608 | if (ret < 0) | 618 | if (ret < 0) |
609 | goto clk_disable; | 619 | goto clk_disable; |
610 | host->mclk = clk_get_rate(host->clk); | 620 | host->mclk = clk_get_rate(host->clk); |
611 | DBG(host, "eventual mclk rate: %u Hz\n", host->mclk); | 621 | dev_dbg(mmc_dev(mmc), "eventual mclk rate: %u Hz\n", |
622 | host->mclk); | ||
612 | } | 623 | } |
613 | host->base = ioremap(dev->res.start, resource_size(&dev->res)); | 624 | host->base = ioremap(dev->res.start, resource_size(&dev->res)); |
614 | if (!host->base) { | 625 | if (!host->base) { |
@@ -619,6 +630,8 @@ static int __devinit mmci_probe(struct amba_device *dev, struct amba_id *id) | |||
619 | mmc->ops = &mmci_ops; | 630 | mmc->ops = &mmci_ops; |
620 | mmc->f_min = (host->mclk + 511) / 512; | 631 | mmc->f_min = (host->mclk + 511) / 512; |
621 | mmc->f_max = min(host->mclk, fmax); | 632 | mmc->f_max = min(host->mclk, fmax); |
633 | dev_dbg(mmc_dev(mmc), "clocking block at %u Hz\n", mmc->f_max); | ||
634 | |||
622 | #ifdef CONFIG_REGULATOR | 635 | #ifdef CONFIG_REGULATOR |
623 | /* If we're using the regulator framework, try to fetch a regulator */ | 636 | /* If we're using the regulator framework, try to fetch a regulator */ |
624 | host->vcc = regulator_get(&dev->dev, "vmmc"); | 637 | host->vcc = regulator_get(&dev->dev, "vmmc"); |
@@ -712,7 +725,7 @@ static int __devinit mmci_probe(struct amba_device *dev, struct amba_id *id) | |||
712 | 725 | ||
713 | mmc_add_host(mmc); | 726 | mmc_add_host(mmc); |
714 | 727 | ||
715 | printk(KERN_INFO "%s: MMCI rev %x cfg %02x at 0x%016llx irq %d,%d\n", | 728 | dev_info(&dev->dev, "%s: MMCI rev %x cfg %02x at 0x%016llx irq %d,%d\n", |
716 | mmc_hostname(mmc), amba_rev(dev), amba_config(dev), | 729 | mmc_hostname(mmc), amba_rev(dev), amba_config(dev), |
717 | (unsigned long long)dev->res.start, dev->irq[0], dev->irq[1]); | 730 | (unsigned long long)dev->res.start, dev->irq[0], dev->irq[1]); |
718 | 731 | ||
diff --git a/drivers/mmc/host/tmio_mmc.c b/drivers/mmc/host/tmio_mmc.c index 7cccc8523747..e22c3fa3516a 100644 --- a/drivers/mmc/host/tmio_mmc.c +++ b/drivers/mmc/host/tmio_mmc.c | |||
@@ -46,7 +46,9 @@ static void tmio_mmc_set_clock(struct tmio_mmc_host *host, int new_clock) | |||
46 | clk |= 0x100; | 46 | clk |= 0x100; |
47 | } | 47 | } |
48 | 48 | ||
49 | sd_config_write8(host, CNF_SD_CLK_MODE, clk >> 22); | 49 | if (host->set_clk_div) |
50 | host->set_clk_div(host->pdev, (clk>>22) & 1); | ||
51 | |||
50 | sd_ctrl_write16(host, CTL_SD_CARD_CLK_CTL, clk & 0x1ff); | 52 | sd_ctrl_write16(host, CTL_SD_CARD_CLK_CTL, clk & 0x1ff); |
51 | } | 53 | } |
52 | 54 | ||
@@ -427,12 +429,13 @@ static void tmio_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) | |||
427 | /* Power sequence - OFF -> ON -> UP */ | 429 | /* Power sequence - OFF -> ON -> UP */ |
428 | switch (ios->power_mode) { | 430 | switch (ios->power_mode) { |
429 | case MMC_POWER_OFF: /* power down SD bus */ | 431 | case MMC_POWER_OFF: /* power down SD bus */ |
430 | sd_config_write8(host, CNF_PWR_CTL_2, 0x00); | 432 | if (host->set_pwr) |
433 | host->set_pwr(host->pdev, 0); | ||
431 | tmio_mmc_clk_stop(host); | 434 | tmio_mmc_clk_stop(host); |
432 | break; | 435 | break; |
433 | case MMC_POWER_ON: /* power up SD bus */ | 436 | case MMC_POWER_ON: /* power up SD bus */ |
434 | 437 | if (host->set_pwr) | |
435 | sd_config_write8(host, CNF_PWR_CTL_2, 0x02); | 438 | host->set_pwr(host->pdev, 1); |
436 | break; | 439 | break; |
437 | case MMC_POWER_UP: /* start bus clock */ | 440 | case MMC_POWER_UP: /* start bus clock */ |
438 | tmio_mmc_clk_start(host); | 441 | tmio_mmc_clk_start(host); |
@@ -485,21 +488,15 @@ static int tmio_mmc_resume(struct platform_device *dev) | |||
485 | { | 488 | { |
486 | struct mfd_cell *cell = (struct mfd_cell *)dev->dev.platform_data; | 489 | struct mfd_cell *cell = (struct mfd_cell *)dev->dev.platform_data; |
487 | struct mmc_host *mmc = platform_get_drvdata(dev); | 490 | struct mmc_host *mmc = platform_get_drvdata(dev); |
488 | struct tmio_mmc_host *host = mmc_priv(mmc); | ||
489 | int ret = 0; | 491 | int ret = 0; |
490 | 492 | ||
491 | /* Tell the MFD core we are ready to be enabled */ | 493 | /* Tell the MFD core we are ready to be enabled */ |
492 | if (cell->enable) { | 494 | if (cell->resume) { |
493 | ret = cell->enable(dev); | 495 | ret = cell->resume(dev); |
494 | if (ret) | 496 | if (ret) |
495 | goto out; | 497 | goto out; |
496 | } | 498 | } |
497 | 499 | ||
498 | /* Enable the MMC/SD Control registers */ | ||
499 | sd_config_write16(host, CNF_CMD, SDCREN); | ||
500 | sd_config_write32(host, CNF_CTL_BASE, | ||
501 | (dev->resource[0].start >> host->bus_shift) & 0xfffe); | ||
502 | |||
503 | mmc_resume_host(mmc); | 500 | mmc_resume_host(mmc); |
504 | 501 | ||
505 | out: | 502 | out: |
@@ -514,17 +511,16 @@ static int __devinit tmio_mmc_probe(struct platform_device *dev) | |||
514 | { | 511 | { |
515 | struct mfd_cell *cell = (struct mfd_cell *)dev->dev.platform_data; | 512 | struct mfd_cell *cell = (struct mfd_cell *)dev->dev.platform_data; |
516 | struct tmio_mmc_data *pdata; | 513 | struct tmio_mmc_data *pdata; |
517 | struct resource *res_ctl, *res_cnf; | 514 | struct resource *res_ctl; |
518 | struct tmio_mmc_host *host; | 515 | struct tmio_mmc_host *host; |
519 | struct mmc_host *mmc; | 516 | struct mmc_host *mmc; |
520 | int ret = -EINVAL; | 517 | int ret = -EINVAL; |
521 | 518 | ||
522 | if (dev->num_resources != 3) | 519 | if (dev->num_resources != 2) |
523 | goto out; | 520 | goto out; |
524 | 521 | ||
525 | res_ctl = platform_get_resource(dev, IORESOURCE_MEM, 0); | 522 | res_ctl = platform_get_resource(dev, IORESOURCE_MEM, 0); |
526 | res_cnf = platform_get_resource(dev, IORESOURCE_MEM, 1); | 523 | if (!res_ctl) |
527 | if (!res_ctl || !res_cnf) | ||
528 | goto out; | 524 | goto out; |
529 | 525 | ||
530 | pdata = cell->driver_data; | 526 | pdata = cell->driver_data; |
@@ -539,8 +535,12 @@ static int __devinit tmio_mmc_probe(struct platform_device *dev) | |||
539 | 535 | ||
540 | host = mmc_priv(mmc); | 536 | host = mmc_priv(mmc); |
541 | host->mmc = mmc; | 537 | host->mmc = mmc; |
538 | host->pdev = dev; | ||
542 | platform_set_drvdata(dev, mmc); | 539 | platform_set_drvdata(dev, mmc); |
543 | 540 | ||
541 | host->set_pwr = pdata->set_pwr; | ||
542 | host->set_clk_div = pdata->set_clk_div; | ||
543 | |||
544 | /* SD control register space size is 0x200, 0x400 for bus_shift=1 */ | 544 | /* SD control register space size is 0x200, 0x400 for bus_shift=1 */ |
545 | host->bus_shift = resource_size(res_ctl) >> 10; | 545 | host->bus_shift = resource_size(res_ctl) >> 10; |
546 | 546 | ||
@@ -548,10 +548,6 @@ static int __devinit tmio_mmc_probe(struct platform_device *dev) | |||
548 | if (!host->ctl) | 548 | if (!host->ctl) |
549 | goto host_free; | 549 | goto host_free; |
550 | 550 | ||
551 | host->cnf = ioremap(res_cnf->start, resource_size(res_cnf)); | ||
552 | if (!host->cnf) | ||
553 | goto unmap_ctl; | ||
554 | |||
555 | mmc->ops = &tmio_mmc_ops; | 551 | mmc->ops = &tmio_mmc_ops; |
556 | mmc->caps = MMC_CAP_4_BIT_DATA; | 552 | mmc->caps = MMC_CAP_4_BIT_DATA; |
557 | mmc->f_max = pdata->hclk; | 553 | mmc->f_max = pdata->hclk; |
@@ -562,23 +558,9 @@ static int __devinit tmio_mmc_probe(struct platform_device *dev) | |||
562 | if (cell->enable) { | 558 | if (cell->enable) { |
563 | ret = cell->enable(dev); | 559 | ret = cell->enable(dev); |
564 | if (ret) | 560 | if (ret) |
565 | goto unmap_cnf; | 561 | goto unmap_ctl; |
566 | } | 562 | } |
567 | 563 | ||
568 | /* Enable the MMC/SD Control registers */ | ||
569 | sd_config_write16(host, CNF_CMD, SDCREN); | ||
570 | sd_config_write32(host, CNF_CTL_BASE, | ||
571 | (dev->resource[0].start >> host->bus_shift) & 0xfffe); | ||
572 | |||
573 | /* Disable SD power during suspend */ | ||
574 | sd_config_write8(host, CNF_PWR_CTL_3, 0x01); | ||
575 | |||
576 | /* The below is required but why? FIXME */ | ||
577 | sd_config_write8(host, CNF_STOP_CLK_CTL, 0x1f); | ||
578 | |||
579 | /* Power down SD bus*/ | ||
580 | sd_config_write8(host, CNF_PWR_CTL_2, 0x00); | ||
581 | |||
582 | tmio_mmc_clk_stop(host); | 564 | tmio_mmc_clk_stop(host); |
583 | reset(host); | 565 | reset(host); |
584 | 566 | ||
@@ -586,14 +568,14 @@ static int __devinit tmio_mmc_probe(struct platform_device *dev) | |||
586 | if (ret >= 0) | 568 | if (ret >= 0) |
587 | host->irq = ret; | 569 | host->irq = ret; |
588 | else | 570 | else |
589 | goto unmap_cnf; | 571 | goto unmap_ctl; |
590 | 572 | ||
591 | disable_mmc_irqs(host, TMIO_MASK_ALL); | 573 | disable_mmc_irqs(host, TMIO_MASK_ALL); |
592 | 574 | ||
593 | ret = request_irq(host->irq, tmio_mmc_irq, IRQF_DISABLED | | 575 | ret = request_irq(host->irq, tmio_mmc_irq, IRQF_DISABLED | |
594 | IRQF_TRIGGER_FALLING, dev_name(&dev->dev), host); | 576 | IRQF_TRIGGER_FALLING, dev_name(&dev->dev), host); |
595 | if (ret) | 577 | if (ret) |
596 | goto unmap_cnf; | 578 | goto unmap_ctl; |
597 | 579 | ||
598 | mmc_add_host(mmc); | 580 | mmc_add_host(mmc); |
599 | 581 | ||
@@ -605,8 +587,6 @@ static int __devinit tmio_mmc_probe(struct platform_device *dev) | |||
605 | 587 | ||
606 | return 0; | 588 | return 0; |
607 | 589 | ||
608 | unmap_cnf: | ||
609 | iounmap(host->cnf); | ||
610 | unmap_ctl: | 590 | unmap_ctl: |
611 | iounmap(host->ctl); | 591 | iounmap(host->ctl); |
612 | host_free: | 592 | host_free: |
@@ -626,7 +606,6 @@ static int __devexit tmio_mmc_remove(struct platform_device *dev) | |||
626 | mmc_remove_host(mmc); | 606 | mmc_remove_host(mmc); |
627 | free_irq(host->irq, host); | 607 | free_irq(host->irq, host); |
628 | iounmap(host->ctl); | 608 | iounmap(host->ctl); |
629 | iounmap(host->cnf); | ||
630 | mmc_free_host(mmc); | 609 | mmc_free_host(mmc); |
631 | } | 610 | } |
632 | 611 | ||
diff --git a/drivers/mmc/host/tmio_mmc.h b/drivers/mmc/host/tmio_mmc.h index 9fa998594974..692dc23363b9 100644 --- a/drivers/mmc/host/tmio_mmc.h +++ b/drivers/mmc/host/tmio_mmc.h | |||
@@ -11,26 +11,6 @@ | |||
11 | 11 | ||
12 | #include <linux/highmem.h> | 12 | #include <linux/highmem.h> |
13 | 13 | ||
14 | #define CNF_CMD 0x04 | ||
15 | #define CNF_CTL_BASE 0x10 | ||
16 | #define CNF_INT_PIN 0x3d | ||
17 | #define CNF_STOP_CLK_CTL 0x40 | ||
18 | #define CNF_GCLK_CTL 0x41 | ||
19 | #define CNF_SD_CLK_MODE 0x42 | ||
20 | #define CNF_PIN_STATUS 0x44 | ||
21 | #define CNF_PWR_CTL_1 0x48 | ||
22 | #define CNF_PWR_CTL_2 0x49 | ||
23 | #define CNF_PWR_CTL_3 0x4a | ||
24 | #define CNF_CARD_DETECT_MODE 0x4c | ||
25 | #define CNF_SD_SLOT 0x50 | ||
26 | #define CNF_EXT_GCLK_CTL_1 0xf0 | ||
27 | #define CNF_EXT_GCLK_CTL_2 0xf1 | ||
28 | #define CNF_EXT_GCLK_CTL_3 0xf9 | ||
29 | #define CNF_SD_LED_EN_1 0xfa | ||
30 | #define CNF_SD_LED_EN_2 0xfe | ||
31 | |||
32 | #define SDCREN 0x2 /* Enable access to MMC CTL regs. (flag in COMMAND_REG)*/ | ||
33 | |||
34 | #define CTL_SD_CMD 0x00 | 14 | #define CTL_SD_CMD 0x00 |
35 | #define CTL_ARG_REG 0x04 | 15 | #define CTL_ARG_REG 0x04 |
36 | #define CTL_STOP_INTERNAL_ACTION 0x08 | 16 | #define CTL_STOP_INTERNAL_ACTION 0x08 |
@@ -110,7 +90,6 @@ | |||
110 | 90 | ||
111 | 91 | ||
112 | struct tmio_mmc_host { | 92 | struct tmio_mmc_host { |
113 | void __iomem *cnf; | ||
114 | void __iomem *ctl; | 93 | void __iomem *ctl; |
115 | unsigned long bus_shift; | 94 | unsigned long bus_shift; |
116 | struct mmc_command *cmd; | 95 | struct mmc_command *cmd; |
@@ -119,10 +98,16 @@ struct tmio_mmc_host { | |||
119 | struct mmc_host *mmc; | 98 | struct mmc_host *mmc; |
120 | int irq; | 99 | int irq; |
121 | 100 | ||
101 | /* Callbacks for clock / power control */ | ||
102 | void (*set_pwr)(struct platform_device *host, int state); | ||
103 | void (*set_clk_div)(struct platform_device *host, int state); | ||
104 | |||
122 | /* pio related stuff */ | 105 | /* pio related stuff */ |
123 | struct scatterlist *sg_ptr; | 106 | struct scatterlist *sg_ptr; |
124 | unsigned int sg_len; | 107 | unsigned int sg_len; |
125 | unsigned int sg_off; | 108 | unsigned int sg_off; |
109 | |||
110 | struct platform_device *pdev; | ||
126 | }; | 111 | }; |
127 | 112 | ||
128 | #include <linux/io.h> | 113 | #include <linux/io.h> |
@@ -163,25 +148,6 @@ static inline void sd_ctrl_write32(struct tmio_mmc_host *host, int addr, | |||
163 | writew(val >> 16, host->ctl + ((addr + 2) << host->bus_shift)); | 148 | writew(val >> 16, host->ctl + ((addr + 2) << host->bus_shift)); |
164 | } | 149 | } |
165 | 150 | ||
166 | static inline void sd_config_write8(struct tmio_mmc_host *host, int addr, | ||
167 | u8 val) | ||
168 | { | ||
169 | writeb(val, host->cnf + (addr << host->bus_shift)); | ||
170 | } | ||
171 | |||
172 | static inline void sd_config_write16(struct tmio_mmc_host *host, int addr, | ||
173 | u16 val) | ||
174 | { | ||
175 | writew(val, host->cnf + (addr << host->bus_shift)); | ||
176 | } | ||
177 | |||
178 | static inline void sd_config_write32(struct tmio_mmc_host *host, int addr, | ||
179 | u32 val) | ||
180 | { | ||
181 | writew(val, host->cnf + (addr << host->bus_shift)); | ||
182 | writew(val >> 16, host->cnf + ((addr + 2) << host->bus_shift)); | ||
183 | } | ||
184 | |||
185 | #include <linux/scatterlist.h> | 151 | #include <linux/scatterlist.h> |
186 | #include <linux/blkdev.h> | 152 | #include <linux/blkdev.h> |
187 | 153 | ||
diff --git a/drivers/net/arm/Kconfig b/drivers/net/arm/Kconfig index c37ee9e6b67b..39e1c0d39476 100644 --- a/drivers/net/arm/Kconfig +++ b/drivers/net/arm/Kconfig | |||
@@ -68,6 +68,7 @@ config W90P910_ETH | |||
68 | tristate "Nuvoton w90p910 Ethernet support" | 68 | tristate "Nuvoton w90p910 Ethernet support" |
69 | depends on ARM && ARCH_W90X900 | 69 | depends on ARM && ARCH_W90X900 |
70 | select PHYLIB | 70 | select PHYLIB |
71 | select MII | ||
71 | help | 72 | help |
72 | Say Y here if you want to use built-in Ethernet ports | 73 | Say Y here if you want to use built-in Ethernet ports |
73 | on w90p910 processor. | 74 | on w90p910 processor. |
diff --git a/drivers/net/atarilance.c b/drivers/net/atarilance.c index c5721cb38265..cc9ed8643910 100644 --- a/drivers/net/atarilance.c +++ b/drivers/net/atarilance.c | |||
@@ -663,7 +663,7 @@ static int lance_open( struct net_device *dev ) | |||
663 | while (--i > 0) | 663 | while (--i > 0) |
664 | if (DREG & CSR0_IDON) | 664 | if (DREG & CSR0_IDON) |
665 | break; | 665 | break; |
666 | if (i < 0 || (DREG & CSR0_ERR)) { | 666 | if (i <= 0 || (DREG & CSR0_ERR)) { |
667 | DPRINTK( 2, ( "lance_open(): opening %s failed, i=%d, csr0=%04x\n", | 667 | DPRINTK( 2, ( "lance_open(): opening %s failed, i=%d, csr0=%04x\n", |
668 | dev->name, i, DREG )); | 668 | dev->name, i, DREG )); |
669 | DREG = CSR0_STOP; | 669 | DREG = CSR0_STOP; |
diff --git a/drivers/net/atlx/atl2.c b/drivers/net/atlx/atl2.c index c0451d75cdcf..ec52529394ad 100644 --- a/drivers/net/atlx/atl2.c +++ b/drivers/net/atlx/atl2.c | |||
@@ -1959,12 +1959,15 @@ static int atl2_get_eeprom(struct net_device *netdev, | |||
1959 | return -ENOMEM; | 1959 | return -ENOMEM; |
1960 | 1960 | ||
1961 | for (i = first_dword; i < last_dword; i++) { | 1961 | for (i = first_dword; i < last_dword; i++) { |
1962 | if (!atl2_read_eeprom(hw, i*4, &(eeprom_buff[i-first_dword]))) | 1962 | if (!atl2_read_eeprom(hw, i*4, &(eeprom_buff[i-first_dword]))) { |
1963 | return -EIO; | 1963 | ret_val = -EIO; |
1964 | goto free; | ||
1965 | } | ||
1964 | } | 1966 | } |
1965 | 1967 | ||
1966 | memcpy(bytes, (u8 *)eeprom_buff + (eeprom->offset & 3), | 1968 | memcpy(bytes, (u8 *)eeprom_buff + (eeprom->offset & 3), |
1967 | eeprom->len); | 1969 | eeprom->len); |
1970 | free: | ||
1968 | kfree(eeprom_buff); | 1971 | kfree(eeprom_buff); |
1969 | 1972 | ||
1970 | return ret_val; | 1973 | return ret_val; |
diff --git a/drivers/net/can/mcp251x.c b/drivers/net/can/mcp251x.c index 9c5a1537939c..1a72ca066a17 100644 --- a/drivers/net/can/mcp251x.c +++ b/drivers/net/can/mcp251x.c | |||
@@ -990,7 +990,7 @@ static int __devinit mcp251x_can_probe(struct spi_device *spi) | |||
990 | goto error_tx_buf; | 990 | goto error_tx_buf; |
991 | } | 991 | } |
992 | priv->spi_rx_buf = kmalloc(SPI_TRANSFER_BUF_LEN, GFP_KERNEL); | 992 | priv->spi_rx_buf = kmalloc(SPI_TRANSFER_BUF_LEN, GFP_KERNEL); |
993 | if (!priv->spi_tx_buf) { | 993 | if (!priv->spi_rx_buf) { |
994 | ret = -ENOMEM; | 994 | ret = -ENOMEM; |
995 | goto error_rx_buf; | 995 | goto error_rx_buf; |
996 | } | 996 | } |
diff --git a/drivers/net/cs89x0.c b/drivers/net/cs89x0.c index af9321617ce4..0e79cef95c0a 100644 --- a/drivers/net/cs89x0.c +++ b/drivers/net/cs89x0.c | |||
@@ -1325,8 +1325,7 @@ net_open(struct net_device *dev) | |||
1325 | write_irq(dev, lp->chip_type, dev->irq); | 1325 | write_irq(dev, lp->chip_type, dev->irq); |
1326 | ret = request_irq(dev->irq, net_interrupt, 0, dev->name, dev); | 1326 | ret = request_irq(dev->irq, net_interrupt, 0, dev->name, dev); |
1327 | if (ret) { | 1327 | if (ret) { |
1328 | if (net_debug) | 1328 | printk(KERN_ERR "cs89x0: request_irq(%d) failed\n", dev->irq); |
1329 | printk(KERN_DEBUG "cs89x0: request_irq(%d) failed\n", dev->irq); | ||
1330 | goto bad_out; | 1329 | goto bad_out; |
1331 | } | 1330 | } |
1332 | } | 1331 | } |
diff --git a/drivers/net/davinci_emac.c b/drivers/net/davinci_emac.c index 34e03104c3c1..33c4fe26178c 100644 --- a/drivers/net/davinci_emac.c +++ b/drivers/net/davinci_emac.c | |||
@@ -2711,6 +2711,8 @@ static int __devinit davinci_emac_probe(struct platform_device *pdev) | |||
2711 | SET_ETHTOOL_OPS(ndev, ðtool_ops); | 2711 | SET_ETHTOOL_OPS(ndev, ðtool_ops); |
2712 | netif_napi_add(ndev, &priv->napi, emac_poll, EMAC_POLL_WEIGHT); | 2712 | netif_napi_add(ndev, &priv->napi, emac_poll, EMAC_POLL_WEIGHT); |
2713 | 2713 | ||
2714 | clk_enable(emac_clk); | ||
2715 | |||
2714 | /* register the network device */ | 2716 | /* register the network device */ |
2715 | SET_NETDEV_DEV(ndev, &pdev->dev); | 2717 | SET_NETDEV_DEV(ndev, &pdev->dev); |
2716 | rc = register_netdev(ndev); | 2718 | rc = register_netdev(ndev); |
@@ -2720,7 +2722,6 @@ static int __devinit davinci_emac_probe(struct platform_device *pdev) | |||
2720 | goto netdev_reg_err; | 2722 | goto netdev_reg_err; |
2721 | } | 2723 | } |
2722 | 2724 | ||
2723 | clk_enable(emac_clk); | ||
2724 | 2725 | ||
2725 | /* MII/Phy intialisation, mdio bus registration */ | 2726 | /* MII/Phy intialisation, mdio bus registration */ |
2726 | emac_mii = mdiobus_alloc(); | 2727 | emac_mii = mdiobus_alloc(); |
@@ -2760,6 +2761,7 @@ mdiobus_quit: | |||
2760 | 2761 | ||
2761 | netdev_reg_err: | 2762 | netdev_reg_err: |
2762 | mdio_alloc_err: | 2763 | mdio_alloc_err: |
2764 | clk_disable(emac_clk); | ||
2763 | no_irq_res: | 2765 | no_irq_res: |
2764 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 2766 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
2765 | release_mem_region(res->start, res->end - res->start + 1); | 2767 | release_mem_region(res->start, res->end - res->start + 1); |
diff --git a/drivers/net/e1000e/82571.c b/drivers/net/e1000e/82571.c index b979464091bb..02d67d047d96 100644 --- a/drivers/net/e1000e/82571.c +++ b/drivers/net/e1000e/82571.c | |||
@@ -237,6 +237,8 @@ static s32 e1000_init_mac_params_82571(struct e1000_adapter *adapter) | |||
237 | /* Set if manageability features are enabled. */ | 237 | /* Set if manageability features are enabled. */ |
238 | mac->arc_subsystem_valid = (er32(FWSM) & E1000_FWSM_MODE_MASK) | 238 | mac->arc_subsystem_valid = (er32(FWSM) & E1000_FWSM_MODE_MASK) |
239 | ? true : false; | 239 | ? true : false; |
240 | /* Adaptive IFS supported */ | ||
241 | mac->adaptive_ifs = true; | ||
240 | 242 | ||
241 | /* check for link */ | 243 | /* check for link */ |
242 | switch (hw->phy.media_type) { | 244 | switch (hw->phy.media_type) { |
diff --git a/drivers/net/e1000e/e1000.h b/drivers/net/e1000e/e1000.h index cebbd9079d53..d6ee28f6ea08 100644 --- a/drivers/net/e1000e/e1000.h +++ b/drivers/net/e1000e/e1000.h | |||
@@ -582,7 +582,6 @@ extern s32 e1000_read_phy_reg_hv_locked(struct e1000_hw *hw, u32 offset, | |||
582 | extern s32 e1000_write_phy_reg_hv(struct e1000_hw *hw, u32 offset, u16 data); | 582 | extern s32 e1000_write_phy_reg_hv(struct e1000_hw *hw, u32 offset, u16 data); |
583 | extern s32 e1000_write_phy_reg_hv_locked(struct e1000_hw *hw, u32 offset, | 583 | extern s32 e1000_write_phy_reg_hv_locked(struct e1000_hw *hw, u32 offset, |
584 | u16 data); | 584 | u16 data); |
585 | extern s32 e1000_set_mdio_slow_mode_hv(struct e1000_hw *hw, bool slow); | ||
586 | extern s32 e1000_link_stall_workaround_hv(struct e1000_hw *hw); | 585 | extern s32 e1000_link_stall_workaround_hv(struct e1000_hw *hw); |
587 | extern s32 e1000_copper_link_setup_82577(struct e1000_hw *hw); | 586 | extern s32 e1000_copper_link_setup_82577(struct e1000_hw *hw); |
588 | extern s32 e1000_check_polarity_82577(struct e1000_hw *hw); | 587 | extern s32 e1000_check_polarity_82577(struct e1000_hw *hw); |
diff --git a/drivers/net/e1000e/es2lan.c b/drivers/net/e1000e/es2lan.c index 3028f23da891..e2aa3b788564 100644 --- a/drivers/net/e1000e/es2lan.c +++ b/drivers/net/e1000e/es2lan.c | |||
@@ -224,6 +224,8 @@ static s32 e1000_init_mac_params_80003es2lan(struct e1000_adapter *adapter) | |||
224 | /* Set if manageability features are enabled. */ | 224 | /* Set if manageability features are enabled. */ |
225 | mac->arc_subsystem_valid = (er32(FWSM) & E1000_FWSM_MODE_MASK) | 225 | mac->arc_subsystem_valid = (er32(FWSM) & E1000_FWSM_MODE_MASK) |
226 | ? true : false; | 226 | ? true : false; |
227 | /* Adaptive IFS not supported */ | ||
228 | mac->adaptive_ifs = false; | ||
227 | 229 | ||
228 | /* check for link */ | 230 | /* check for link */ |
229 | switch (hw->phy.media_type) { | 231 | switch (hw->phy.media_type) { |
diff --git a/drivers/net/e1000e/hw.h b/drivers/net/e1000e/hw.h index 2784cf44a6f3..eccf29b75c41 100644 --- a/drivers/net/e1000e/hw.h +++ b/drivers/net/e1000e/hw.h | |||
@@ -818,6 +818,7 @@ struct e1000_mac_info { | |||
818 | 818 | ||
819 | u8 forced_speed_duplex; | 819 | u8 forced_speed_duplex; |
820 | 820 | ||
821 | bool adaptive_ifs; | ||
821 | bool arc_subsystem_valid; | 822 | bool arc_subsystem_valid; |
822 | bool autoneg; | 823 | bool autoneg; |
823 | bool autoneg_failed; | 824 | bool autoneg_failed; |
diff --git a/drivers/net/e1000e/ich8lan.c b/drivers/net/e1000e/ich8lan.c index 9b09246af064..8b6ecd127889 100644 --- a/drivers/net/e1000e/ich8lan.c +++ b/drivers/net/e1000e/ich8lan.c | |||
@@ -138,6 +138,10 @@ | |||
138 | #define E1000_NVM_K1_CONFIG 0x1B /* NVM K1 Config Word */ | 138 | #define E1000_NVM_K1_CONFIG 0x1B /* NVM K1 Config Word */ |
139 | #define E1000_NVM_K1_ENABLE 0x1 /* NVM Enable K1 bit */ | 139 | #define E1000_NVM_K1_ENABLE 0x1 /* NVM Enable K1 bit */ |
140 | 140 | ||
141 | /* KMRN Mode Control */ | ||
142 | #define HV_KMRN_MODE_CTRL PHY_REG(769, 16) | ||
143 | #define HV_KMRN_MDIO_SLOW 0x0400 | ||
144 | |||
141 | /* ICH GbE Flash Hardware Sequencing Flash Status Register bit breakdown */ | 145 | /* ICH GbE Flash Hardware Sequencing Flash Status Register bit breakdown */ |
142 | /* Offset 04h HSFSTS */ | 146 | /* Offset 04h HSFSTS */ |
143 | union ich8_hws_flash_status { | 147 | union ich8_hws_flash_status { |
@@ -219,6 +223,7 @@ static s32 e1000_set_lplu_state_pchlan(struct e1000_hw *hw, bool active); | |||
219 | static void e1000_power_down_phy_copper_ich8lan(struct e1000_hw *hw); | 223 | static void e1000_power_down_phy_copper_ich8lan(struct e1000_hw *hw); |
220 | static void e1000_lan_init_done_ich8lan(struct e1000_hw *hw); | 224 | static void e1000_lan_init_done_ich8lan(struct e1000_hw *hw); |
221 | static s32 e1000_k1_gig_workaround_hv(struct e1000_hw *hw, bool link); | 225 | static s32 e1000_k1_gig_workaround_hv(struct e1000_hw *hw, bool link); |
226 | static s32 e1000_set_mdio_slow_mode_hv(struct e1000_hw *hw); | ||
222 | 227 | ||
223 | static inline u16 __er16flash(struct e1000_hw *hw, unsigned long reg) | 228 | static inline u16 __er16flash(struct e1000_hw *hw, unsigned long reg) |
224 | { | 229 | { |
@@ -270,7 +275,21 @@ static s32 e1000_init_phy_params_pchlan(struct e1000_hw *hw) | |||
270 | phy->autoneg_mask = AUTONEG_ADVERTISE_SPEED_DEFAULT; | 275 | phy->autoneg_mask = AUTONEG_ADVERTISE_SPEED_DEFAULT; |
271 | 276 | ||
272 | phy->id = e1000_phy_unknown; | 277 | phy->id = e1000_phy_unknown; |
273 | e1000e_get_phy_id(hw); | 278 | ret_val = e1000e_get_phy_id(hw); |
279 | if (ret_val) | ||
280 | goto out; | ||
281 | if ((phy->id == 0) || (phy->id == PHY_REVISION_MASK)) { | ||
282 | /* | ||
283 | * In case the PHY needs to be in mdio slow mode (eg. 82577), | ||
284 | * set slow mode and try to get the PHY id again. | ||
285 | */ | ||
286 | ret_val = e1000_set_mdio_slow_mode_hv(hw); | ||
287 | if (ret_val) | ||
288 | goto out; | ||
289 | ret_val = e1000e_get_phy_id(hw); | ||
290 | if (ret_val) | ||
291 | goto out; | ||
292 | } | ||
274 | phy->type = e1000e_get_phy_type_from_id(phy->id); | 293 | phy->type = e1000e_get_phy_type_from_id(phy->id); |
275 | 294 | ||
276 | switch (phy->type) { | 295 | switch (phy->type) { |
@@ -292,6 +311,7 @@ static s32 e1000_init_phy_params_pchlan(struct e1000_hw *hw) | |||
292 | break; | 311 | break; |
293 | } | 312 | } |
294 | 313 | ||
314 | out: | ||
295 | return ret_val; | 315 | return ret_val; |
296 | } | 316 | } |
297 | 317 | ||
@@ -454,6 +474,8 @@ static s32 e1000_init_mac_params_ich8lan(struct e1000_adapter *adapter) | |||
454 | mac->rar_entry_count--; | 474 | mac->rar_entry_count--; |
455 | /* Set if manageability features are enabled. */ | 475 | /* Set if manageability features are enabled. */ |
456 | mac->arc_subsystem_valid = true; | 476 | mac->arc_subsystem_valid = true; |
477 | /* Adaptive IFS supported */ | ||
478 | mac->adaptive_ifs = true; | ||
457 | 479 | ||
458 | /* LED operations */ | 480 | /* LED operations */ |
459 | switch (mac->type) { | 481 | switch (mac->type) { |
@@ -1074,16 +1096,44 @@ out: | |||
1074 | 1096 | ||
1075 | 1097 | ||
1076 | /** | 1098 | /** |
1099 | * e1000_set_mdio_slow_mode_hv - Set slow MDIO access mode | ||
1100 | * @hw: pointer to the HW structure | ||
1101 | **/ | ||
1102 | static s32 e1000_set_mdio_slow_mode_hv(struct e1000_hw *hw) | ||
1103 | { | ||
1104 | s32 ret_val; | ||
1105 | u16 data; | ||
1106 | |||
1107 | ret_val = e1e_rphy(hw, HV_KMRN_MODE_CTRL, &data); | ||
1108 | if (ret_val) | ||
1109 | return ret_val; | ||
1110 | |||
1111 | data |= HV_KMRN_MDIO_SLOW; | ||
1112 | |||
1113 | ret_val = e1e_wphy(hw, HV_KMRN_MODE_CTRL, data); | ||
1114 | |||
1115 | return ret_val; | ||
1116 | } | ||
1117 | |||
1118 | /** | ||
1077 | * e1000_hv_phy_workarounds_ich8lan - A series of Phy workarounds to be | 1119 | * e1000_hv_phy_workarounds_ich8lan - A series of Phy workarounds to be |
1078 | * done after every PHY reset. | 1120 | * done after every PHY reset. |
1079 | **/ | 1121 | **/ |
1080 | static s32 e1000_hv_phy_workarounds_ich8lan(struct e1000_hw *hw) | 1122 | static s32 e1000_hv_phy_workarounds_ich8lan(struct e1000_hw *hw) |
1081 | { | 1123 | { |
1082 | s32 ret_val = 0; | 1124 | s32 ret_val = 0; |
1125 | u16 phy_data; | ||
1083 | 1126 | ||
1084 | if (hw->mac.type != e1000_pchlan) | 1127 | if (hw->mac.type != e1000_pchlan) |
1085 | return ret_val; | 1128 | return ret_val; |
1086 | 1129 | ||
1130 | /* Set MDIO slow mode before any other MDIO access */ | ||
1131 | if (hw->phy.type == e1000_phy_82577) { | ||
1132 | ret_val = e1000_set_mdio_slow_mode_hv(hw); | ||
1133 | if (ret_val) | ||
1134 | goto out; | ||
1135 | } | ||
1136 | |||
1087 | if (((hw->phy.type == e1000_phy_82577) && | 1137 | if (((hw->phy.type == e1000_phy_82577) && |
1088 | ((hw->phy.revision == 1) || (hw->phy.revision == 2))) || | 1138 | ((hw->phy.revision == 1) || (hw->phy.revision == 2))) || |
1089 | ((hw->phy.type == e1000_phy_82578) && (hw->phy.revision == 1))) { | 1139 | ((hw->phy.type == e1000_phy_82578) && (hw->phy.revision == 1))) { |
@@ -1116,16 +1166,32 @@ static s32 e1000_hv_phy_workarounds_ich8lan(struct e1000_hw *hw) | |||
1116 | 1166 | ||
1117 | hw->phy.addr = 1; | 1167 | hw->phy.addr = 1; |
1118 | ret_val = e1000e_write_phy_reg_mdic(hw, IGP01E1000_PHY_PAGE_SELECT, 0); | 1168 | ret_val = e1000e_write_phy_reg_mdic(hw, IGP01E1000_PHY_PAGE_SELECT, 0); |
1169 | hw->phy.ops.release(hw); | ||
1119 | if (ret_val) | 1170 | if (ret_val) |
1120 | goto out; | 1171 | goto out; |
1121 | hw->phy.ops.release(hw); | ||
1122 | 1172 | ||
1123 | /* | 1173 | /* |
1124 | * Configure the K1 Si workaround during phy reset assuming there is | 1174 | * Configure the K1 Si workaround during phy reset assuming there is |
1125 | * link so that it disables K1 if link is in 1Gbps. | 1175 | * link so that it disables K1 if link is in 1Gbps. |
1126 | */ | 1176 | */ |
1127 | ret_val = e1000_k1_gig_workaround_hv(hw, true); | 1177 | ret_val = e1000_k1_gig_workaround_hv(hw, true); |
1178 | if (ret_val) | ||
1179 | goto out; | ||
1128 | 1180 | ||
1181 | /* Workaround for link disconnects on a busy hub in half duplex */ | ||
1182 | ret_val = hw->phy.ops.acquire(hw); | ||
1183 | if (ret_val) | ||
1184 | goto out; | ||
1185 | ret_val = hw->phy.ops.read_reg_locked(hw, | ||
1186 | PHY_REG(BM_PORT_CTRL_PAGE, 17), | ||
1187 | &phy_data); | ||
1188 | if (ret_val) | ||
1189 | goto release; | ||
1190 | ret_val = hw->phy.ops.write_reg_locked(hw, | ||
1191 | PHY_REG(BM_PORT_CTRL_PAGE, 17), | ||
1192 | phy_data & 0x00FF); | ||
1193 | release: | ||
1194 | hw->phy.ops.release(hw); | ||
1129 | out: | 1195 | out: |
1130 | return ret_val; | 1196 | return ret_val; |
1131 | } | 1197 | } |
@@ -1182,6 +1248,7 @@ static s32 e1000_phy_hw_reset_ich8lan(struct e1000_hw *hw) | |||
1182 | /* Allow time for h/w to get to a quiescent state after reset */ | 1248 | /* Allow time for h/w to get to a quiescent state after reset */ |
1183 | mdelay(10); | 1249 | mdelay(10); |
1184 | 1250 | ||
1251 | /* Perform any necessary post-reset workarounds */ | ||
1185 | if (hw->mac.type == e1000_pchlan) { | 1252 | if (hw->mac.type == e1000_pchlan) { |
1186 | ret_val = e1000_hv_phy_workarounds_ich8lan(hw); | 1253 | ret_val = e1000_hv_phy_workarounds_ich8lan(hw); |
1187 | if (ret_val) | 1254 | if (ret_val) |
@@ -2482,6 +2549,10 @@ static s32 e1000_reset_hw_ich8lan(struct e1000_hw *hw) | |||
2482 | if (!ret_val) | 2549 | if (!ret_val) |
2483 | e1000_release_swflag_ich8lan(hw); | 2550 | e1000_release_swflag_ich8lan(hw); |
2484 | 2551 | ||
2552 | /* Perform any necessary post-reset workarounds */ | ||
2553 | if (hw->mac.type == e1000_pchlan) | ||
2554 | ret_val = e1000_hv_phy_workarounds_ich8lan(hw); | ||
2555 | |||
2485 | if (ctrl & E1000_CTRL_PHY_RST) | 2556 | if (ctrl & E1000_CTRL_PHY_RST) |
2486 | ret_val = hw->phy.ops.get_cfg_done(hw); | 2557 | ret_val = hw->phy.ops.get_cfg_done(hw); |
2487 | 2558 | ||
@@ -2526,9 +2597,6 @@ static s32 e1000_reset_hw_ich8lan(struct e1000_hw *hw) | |||
2526 | kab |= E1000_KABGTXD_BGSQLBIAS; | 2597 | kab |= E1000_KABGTXD_BGSQLBIAS; |
2527 | ew32(KABGTXD, kab); | 2598 | ew32(KABGTXD, kab); |
2528 | 2599 | ||
2529 | if (hw->mac.type == e1000_pchlan) | ||
2530 | ret_val = e1000_hv_phy_workarounds_ich8lan(hw); | ||
2531 | |||
2532 | out: | 2600 | out: |
2533 | return ret_val; | 2601 | return ret_val; |
2534 | } | 2602 | } |
diff --git a/drivers/net/e1000e/lib.c b/drivers/net/e1000e/lib.c index a86c17548c1e..2fa9b36a2c5a 100644 --- a/drivers/net/e1000e/lib.c +++ b/drivers/net/e1000e/lib.c | |||
@@ -125,6 +125,7 @@ void e1000_write_vfta_generic(struct e1000_hw *hw, u32 offset, u32 value) | |||
125 | void e1000e_init_rx_addrs(struct e1000_hw *hw, u16 rar_count) | 125 | void e1000e_init_rx_addrs(struct e1000_hw *hw, u16 rar_count) |
126 | { | 126 | { |
127 | u32 i; | 127 | u32 i; |
128 | u8 mac_addr[ETH_ALEN] = {0}; | ||
128 | 129 | ||
129 | /* Setup the receive address */ | 130 | /* Setup the receive address */ |
130 | e_dbg("Programming MAC Address into RAR[0]\n"); | 131 | e_dbg("Programming MAC Address into RAR[0]\n"); |
@@ -133,12 +134,8 @@ void e1000e_init_rx_addrs(struct e1000_hw *hw, u16 rar_count) | |||
133 | 134 | ||
134 | /* Zero out the other (rar_entry_count - 1) receive addresses */ | 135 | /* Zero out the other (rar_entry_count - 1) receive addresses */ |
135 | e_dbg("Clearing RAR[1-%u]\n", rar_count-1); | 136 | e_dbg("Clearing RAR[1-%u]\n", rar_count-1); |
136 | for (i = 1; i < rar_count; i++) { | 137 | for (i = 1; i < rar_count; i++) |
137 | E1000_WRITE_REG_ARRAY(hw, E1000_RA, (i << 1), 0); | 138 | e1000e_rar_set(hw, mac_addr, i); |
138 | e1e_flush(); | ||
139 | E1000_WRITE_REG_ARRAY(hw, E1000_RA, ((i << 1) + 1), 0); | ||
140 | e1e_flush(); | ||
141 | } | ||
142 | } | 139 | } |
143 | 140 | ||
144 | /** | 141 | /** |
@@ -164,10 +161,19 @@ void e1000e_rar_set(struct e1000_hw *hw, u8 *addr, u32 index) | |||
164 | 161 | ||
165 | rar_high = ((u32) addr[4] | ((u32) addr[5] << 8)); | 162 | rar_high = ((u32) addr[4] | ((u32) addr[5] << 8)); |
166 | 163 | ||
167 | rar_high |= E1000_RAH_AV; | 164 | /* If MAC address zero, no need to set the AV bit */ |
165 | if (rar_low || rar_high) | ||
166 | rar_high |= E1000_RAH_AV; | ||
168 | 167 | ||
169 | E1000_WRITE_REG_ARRAY(hw, E1000_RA, (index << 1), rar_low); | 168 | /* |
170 | E1000_WRITE_REG_ARRAY(hw, E1000_RA, ((index << 1) + 1), rar_high); | 169 | * Some bridges will combine consecutive 32-bit writes into |
170 | * a single burst write, which will malfunction on some parts. | ||
171 | * The flushes avoid this. | ||
172 | */ | ||
173 | ew32(RAL(index), rar_low); | ||
174 | e1e_flush(); | ||
175 | ew32(RAH(index), rar_high); | ||
176 | e1e_flush(); | ||
171 | } | 177 | } |
172 | 178 | ||
173 | /** | 179 | /** |
@@ -1609,6 +1615,11 @@ void e1000e_reset_adaptive(struct e1000_hw *hw) | |||
1609 | { | 1615 | { |
1610 | struct e1000_mac_info *mac = &hw->mac; | 1616 | struct e1000_mac_info *mac = &hw->mac; |
1611 | 1617 | ||
1618 | if (!mac->adaptive_ifs) { | ||
1619 | e_dbg("Not in Adaptive IFS mode!\n"); | ||
1620 | goto out; | ||
1621 | } | ||
1622 | |||
1612 | mac->current_ifs_val = 0; | 1623 | mac->current_ifs_val = 0; |
1613 | mac->ifs_min_val = IFS_MIN; | 1624 | mac->ifs_min_val = IFS_MIN; |
1614 | mac->ifs_max_val = IFS_MAX; | 1625 | mac->ifs_max_val = IFS_MAX; |
@@ -1617,6 +1628,8 @@ void e1000e_reset_adaptive(struct e1000_hw *hw) | |||
1617 | 1628 | ||
1618 | mac->in_ifs_mode = false; | 1629 | mac->in_ifs_mode = false; |
1619 | ew32(AIT, 0); | 1630 | ew32(AIT, 0); |
1631 | out: | ||
1632 | return; | ||
1620 | } | 1633 | } |
1621 | 1634 | ||
1622 | /** | 1635 | /** |
@@ -1630,6 +1643,11 @@ void e1000e_update_adaptive(struct e1000_hw *hw) | |||
1630 | { | 1643 | { |
1631 | struct e1000_mac_info *mac = &hw->mac; | 1644 | struct e1000_mac_info *mac = &hw->mac; |
1632 | 1645 | ||
1646 | if (!mac->adaptive_ifs) { | ||
1647 | e_dbg("Not in Adaptive IFS mode!\n"); | ||
1648 | goto out; | ||
1649 | } | ||
1650 | |||
1633 | if ((mac->collision_delta * mac->ifs_ratio) > mac->tx_packet_delta) { | 1651 | if ((mac->collision_delta * mac->ifs_ratio) > mac->tx_packet_delta) { |
1634 | if (mac->tx_packet_delta > MIN_NUM_XMITS) { | 1652 | if (mac->tx_packet_delta > MIN_NUM_XMITS) { |
1635 | mac->in_ifs_mode = true; | 1653 | mac->in_ifs_mode = true; |
@@ -1650,6 +1668,8 @@ void e1000e_update_adaptive(struct e1000_hw *hw) | |||
1650 | ew32(AIT, 0); | 1668 | ew32(AIT, 0); |
1651 | } | 1669 | } |
1652 | } | 1670 | } |
1671 | out: | ||
1672 | return; | ||
1653 | } | 1673 | } |
1654 | 1674 | ||
1655 | /** | 1675 | /** |
@@ -2287,10 +2307,12 @@ bool e1000e_enable_tx_pkt_filtering(struct e1000_hw *hw) | |||
2287 | s32 ret_val, hdr_csum, csum; | 2307 | s32 ret_val, hdr_csum, csum; |
2288 | u8 i, len; | 2308 | u8 i, len; |
2289 | 2309 | ||
2310 | hw->mac.tx_pkt_filtering = true; | ||
2311 | |||
2290 | /* No manageability, no filtering */ | 2312 | /* No manageability, no filtering */ |
2291 | if (!e1000e_check_mng_mode(hw)) { | 2313 | if (!e1000e_check_mng_mode(hw)) { |
2292 | hw->mac.tx_pkt_filtering = false; | 2314 | hw->mac.tx_pkt_filtering = false; |
2293 | return 0; | 2315 | goto out; |
2294 | } | 2316 | } |
2295 | 2317 | ||
2296 | /* | 2318 | /* |
@@ -2298,9 +2320,9 @@ bool e1000e_enable_tx_pkt_filtering(struct e1000_hw *hw) | |||
2298 | * reason, disable filtering. | 2320 | * reason, disable filtering. |
2299 | */ | 2321 | */ |
2300 | ret_val = e1000_mng_enable_host_if(hw); | 2322 | ret_val = e1000_mng_enable_host_if(hw); |
2301 | if (ret_val != 0) { | 2323 | if (ret_val) { |
2302 | hw->mac.tx_pkt_filtering = false; | 2324 | hw->mac.tx_pkt_filtering = false; |
2303 | return ret_val; | 2325 | goto out; |
2304 | } | 2326 | } |
2305 | 2327 | ||
2306 | /* Read in the header. Length and offset are in dwords. */ | 2328 | /* Read in the header. Length and offset are in dwords. */ |
@@ -2319,17 +2341,17 @@ bool e1000e_enable_tx_pkt_filtering(struct e1000_hw *hw) | |||
2319 | */ | 2341 | */ |
2320 | if ((hdr_csum != csum) || (hdr->signature != E1000_IAMT_SIGNATURE)) { | 2342 | if ((hdr_csum != csum) || (hdr->signature != E1000_IAMT_SIGNATURE)) { |
2321 | hw->mac.tx_pkt_filtering = true; | 2343 | hw->mac.tx_pkt_filtering = true; |
2322 | return 1; | 2344 | goto out; |
2323 | } | 2345 | } |
2324 | 2346 | ||
2325 | /* Cookie area is valid, make the final check for filtering. */ | 2347 | /* Cookie area is valid, make the final check for filtering. */ |
2326 | if (!(hdr->status & E1000_MNG_DHCP_COOKIE_STATUS_PARSING)) { | 2348 | if (!(hdr->status & E1000_MNG_DHCP_COOKIE_STATUS_PARSING)) { |
2327 | hw->mac.tx_pkt_filtering = false; | 2349 | hw->mac.tx_pkt_filtering = false; |
2328 | return 0; | 2350 | goto out; |
2329 | } | 2351 | } |
2330 | 2352 | ||
2331 | hw->mac.tx_pkt_filtering = true; | 2353 | out: |
2332 | return 1; | 2354 | return hw->mac.tx_pkt_filtering; |
2333 | } | 2355 | } |
2334 | 2356 | ||
2335 | /** | 2357 | /** |
diff --git a/drivers/net/e1000e/netdev.c b/drivers/net/e1000e/netdev.c index 762b697ce731..c45965a256b6 100644 --- a/drivers/net/e1000e/netdev.c +++ b/drivers/net/e1000e/netdev.c | |||
@@ -3315,24 +3315,24 @@ void e1000e_update_stats(struct e1000_adapter *adapter) | |||
3315 | if ((hw->phy.type == e1000_phy_82578) || | 3315 | if ((hw->phy.type == e1000_phy_82578) || |
3316 | (hw->phy.type == e1000_phy_82577)) { | 3316 | (hw->phy.type == e1000_phy_82577)) { |
3317 | e1e_rphy(hw, HV_SCC_UPPER, &phy_data); | 3317 | e1e_rphy(hw, HV_SCC_UPPER, &phy_data); |
3318 | e1e_rphy(hw, HV_SCC_LOWER, &phy_data); | 3318 | if (!e1e_rphy(hw, HV_SCC_LOWER, &phy_data)) |
3319 | adapter->stats.scc += phy_data; | 3319 | adapter->stats.scc += phy_data; |
3320 | 3320 | ||
3321 | e1e_rphy(hw, HV_ECOL_UPPER, &phy_data); | 3321 | e1e_rphy(hw, HV_ECOL_UPPER, &phy_data); |
3322 | e1e_rphy(hw, HV_ECOL_LOWER, &phy_data); | 3322 | if (!e1e_rphy(hw, HV_ECOL_LOWER, &phy_data)) |
3323 | adapter->stats.ecol += phy_data; | 3323 | adapter->stats.ecol += phy_data; |
3324 | 3324 | ||
3325 | e1e_rphy(hw, HV_MCC_UPPER, &phy_data); | 3325 | e1e_rphy(hw, HV_MCC_UPPER, &phy_data); |
3326 | e1e_rphy(hw, HV_MCC_LOWER, &phy_data); | 3326 | if (!e1e_rphy(hw, HV_MCC_LOWER, &phy_data)) |
3327 | adapter->stats.mcc += phy_data; | 3327 | adapter->stats.mcc += phy_data; |
3328 | 3328 | ||
3329 | e1e_rphy(hw, HV_LATECOL_UPPER, &phy_data); | 3329 | e1e_rphy(hw, HV_LATECOL_UPPER, &phy_data); |
3330 | e1e_rphy(hw, HV_LATECOL_LOWER, &phy_data); | 3330 | if (!e1e_rphy(hw, HV_LATECOL_LOWER, &phy_data)) |
3331 | adapter->stats.latecol += phy_data; | 3331 | adapter->stats.latecol += phy_data; |
3332 | 3332 | ||
3333 | e1e_rphy(hw, HV_DC_UPPER, &phy_data); | 3333 | e1e_rphy(hw, HV_DC_UPPER, &phy_data); |
3334 | e1e_rphy(hw, HV_DC_LOWER, &phy_data); | 3334 | if (!e1e_rphy(hw, HV_DC_LOWER, &phy_data)) |
3335 | adapter->stats.dc += phy_data; | 3335 | adapter->stats.dc += phy_data; |
3336 | } else { | 3336 | } else { |
3337 | adapter->stats.scc += er32(SCC); | 3337 | adapter->stats.scc += er32(SCC); |
3338 | adapter->stats.ecol += er32(ECOL); | 3338 | adapter->stats.ecol += er32(ECOL); |
@@ -3360,8 +3360,8 @@ void e1000e_update_stats(struct e1000_adapter *adapter) | |||
3360 | if ((hw->phy.type == e1000_phy_82578) || | 3360 | if ((hw->phy.type == e1000_phy_82578) || |
3361 | (hw->phy.type == e1000_phy_82577)) { | 3361 | (hw->phy.type == e1000_phy_82577)) { |
3362 | e1e_rphy(hw, HV_COLC_UPPER, &phy_data); | 3362 | e1e_rphy(hw, HV_COLC_UPPER, &phy_data); |
3363 | e1e_rphy(hw, HV_COLC_LOWER, &phy_data); | 3363 | if (!e1e_rphy(hw, HV_COLC_LOWER, &phy_data)) |
3364 | hw->mac.collision_delta = phy_data; | 3364 | hw->mac.collision_delta = phy_data; |
3365 | } else { | 3365 | } else { |
3366 | hw->mac.collision_delta = er32(COLC); | 3366 | hw->mac.collision_delta = er32(COLC); |
3367 | } | 3367 | } |
@@ -3372,8 +3372,8 @@ void e1000e_update_stats(struct e1000_adapter *adapter) | |||
3372 | if ((hw->phy.type == e1000_phy_82578) || | 3372 | if ((hw->phy.type == e1000_phy_82578) || |
3373 | (hw->phy.type == e1000_phy_82577)) { | 3373 | (hw->phy.type == e1000_phy_82577)) { |
3374 | e1e_rphy(hw, HV_TNCRS_UPPER, &phy_data); | 3374 | e1e_rphy(hw, HV_TNCRS_UPPER, &phy_data); |
3375 | e1e_rphy(hw, HV_TNCRS_LOWER, &phy_data); | 3375 | if (!e1e_rphy(hw, HV_TNCRS_LOWER, &phy_data)) |
3376 | adapter->stats.tncrs += phy_data; | 3376 | adapter->stats.tncrs += phy_data; |
3377 | } else { | 3377 | } else { |
3378 | if ((hw->mac.type != e1000_82574) && | 3378 | if ((hw->mac.type != e1000_82574) && |
3379 | (hw->mac.type != e1000_82583)) | 3379 | (hw->mac.type != e1000_82583)) |
@@ -4674,6 +4674,7 @@ static int e1000_resume(struct pci_dev *pdev) | |||
4674 | 4674 | ||
4675 | pci_set_power_state(pdev, PCI_D0); | 4675 | pci_set_power_state(pdev, PCI_D0); |
4676 | pci_restore_state(pdev); | 4676 | pci_restore_state(pdev); |
4677 | pci_save_state(pdev); | ||
4677 | e1000e_disable_l1aspm(pdev); | 4678 | e1000e_disable_l1aspm(pdev); |
4678 | 4679 | ||
4679 | err = pci_enable_device_mem(pdev); | 4680 | err = pci_enable_device_mem(pdev); |
@@ -4825,6 +4826,7 @@ static pci_ers_result_t e1000_io_slot_reset(struct pci_dev *pdev) | |||
4825 | } else { | 4826 | } else { |
4826 | pci_set_master(pdev); | 4827 | pci_set_master(pdev); |
4827 | pci_restore_state(pdev); | 4828 | pci_restore_state(pdev); |
4829 | pci_save_state(pdev); | ||
4828 | 4830 | ||
4829 | pci_enable_wake(pdev, PCI_D3hot, 0); | 4831 | pci_enable_wake(pdev, PCI_D3hot, 0); |
4830 | pci_enable_wake(pdev, PCI_D3cold, 0); | 4832 | pci_enable_wake(pdev, PCI_D3cold, 0); |
diff --git a/drivers/net/e1000e/phy.c b/drivers/net/e1000e/phy.c index 55a2c0acfee7..7f3ceb9dad6a 100644 --- a/drivers/net/e1000e/phy.c +++ b/drivers/net/e1000e/phy.c | |||
@@ -152,32 +152,9 @@ s32 e1000e_get_phy_id(struct e1000_hw *hw) | |||
152 | if (phy->id != 0 && phy->id != PHY_REVISION_MASK) | 152 | if (phy->id != 0 && phy->id != PHY_REVISION_MASK) |
153 | goto out; | 153 | goto out; |
154 | 154 | ||
155 | /* | ||
156 | * If the PHY ID is still unknown, we may have an 82577 | ||
157 | * without link. We will try again after setting Slow MDIC | ||
158 | * mode. No harm in trying again in this case since the PHY | ||
159 | * ID is unknown at this point anyway. | ||
160 | */ | ||
161 | ret_val = phy->ops.acquire(hw); | ||
162 | if (ret_val) | ||
163 | goto out; | ||
164 | ret_val = e1000_set_mdio_slow_mode_hv(hw, true); | ||
165 | if (ret_val) | ||
166 | goto out; | ||
167 | phy->ops.release(hw); | ||
168 | |||
169 | retry_count++; | 155 | retry_count++; |
170 | } | 156 | } |
171 | out: | 157 | out: |
172 | /* Revert to MDIO fast mode, if applicable */ | ||
173 | if (retry_count) { | ||
174 | ret_val = phy->ops.acquire(hw); | ||
175 | if (ret_val) | ||
176 | return ret_val; | ||
177 | ret_val = e1000_set_mdio_slow_mode_hv(hw, false); | ||
178 | phy->ops.release(hw); | ||
179 | } | ||
180 | |||
181 | return ret_val; | 158 | return ret_val; |
182 | } | 159 | } |
183 | 160 | ||
@@ -2791,38 +2768,6 @@ static s32 e1000_set_d0_lplu_state(struct e1000_hw *hw, bool active) | |||
2791 | } | 2768 | } |
2792 | 2769 | ||
2793 | /** | 2770 | /** |
2794 | * e1000_set_mdio_slow_mode_hv - Set slow MDIO access mode | ||
2795 | * @hw: pointer to the HW structure | ||
2796 | * @slow: true for slow mode, false for normal mode | ||
2797 | * | ||
2798 | * Assumes semaphore already acquired. | ||
2799 | **/ | ||
2800 | s32 e1000_set_mdio_slow_mode_hv(struct e1000_hw *hw, bool slow) | ||
2801 | { | ||
2802 | s32 ret_val = 0; | ||
2803 | u16 data = 0; | ||
2804 | |||
2805 | /* Set MDIO mode - page 769, register 16: 0x2580==slow, 0x2180==fast */ | ||
2806 | hw->phy.addr = 1; | ||
2807 | ret_val = e1000e_write_phy_reg_mdic(hw, IGP01E1000_PHY_PAGE_SELECT, | ||
2808 | (BM_PORT_CTRL_PAGE << IGP_PAGE_SHIFT)); | ||
2809 | if (ret_val) | ||
2810 | goto out; | ||
2811 | |||
2812 | ret_val = e1000e_write_phy_reg_mdic(hw, BM_CS_CTRL1, | ||
2813 | (0x2180 | (slow << 10))); | ||
2814 | if (ret_val) | ||
2815 | goto out; | ||
2816 | |||
2817 | /* dummy read when reverting to fast mode - throw away result */ | ||
2818 | if (!slow) | ||
2819 | ret_val = e1000e_read_phy_reg_mdic(hw, BM_CS_CTRL1, &data); | ||
2820 | |||
2821 | out: | ||
2822 | return ret_val; | ||
2823 | } | ||
2824 | |||
2825 | /** | ||
2826 | * __e1000_read_phy_reg_hv - Read HV PHY register | 2771 | * __e1000_read_phy_reg_hv - Read HV PHY register |
2827 | * @hw: pointer to the HW structure | 2772 | * @hw: pointer to the HW structure |
2828 | * @offset: register offset to be read | 2773 | * @offset: register offset to be read |
@@ -2839,7 +2784,6 @@ static s32 __e1000_read_phy_reg_hv(struct e1000_hw *hw, u32 offset, u16 *data, | |||
2839 | s32 ret_val; | 2784 | s32 ret_val; |
2840 | u16 page = BM_PHY_REG_PAGE(offset); | 2785 | u16 page = BM_PHY_REG_PAGE(offset); |
2841 | u16 reg = BM_PHY_REG_NUM(offset); | 2786 | u16 reg = BM_PHY_REG_NUM(offset); |
2842 | bool in_slow_mode = false; | ||
2843 | 2787 | ||
2844 | if (!locked) { | 2788 | if (!locked) { |
2845 | ret_val = hw->phy.ops.acquire(hw); | 2789 | ret_val = hw->phy.ops.acquire(hw); |
@@ -2847,16 +2791,6 @@ static s32 __e1000_read_phy_reg_hv(struct e1000_hw *hw, u32 offset, u16 *data, | |||
2847 | return ret_val; | 2791 | return ret_val; |
2848 | } | 2792 | } |
2849 | 2793 | ||
2850 | /* Workaround failure in MDIO access while cable is disconnected */ | ||
2851 | if ((hw->phy.type == e1000_phy_82577) && | ||
2852 | !(er32(STATUS) & E1000_STATUS_LU)) { | ||
2853 | ret_val = e1000_set_mdio_slow_mode_hv(hw, true); | ||
2854 | if (ret_val) | ||
2855 | goto out; | ||
2856 | |||
2857 | in_slow_mode = true; | ||
2858 | } | ||
2859 | |||
2860 | /* Page 800 works differently than the rest so it has its own func */ | 2794 | /* Page 800 works differently than the rest so it has its own func */ |
2861 | if (page == BM_WUC_PAGE) { | 2795 | if (page == BM_WUC_PAGE) { |
2862 | ret_val = e1000_access_phy_wakeup_reg_bm(hw, offset, | 2796 | ret_val = e1000_access_phy_wakeup_reg_bm(hw, offset, |
@@ -2893,10 +2827,6 @@ static s32 __e1000_read_phy_reg_hv(struct e1000_hw *hw, u32 offset, u16 *data, | |||
2893 | ret_val = e1000e_read_phy_reg_mdic(hw, MAX_PHY_REG_ADDRESS & reg, | 2827 | ret_val = e1000e_read_phy_reg_mdic(hw, MAX_PHY_REG_ADDRESS & reg, |
2894 | data); | 2828 | data); |
2895 | out: | 2829 | out: |
2896 | /* Revert to MDIO fast mode, if applicable */ | ||
2897 | if ((hw->phy.type == e1000_phy_82577) && in_slow_mode) | ||
2898 | ret_val |= e1000_set_mdio_slow_mode_hv(hw, false); | ||
2899 | |||
2900 | if (!locked) | 2830 | if (!locked) |
2901 | hw->phy.ops.release(hw); | 2831 | hw->phy.ops.release(hw); |
2902 | 2832 | ||
@@ -2948,7 +2878,6 @@ static s32 __e1000_write_phy_reg_hv(struct e1000_hw *hw, u32 offset, u16 data, | |||
2948 | s32 ret_val; | 2878 | s32 ret_val; |
2949 | u16 page = BM_PHY_REG_PAGE(offset); | 2879 | u16 page = BM_PHY_REG_PAGE(offset); |
2950 | u16 reg = BM_PHY_REG_NUM(offset); | 2880 | u16 reg = BM_PHY_REG_NUM(offset); |
2951 | bool in_slow_mode = false; | ||
2952 | 2881 | ||
2953 | if (!locked) { | 2882 | if (!locked) { |
2954 | ret_val = hw->phy.ops.acquire(hw); | 2883 | ret_val = hw->phy.ops.acquire(hw); |
@@ -2956,16 +2885,6 @@ static s32 __e1000_write_phy_reg_hv(struct e1000_hw *hw, u32 offset, u16 data, | |||
2956 | return ret_val; | 2885 | return ret_val; |
2957 | } | 2886 | } |
2958 | 2887 | ||
2959 | /* Workaround failure in MDIO access while cable is disconnected */ | ||
2960 | if ((hw->phy.type == e1000_phy_82577) && | ||
2961 | !(er32(STATUS) & E1000_STATUS_LU)) { | ||
2962 | ret_val = e1000_set_mdio_slow_mode_hv(hw, true); | ||
2963 | if (ret_val) | ||
2964 | goto out; | ||
2965 | |||
2966 | in_slow_mode = true; | ||
2967 | } | ||
2968 | |||
2969 | /* Page 800 works differently than the rest so it has its own func */ | 2888 | /* Page 800 works differently than the rest so it has its own func */ |
2970 | if (page == BM_WUC_PAGE) { | 2889 | if (page == BM_WUC_PAGE) { |
2971 | ret_val = e1000_access_phy_wakeup_reg_bm(hw, offset, | 2890 | ret_val = e1000_access_phy_wakeup_reg_bm(hw, offset, |
@@ -3019,10 +2938,6 @@ static s32 __e1000_write_phy_reg_hv(struct e1000_hw *hw, u32 offset, u16 data, | |||
3019 | data); | 2938 | data); |
3020 | 2939 | ||
3021 | out: | 2940 | out: |
3022 | /* Revert to MDIO fast mode, if applicable */ | ||
3023 | if ((hw->phy.type == e1000_phy_82577) && in_slow_mode) | ||
3024 | ret_val |= e1000_set_mdio_slow_mode_hv(hw, false); | ||
3025 | |||
3026 | if (!locked) | 2941 | if (!locked) |
3027 | hw->phy.ops.release(hw); | 2942 | hw->phy.ops.release(hw); |
3028 | 2943 | ||
diff --git a/drivers/net/fsl_pq_mdio.c b/drivers/net/fsl_pq_mdio.c index 25fabb3eedc5..d5160edf2fcf 100644 --- a/drivers/net/fsl_pq_mdio.c +++ b/drivers/net/fsl_pq_mdio.c | |||
@@ -46,6 +46,11 @@ | |||
46 | #include "gianfar.h" | 46 | #include "gianfar.h" |
47 | #include "fsl_pq_mdio.h" | 47 | #include "fsl_pq_mdio.h" |
48 | 48 | ||
49 | struct fsl_pq_mdio_priv { | ||
50 | void __iomem *map; | ||
51 | struct fsl_pq_mdio __iomem *regs; | ||
52 | }; | ||
53 | |||
49 | /* | 54 | /* |
50 | * Write value to the PHY at mii_id at register regnum, | 55 | * Write value to the PHY at mii_id at register regnum, |
51 | * on the bus attached to the local interface, which may be different from the | 56 | * on the bus attached to the local interface, which may be different from the |
@@ -105,7 +110,9 @@ int fsl_pq_local_mdio_read(struct fsl_pq_mdio __iomem *regs, | |||
105 | 110 | ||
106 | static struct fsl_pq_mdio __iomem *fsl_pq_mdio_get_regs(struct mii_bus *bus) | 111 | static struct fsl_pq_mdio __iomem *fsl_pq_mdio_get_regs(struct mii_bus *bus) |
107 | { | 112 | { |
108 | return (void __iomem __force *)bus->priv; | 113 | struct fsl_pq_mdio_priv *priv = bus->priv; |
114 | |||
115 | return priv->regs; | ||
109 | } | 116 | } |
110 | 117 | ||
111 | /* | 118 | /* |
@@ -266,6 +273,7 @@ static int fsl_pq_mdio_probe(struct of_device *ofdev, | |||
266 | { | 273 | { |
267 | struct device_node *np = ofdev->node; | 274 | struct device_node *np = ofdev->node; |
268 | struct device_node *tbi; | 275 | struct device_node *tbi; |
276 | struct fsl_pq_mdio_priv *priv; | ||
269 | struct fsl_pq_mdio __iomem *regs = NULL; | 277 | struct fsl_pq_mdio __iomem *regs = NULL; |
270 | void __iomem *map; | 278 | void __iomem *map; |
271 | u32 __iomem *tbipa; | 279 | u32 __iomem *tbipa; |
@@ -274,14 +282,19 @@ static int fsl_pq_mdio_probe(struct of_device *ofdev, | |||
274 | u64 addr = 0, size = 0; | 282 | u64 addr = 0, size = 0; |
275 | int err = 0; | 283 | int err = 0; |
276 | 284 | ||
285 | priv = kzalloc(sizeof(*priv), GFP_KERNEL); | ||
286 | if (!priv) | ||
287 | return -ENOMEM; | ||
288 | |||
277 | new_bus = mdiobus_alloc(); | 289 | new_bus = mdiobus_alloc(); |
278 | if (NULL == new_bus) | 290 | if (NULL == new_bus) |
279 | return -ENOMEM; | 291 | goto err_free_priv; |
280 | 292 | ||
281 | new_bus->name = "Freescale PowerQUICC MII Bus", | 293 | new_bus->name = "Freescale PowerQUICC MII Bus", |
282 | new_bus->read = &fsl_pq_mdio_read, | 294 | new_bus->read = &fsl_pq_mdio_read, |
283 | new_bus->write = &fsl_pq_mdio_write, | 295 | new_bus->write = &fsl_pq_mdio_write, |
284 | new_bus->reset = &fsl_pq_mdio_reset, | 296 | new_bus->reset = &fsl_pq_mdio_reset, |
297 | new_bus->priv = priv; | ||
285 | fsl_pq_mdio_bus_name(new_bus->id, np); | 298 | fsl_pq_mdio_bus_name(new_bus->id, np); |
286 | 299 | ||
287 | /* Set the PHY base address */ | 300 | /* Set the PHY base address */ |
@@ -291,6 +304,7 @@ static int fsl_pq_mdio_probe(struct of_device *ofdev, | |||
291 | err = -ENOMEM; | 304 | err = -ENOMEM; |
292 | goto err_free_bus; | 305 | goto err_free_bus; |
293 | } | 306 | } |
307 | priv->map = map; | ||
294 | 308 | ||
295 | if (of_device_is_compatible(np, "fsl,gianfar-mdio") || | 309 | if (of_device_is_compatible(np, "fsl,gianfar-mdio") || |
296 | of_device_is_compatible(np, "fsl,gianfar-tbi") || | 310 | of_device_is_compatible(np, "fsl,gianfar-tbi") || |
@@ -298,8 +312,7 @@ static int fsl_pq_mdio_probe(struct of_device *ofdev, | |||
298 | of_device_is_compatible(np, "ucc_geth_phy")) | 312 | of_device_is_compatible(np, "ucc_geth_phy")) |
299 | map -= offsetof(struct fsl_pq_mdio, miimcfg); | 313 | map -= offsetof(struct fsl_pq_mdio, miimcfg); |
300 | regs = map; | 314 | regs = map; |
301 | 315 | priv->regs = regs; | |
302 | new_bus->priv = (void __force *)regs; | ||
303 | 316 | ||
304 | new_bus->irq = kcalloc(PHY_MAX_ADDR, sizeof(int), GFP_KERNEL); | 317 | new_bus->irq = kcalloc(PHY_MAX_ADDR, sizeof(int), GFP_KERNEL); |
305 | 318 | ||
@@ -392,10 +405,11 @@ static int fsl_pq_mdio_probe(struct of_device *ofdev, | |||
392 | err_free_irqs: | 405 | err_free_irqs: |
393 | kfree(new_bus->irq); | 406 | kfree(new_bus->irq); |
394 | err_unmap_regs: | 407 | err_unmap_regs: |
395 | iounmap(regs); | 408 | iounmap(priv->map); |
396 | err_free_bus: | 409 | err_free_bus: |
397 | kfree(new_bus); | 410 | kfree(new_bus); |
398 | 411 | err_free_priv: | |
412 | kfree(priv); | ||
399 | return err; | 413 | return err; |
400 | } | 414 | } |
401 | 415 | ||
@@ -404,14 +418,16 @@ static int fsl_pq_mdio_remove(struct of_device *ofdev) | |||
404 | { | 418 | { |
405 | struct device *device = &ofdev->dev; | 419 | struct device *device = &ofdev->dev; |
406 | struct mii_bus *bus = dev_get_drvdata(device); | 420 | struct mii_bus *bus = dev_get_drvdata(device); |
421 | struct fsl_pq_mdio_priv *priv = bus->priv; | ||
407 | 422 | ||
408 | mdiobus_unregister(bus); | 423 | mdiobus_unregister(bus); |
409 | 424 | ||
410 | dev_set_drvdata(device, NULL); | 425 | dev_set_drvdata(device, NULL); |
411 | 426 | ||
412 | iounmap(fsl_pq_mdio_get_regs(bus)); | 427 | iounmap(priv->map); |
413 | bus->priv = NULL; | 428 | bus->priv = NULL; |
414 | mdiobus_free(bus); | 429 | mdiobus_free(bus); |
430 | kfree(priv); | ||
415 | 431 | ||
416 | return 0; | 432 | return 0; |
417 | } | 433 | } |
diff --git a/drivers/net/hamradio/bpqether.c b/drivers/net/hamradio/bpqether.c index ae5f11c8fc13..bdadf3e23c94 100644 --- a/drivers/net/hamradio/bpqether.c +++ b/drivers/net/hamradio/bpqether.c | |||
@@ -248,6 +248,7 @@ static netdev_tx_t bpq_xmit(struct sk_buff *skb, struct net_device *dev) | |||
248 | { | 248 | { |
249 | unsigned char *ptr; | 249 | unsigned char *ptr; |
250 | struct bpqdev *bpq; | 250 | struct bpqdev *bpq; |
251 | struct net_device *orig_dev; | ||
251 | int size; | 252 | int size; |
252 | 253 | ||
253 | /* | 254 | /* |
@@ -282,8 +283,9 @@ static netdev_tx_t bpq_xmit(struct sk_buff *skb, struct net_device *dev) | |||
282 | 283 | ||
283 | bpq = netdev_priv(dev); | 284 | bpq = netdev_priv(dev); |
284 | 285 | ||
286 | orig_dev = dev; | ||
285 | if ((dev = bpq_get_ether_dev(dev)) == NULL) { | 287 | if ((dev = bpq_get_ether_dev(dev)) == NULL) { |
286 | dev->stats.tx_dropped++; | 288 | orig_dev->stats.tx_dropped++; |
287 | kfree_skb(skb); | 289 | kfree_skb(skb); |
288 | return NETDEV_TX_OK; | 290 | return NETDEV_TX_OK; |
289 | } | 291 | } |
diff --git a/drivers/net/ixgbe/Makefile b/drivers/net/ixgbe/Makefile index 21b41f42b61c..bfef0ebcba9a 100644 --- a/drivers/net/ixgbe/Makefile +++ b/drivers/net/ixgbe/Makefile | |||
@@ -1,7 +1,7 @@ | |||
1 | ################################################################################ | 1 | ################################################################################ |
2 | # | 2 | # |
3 | # Intel 10 Gigabit PCI Express Linux driver | 3 | # Intel 10 Gigabit PCI Express Linux driver |
4 | # Copyright(c) 1999 - 2009 Intel Corporation. | 4 | # Copyright(c) 1999 - 2010 Intel Corporation. |
5 | # | 5 | # |
6 | # This program is free software; you can redistribute it and/or modify it | 6 | # This program is free software; you can redistribute it and/or modify it |
7 | # under the terms and conditions of the GNU General Public License, | 7 | # under the terms and conditions of the GNU General Public License, |
diff --git a/drivers/net/ixgbe/ixgbe.h b/drivers/net/ixgbe/ixgbe.h index 8da8eb535084..303e7bd39b67 100644 --- a/drivers/net/ixgbe/ixgbe.h +++ b/drivers/net/ixgbe/ixgbe.h | |||
@@ -1,7 +1,7 @@ | |||
1 | /******************************************************************************* | 1 | /******************************************************************************* |
2 | 2 | ||
3 | Intel 10 Gigabit PCI Express Linux driver | 3 | Intel 10 Gigabit PCI Express Linux driver |
4 | Copyright(c) 1999 - 2009 Intel Corporation. | 4 | Copyright(c) 1999 - 2010 Intel Corporation. |
5 | 5 | ||
6 | This program is free software; you can redistribute it and/or modify it | 6 | This program is free software; you can redistribute it and/or modify it |
7 | under the terms and conditions of the GNU General Public License, | 7 | under the terms and conditions of the GNU General Public License, |
diff --git a/drivers/net/ixgbe/ixgbe_82598.c b/drivers/net/ixgbe/ixgbe_82598.c index 204177d78cec..3103f4165311 100644 --- a/drivers/net/ixgbe/ixgbe_82598.c +++ b/drivers/net/ixgbe/ixgbe_82598.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /******************************************************************************* | 1 | /******************************************************************************* |
2 | 2 | ||
3 | Intel 10 Gigabit PCI Express Linux driver | 3 | Intel 10 Gigabit PCI Express Linux driver |
4 | Copyright(c) 1999 - 2009 Intel Corporation. | 4 | Copyright(c) 1999 - 2010 Intel Corporation. |
5 | 5 | ||
6 | This program is free software; you can redistribute it and/or modify it | 6 | This program is free software; you can redistribute it and/or modify it |
7 | under the terms and conditions of the GNU General Public License, | 7 | under the terms and conditions of the GNU General Public License, |
diff --git a/drivers/net/ixgbe/ixgbe_82599.c b/drivers/net/ixgbe/ixgbe_82599.c index 538340527aa6..b49bd6b9feb7 100644 --- a/drivers/net/ixgbe/ixgbe_82599.c +++ b/drivers/net/ixgbe/ixgbe_82599.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /******************************************************************************* | 1 | /******************************************************************************* |
2 | 2 | ||
3 | Intel 10 Gigabit PCI Express Linux driver | 3 | Intel 10 Gigabit PCI Express Linux driver |
4 | Copyright(c) 1999 - 2009 Intel Corporation. | 4 | Copyright(c) 1999 - 2010 Intel Corporation. |
5 | 5 | ||
6 | This program is free software; you can redistribute it and/or modify it | 6 | This program is free software; you can redistribute it and/or modify it |
7 | under the terms and conditions of the GNU General Public License, | 7 | under the terms and conditions of the GNU General Public License, |
diff --git a/drivers/net/ixgbe/ixgbe_common.c b/drivers/net/ixgbe/ixgbe_common.c index 688b8ca5da32..21f158f79dd0 100644 --- a/drivers/net/ixgbe/ixgbe_common.c +++ b/drivers/net/ixgbe/ixgbe_common.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /******************************************************************************* | 1 | /******************************************************************************* |
2 | 2 | ||
3 | Intel 10 Gigabit PCI Express Linux driver | 3 | Intel 10 Gigabit PCI Express Linux driver |
4 | Copyright(c) 1999 - 2009 Intel Corporation. | 4 | Copyright(c) 1999 - 2010 Intel Corporation. |
5 | 5 | ||
6 | This program is free software; you can redistribute it and/or modify it | 6 | This program is free software; you can redistribute it and/or modify it |
7 | under the terms and conditions of the GNU General Public License, | 7 | under the terms and conditions of the GNU General Public License, |
diff --git a/drivers/net/ixgbe/ixgbe_common.h b/drivers/net/ixgbe/ixgbe_common.h index 27f3214bed2e..dfff0ffaa502 100644 --- a/drivers/net/ixgbe/ixgbe_common.h +++ b/drivers/net/ixgbe/ixgbe_common.h | |||
@@ -1,7 +1,7 @@ | |||
1 | /******************************************************************************* | 1 | /******************************************************************************* |
2 | 2 | ||
3 | Intel 10 Gigabit PCI Express Linux driver | 3 | Intel 10 Gigabit PCI Express Linux driver |
4 | Copyright(c) 1999 - 2009 Intel Corporation. | 4 | Copyright(c) 1999 - 2010 Intel Corporation. |
5 | 5 | ||
6 | This program is free software; you can redistribute it and/or modify it | 6 | This program is free software; you can redistribute it and/or modify it |
7 | under the terms and conditions of the GNU General Public License, | 7 | under the terms and conditions of the GNU General Public License, |
diff --git a/drivers/net/ixgbe/ixgbe_dcb.c b/drivers/net/ixgbe/ixgbe_dcb.c index a1562287342f..9aea4f04bbd2 100644 --- a/drivers/net/ixgbe/ixgbe_dcb.c +++ b/drivers/net/ixgbe/ixgbe_dcb.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /******************************************************************************* | 1 | /******************************************************************************* |
2 | 2 | ||
3 | Intel 10 Gigabit PCI Express Linux driver | 3 | Intel 10 Gigabit PCI Express Linux driver |
4 | Copyright(c) 1999 - 2009 Intel Corporation. | 4 | Copyright(c) 1999 - 2010 Intel Corporation. |
5 | 5 | ||
6 | This program is free software; you can redistribute it and/or modify it | 6 | This program is free software; you can redistribute it and/or modify it |
7 | under the terms and conditions of the GNU General Public License, | 7 | under the terms and conditions of the GNU General Public License, |
diff --git a/drivers/net/ixgbe/ixgbe_dcb.h b/drivers/net/ixgbe/ixgbe_dcb.h index 64a9fa15c059..5caafd4afbc3 100644 --- a/drivers/net/ixgbe/ixgbe_dcb.h +++ b/drivers/net/ixgbe/ixgbe_dcb.h | |||
@@ -1,7 +1,7 @@ | |||
1 | /******************************************************************************* | 1 | /******************************************************************************* |
2 | 2 | ||
3 | Intel 10 Gigabit PCI Express Linux driver | 3 | Intel 10 Gigabit PCI Express Linux driver |
4 | Copyright(c) 1999 - 2009 Intel Corporation. | 4 | Copyright(c) 1999 - 2010 Intel Corporation. |
5 | 5 | ||
6 | This program is free software; you can redistribute it and/or modify it | 6 | This program is free software; you can redistribute it and/or modify it |
7 | under the terms and conditions of the GNU General Public License, | 7 | under the terms and conditions of the GNU General Public License, |
diff --git a/drivers/net/ixgbe/ixgbe_dcb_82598.c b/drivers/net/ixgbe/ixgbe_dcb_82598.c index f30263898ebc..f0e9279d4669 100644 --- a/drivers/net/ixgbe/ixgbe_dcb_82598.c +++ b/drivers/net/ixgbe/ixgbe_dcb_82598.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /******************************************************************************* | 1 | /******************************************************************************* |
2 | 2 | ||
3 | Intel 10 Gigabit PCI Express Linux driver | 3 | Intel 10 Gigabit PCI Express Linux driver |
4 | Copyright(c) 1999 - 2009 Intel Corporation. | 4 | Copyright(c) 1999 - 2010 Intel Corporation. |
5 | 5 | ||
6 | This program is free software; you can redistribute it and/or modify it | 6 | This program is free software; you can redistribute it and/or modify it |
7 | under the terms and conditions of the GNU General Public License, | 7 | under the terms and conditions of the GNU General Public License, |
diff --git a/drivers/net/ixgbe/ixgbe_dcb_82598.h b/drivers/net/ixgbe/ixgbe_dcb_82598.h index ebbe53c352a7..cc728fa092e2 100644 --- a/drivers/net/ixgbe/ixgbe_dcb_82598.h +++ b/drivers/net/ixgbe/ixgbe_dcb_82598.h | |||
@@ -1,7 +1,7 @@ | |||
1 | /******************************************************************************* | 1 | /******************************************************************************* |
2 | 2 | ||
3 | Intel 10 Gigabit PCI Express Linux driver | 3 | Intel 10 Gigabit PCI Express Linux driver |
4 | Copyright(c) 1999 - 2009 Intel Corporation. | 4 | Copyright(c) 1999 - 2010 Intel Corporation. |
5 | 5 | ||
6 | This program is free software; you can redistribute it and/or modify it | 6 | This program is free software; you can redistribute it and/or modify it |
7 | under the terms and conditions of the GNU General Public License, | 7 | under the terms and conditions of the GNU General Public License, |
diff --git a/drivers/net/ixgbe/ixgbe_dcb_82599.c b/drivers/net/ixgbe/ixgbe_dcb_82599.c index ec8a252636d3..4f7a26ab411e 100644 --- a/drivers/net/ixgbe/ixgbe_dcb_82599.c +++ b/drivers/net/ixgbe/ixgbe_dcb_82599.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /******************************************************************************* | 1 | /******************************************************************************* |
2 | 2 | ||
3 | Intel 10 Gigabit PCI Express Linux driver | 3 | Intel 10 Gigabit PCI Express Linux driver |
4 | Copyright(c) 1999 - 2009 Intel Corporation. | 4 | Copyright(c) 1999 - 2010 Intel Corporation. |
5 | 5 | ||
6 | This program is free software; you can redistribute it and/or modify it | 6 | This program is free software; you can redistribute it and/or modify it |
7 | under the terms and conditions of the GNU General Public License, | 7 | under the terms and conditions of the GNU General Public License, |
diff --git a/drivers/net/ixgbe/ixgbe_dcb_82599.h b/drivers/net/ixgbe/ixgbe_dcb_82599.h index 9e5e2827e4af..0f3f791e1e1d 100644 --- a/drivers/net/ixgbe/ixgbe_dcb_82599.h +++ b/drivers/net/ixgbe/ixgbe_dcb_82599.h | |||
@@ -1,7 +1,7 @@ | |||
1 | /******************************************************************************* | 1 | /******************************************************************************* |
2 | 2 | ||
3 | Intel 10 Gigabit PCI Express Linux driver | 3 | Intel 10 Gigabit PCI Express Linux driver |
4 | Copyright(c) 1999 - 2009 Intel Corporation. | 4 | Copyright(c) 1999 - 2010 Intel Corporation. |
5 | 5 | ||
6 | This program is free software; you can redistribute it and/or modify it | 6 | This program is free software; you can redistribute it and/or modify it |
7 | under the terms and conditions of the GNU General Public License, | 7 | under the terms and conditions of the GNU General Public License, |
diff --git a/drivers/net/ixgbe/ixgbe_dcb_nl.c b/drivers/net/ixgbe/ixgbe_dcb_nl.c index 3c7a79a7d7c6..56f37f66b696 100644 --- a/drivers/net/ixgbe/ixgbe_dcb_nl.c +++ b/drivers/net/ixgbe/ixgbe_dcb_nl.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /******************************************************************************* | 1 | /******************************************************************************* |
2 | 2 | ||
3 | Intel 10 Gigabit PCI Express Linux driver | 3 | Intel 10 Gigabit PCI Express Linux driver |
4 | Copyright(c) 1999 - 2009 Intel Corporation. | 4 | Copyright(c) 1999 - 2010 Intel Corporation. |
5 | 5 | ||
6 | This program is free software; you can redistribute it and/or modify it | 6 | This program is free software; you can redistribute it and/or modify it |
7 | under the terms and conditions of the GNU General Public License, | 7 | under the terms and conditions of the GNU General Public License, |
diff --git a/drivers/net/ixgbe/ixgbe_ethtool.c b/drivers/net/ixgbe/ixgbe_ethtool.c index 0bd49d3b9f65..d77961fc75f9 100644 --- a/drivers/net/ixgbe/ixgbe_ethtool.c +++ b/drivers/net/ixgbe/ixgbe_ethtool.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /******************************************************************************* | 1 | /******************************************************************************* |
2 | 2 | ||
3 | Intel 10 Gigabit PCI Express Linux driver | 3 | Intel 10 Gigabit PCI Express Linux driver |
4 | Copyright(c) 1999 - 2009 Intel Corporation. | 4 | Copyright(c) 1999 - 2010 Intel Corporation. |
5 | 5 | ||
6 | This program is free software; you can redistribute it and/or modify it | 6 | This program is free software; you can redistribute it and/or modify it |
7 | under the terms and conditions of the GNU General Public License, | 7 | under the terms and conditions of the GNU General Public License, |
diff --git a/drivers/net/ixgbe/ixgbe_fcoe.c b/drivers/net/ixgbe/ixgbe_fcoe.c index da32a108a7b4..e9a20c88c155 100644 --- a/drivers/net/ixgbe/ixgbe_fcoe.c +++ b/drivers/net/ixgbe/ixgbe_fcoe.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /******************************************************************************* | 1 | /******************************************************************************* |
2 | 2 | ||
3 | Intel 10 Gigabit PCI Express Linux driver | 3 | Intel 10 Gigabit PCI Express Linux driver |
4 | Copyright(c) 1999 - 2009 Intel Corporation. | 4 | Copyright(c) 1999 - 2010 Intel Corporation. |
5 | 5 | ||
6 | This program is free software; you can redistribute it and/or modify it | 6 | This program is free software; you can redistribute it and/or modify it |
7 | under the terms and conditions of the GNU General Public License, | 7 | under the terms and conditions of the GNU General Public License, |
diff --git a/drivers/net/ixgbe/ixgbe_fcoe.h b/drivers/net/ixgbe/ixgbe_fcoe.h index de8ff53187da..abf4b2b3f252 100644 --- a/drivers/net/ixgbe/ixgbe_fcoe.h +++ b/drivers/net/ixgbe/ixgbe_fcoe.h | |||
@@ -1,7 +1,7 @@ | |||
1 | /******************************************************************************* | 1 | /******************************************************************************* |
2 | 2 | ||
3 | Intel 10 Gigabit PCI Express Linux driver | 3 | Intel 10 Gigabit PCI Express Linux driver |
4 | Copyright(c) 1999 - 2009 Intel Corporation. | 4 | Copyright(c) 1999 - 2010 Intel Corporation. |
5 | 5 | ||
6 | This program is free software; you can redistribute it and/or modify it | 6 | This program is free software; you can redistribute it and/or modify it |
7 | under the terms and conditions of the GNU General Public License, | 7 | under the terms and conditions of the GNU General Public License, |
diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index 1a2ea621e371..9c9202f40b10 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /******************************************************************************* | 1 | /******************************************************************************* |
2 | 2 | ||
3 | Intel 10 Gigabit PCI Express Linux driver | 3 | Intel 10 Gigabit PCI Express Linux driver |
4 | Copyright(c) 1999 - 2009 Intel Corporation. | 4 | Copyright(c) 1999 - 2010 Intel Corporation. |
5 | 5 | ||
6 | This program is free software; you can redistribute it and/or modify it | 6 | This program is free software; you can redistribute it and/or modify it |
7 | under the terms and conditions of the GNU General Public License, | 7 | under the terms and conditions of the GNU General Public License, |
@@ -52,7 +52,7 @@ static const char ixgbe_driver_string[] = | |||
52 | 52 | ||
53 | #define DRV_VERSION "2.0.44-k2" | 53 | #define DRV_VERSION "2.0.44-k2" |
54 | const char ixgbe_driver_version[] = DRV_VERSION; | 54 | const char ixgbe_driver_version[] = DRV_VERSION; |
55 | static char ixgbe_copyright[] = "Copyright (c) 1999-2009 Intel Corporation."; | 55 | static char ixgbe_copyright[] = "Copyright (c) 1999-2010 Intel Corporation."; |
56 | 56 | ||
57 | static const struct ixgbe_info *ixgbe_info_tbl[] = { | 57 | static const struct ixgbe_info *ixgbe_info_tbl[] = { |
58 | [board_82598] = &ixgbe_82598_info, | 58 | [board_82598] = &ixgbe_82598_info, |
@@ -262,10 +262,12 @@ static inline bool ixgbe_tx_is_paused(struct ixgbe_adapter *adapter, | |||
262 | int reg_idx = tx_ring->reg_idx; | 262 | int reg_idx = tx_ring->reg_idx; |
263 | int dcb_i = adapter->ring_feature[RING_F_DCB].indices; | 263 | int dcb_i = adapter->ring_feature[RING_F_DCB].indices; |
264 | 264 | ||
265 | if (adapter->hw.mac.type == ixgbe_mac_82598EB) { | 265 | switch (adapter->hw.mac.type) { |
266 | case ixgbe_mac_82598EB: | ||
266 | tc = reg_idx >> 2; | 267 | tc = reg_idx >> 2; |
267 | txoff = IXGBE_TFCS_TXOFF0; | 268 | txoff = IXGBE_TFCS_TXOFF0; |
268 | } else if (adapter->hw.mac.type == ixgbe_mac_82599EB) { | 269 | break; |
270 | case ixgbe_mac_82599EB: | ||
269 | tc = 0; | 271 | tc = 0; |
270 | txoff = IXGBE_TFCS_TXOFF; | 272 | txoff = IXGBE_TFCS_TXOFF; |
271 | if (dcb_i == 8) { | 273 | if (dcb_i == 8) { |
@@ -284,6 +286,9 @@ static inline bool ixgbe_tx_is_paused(struct ixgbe_adapter *adapter, | |||
284 | tc += (reg_idx - 96) >> 4; | 286 | tc += (reg_idx - 96) >> 4; |
285 | } | 287 | } |
286 | } | 288 | } |
289 | break; | ||
290 | default: | ||
291 | tc = 0; | ||
287 | } | 292 | } |
288 | txoff <<= tc; | 293 | txoff <<= tc; |
289 | } | 294 | } |
@@ -5571,6 +5576,10 @@ static void ixgbe_netpoll(struct net_device *netdev) | |||
5571 | struct ixgbe_adapter *adapter = netdev_priv(netdev); | 5576 | struct ixgbe_adapter *adapter = netdev_priv(netdev); |
5572 | int i; | 5577 | int i; |
5573 | 5578 | ||
5579 | /* if interface is down do nothing */ | ||
5580 | if (test_bit(__IXGBE_DOWN, &adapter->state)) | ||
5581 | return; | ||
5582 | |||
5574 | adapter->flags |= IXGBE_FLAG_IN_NETPOLL; | 5583 | adapter->flags |= IXGBE_FLAG_IN_NETPOLL; |
5575 | if (adapter->flags & IXGBE_FLAG_MSIX_ENABLED) { | 5584 | if (adapter->flags & IXGBE_FLAG_MSIX_ENABLED) { |
5576 | int num_q_vectors = adapter->num_msix_vectors - NON_Q_VECTORS; | 5585 | int num_q_vectors = adapter->num_msix_vectors - NON_Q_VECTORS; |
diff --git a/drivers/net/ixgbe/ixgbe_phy.c b/drivers/net/ixgbe/ixgbe_phy.c index 9ecad17522c3..1c1efd386956 100644 --- a/drivers/net/ixgbe/ixgbe_phy.c +++ b/drivers/net/ixgbe/ixgbe_phy.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /******************************************************************************* | 1 | /******************************************************************************* |
2 | 2 | ||
3 | Intel 10 Gigabit PCI Express Linux driver | 3 | Intel 10 Gigabit PCI Express Linux driver |
4 | Copyright(c) 1999 - 2009 Intel Corporation. | 4 | Copyright(c) 1999 - 2010 Intel Corporation. |
5 | 5 | ||
6 | This program is free software; you can redistribute it and/or modify it | 6 | This program is free software; you can redistribute it and/or modify it |
7 | under the terms and conditions of the GNU General Public License, | 7 | under the terms and conditions of the GNU General Public License, |
diff --git a/drivers/net/ixgbe/ixgbe_phy.h b/drivers/net/ixgbe/ixgbe_phy.h index 9b700f5bf1ed..9cf5f3b4cc5d 100644 --- a/drivers/net/ixgbe/ixgbe_phy.h +++ b/drivers/net/ixgbe/ixgbe_phy.h | |||
@@ -1,7 +1,7 @@ | |||
1 | /******************************************************************************* | 1 | /******************************************************************************* |
2 | 2 | ||
3 | Intel 10 Gigabit PCI Express Linux driver | 3 | Intel 10 Gigabit PCI Express Linux driver |
4 | Copyright(c) 1999 - 2009 Intel Corporation. | 4 | Copyright(c) 1999 - 2010 Intel Corporation. |
5 | 5 | ||
6 | This program is free software; you can redistribute it and/or modify it | 6 | This program is free software; you can redistribute it and/or modify it |
7 | under the terms and conditions of the GNU General Public License, | 7 | under the terms and conditions of the GNU General Public License, |
diff --git a/drivers/net/ixgbe/ixgbe_type.h b/drivers/net/ixgbe/ixgbe_type.h index 84650c6ebe03..9eafddfa1b97 100644 --- a/drivers/net/ixgbe/ixgbe_type.h +++ b/drivers/net/ixgbe/ixgbe_type.h | |||
@@ -1,7 +1,7 @@ | |||
1 | /******************************************************************************* | 1 | /******************************************************************************* |
2 | 2 | ||
3 | Intel 10 Gigabit PCI Express Linux driver | 3 | Intel 10 Gigabit PCI Express Linux driver |
4 | Copyright(c) 1999 - 2009 Intel Corporation. | 4 | Copyright(c) 1999 - 2010 Intel Corporation. |
5 | 5 | ||
6 | This program is free software; you can redistribute it and/or modify it | 6 | This program is free software; you can redistribute it and/or modify it |
7 | under the terms and conditions of the GNU General Public License, | 7 | under the terms and conditions of the GNU General Public License, |
diff --git a/drivers/net/ll_temac_main.c b/drivers/net/ll_temac_main.c index 336e7c7a9275..a8522bd73ae7 100644 --- a/drivers/net/ll_temac_main.c +++ b/drivers/net/ll_temac_main.c | |||
@@ -134,7 +134,7 @@ static int temac_dma_bd_init(struct net_device *ndev) | |||
134 | struct sk_buff *skb; | 134 | struct sk_buff *skb; |
135 | int i; | 135 | int i; |
136 | 136 | ||
137 | lp->rx_skb = kzalloc(sizeof(struct sk_buff)*RX_BD_NUM, GFP_KERNEL); | 137 | lp->rx_skb = kzalloc(sizeof(*lp->rx_skb) * RX_BD_NUM, GFP_KERNEL); |
138 | /* allocate the tx and rx ring buffer descriptors. */ | 138 | /* allocate the tx and rx ring buffer descriptors. */ |
139 | /* returns a virtual addres and a physical address. */ | 139 | /* returns a virtual addres and a physical address. */ |
140 | lp->tx_bd_v = dma_alloc_coherent(ndev->dev.parent, | 140 | lp->tx_bd_v = dma_alloc_coherent(ndev->dev.parent, |
diff --git a/drivers/net/mlx4/main.c b/drivers/net/mlx4/main.c index 291a505fd4fc..3cf56d90d859 100644 --- a/drivers/net/mlx4/main.c +++ b/drivers/net/mlx4/main.c | |||
@@ -1174,7 +1174,7 @@ static int __mlx4_init_one(struct pci_dev *pdev, const struct pci_device_id *id) | |||
1174 | return 0; | 1174 | return 0; |
1175 | 1175 | ||
1176 | err_port: | 1176 | err_port: |
1177 | for (port = 1; port <= dev->caps.num_ports; port++) | 1177 | for (--port; port >= 1; --port) |
1178 | mlx4_cleanup_port_info(&priv->port[port]); | 1178 | mlx4_cleanup_port_info(&priv->port[port]); |
1179 | 1179 | ||
1180 | mlx4_cleanup_mcg_table(dev); | 1180 | mlx4_cleanup_mcg_table(dev); |
diff --git a/drivers/net/mv643xx_eth.c b/drivers/net/mv643xx_eth.c index 1405a170bb43..af67af55efe7 100644 --- a/drivers/net/mv643xx_eth.c +++ b/drivers/net/mv643xx_eth.c | |||
@@ -656,6 +656,7 @@ static int rxq_refill(struct rx_queue *rxq, int budget) | |||
656 | struct sk_buff *skb; | 656 | struct sk_buff *skb; |
657 | int rx; | 657 | int rx; |
658 | struct rx_desc *rx_desc; | 658 | struct rx_desc *rx_desc; |
659 | int size; | ||
659 | 660 | ||
660 | skb = __skb_dequeue(&mp->rx_recycle); | 661 | skb = __skb_dequeue(&mp->rx_recycle); |
661 | if (skb == NULL) | 662 | if (skb == NULL) |
@@ -678,10 +679,11 @@ static int rxq_refill(struct rx_queue *rxq, int budget) | |||
678 | 679 | ||
679 | rx_desc = rxq->rx_desc_area + rx; | 680 | rx_desc = rxq->rx_desc_area + rx; |
680 | 681 | ||
682 | size = skb->end - skb->data; | ||
681 | rx_desc->buf_ptr = dma_map_single(mp->dev->dev.parent, | 683 | rx_desc->buf_ptr = dma_map_single(mp->dev->dev.parent, |
682 | skb->data, mp->skb_size, | 684 | skb->data, size, |
683 | DMA_FROM_DEVICE); | 685 | DMA_FROM_DEVICE); |
684 | rx_desc->buf_size = mp->skb_size; | 686 | rx_desc->buf_size = size; |
685 | rxq->rx_skb[rx] = skb; | 687 | rxq->rx_skb[rx] = skb; |
686 | wmb(); | 688 | wmb(); |
687 | rx_desc->cmd_sts = BUFFER_OWNED_BY_DMA | RX_ENABLE_INTERRUPT; | 689 | rx_desc->cmd_sts = BUFFER_OWNED_BY_DMA | RX_ENABLE_INTERRUPT; |
diff --git a/drivers/net/netxen/netxen_nic.h b/drivers/net/netxen/netxen_nic.h index 76cd1f3e9fc8..9bc5bd1d538a 100644 --- a/drivers/net/netxen/netxen_nic.h +++ b/drivers/net/netxen/netxen_nic.h | |||
@@ -53,8 +53,8 @@ | |||
53 | 53 | ||
54 | #define _NETXEN_NIC_LINUX_MAJOR 4 | 54 | #define _NETXEN_NIC_LINUX_MAJOR 4 |
55 | #define _NETXEN_NIC_LINUX_MINOR 0 | 55 | #define _NETXEN_NIC_LINUX_MINOR 0 |
56 | #define _NETXEN_NIC_LINUX_SUBVERSION 65 | 56 | #define _NETXEN_NIC_LINUX_SUBVERSION 72 |
57 | #define NETXEN_NIC_LINUX_VERSIONID "4.0.65" | 57 | #define NETXEN_NIC_LINUX_VERSIONID "4.0.72" |
58 | 58 | ||
59 | #define NETXEN_VERSION_CODE(a, b, c) (((a) << 24) + ((b) << 16) + (c)) | 59 | #define NETXEN_VERSION_CODE(a, b, c) (((a) << 24) + ((b) << 16) + (c)) |
60 | #define _major(v) (((v) >> 24) & 0xff) | 60 | #define _major(v) (((v) >> 24) & 0xff) |
diff --git a/drivers/net/netxen/netxen_nic_ethtool.c b/drivers/net/netxen/netxen_nic_ethtool.c index ddd704ae0188..542f408333ff 100644 --- a/drivers/net/netxen/netxen_nic_ethtool.c +++ b/drivers/net/netxen/netxen_nic_ethtool.c | |||
@@ -66,7 +66,7 @@ static const char netxen_nic_gstrings_test[][ETH_GSTRING_LEN] = { | |||
66 | 66 | ||
67 | #define NETXEN_NIC_TEST_LEN ARRAY_SIZE(netxen_nic_gstrings_test) | 67 | #define NETXEN_NIC_TEST_LEN ARRAY_SIZE(netxen_nic_gstrings_test) |
68 | 68 | ||
69 | #define NETXEN_NIC_REGS_COUNT 42 | 69 | #define NETXEN_NIC_REGS_COUNT 30 |
70 | #define NETXEN_NIC_REGS_LEN (NETXEN_NIC_REGS_COUNT * sizeof(__le32)) | 70 | #define NETXEN_NIC_REGS_LEN (NETXEN_NIC_REGS_COUNT * sizeof(__le32)) |
71 | #define NETXEN_MAX_EEPROM_LEN 1024 | 71 | #define NETXEN_MAX_EEPROM_LEN 1024 |
72 | 72 | ||
@@ -312,150 +312,91 @@ static int netxen_nic_get_regs_len(struct net_device *dev) | |||
312 | return NETXEN_NIC_REGS_LEN; | 312 | return NETXEN_NIC_REGS_LEN; |
313 | } | 313 | } |
314 | 314 | ||
315 | struct netxen_niu_regs { | ||
316 | __u32 reg[NETXEN_NIC_REGS_COUNT]; | ||
317 | }; | ||
318 | |||
319 | static struct netxen_niu_regs niu_registers[] = { | ||
320 | { | ||
321 | /* GB Mode */ | ||
322 | { | ||
323 | NETXEN_NIU_GB_SERDES_RESET, | ||
324 | NETXEN_NIU_GB0_MII_MODE, | ||
325 | NETXEN_NIU_GB1_MII_MODE, | ||
326 | NETXEN_NIU_GB2_MII_MODE, | ||
327 | NETXEN_NIU_GB3_MII_MODE, | ||
328 | NETXEN_NIU_GB0_GMII_MODE, | ||
329 | NETXEN_NIU_GB1_GMII_MODE, | ||
330 | NETXEN_NIU_GB2_GMII_MODE, | ||
331 | NETXEN_NIU_GB3_GMII_MODE, | ||
332 | NETXEN_NIU_REMOTE_LOOPBACK, | ||
333 | NETXEN_NIU_GB0_HALF_DUPLEX, | ||
334 | NETXEN_NIU_GB1_HALF_DUPLEX, | ||
335 | NETXEN_NIU_RESET_SYS_FIFOS, | ||
336 | NETXEN_NIU_GB_CRC_DROP, | ||
337 | NETXEN_NIU_GB_DROP_WRONGADDR, | ||
338 | NETXEN_NIU_TEST_MUX_CTL, | ||
339 | |||
340 | NETXEN_NIU_GB_MAC_CONFIG_0(0), | ||
341 | NETXEN_NIU_GB_MAC_CONFIG_1(0), | ||
342 | NETXEN_NIU_GB_HALF_DUPLEX_CTRL(0), | ||
343 | NETXEN_NIU_GB_MAX_FRAME_SIZE(0), | ||
344 | NETXEN_NIU_GB_TEST_REG(0), | ||
345 | NETXEN_NIU_GB_MII_MGMT_CONFIG(0), | ||
346 | NETXEN_NIU_GB_MII_MGMT_COMMAND(0), | ||
347 | NETXEN_NIU_GB_MII_MGMT_ADDR(0), | ||
348 | NETXEN_NIU_GB_MII_MGMT_CTRL(0), | ||
349 | NETXEN_NIU_GB_MII_MGMT_STATUS(0), | ||
350 | NETXEN_NIU_GB_MII_MGMT_INDICATE(0), | ||
351 | NETXEN_NIU_GB_INTERFACE_CTRL(0), | ||
352 | NETXEN_NIU_GB_INTERFACE_STATUS(0), | ||
353 | NETXEN_NIU_GB_STATION_ADDR_0(0), | ||
354 | NETXEN_NIU_GB_STATION_ADDR_1(0), | ||
355 | -1, | ||
356 | } | ||
357 | }, | ||
358 | { | ||
359 | /* XG Mode */ | ||
360 | { | ||
361 | NETXEN_NIU_XG_SINGLE_TERM, | ||
362 | NETXEN_NIU_XG_DRIVE_HI, | ||
363 | NETXEN_NIU_XG_DRIVE_LO, | ||
364 | NETXEN_NIU_XG_DTX, | ||
365 | NETXEN_NIU_XG_DEQ, | ||
366 | NETXEN_NIU_XG_WORD_ALIGN, | ||
367 | NETXEN_NIU_XG_RESET, | ||
368 | NETXEN_NIU_XG_POWER_DOWN, | ||
369 | NETXEN_NIU_XG_RESET_PLL, | ||
370 | NETXEN_NIU_XG_SERDES_LOOPBACK, | ||
371 | NETXEN_NIU_XG_DO_BYTE_ALIGN, | ||
372 | NETXEN_NIU_XG_TX_ENABLE, | ||
373 | NETXEN_NIU_XG_RX_ENABLE, | ||
374 | NETXEN_NIU_XG_STATUS, | ||
375 | NETXEN_NIU_XG_PAUSE_THRESHOLD, | ||
376 | NETXEN_NIU_XGE_CONFIG_0, | ||
377 | NETXEN_NIU_XGE_CONFIG_1, | ||
378 | NETXEN_NIU_XGE_IPG, | ||
379 | NETXEN_NIU_XGE_STATION_ADDR_0_HI, | ||
380 | NETXEN_NIU_XGE_STATION_ADDR_0_1, | ||
381 | NETXEN_NIU_XGE_STATION_ADDR_1_LO, | ||
382 | NETXEN_NIU_XGE_STATUS, | ||
383 | NETXEN_NIU_XGE_MAX_FRAME_SIZE, | ||
384 | NETXEN_NIU_XGE_PAUSE_FRAME_VALUE, | ||
385 | NETXEN_NIU_XGE_TX_BYTE_CNT, | ||
386 | NETXEN_NIU_XGE_TX_FRAME_CNT, | ||
387 | NETXEN_NIU_XGE_RX_BYTE_CNT, | ||
388 | NETXEN_NIU_XGE_RX_FRAME_CNT, | ||
389 | NETXEN_NIU_XGE_AGGR_ERROR_CNT, | ||
390 | NETXEN_NIU_XGE_MULTICAST_FRAME_CNT, | ||
391 | NETXEN_NIU_XGE_UNICAST_FRAME_CNT, | ||
392 | NETXEN_NIU_XGE_CRC_ERROR_CNT, | ||
393 | NETXEN_NIU_XGE_OVERSIZE_FRAME_ERR, | ||
394 | NETXEN_NIU_XGE_UNDERSIZE_FRAME_ERR, | ||
395 | NETXEN_NIU_XGE_LOCAL_ERROR_CNT, | ||
396 | NETXEN_NIU_XGE_REMOTE_ERROR_CNT, | ||
397 | NETXEN_NIU_XGE_CONTROL_CHAR_CNT, | ||
398 | NETXEN_NIU_XGE_PAUSE_FRAME_CNT, | ||
399 | -1, | ||
400 | } | ||
401 | } | ||
402 | }; | ||
403 | |||
404 | static void | 315 | static void |
405 | netxen_nic_get_regs(struct net_device *dev, struct ethtool_regs *regs, void *p) | 316 | netxen_nic_get_regs(struct net_device *dev, struct ethtool_regs *regs, void *p) |
406 | { | 317 | { |
407 | struct netxen_adapter *adapter = netdev_priv(dev); | 318 | struct netxen_adapter *adapter = netdev_priv(dev); |
408 | __u32 mode, *regs_buff = p; | 319 | struct netxen_recv_context *recv_ctx = &adapter->recv_ctx; |
409 | int i, window; | 320 | struct nx_host_sds_ring *sds_ring; |
321 | u32 *regs_buff = p; | ||
322 | int ring, i = 0; | ||
323 | int port = adapter->physical_port; | ||
410 | 324 | ||
411 | memset(p, 0, NETXEN_NIC_REGS_LEN); | 325 | memset(p, 0, NETXEN_NIC_REGS_LEN); |
326 | |||
412 | regs->version = (1 << 24) | (adapter->ahw.revision_id << 16) | | 327 | regs->version = (1 << 24) | (adapter->ahw.revision_id << 16) | |
413 | (adapter->pdev)->device; | 328 | (adapter->pdev)->device; |
414 | /* which mode */ | ||
415 | regs_buff[0] = NXRD32(adapter, NETXEN_NIU_MODE); | ||
416 | mode = regs_buff[0]; | ||
417 | |||
418 | /* Common registers to all the modes */ | ||
419 | regs_buff[2] = NXRD32(adapter, NETXEN_NIU_STRAP_VALUE_SAVE_HIGHER); | ||
420 | /* GB/XGB Mode */ | ||
421 | mode = (mode / 2) - 1; | ||
422 | window = 0; | ||
423 | if (mode <= 1) { | ||
424 | for (i = 3; niu_registers[mode].reg[i - 3] != -1; i++) { | ||
425 | /* GB: port specific registers */ | ||
426 | if (mode == 0 && i >= 19) | ||
427 | window = adapter->physical_port * | ||
428 | NETXEN_NIC_PORT_WINDOW; | ||
429 | |||
430 | regs_buff[i] = NXRD32(adapter, | ||
431 | niu_registers[mode].reg[i - 3] + window); | ||
432 | } | ||
433 | 329 | ||
330 | if (adapter->is_up != NETXEN_ADAPTER_UP_MAGIC) | ||
331 | return; | ||
332 | |||
333 | regs_buff[i++] = NXRD32(adapter, CRB_CMDPEG_STATE); | ||
334 | regs_buff[i++] = NXRD32(adapter, CRB_RCVPEG_STATE); | ||
335 | regs_buff[i++] = NXRD32(adapter, CRB_FW_CAPABILITIES_1); | ||
336 | regs_buff[i++] = NXRDIO(adapter, adapter->crb_int_state_reg); | ||
337 | regs_buff[i++] = NXRD32(adapter, NX_CRB_DEV_REF_COUNT); | ||
338 | regs_buff[i++] = NXRD32(adapter, NX_CRB_DEV_STATE); | ||
339 | regs_buff[i++] = NXRD32(adapter, NETXEN_PEG_ALIVE_COUNTER); | ||
340 | regs_buff[i++] = NXRD32(adapter, NETXEN_PEG_HALT_STATUS1); | ||
341 | regs_buff[i++] = NXRD32(adapter, NETXEN_PEG_HALT_STATUS2); | ||
342 | |||
343 | regs_buff[i++] = NXRD32(adapter, NETXEN_CRB_PEG_NET_0+0x3c); | ||
344 | regs_buff[i++] = NXRD32(adapter, NETXEN_CRB_PEG_NET_1+0x3c); | ||
345 | regs_buff[i++] = NXRD32(adapter, NETXEN_CRB_PEG_NET_2+0x3c); | ||
346 | regs_buff[i++] = NXRD32(adapter, NETXEN_CRB_PEG_NET_3+0x3c); | ||
347 | |||
348 | if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) { | ||
349 | |||
350 | regs_buff[i++] = NXRD32(adapter, NETXEN_CRB_PEG_NET_4+0x3c); | ||
351 | i += 2; | ||
352 | |||
353 | regs_buff[i++] = NXRD32(adapter, CRB_XG_STATE_P3); | ||
354 | regs_buff[i++] = le32_to_cpu(*(adapter->tx_ring->hw_consumer)); | ||
355 | |||
356 | } else { | ||
357 | i++; | ||
358 | |||
359 | regs_buff[i++] = NXRD32(adapter, | ||
360 | NETXEN_NIU_XGE_CONFIG_0+(0x10000*port)); | ||
361 | regs_buff[i++] = NXRD32(adapter, | ||
362 | NETXEN_NIU_XGE_CONFIG_1+(0x10000*port)); | ||
363 | |||
364 | regs_buff[i++] = NXRD32(adapter, CRB_XG_STATE); | ||
365 | regs_buff[i++] = NXRDIO(adapter, | ||
366 | adapter->tx_ring->crb_cmd_consumer); | ||
367 | } | ||
368 | |||
369 | regs_buff[i++] = NXRDIO(adapter, adapter->tx_ring->crb_cmd_producer); | ||
370 | |||
371 | regs_buff[i++] = NXRDIO(adapter, | ||
372 | recv_ctx->rds_rings[0].crb_rcv_producer); | ||
373 | regs_buff[i++] = NXRDIO(adapter, | ||
374 | recv_ctx->rds_rings[1].crb_rcv_producer); | ||
375 | |||
376 | regs_buff[i++] = adapter->max_sds_rings; | ||
377 | |||
378 | for (ring = 0; ring < adapter->max_sds_rings; ring++) { | ||
379 | sds_ring = &(recv_ctx->sds_rings[ring]); | ||
380 | regs_buff[i++] = NXRDIO(adapter, | ||
381 | sds_ring->crb_sts_consumer); | ||
434 | } | 382 | } |
435 | } | 383 | } |
436 | 384 | ||
437 | static u32 netxen_nic_test_link(struct net_device *dev) | 385 | static u32 netxen_nic_test_link(struct net_device *dev) |
438 | { | 386 | { |
439 | struct netxen_adapter *adapter = netdev_priv(dev); | 387 | struct netxen_adapter *adapter = netdev_priv(dev); |
440 | __u32 status; | 388 | u32 val, port; |
441 | int val; | ||
442 | 389 | ||
443 | /* read which mode */ | 390 | port = adapter->physical_port; |
444 | if (adapter->ahw.port_type == NETXEN_NIC_GBE) { | 391 | if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) { |
445 | if (adapter->phy_read && | 392 | val = NXRD32(adapter, CRB_XG_STATE_P3); |
446 | adapter->phy_read(adapter, | 393 | val = XG_LINK_STATE_P3(adapter->ahw.pci_func, val); |
447 | NETXEN_NIU_GB_MII_MGMT_ADDR_PHY_STATUS, | 394 | return (val == XG_LINK_UP_P3) ? 0 : 1; |
448 | &status) != 0) | 395 | } else { |
449 | return -EIO; | ||
450 | else { | ||
451 | val = netxen_get_phy_link(status); | ||
452 | return !val; | ||
453 | } | ||
454 | } else if (adapter->ahw.port_type == NETXEN_NIC_XGBE) { | ||
455 | val = NXRD32(adapter, CRB_XG_STATE); | 396 | val = NXRD32(adapter, CRB_XG_STATE); |
397 | val = (val >> port*8) & 0xff; | ||
456 | return (val == XG_LINK_UP) ? 0 : 1; | 398 | return (val == XG_LINK_UP) ? 0 : 1; |
457 | } | 399 | } |
458 | return -EIO; | ||
459 | } | 400 | } |
460 | 401 | ||
461 | static int | 402 | static int |
diff --git a/drivers/net/netxen/netxen_nic_hw.c b/drivers/net/netxen/netxen_nic_hw.c index 2e364fee3cbb..85e28e60ecf1 100644 --- a/drivers/net/netxen/netxen_nic_hw.c +++ b/drivers/net/netxen/netxen_nic_hw.c | |||
@@ -345,8 +345,7 @@ netxen_pcie_sem_lock(struct netxen_adapter *adapter, int sem, u32 id_reg) | |||
345 | void | 345 | void |
346 | netxen_pcie_sem_unlock(struct netxen_adapter *adapter, int sem) | 346 | netxen_pcie_sem_unlock(struct netxen_adapter *adapter, int sem) |
347 | { | 347 | { |
348 | int val; | 348 | NXRD32(adapter, NETXEN_PCIE_REG(PCIE_SEM_UNLOCK(sem))); |
349 | val = NXRD32(adapter, NETXEN_PCIE_REG(PCIE_SEM_UNLOCK(sem))); | ||
350 | } | 349 | } |
351 | 350 | ||
352 | int netxen_niu_xg_init_port(struct netxen_adapter *adapter, int port) | 351 | int netxen_niu_xg_init_port(struct netxen_adapter *adapter, int port) |
@@ -691,6 +690,9 @@ void netxen_p3_nic_set_multi(struct net_device *netdev) | |||
691 | struct list_head *head; | 690 | struct list_head *head; |
692 | nx_mac_list_t *cur; | 691 | nx_mac_list_t *cur; |
693 | 692 | ||
693 | if (adapter->is_up != NETXEN_ADAPTER_UP_MAGIC) | ||
694 | return; | ||
695 | |||
694 | list_splice_tail_init(&adapter->mac_list, &del_list); | 696 | list_splice_tail_init(&adapter->mac_list, &del_list); |
695 | 697 | ||
696 | nx_p3_nic_add_mac(adapter, adapter->mac_addr, &del_list); | 698 | nx_p3_nic_add_mac(adapter, adapter->mac_addr, &del_list); |
diff --git a/drivers/net/netxen/netxen_nic_init.c b/drivers/net/netxen/netxen_nic_init.c index 02f8d4b4db63..64cff68d372c 100644 --- a/drivers/net/netxen/netxen_nic_init.c +++ b/drivers/net/netxen/netxen_nic_init.c | |||
@@ -184,6 +184,8 @@ skip_rds: | |||
184 | 184 | ||
185 | tx_ring = adapter->tx_ring; | 185 | tx_ring = adapter->tx_ring; |
186 | vfree(tx_ring->cmd_buf_arr); | 186 | vfree(tx_ring->cmd_buf_arr); |
187 | kfree(tx_ring); | ||
188 | adapter->tx_ring = NULL; | ||
187 | } | 189 | } |
188 | 190 | ||
189 | int netxen_alloc_sw_resources(struct netxen_adapter *adapter) | 191 | int netxen_alloc_sw_resources(struct netxen_adapter *adapter) |
@@ -782,7 +784,7 @@ netxen_need_fw_reset(struct netxen_adapter *adapter) | |||
782 | if (NXRD32(adapter, CRB_CMDPEG_STATE) == PHAN_INITIALIZE_FAILED) | 784 | if (NXRD32(adapter, CRB_CMDPEG_STATE) == PHAN_INITIALIZE_FAILED) |
783 | return 1; | 785 | return 1; |
784 | 786 | ||
785 | old_count = count = NXRD32(adapter, NETXEN_PEG_ALIVE_COUNTER); | 787 | old_count = NXRD32(adapter, NETXEN_PEG_ALIVE_COUNTER); |
786 | 788 | ||
787 | for (i = 0; i < 10; i++) { | 789 | for (i = 0; i < 10; i++) { |
788 | 790 | ||
diff --git a/drivers/net/netxen/netxen_nic_main.c b/drivers/net/netxen/netxen_nic_main.c index 6cae26a5bd67..9f9d6081959b 100644 --- a/drivers/net/netxen/netxen_nic_main.c +++ b/drivers/net/netxen/netxen_nic_main.c | |||
@@ -340,7 +340,7 @@ netxen_check_hw_init(struct netxen_adapter *adapter, int first_boot) | |||
340 | if (!(first_boot & 0x4)) { | 340 | if (!(first_boot & 0x4)) { |
341 | first_boot |= 0x4; | 341 | first_boot |= 0x4; |
342 | NXWR32(adapter, NETXEN_PCIE_REG(0x4), first_boot); | 342 | NXWR32(adapter, NETXEN_PCIE_REG(0x4), first_boot); |
343 | first_boot = NXRD32(adapter, NETXEN_PCIE_REG(0x4)); | 343 | NXRD32(adapter, NETXEN_PCIE_REG(0x4)); |
344 | } | 344 | } |
345 | 345 | ||
346 | /* This is the first boot after power up */ | 346 | /* This is the first boot after power up */ |
@@ -1898,12 +1898,8 @@ static void netxen_nic_handle_phy_intr(struct netxen_adapter *adapter) | |||
1898 | linkup = (val == XG_LINK_UP_P3); | 1898 | linkup = (val == XG_LINK_UP_P3); |
1899 | } else { | 1899 | } else { |
1900 | val = NXRD32(adapter, CRB_XG_STATE); | 1900 | val = NXRD32(adapter, CRB_XG_STATE); |
1901 | if (adapter->ahw.port_type == NETXEN_NIC_GBE) | 1901 | val = (val >> port*8) & 0xff; |
1902 | linkup = (val >> port) & 1; | 1902 | linkup = (val == XG_LINK_UP); |
1903 | else { | ||
1904 | val = (val >> port*8) & 0xff; | ||
1905 | linkup = (val == XG_LINK_UP); | ||
1906 | } | ||
1907 | } | 1903 | } |
1908 | 1904 | ||
1909 | netxen_advert_link_change(adapter, linkup); | 1905 | netxen_advert_link_change(adapter, linkup); |
diff --git a/drivers/net/niu.c b/drivers/net/niu.c index 8ce58c4c7dd3..2aed2b382c40 100644 --- a/drivers/net/niu.c +++ b/drivers/net/niu.c | |||
@@ -2844,7 +2844,7 @@ static int tcam_wait_bit(struct niu *np, u64 bit) | |||
2844 | break; | 2844 | break; |
2845 | udelay(1); | 2845 | udelay(1); |
2846 | } | 2846 | } |
2847 | if (limit < 0) | 2847 | if (limit <= 0) |
2848 | return -ENODEV; | 2848 | return -ENODEV; |
2849 | 2849 | ||
2850 | return 0; | 2850 | return 0; |
diff --git a/drivers/net/pcmcia/nmclan_cs.c b/drivers/net/pcmcia/nmclan_cs.c index 8a5ae3b182ed..12e3233868e9 100644 --- a/drivers/net/pcmcia/nmclan_cs.c +++ b/drivers/net/pcmcia/nmclan_cs.c | |||
@@ -1402,7 +1402,6 @@ static void BuildLAF(int *ladrf, int *adr) | |||
1402 | for (i = 0; i < 8; i++) | 1402 | for (i = 0; i < 8; i++) |
1403 | printk(KERN_CONT " %02X", ladrf[i]); | 1403 | printk(KERN_CONT " %02X", ladrf[i]); |
1404 | printk(KERN_CONT "\n"); | 1404 | printk(KERN_CONT "\n"); |
1405 | } | ||
1406 | #endif | 1405 | #endif |
1407 | } /* BuildLAF */ | 1406 | } /* BuildLAF */ |
1408 | 1407 | ||
diff --git a/drivers/net/pcmcia/pcnet_cs.c b/drivers/net/pcmcia/pcnet_cs.c index 92ed3fbf89a5..776cad2f5715 100644 --- a/drivers/net/pcmcia/pcnet_cs.c +++ b/drivers/net/pcmcia/pcnet_cs.c | |||
@@ -1741,7 +1741,7 @@ static struct pcmcia_device_id pcnet_ids[] = { | |||
1741 | PCMCIA_MFC_DEVICE_CIS_PROD_ID4(0, "NSC MF LAN/Modem", 0x58fc6056, "cis/DP83903.cis"), | 1741 | PCMCIA_MFC_DEVICE_CIS_PROD_ID4(0, "NSC MF LAN/Modem", 0x58fc6056, "cis/DP83903.cis"), |
1742 | PCMCIA_MFC_DEVICE_CIS_MANF_CARD(0, 0x0175, 0x0000, "cis/DP83903.cis"), | 1742 | PCMCIA_MFC_DEVICE_CIS_MANF_CARD(0, 0x0175, 0x0000, "cis/DP83903.cis"), |
1743 | PCMCIA_DEVICE_CIS_MANF_CARD(0xc00f, 0x0002, "cis/LA-PCM.cis"), | 1743 | PCMCIA_DEVICE_CIS_MANF_CARD(0xc00f, 0x0002, "cis/LA-PCM.cis"), |
1744 | PCMCIA_DEVICE_CIS_PROD_ID12("KTI", "PE520 PLUS", 0xad180345, 0x9d58d392, "PE520.cis"), | 1744 | PCMCIA_DEVICE_CIS_PROD_ID12("KTI", "PE520 PLUS", 0xad180345, 0x9d58d392, "cis/PE520.cis"), |
1745 | PCMCIA_DEVICE_CIS_PROD_ID12("NDC", "Ethernet", 0x01c43ae1, 0x00b2e941, "cis/NE2K.cis"), | 1745 | PCMCIA_DEVICE_CIS_PROD_ID12("NDC", "Ethernet", 0x01c43ae1, 0x00b2e941, "cis/NE2K.cis"), |
1746 | PCMCIA_DEVICE_CIS_PROD_ID12("PMX ", "PE-200", 0x34f3f1c8, 0x10b59f8c, "cis/PE-200.cis"), | 1746 | PCMCIA_DEVICE_CIS_PROD_ID12("PMX ", "PE-200", 0x34f3f1c8, 0x10b59f8c, "cis/PE-200.cis"), |
1747 | PCMCIA_DEVICE_CIS_PROD_ID12("TAMARACK", "Ethernet", 0xcf434fba, 0x00b2e941, "cis/tamarack.cis"), | 1747 | PCMCIA_DEVICE_CIS_PROD_ID12("TAMARACK", "Ethernet", 0xcf434fba, 0x00b2e941, "cis/tamarack.cis"), |
@@ -1754,7 +1754,7 @@ MODULE_DEVICE_TABLE(pcmcia, pcnet_ids); | |||
1754 | MODULE_FIRMWARE("cis/PCMLM28.cis"); | 1754 | MODULE_FIRMWARE("cis/PCMLM28.cis"); |
1755 | MODULE_FIRMWARE("cis/DP83903.cis"); | 1755 | MODULE_FIRMWARE("cis/DP83903.cis"); |
1756 | MODULE_FIRMWARE("cis/LA-PCM.cis"); | 1756 | MODULE_FIRMWARE("cis/LA-PCM.cis"); |
1757 | MODULE_FIRMWARE("PE520.cis"); | 1757 | MODULE_FIRMWARE("cis/PE520.cis"); |
1758 | MODULE_FIRMWARE("cis/NE2K.cis"); | 1758 | MODULE_FIRMWARE("cis/NE2K.cis"); |
1759 | MODULE_FIRMWARE("cis/PE-200.cis"); | 1759 | MODULE_FIRMWARE("cis/PE-200.cis"); |
1760 | MODULE_FIRMWARE("cis/tamarack.cis"); | 1760 | MODULE_FIRMWARE("cis/tamarack.cis"); |
diff --git a/drivers/net/phy/broadcom.c b/drivers/net/phy/broadcom.c index c13cf64095b6..33c4b12a63ba 100644 --- a/drivers/net/phy/broadcom.c +++ b/drivers/net/phy/broadcom.c | |||
@@ -331,8 +331,8 @@ static void bcm54xx_adjust_rxrefclk(struct phy_device *phydev) | |||
331 | bool clk125en = true; | 331 | bool clk125en = true; |
332 | 332 | ||
333 | /* Abort if we are using an untested phy. */ | 333 | /* Abort if we are using an untested phy. */ |
334 | if (BRCM_PHY_MODEL(phydev) != PHY_ID_BCM57780 || | 334 | if (BRCM_PHY_MODEL(phydev) != PHY_ID_BCM57780 && |
335 | BRCM_PHY_MODEL(phydev) != PHY_ID_BCM50610 || | 335 | BRCM_PHY_MODEL(phydev) != PHY_ID_BCM50610 && |
336 | BRCM_PHY_MODEL(phydev) != PHY_ID_BCM50610M) | 336 | BRCM_PHY_MODEL(phydev) != PHY_ID_BCM50610M) |
337 | return; | 337 | return; |
338 | 338 | ||
diff --git a/drivers/net/phy/mdio_bus.c b/drivers/net/phy/mdio_bus.c index bd4e8d72dc08..e17b70291bbc 100644 --- a/drivers/net/phy/mdio_bus.c +++ b/drivers/net/phy/mdio_bus.c | |||
@@ -264,6 +264,8 @@ static int mdio_bus_match(struct device *dev, struct device_driver *drv) | |||
264 | (phydev->phy_id & phydrv->phy_id_mask)); | 264 | (phydev->phy_id & phydrv->phy_id_mask)); |
265 | } | 265 | } |
266 | 266 | ||
267 | #ifdef CONFIG_PM | ||
268 | |||
267 | static bool mdio_bus_phy_may_suspend(struct phy_device *phydev) | 269 | static bool mdio_bus_phy_may_suspend(struct phy_device *phydev) |
268 | { | 270 | { |
269 | struct device_driver *drv = phydev->dev.driver; | 271 | struct device_driver *drv = phydev->dev.driver; |
@@ -295,34 +297,88 @@ static bool mdio_bus_phy_may_suspend(struct phy_device *phydev) | |||
295 | return true; | 297 | return true; |
296 | } | 298 | } |
297 | 299 | ||
298 | /* Suspend and resume. Copied from platform_suspend and | 300 | static int mdio_bus_suspend(struct device *dev) |
299 | * platform_resume | ||
300 | */ | ||
301 | static int mdio_bus_suspend(struct device * dev, pm_message_t state) | ||
302 | { | 301 | { |
303 | struct phy_driver *phydrv = to_phy_driver(dev->driver); | 302 | struct phy_driver *phydrv = to_phy_driver(dev->driver); |
304 | struct phy_device *phydev = to_phy_device(dev); | 303 | struct phy_device *phydev = to_phy_device(dev); |
305 | 304 | ||
305 | /* | ||
306 | * We must stop the state machine manually, otherwise it stops out of | ||
307 | * control, possibly with the phydev->lock held. Upon resume, netdev | ||
308 | * may call phy routines that try to grab the same lock, and that may | ||
309 | * lead to a deadlock. | ||
310 | */ | ||
311 | if (phydev->attached_dev) | ||
312 | phy_stop_machine(phydev); | ||
313 | |||
306 | if (!mdio_bus_phy_may_suspend(phydev)) | 314 | if (!mdio_bus_phy_may_suspend(phydev)) |
307 | return 0; | 315 | return 0; |
316 | |||
308 | return phydrv->suspend(phydev); | 317 | return phydrv->suspend(phydev); |
309 | } | 318 | } |
310 | 319 | ||
311 | static int mdio_bus_resume(struct device * dev) | 320 | static int mdio_bus_resume(struct device *dev) |
312 | { | 321 | { |
313 | struct phy_driver *phydrv = to_phy_driver(dev->driver); | 322 | struct phy_driver *phydrv = to_phy_driver(dev->driver); |
314 | struct phy_device *phydev = to_phy_device(dev); | 323 | struct phy_device *phydev = to_phy_device(dev); |
324 | int ret; | ||
315 | 325 | ||
316 | if (!mdio_bus_phy_may_suspend(phydev)) | 326 | if (!mdio_bus_phy_may_suspend(phydev)) |
327 | goto no_resume; | ||
328 | |||
329 | ret = phydrv->resume(phydev); | ||
330 | if (ret < 0) | ||
331 | return ret; | ||
332 | |||
333 | no_resume: | ||
334 | if (phydev->attached_dev) | ||
335 | phy_start_machine(phydev, NULL); | ||
336 | |||
337 | return 0; | ||
338 | } | ||
339 | |||
340 | static int mdio_bus_restore(struct device *dev) | ||
341 | { | ||
342 | struct phy_device *phydev = to_phy_device(dev); | ||
343 | struct net_device *netdev = phydev->attached_dev; | ||
344 | int ret; | ||
345 | |||
346 | if (!netdev) | ||
317 | return 0; | 347 | return 0; |
318 | return phydrv->resume(phydev); | 348 | |
349 | ret = phy_init_hw(phydev); | ||
350 | if (ret < 0) | ||
351 | return ret; | ||
352 | |||
353 | /* The PHY needs to renegotiate. */ | ||
354 | phydev->link = 0; | ||
355 | phydev->state = PHY_UP; | ||
356 | |||
357 | phy_start_machine(phydev, NULL); | ||
358 | |||
359 | return 0; | ||
319 | } | 360 | } |
320 | 361 | ||
362 | static struct dev_pm_ops mdio_bus_pm_ops = { | ||
363 | .suspend = mdio_bus_suspend, | ||
364 | .resume = mdio_bus_resume, | ||
365 | .freeze = mdio_bus_suspend, | ||
366 | .thaw = mdio_bus_resume, | ||
367 | .restore = mdio_bus_restore, | ||
368 | }; | ||
369 | |||
370 | #define MDIO_BUS_PM_OPS (&mdio_bus_pm_ops) | ||
371 | |||
372 | #else | ||
373 | |||
374 | #define MDIO_BUS_PM_OPS NULL | ||
375 | |||
376 | #endif /* CONFIG_PM */ | ||
377 | |||
321 | struct bus_type mdio_bus_type = { | 378 | struct bus_type mdio_bus_type = { |
322 | .name = "mdio_bus", | 379 | .name = "mdio_bus", |
323 | .match = mdio_bus_match, | 380 | .match = mdio_bus_match, |
324 | .suspend = mdio_bus_suspend, | 381 | .pm = MDIO_BUS_PM_OPS, |
325 | .resume = mdio_bus_resume, | ||
326 | }; | 382 | }; |
327 | EXPORT_SYMBOL(mdio_bus_type); | 383 | EXPORT_SYMBOL(mdio_bus_type); |
328 | 384 | ||
diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c index b10fedd82143..8212b2b93422 100644 --- a/drivers/net/phy/phy_device.c +++ b/drivers/net/phy/phy_device.c | |||
@@ -378,6 +378,20 @@ void phy_disconnect(struct phy_device *phydev) | |||
378 | } | 378 | } |
379 | EXPORT_SYMBOL(phy_disconnect); | 379 | EXPORT_SYMBOL(phy_disconnect); |
380 | 380 | ||
381 | int phy_init_hw(struct phy_device *phydev) | ||
382 | { | ||
383 | int ret; | ||
384 | |||
385 | if (!phydev->drv || !phydev->drv->config_init) | ||
386 | return 0; | ||
387 | |||
388 | ret = phy_scan_fixups(phydev); | ||
389 | if (ret < 0) | ||
390 | return ret; | ||
391 | |||
392 | return phydev->drv->config_init(phydev); | ||
393 | } | ||
394 | |||
381 | /** | 395 | /** |
382 | * phy_attach_direct - attach a network device to a given PHY device pointer | 396 | * phy_attach_direct - attach a network device to a given PHY device pointer |
383 | * @dev: network device to attach | 397 | * @dev: network device to attach |
@@ -425,21 +439,7 @@ int phy_attach_direct(struct net_device *dev, struct phy_device *phydev, | |||
425 | /* Do initial configuration here, now that | 439 | /* Do initial configuration here, now that |
426 | * we have certain key parameters | 440 | * we have certain key parameters |
427 | * (dev_flags and interface) */ | 441 | * (dev_flags and interface) */ |
428 | if (phydev->drv->config_init) { | 442 | return phy_init_hw(phydev); |
429 | int err; | ||
430 | |||
431 | err = phy_scan_fixups(phydev); | ||
432 | |||
433 | if (err < 0) | ||
434 | return err; | ||
435 | |||
436 | err = phydev->drv->config_init(phydev); | ||
437 | |||
438 | if (err < 0) | ||
439 | return err; | ||
440 | } | ||
441 | |||
442 | return 0; | ||
443 | } | 443 | } |
444 | EXPORT_SYMBOL(phy_attach_direct); | 444 | EXPORT_SYMBOL(phy_attach_direct); |
445 | 445 | ||
diff --git a/drivers/net/rrunner.c b/drivers/net/rrunner.c index 20a71749154a..1c257098d0a6 100644 --- a/drivers/net/rrunner.c +++ b/drivers/net/rrunner.c | |||
@@ -1293,7 +1293,7 @@ static void rr_dump(struct net_device *dev) | |||
1293 | 1293 | ||
1294 | printk("Error code 0x%x\n", readl(®s->Fail1)); | 1294 | printk("Error code 0x%x\n", readl(®s->Fail1)); |
1295 | 1295 | ||
1296 | index = (((readl(®s->EvtPrd) >> 8) & 0xff ) - 1) % EVT_RING_ENTRIES; | 1296 | index = (((readl(®s->EvtPrd) >> 8) & 0xff) - 1) % TX_RING_ENTRIES; |
1297 | cons = rrpriv->dirty_tx; | 1297 | cons = rrpriv->dirty_tx; |
1298 | printk("TX ring index %i, TX consumer %i\n", | 1298 | printk("TX ring index %i, TX consumer %i\n", |
1299 | index, cons); | 1299 | index, cons); |
diff --git a/drivers/net/sfc/mcdi.c b/drivers/net/sfc/mcdi.c index 683353b904c7..0d4eba7266ec 100644 --- a/drivers/net/sfc/mcdi.c +++ b/drivers/net/sfc/mcdi.c | |||
@@ -142,8 +142,9 @@ static int efx_mcdi_poll(struct efx_nic *efx) | |||
142 | if (spins != 0) { | 142 | if (spins != 0) { |
143 | --spins; | 143 | --spins; |
144 | udelay(1); | 144 | udelay(1); |
145 | } else | 145 | } else { |
146 | schedule(); | 146 | schedule_timeout_uninterruptible(1); |
147 | } | ||
147 | 148 | ||
148 | time = get_seconds(); | 149 | time = get_seconds(); |
149 | 150 | ||
diff --git a/drivers/net/sfc/selftest.c b/drivers/net/sfc/selftest.c index af3933579790..250c8827b842 100644 --- a/drivers/net/sfc/selftest.c +++ b/drivers/net/sfc/selftest.c | |||
@@ -79,10 +79,14 @@ struct efx_loopback_state { | |||
79 | static int efx_test_mdio(struct efx_nic *efx, struct efx_self_tests *tests) | 79 | static int efx_test_mdio(struct efx_nic *efx, struct efx_self_tests *tests) |
80 | { | 80 | { |
81 | int rc = 0; | 81 | int rc = 0; |
82 | int devad = __ffs(efx->mdio.mmds); | 82 | int devad; |
83 | u16 physid1, physid2; | 83 | u16 physid1, physid2; |
84 | 84 | ||
85 | if (efx->phy_type == PHY_TYPE_NONE) | 85 | if (efx->mdio.mode_support & MDIO_SUPPORTS_C45) |
86 | devad = __ffs(efx->mdio.mmds); | ||
87 | else if (efx->mdio.mode_support & MDIO_SUPPORTS_C22) | ||
88 | devad = MDIO_DEVAD_NONE; | ||
89 | else | ||
86 | return 0; | 90 | return 0; |
87 | 91 | ||
88 | mutex_lock(&efx->mac_lock); | 92 | mutex_lock(&efx->mac_lock); |
diff --git a/drivers/net/sh_eth.c b/drivers/net/sh_eth.c index ca6285016dfd..7402b858cab7 100644 --- a/drivers/net/sh_eth.c +++ b/drivers/net/sh_eth.c | |||
@@ -110,7 +110,7 @@ static void sh_eth_reset(struct net_device *ndev) | |||
110 | mdelay(1); | 110 | mdelay(1); |
111 | cnt--; | 111 | cnt--; |
112 | } | 112 | } |
113 | if (cnt < 0) | 113 | if (cnt == 0) |
114 | printk(KERN_ERR "Device reset fail\n"); | 114 | printk(KERN_ERR "Device reset fail\n"); |
115 | 115 | ||
116 | /* Table Init */ | 116 | /* Table Init */ |
diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c index 1c01b96c9611..37f486b65f63 100644 --- a/drivers/net/sky2.c +++ b/drivers/net/sky2.c | |||
@@ -1844,7 +1844,8 @@ static void sky2_tx_complete(struct sky2_port *sky2, u16 done) | |||
1844 | sky2->tx_cons = idx; | 1844 | sky2->tx_cons = idx; |
1845 | smp_mb(); | 1845 | smp_mb(); |
1846 | 1846 | ||
1847 | if (tx_avail(sky2) > MAX_SKB_TX_LE + 4) | 1847 | /* Wake unless it's detached, and called e.g. from sky2_down() */ |
1848 | if (tx_avail(sky2) > MAX_SKB_TX_LE + 4 && netif_device_present(dev)) | ||
1848 | netif_wake_queue(dev); | 1849 | netif_wake_queue(dev); |
1849 | } | 1850 | } |
1850 | 1851 | ||
@@ -4684,6 +4685,7 @@ static int __devinit sky2_probe(struct pci_dev *pdev, | |||
4684 | INIT_WORK(&hw->restart_work, sky2_restart); | 4685 | INIT_WORK(&hw->restart_work, sky2_restart); |
4685 | 4686 | ||
4686 | pci_set_drvdata(pdev, hw); | 4687 | pci_set_drvdata(pdev, hw); |
4688 | pdev->d3_delay = 150; | ||
4687 | 4689 | ||
4688 | return 0; | 4690 | return 0; |
4689 | 4691 | ||
diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index 3a74d2168598..7f82b0238e08 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c | |||
@@ -4,7 +4,7 @@ | |||
4 | * Copyright (C) 2001, 2002, 2003, 2004 David S. Miller (davem@redhat.com) | 4 | * Copyright (C) 2001, 2002, 2003, 2004 David S. Miller (davem@redhat.com) |
5 | * Copyright (C) 2001, 2002, 2003 Jeff Garzik (jgarzik@pobox.com) | 5 | * Copyright (C) 2001, 2002, 2003 Jeff Garzik (jgarzik@pobox.com) |
6 | * Copyright (C) 2004 Sun Microsystems Inc. | 6 | * Copyright (C) 2004 Sun Microsystems Inc. |
7 | * Copyright (C) 2005-2009 Broadcom Corporation. | 7 | * Copyright (C) 2005-2010 Broadcom Corporation. |
8 | * | 8 | * |
9 | * Firmware is: | 9 | * Firmware is: |
10 | * Derived from proprietary unpublished source code, | 10 | * Derived from proprietary unpublished source code, |
@@ -68,8 +68,8 @@ | |||
68 | 68 | ||
69 | #define DRV_MODULE_NAME "tg3" | 69 | #define DRV_MODULE_NAME "tg3" |
70 | #define PFX DRV_MODULE_NAME ": " | 70 | #define PFX DRV_MODULE_NAME ": " |
71 | #define DRV_MODULE_VERSION "3.105" | 71 | #define DRV_MODULE_VERSION "3.106" |
72 | #define DRV_MODULE_RELDATE "December 2, 2009" | 72 | #define DRV_MODULE_RELDATE "January 12, 2010" |
73 | 73 | ||
74 | #define TG3_DEF_MAC_MODE 0 | 74 | #define TG3_DEF_MAC_MODE 0 |
75 | #define TG3_DEF_RX_MODE 0 | 75 | #define TG3_DEF_RX_MODE 0 |
@@ -1037,7 +1037,11 @@ static void tg3_mdio_start(struct tg3 *tp) | |||
1037 | else | 1037 | else |
1038 | tp->phy_addr = 1; | 1038 | tp->phy_addr = 1; |
1039 | 1039 | ||
1040 | is_serdes = tr32(SG_DIG_STATUS) & SG_DIG_IS_SERDES; | 1040 | if (tp->pci_chip_rev_id != CHIPREV_ID_5717_A0) |
1041 | is_serdes = tr32(SG_DIG_STATUS) & SG_DIG_IS_SERDES; | ||
1042 | else | ||
1043 | is_serdes = tr32(TG3_CPMU_PHY_STRAP) & | ||
1044 | TG3_CPMU_PHY_STRAP_IS_SERDES; | ||
1041 | if (is_serdes) | 1045 | if (is_serdes) |
1042 | tp->phy_addr += 7; | 1046 | tp->phy_addr += 7; |
1043 | } else | 1047 | } else |
@@ -4693,8 +4697,9 @@ next_pkt: | |||
4693 | (*post_ptr)++; | 4697 | (*post_ptr)++; |
4694 | 4698 | ||
4695 | if (unlikely(rx_std_posted >= tp->rx_std_max_post)) { | 4699 | if (unlikely(rx_std_posted >= tp->rx_std_max_post)) { |
4696 | u32 idx = *post_ptr % TG3_RX_RING_SIZE; | 4700 | tpr->rx_std_prod_idx = std_prod_idx % TG3_RX_RING_SIZE; |
4697 | tw32_rx_mbox(TG3_RX_STD_PROD_IDX_REG, idx); | 4701 | tw32_rx_mbox(TG3_RX_STD_PROD_IDX_REG, |
4702 | tpr->rx_std_prod_idx); | ||
4698 | work_mask &= ~RXD_OPAQUE_RING_STD; | 4703 | work_mask &= ~RXD_OPAQUE_RING_STD; |
4699 | rx_std_posted = 0; | 4704 | rx_std_posted = 0; |
4700 | } | 4705 | } |
@@ -7742,7 +7747,7 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy) | |||
7742 | ((u64) tpr->rx_std_mapping >> 32)); | 7747 | ((u64) tpr->rx_std_mapping >> 32)); |
7743 | tw32(RCVDBDI_STD_BD + TG3_BDINFO_HOST_ADDR + TG3_64BIT_REG_LOW, | 7748 | tw32(RCVDBDI_STD_BD + TG3_BDINFO_HOST_ADDR + TG3_64BIT_REG_LOW, |
7744 | ((u64) tpr->rx_std_mapping & 0xffffffff)); | 7749 | ((u64) tpr->rx_std_mapping & 0xffffffff)); |
7745 | if (!(tp->tg3_flags3 & TG3_FLG3_5755_PLUS)) | 7750 | if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5717) |
7746 | tw32(RCVDBDI_STD_BD + TG3_BDINFO_NIC_ADDR, | 7751 | tw32(RCVDBDI_STD_BD + TG3_BDINFO_NIC_ADDR, |
7747 | NIC_SRAM_RX_BUFFER_DESC); | 7752 | NIC_SRAM_RX_BUFFER_DESC); |
7748 | 7753 | ||
@@ -12122,7 +12127,8 @@ static void __devinit tg3_get_eeprom_hw_cfg(struct tg3 *tp) | |||
12122 | 12127 | ||
12123 | tp->phy_id = eeprom_phy_id; | 12128 | tp->phy_id = eeprom_phy_id; |
12124 | if (eeprom_phy_serdes) { | 12129 | if (eeprom_phy_serdes) { |
12125 | if (tp->tg3_flags2 & TG3_FLG2_5780_CLASS) | 12130 | if ((tp->tg3_flags2 & TG3_FLG2_5780_CLASS) || |
12131 | GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717) | ||
12126 | tp->tg3_flags2 |= TG3_FLG2_MII_SERDES; | 12132 | tp->tg3_flags2 |= TG3_FLG2_MII_SERDES; |
12127 | else | 12133 | else |
12128 | tp->tg3_flags2 |= TG3_FLG2_PHY_SERDES; | 12134 | tp->tg3_flags2 |= TG3_FLG2_PHY_SERDES; |
@@ -13384,6 +13390,11 @@ static int __devinit tg3_get_invariants(struct tg3 *tp) | |||
13384 | if (err) | 13390 | if (err) |
13385 | return err; | 13391 | return err; |
13386 | 13392 | ||
13393 | if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 && | ||
13394 | (tp->pci_chip_rev_id != CHIPREV_ID_5717_A0 || | ||
13395 | (tp->tg3_flags2 & TG3_FLG2_MII_SERDES))) | ||
13396 | return -ENOTSUPP; | ||
13397 | |||
13387 | /* Initialize data/descriptor byte/word swapping. */ | 13398 | /* Initialize data/descriptor byte/word swapping. */ |
13388 | val = tr32(GRC_MODE); | 13399 | val = tr32(GRC_MODE); |
13389 | val &= GRC_MODE_HOST_STACKUP; | 13400 | val &= GRC_MODE_HOST_STACKUP; |
diff --git a/drivers/net/tg3.h b/drivers/net/tg3.h index cd30889650f8..8a167912902b 100644 --- a/drivers/net/tg3.h +++ b/drivers/net/tg3.h | |||
@@ -4,6 +4,7 @@ | |||
4 | * Copyright (C) 2001, 2002, 2003, 2004 David S. Miller (davem@redhat.com) | 4 | * Copyright (C) 2001, 2002, 2003, 2004 David S. Miller (davem@redhat.com) |
5 | * Copyright (C) 2001 Jeff Garzik (jgarzik@pobox.com) | 5 | * Copyright (C) 2001 Jeff Garzik (jgarzik@pobox.com) |
6 | * Copyright (C) 2004 Sun Microsystems Inc. | 6 | * Copyright (C) 2004 Sun Microsystems Inc. |
7 | * Copyright (C) 2007-2010 Broadcom Corporation. | ||
7 | */ | 8 | */ |
8 | 9 | ||
9 | #ifndef _T3_H | 10 | #ifndef _T3_H |
@@ -1054,6 +1055,8 @@ | |||
1054 | #define CPMU_MUTEX_REQ_DRIVER 0x00001000 | 1055 | #define CPMU_MUTEX_REQ_DRIVER 0x00001000 |
1055 | #define TG3_CPMU_MUTEX_GNT 0x00003660 | 1056 | #define TG3_CPMU_MUTEX_GNT 0x00003660 |
1056 | #define CPMU_MUTEX_GNT_DRIVER 0x00001000 | 1057 | #define CPMU_MUTEX_GNT_DRIVER 0x00001000 |
1058 | #define TG3_CPMU_PHY_STRAP 0x00003664 | ||
1059 | #define TG3_CPMU_PHY_STRAP_IS_SERDES 0x00000020 | ||
1057 | /* 0x3664 --> 0x3800 unused */ | 1060 | /* 0x3664 --> 0x3800 unused */ |
1058 | 1061 | ||
1059 | /* Mbuf cluster free registers */ | 1062 | /* Mbuf cluster free registers */ |
diff --git a/drivers/net/tulip/Kconfig b/drivers/net/tulip/Kconfig index 1cc8cf4425d1..516713fa0a05 100644 --- a/drivers/net/tulip/Kconfig +++ b/drivers/net/tulip/Kconfig | |||
@@ -101,6 +101,10 @@ config TULIP_NAPI_HW_MITIGATION | |||
101 | 101 | ||
102 | If in doubt, say Y. | 102 | If in doubt, say Y. |
103 | 103 | ||
104 | config TULIP_DM910X | ||
105 | def_bool y | ||
106 | depends on TULIP && SPARC | ||
107 | |||
104 | config DE4X5 | 108 | config DE4X5 |
105 | tristate "Generic DECchip & DIGITAL EtherWORKS PCI/EISA" | 109 | tristate "Generic DECchip & DIGITAL EtherWORKS PCI/EISA" |
106 | depends on PCI || EISA | 110 | depends on PCI || EISA |
diff --git a/drivers/net/tulip/dmfe.c b/drivers/net/tulip/dmfe.c index ad63621913c3..6f44ebf58910 100644 --- a/drivers/net/tulip/dmfe.c +++ b/drivers/net/tulip/dmfe.c | |||
@@ -92,6 +92,10 @@ | |||
92 | #include <asm/uaccess.h> | 92 | #include <asm/uaccess.h> |
93 | #include <asm/irq.h> | 93 | #include <asm/irq.h> |
94 | 94 | ||
95 | #ifdef CONFIG_TULIP_DM910X | ||
96 | #include <linux/of.h> | ||
97 | #endif | ||
98 | |||
95 | 99 | ||
96 | /* Board/System/Debug information/definition ---------------- */ | 100 | /* Board/System/Debug information/definition ---------------- */ |
97 | #define PCI_DM9132_ID 0x91321282 /* Davicom DM9132 ID */ | 101 | #define PCI_DM9132_ID 0x91321282 /* Davicom DM9132 ID */ |
@@ -377,6 +381,23 @@ static int __devinit dmfe_init_one (struct pci_dev *pdev, | |||
377 | if (!printed_version++) | 381 | if (!printed_version++) |
378 | printk(version); | 382 | printk(version); |
379 | 383 | ||
384 | /* | ||
385 | * SPARC on-board DM910x chips should be handled by the main | ||
386 | * tulip driver, except for early DM9100s. | ||
387 | */ | ||
388 | #ifdef CONFIG_TULIP_DM910X | ||
389 | if ((ent->driver_data == PCI_DM9100_ID && pdev->revision >= 0x30) || | ||
390 | ent->driver_data == PCI_DM9102_ID) { | ||
391 | struct device_node *dp = pci_device_to_OF_node(pdev); | ||
392 | |||
393 | if (dp && of_get_property(dp, "local-mac-address", NULL)) { | ||
394 | printk(KERN_INFO DRV_NAME | ||
395 | ": skipping on-board DM910x (use tulip)\n"); | ||
396 | return -ENODEV; | ||
397 | } | ||
398 | } | ||
399 | #endif | ||
400 | |||
380 | /* Init network device */ | 401 | /* Init network device */ |
381 | dev = alloc_etherdev(sizeof(*db)); | 402 | dev = alloc_etherdev(sizeof(*db)); |
382 | if (dev == NULL) | 403 | if (dev == NULL) |
diff --git a/drivers/net/tulip/tulip_core.c b/drivers/net/tulip/tulip_core.c index 0fa3140d65bf..595777dcadb1 100644 --- a/drivers/net/tulip/tulip_core.c +++ b/drivers/net/tulip/tulip_core.c | |||
@@ -196,9 +196,13 @@ struct tulip_chip_table tulip_tbl[] = { | |||
196 | | HAS_NWAY | HAS_PCI_MWI, tulip_timer, tulip_media_task }, | 196 | | HAS_NWAY | HAS_PCI_MWI, tulip_timer, tulip_media_task }, |
197 | 197 | ||
198 | /* DM910X */ | 198 | /* DM910X */ |
199 | #ifdef CONFIG_TULIP_DM910X | ||
199 | { "Davicom DM9102/DM9102A", 128, 0x0001ebef, | 200 | { "Davicom DM9102/DM9102A", 128, 0x0001ebef, |
200 | HAS_MII | HAS_MEDIA_TABLE | CSR12_IN_SROM | HAS_ACPI, | 201 | HAS_MII | HAS_MEDIA_TABLE | CSR12_IN_SROM | HAS_ACPI, |
201 | tulip_timer, tulip_media_task }, | 202 | tulip_timer, tulip_media_task }, |
203 | #else | ||
204 | { NULL }, | ||
205 | #endif | ||
202 | 206 | ||
203 | /* RS7112 */ | 207 | /* RS7112 */ |
204 | { "Conexant LANfinity", 256, 0x0001ebef, | 208 | { "Conexant LANfinity", 256, 0x0001ebef, |
@@ -228,8 +232,10 @@ static struct pci_device_id tulip_pci_tbl[] = { | |||
228 | { 0x1259, 0xa120, PCI_ANY_ID, PCI_ANY_ID, 0, 0, COMET }, | 232 | { 0x1259, 0xa120, PCI_ANY_ID, PCI_ANY_ID, 0, 0, COMET }, |
229 | { 0x11F6, 0x9881, PCI_ANY_ID, PCI_ANY_ID, 0, 0, COMPEX9881 }, | 233 | { 0x11F6, 0x9881, PCI_ANY_ID, PCI_ANY_ID, 0, 0, COMPEX9881 }, |
230 | { 0x8086, 0x0039, PCI_ANY_ID, PCI_ANY_ID, 0, 0, I21145 }, | 234 | { 0x8086, 0x0039, PCI_ANY_ID, PCI_ANY_ID, 0, 0, I21145 }, |
235 | #ifdef CONFIG_TULIP_DM910X | ||
231 | { 0x1282, 0x9100, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DM910X }, | 236 | { 0x1282, 0x9100, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DM910X }, |
232 | { 0x1282, 0x9102, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DM910X }, | 237 | { 0x1282, 0x9102, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DM910X }, |
238 | #endif | ||
233 | { 0x1113, 0x1216, PCI_ANY_ID, PCI_ANY_ID, 0, 0, COMET }, | 239 | { 0x1113, 0x1216, PCI_ANY_ID, PCI_ANY_ID, 0, 0, COMET }, |
234 | { 0x1113, 0x1217, PCI_ANY_ID, PCI_ANY_ID, 0, 0, MX98715 }, | 240 | { 0x1113, 0x1217, PCI_ANY_ID, PCI_ANY_ID, 0, 0, MX98715 }, |
235 | { 0x1113, 0x9511, PCI_ANY_ID, PCI_ANY_ID, 0, 0, COMET }, | 241 | { 0x1113, 0x9511, PCI_ANY_ID, PCI_ANY_ID, 0, 0, COMET }, |
@@ -1299,18 +1305,30 @@ static int __devinit tulip_init_one (struct pci_dev *pdev, | |||
1299 | } | 1305 | } |
1300 | 1306 | ||
1301 | /* | 1307 | /* |
1302 | * Early DM9100's need software CRC and the DMFE driver | 1308 | * DM910x chips should be handled by the dmfe driver, except |
1309 | * on-board chips on SPARC systems. Also, early DM9100s need | ||
1310 | * software CRC which only the dmfe driver supports. | ||
1303 | */ | 1311 | */ |
1304 | 1312 | ||
1305 | if (pdev->vendor == 0x1282 && pdev->device == 0x9100) | 1313 | #ifdef CONFIG_TULIP_DM910X |
1306 | { | 1314 | if (chip_idx == DM910X) { |
1307 | /* Read Chip revision */ | 1315 | struct device_node *dp; |
1308 | if (pdev->revision < 0x30) | 1316 | |
1309 | { | 1317 | if (pdev->vendor == 0x1282 && pdev->device == 0x9100 && |
1310 | printk(KERN_ERR PFX "skipping early DM9100 with Crc bug (use dmfe)\n"); | 1318 | pdev->revision < 0x30) { |
1319 | printk(KERN_INFO PFX | ||
1320 | "skipping early DM9100 with Crc bug (use dmfe)\n"); | ||
1321 | return -ENODEV; | ||
1322 | } | ||
1323 | |||
1324 | dp = pci_device_to_OF_node(pdev); | ||
1325 | if (!(dp && of_get_property(dp, "local-mac-address", NULL))) { | ||
1326 | printk(KERN_INFO PFX | ||
1327 | "skipping DM910x expansion card (use dmfe)\n"); | ||
1311 | return -ENODEV; | 1328 | return -ENODEV; |
1312 | } | 1329 | } |
1313 | } | 1330 | } |
1331 | #endif | ||
1314 | 1332 | ||
1315 | /* | 1333 | /* |
1316 | * Looks for early PCI chipsets where people report hangs | 1334 | * Looks for early PCI chipsets where people report hangs |
diff --git a/drivers/net/ucc_geth.c b/drivers/net/ucc_geth.c index 41ad2f3697c7..96bdc0b43889 100644 --- a/drivers/net/ucc_geth.c +++ b/drivers/net/ucc_geth.c | |||
@@ -3607,6 +3607,7 @@ static int ucc_geth_suspend(struct of_device *ofdev, pm_message_t state) | |||
3607 | if (!netif_running(ndev)) | 3607 | if (!netif_running(ndev)) |
3608 | return 0; | 3608 | return 0; |
3609 | 3609 | ||
3610 | netif_device_detach(ndev); | ||
3610 | napi_disable(&ugeth->napi); | 3611 | napi_disable(&ugeth->napi); |
3611 | 3612 | ||
3612 | /* | 3613 | /* |
@@ -3665,7 +3666,7 @@ static int ucc_geth_resume(struct of_device *ofdev) | |||
3665 | phy_start(ugeth->phydev); | 3666 | phy_start(ugeth->phydev); |
3666 | 3667 | ||
3667 | napi_enable(&ugeth->napi); | 3668 | napi_enable(&ugeth->napi); |
3668 | netif_start_queue(ndev); | 3669 | netif_device_attach(ndev); |
3669 | 3670 | ||
3670 | return 0; | 3671 | return 0; |
3671 | } | 3672 | } |
diff --git a/drivers/net/ucc_geth.h b/drivers/net/ucc_geth.h index a007e2acf651..ef1fbeb11c6e 100644 --- a/drivers/net/ucc_geth.h +++ b/drivers/net/ucc_geth.h | |||
@@ -838,13 +838,13 @@ struct ucc_geth_hardware_statistics { | |||
838 | using the maximum is | 838 | using the maximum is |
839 | easier */ | 839 | easier */ |
840 | #define UCC_GETH_SEND_QUEUE_QUEUE_DESCRIPTOR_ALIGNMENT 32 | 840 | #define UCC_GETH_SEND_QUEUE_QUEUE_DESCRIPTOR_ALIGNMENT 32 |
841 | #define UCC_GETH_SCHEDULER_ALIGNMENT 4 /* This is a guess */ | 841 | #define UCC_GETH_SCHEDULER_ALIGNMENT 8 /* This is a guess */ |
842 | #define UCC_GETH_TX_STATISTICS_ALIGNMENT 4 /* This is a guess */ | 842 | #define UCC_GETH_TX_STATISTICS_ALIGNMENT 4 /* This is a guess */ |
843 | #define UCC_GETH_RX_STATISTICS_ALIGNMENT 4 /* This is a guess */ | 843 | #define UCC_GETH_RX_STATISTICS_ALIGNMENT 4 /* This is a guess */ |
844 | #define UCC_GETH_RX_INTERRUPT_COALESCING_ALIGNMENT 64 | 844 | #define UCC_GETH_RX_INTERRUPT_COALESCING_ALIGNMENT 64 |
845 | #define UCC_GETH_RX_BD_QUEUES_ALIGNMENT 8 /* This is a guess */ | 845 | #define UCC_GETH_RX_BD_QUEUES_ALIGNMENT 8 /* This is a guess */ |
846 | #define UCC_GETH_RX_PREFETCHED_BDS_ALIGNMENT 128 /* This is a guess */ | 846 | #define UCC_GETH_RX_PREFETCHED_BDS_ALIGNMENT 128 /* This is a guess */ |
847 | #define UCC_GETH_RX_EXTENDED_FILTERING_GLOBAL_PARAMETERS_ALIGNMENT 4 /* This | 847 | #define UCC_GETH_RX_EXTENDED_FILTERING_GLOBAL_PARAMETERS_ALIGNMENT 8 /* This |
848 | is a | 848 | is a |
849 | guess | 849 | guess |
850 | */ | 850 | */ |
@@ -899,16 +899,17 @@ struct ucc_geth_hardware_statistics { | |||
899 | #define UCC_GETH_UTFS_INIT 512 /* Tx virtual FIFO size | 899 | #define UCC_GETH_UTFS_INIT 512 /* Tx virtual FIFO size |
900 | */ | 900 | */ |
901 | #define UCC_GETH_UTFET_INIT 256 /* 1/2 utfs */ | 901 | #define UCC_GETH_UTFET_INIT 256 /* 1/2 utfs */ |
902 | #define UCC_GETH_UTFTT_INIT 128 | 902 | #define UCC_GETH_UTFTT_INIT 512 |
903 | /* Gigabit Ethernet (1000 Mbps) */ | 903 | /* Gigabit Ethernet (1000 Mbps) */ |
904 | #define UCC_GETH_URFS_GIGA_INIT 4096/*2048*/ /* Rx virtual | 904 | #define UCC_GETH_URFS_GIGA_INIT 4096/*2048*/ /* Rx virtual |
905 | FIFO size */ | 905 | FIFO size */ |
906 | #define UCC_GETH_URFET_GIGA_INIT 2048/*1024*/ /* 1/2 urfs */ | 906 | #define UCC_GETH_URFET_GIGA_INIT 2048/*1024*/ /* 1/2 urfs */ |
907 | #define UCC_GETH_URFSET_GIGA_INIT 3072/*1536*/ /* 3/4 urfs */ | 907 | #define UCC_GETH_URFSET_GIGA_INIT 3072/*1536*/ /* 3/4 urfs */ |
908 | #define UCC_GETH_UTFS_GIGA_INIT 8192/*2048*/ /* Tx virtual | 908 | #define UCC_GETH_UTFS_GIGA_INIT 4096/*2048*/ /* Tx virtual |
909 | FIFO size */ | ||
910 | #define UCC_GETH_UTFET_GIGA_INIT 2048/*1024*/ /* 1/2 utfs */ | ||
911 | #define UCC_GETH_UTFTT_GIGA_INIT 4096/*0x40*/ /* Tx virtual | ||
909 | FIFO size */ | 912 | FIFO size */ |
910 | #define UCC_GETH_UTFET_GIGA_INIT 4096/*1024*/ /* 1/2 utfs */ | ||
911 | #define UCC_GETH_UTFTT_GIGA_INIT 0x400/*0x40*/ /* */ | ||
912 | 913 | ||
913 | #define UCC_GETH_REMODER_INIT 0 /* bits that must be | 914 | #define UCC_GETH_REMODER_INIT 0 /* bits that must be |
914 | set */ | 915 | set */ |
diff --git a/drivers/net/usb/hso.c b/drivers/net/usb/hso.c index f78f0903b073..6895f1531238 100644 --- a/drivers/net/usb/hso.c +++ b/drivers/net/usb/hso.c | |||
@@ -286,6 +286,7 @@ struct hso_device { | |||
286 | u8 usb_gone; | 286 | u8 usb_gone; |
287 | struct work_struct async_get_intf; | 287 | struct work_struct async_get_intf; |
288 | struct work_struct async_put_intf; | 288 | struct work_struct async_put_intf; |
289 | struct work_struct reset_device; | ||
289 | 290 | ||
290 | struct usb_device *usb; | 291 | struct usb_device *usb; |
291 | struct usb_interface *interface; | 292 | struct usb_interface *interface; |
@@ -332,7 +333,8 @@ static void hso_kick_transmit(struct hso_serial *serial); | |||
332 | /* Helper functions */ | 333 | /* Helper functions */ |
333 | static int hso_mux_submit_intr_urb(struct hso_shared_int *mux_int, | 334 | static int hso_mux_submit_intr_urb(struct hso_shared_int *mux_int, |
334 | struct usb_device *usb, gfp_t gfp); | 335 | struct usb_device *usb, gfp_t gfp); |
335 | static void log_usb_status(int status, const char *function); | 336 | static void handle_usb_error(int status, const char *function, |
337 | struct hso_device *hso_dev); | ||
336 | static struct usb_endpoint_descriptor *hso_get_ep(struct usb_interface *intf, | 338 | static struct usb_endpoint_descriptor *hso_get_ep(struct usb_interface *intf, |
337 | int type, int dir); | 339 | int type, int dir); |
338 | static int hso_get_mux_ports(struct usb_interface *intf, unsigned char *ports); | 340 | static int hso_get_mux_ports(struct usb_interface *intf, unsigned char *ports); |
@@ -350,6 +352,7 @@ static void async_put_intf(struct work_struct *data); | |||
350 | static int hso_put_activity(struct hso_device *hso_dev); | 352 | static int hso_put_activity(struct hso_device *hso_dev); |
351 | static int hso_get_activity(struct hso_device *hso_dev); | 353 | static int hso_get_activity(struct hso_device *hso_dev); |
352 | static void tiocmget_intr_callback(struct urb *urb); | 354 | static void tiocmget_intr_callback(struct urb *urb); |
355 | static void reset_device(struct work_struct *data); | ||
353 | /*****************************************************************************/ | 356 | /*****************************************************************************/ |
354 | /* Helping functions */ | 357 | /* Helping functions */ |
355 | /*****************************************************************************/ | 358 | /*****************************************************************************/ |
@@ -461,10 +464,17 @@ static const struct usb_device_id hso_ids[] = { | |||
461 | {USB_DEVICE(0x0af0, 0x7501)}, /* GTM 382 */ | 464 | {USB_DEVICE(0x0af0, 0x7501)}, /* GTM 382 */ |
462 | {USB_DEVICE(0x0af0, 0x7601)}, /* GE40x */ | 465 | {USB_DEVICE(0x0af0, 0x7601)}, /* GE40x */ |
463 | {USB_DEVICE(0x0af0, 0x7701)}, | 466 | {USB_DEVICE(0x0af0, 0x7701)}, |
467 | {USB_DEVICE(0x0af0, 0x7706)}, | ||
464 | {USB_DEVICE(0x0af0, 0x7801)}, | 468 | {USB_DEVICE(0x0af0, 0x7801)}, |
465 | {USB_DEVICE(0x0af0, 0x7901)}, | 469 | {USB_DEVICE(0x0af0, 0x7901)}, |
470 | {USB_DEVICE(0x0af0, 0x7A01)}, | ||
471 | {USB_DEVICE(0x0af0, 0x7A05)}, | ||
466 | {USB_DEVICE(0x0af0, 0x8200)}, | 472 | {USB_DEVICE(0x0af0, 0x8200)}, |
467 | {USB_DEVICE(0x0af0, 0x8201)}, | 473 | {USB_DEVICE(0x0af0, 0x8201)}, |
474 | {USB_DEVICE(0x0af0, 0x8300)}, | ||
475 | {USB_DEVICE(0x0af0, 0x8302)}, | ||
476 | {USB_DEVICE(0x0af0, 0x8304)}, | ||
477 | {USB_DEVICE(0x0af0, 0x8400)}, | ||
468 | {USB_DEVICE(0x0af0, 0xd035)}, | 478 | {USB_DEVICE(0x0af0, 0xd035)}, |
469 | {USB_DEVICE(0x0af0, 0xd055)}, | 479 | {USB_DEVICE(0x0af0, 0xd055)}, |
470 | {USB_DEVICE(0x0af0, 0xd155)}, | 480 | {USB_DEVICE(0x0af0, 0xd155)}, |
@@ -473,6 +483,8 @@ static const struct usb_device_id hso_ids[] = { | |||
473 | {USB_DEVICE(0x0af0, 0xd157)}, | 483 | {USB_DEVICE(0x0af0, 0xd157)}, |
474 | {USB_DEVICE(0x0af0, 0xd257)}, | 484 | {USB_DEVICE(0x0af0, 0xd257)}, |
475 | {USB_DEVICE(0x0af0, 0xd357)}, | 485 | {USB_DEVICE(0x0af0, 0xd357)}, |
486 | {USB_DEVICE(0x0af0, 0xd058)}, | ||
487 | {USB_DEVICE(0x0af0, 0xc100)}, | ||
476 | {} | 488 | {} |
477 | }; | 489 | }; |
478 | MODULE_DEVICE_TABLE(usb, hso_ids); | 490 | MODULE_DEVICE_TABLE(usb, hso_ids); |
@@ -655,8 +667,8 @@ static void set_serial_by_index(unsigned index, struct hso_serial *serial) | |||
655 | spin_unlock_irqrestore(&serial_table_lock, flags); | 667 | spin_unlock_irqrestore(&serial_table_lock, flags); |
656 | } | 668 | } |
657 | 669 | ||
658 | /* log a meaningful explanation of an USB status */ | 670 | static void handle_usb_error(int status, const char *function, |
659 | static void log_usb_status(int status, const char *function) | 671 | struct hso_device *hso_dev) |
660 | { | 672 | { |
661 | char *explanation; | 673 | char *explanation; |
662 | 674 | ||
@@ -685,10 +697,20 @@ static void log_usb_status(int status, const char *function) | |||
685 | case -EMSGSIZE: | 697 | case -EMSGSIZE: |
686 | explanation = "internal error"; | 698 | explanation = "internal error"; |
687 | break; | 699 | break; |
700 | case -EILSEQ: | ||
701 | case -EPROTO: | ||
702 | case -ETIME: | ||
703 | case -ETIMEDOUT: | ||
704 | explanation = "protocol error"; | ||
705 | if (hso_dev) | ||
706 | schedule_work(&hso_dev->reset_device); | ||
707 | break; | ||
688 | default: | 708 | default: |
689 | explanation = "unknown status"; | 709 | explanation = "unknown status"; |
690 | break; | 710 | break; |
691 | } | 711 | } |
712 | |||
713 | /* log a meaningful explanation of an USB status */ | ||
692 | D1("%s: received USB status - %s (%d)", function, explanation, status); | 714 | D1("%s: received USB status - %s (%d)", function, explanation, status); |
693 | } | 715 | } |
694 | 716 | ||
@@ -762,7 +784,7 @@ static void write_bulk_callback(struct urb *urb) | |||
762 | /* log status, but don't act on it, we don't need to resubmit anything | 784 | /* log status, but don't act on it, we don't need to resubmit anything |
763 | * anyhow */ | 785 | * anyhow */ |
764 | if (status) | 786 | if (status) |
765 | log_usb_status(status, __func__); | 787 | handle_usb_error(status, __func__, odev->parent); |
766 | 788 | ||
767 | hso_put_activity(odev->parent); | 789 | hso_put_activity(odev->parent); |
768 | 790 | ||
@@ -806,7 +828,7 @@ static netdev_tx_t hso_net_start_xmit(struct sk_buff *skb, | |||
806 | result = usb_submit_urb(odev->mux_bulk_tx_urb, GFP_ATOMIC); | 828 | result = usb_submit_urb(odev->mux_bulk_tx_urb, GFP_ATOMIC); |
807 | if (result) { | 829 | if (result) { |
808 | dev_warn(&odev->parent->interface->dev, | 830 | dev_warn(&odev->parent->interface->dev, |
809 | "failed mux_bulk_tx_urb %d", result); | 831 | "failed mux_bulk_tx_urb %d\n", result); |
810 | net->stats.tx_errors++; | 832 | net->stats.tx_errors++; |
811 | netif_start_queue(net); | 833 | netif_start_queue(net); |
812 | } else { | 834 | } else { |
@@ -998,7 +1020,7 @@ static void read_bulk_callback(struct urb *urb) | |||
998 | 1020 | ||
999 | /* is al ok? (Filip: Who's Al ?) */ | 1021 | /* is al ok? (Filip: Who's Al ?) */ |
1000 | if (status) { | 1022 | if (status) { |
1001 | log_usb_status(status, __func__); | 1023 | handle_usb_error(status, __func__, odev->parent); |
1002 | return; | 1024 | return; |
1003 | } | 1025 | } |
1004 | 1026 | ||
@@ -1019,7 +1041,8 @@ static void read_bulk_callback(struct urb *urb) | |||
1019 | if (odev->parent->port_spec & HSO_INFO_CRC_BUG) { | 1041 | if (odev->parent->port_spec & HSO_INFO_CRC_BUG) { |
1020 | u32 rest; | 1042 | u32 rest; |
1021 | u8 crc_check[4] = { 0xDE, 0xAD, 0xBE, 0xEF }; | 1043 | u8 crc_check[4] = { 0xDE, 0xAD, 0xBE, 0xEF }; |
1022 | rest = urb->actual_length % odev->in_endp->wMaxPacketSize; | 1044 | rest = urb->actual_length % |
1045 | le16_to_cpu(odev->in_endp->wMaxPacketSize); | ||
1023 | if (((rest == 5) || (rest == 6)) && | 1046 | if (((rest == 5) || (rest == 6)) && |
1024 | !memcmp(((u8 *) urb->transfer_buffer) + | 1047 | !memcmp(((u8 *) urb->transfer_buffer) + |
1025 | urb->actual_length - 4, crc_check, 4)) { | 1048 | urb->actual_length - 4, crc_check, 4)) { |
@@ -1053,7 +1076,7 @@ static void read_bulk_callback(struct urb *urb) | |||
1053 | result = usb_submit_urb(urb, GFP_ATOMIC); | 1076 | result = usb_submit_urb(urb, GFP_ATOMIC); |
1054 | if (result) | 1077 | if (result) |
1055 | dev_warn(&odev->parent->interface->dev, | 1078 | dev_warn(&odev->parent->interface->dev, |
1056 | "%s failed submit mux_bulk_rx_urb %d", __func__, | 1079 | "%s failed submit mux_bulk_rx_urb %d\n", __func__, |
1057 | result); | 1080 | result); |
1058 | } | 1081 | } |
1059 | 1082 | ||
@@ -1207,7 +1230,7 @@ static void hso_std_serial_read_bulk_callback(struct urb *urb) | |||
1207 | D1("serial == NULL"); | 1230 | D1("serial == NULL"); |
1208 | return; | 1231 | return; |
1209 | } else if (status) { | 1232 | } else if (status) { |
1210 | log_usb_status(status, __func__); | 1233 | handle_usb_error(status, __func__, serial->parent); |
1211 | return; | 1234 | return; |
1212 | } | 1235 | } |
1213 | 1236 | ||
@@ -1225,7 +1248,7 @@ static void hso_std_serial_read_bulk_callback(struct urb *urb) | |||
1225 | u8 crc_check[4] = { 0xDE, 0xAD, 0xBE, 0xEF }; | 1248 | u8 crc_check[4] = { 0xDE, 0xAD, 0xBE, 0xEF }; |
1226 | rest = | 1249 | rest = |
1227 | urb->actual_length % | 1250 | urb->actual_length % |
1228 | serial->in_endp->wMaxPacketSize; | 1251 | le16_to_cpu(serial->in_endp->wMaxPacketSize); |
1229 | if (((rest == 5) || (rest == 6)) && | 1252 | if (((rest == 5) || (rest == 6)) && |
1230 | !memcmp(((u8 *) urb->transfer_buffer) + | 1253 | !memcmp(((u8 *) urb->transfer_buffer) + |
1231 | urb->actual_length - 4, crc_check, 4)) { | 1254 | urb->actual_length - 4, crc_check, 4)) { |
@@ -1513,7 +1536,7 @@ static void tiocmget_intr_callback(struct urb *urb) | |||
1513 | if (!serial) | 1536 | if (!serial) |
1514 | return; | 1537 | return; |
1515 | if (status) { | 1538 | if (status) { |
1516 | log_usb_status(status, __func__); | 1539 | handle_usb_error(status, __func__, serial->parent); |
1517 | return; | 1540 | return; |
1518 | } | 1541 | } |
1519 | tiocmget = serial->tiocmget; | 1542 | tiocmget = serial->tiocmget; |
@@ -1700,6 +1723,10 @@ static int hso_serial_tiocmset(struct tty_struct *tty, struct file *file, | |||
1700 | D1("no tty structures"); | 1723 | D1("no tty structures"); |
1701 | return -EINVAL; | 1724 | return -EINVAL; |
1702 | } | 1725 | } |
1726 | |||
1727 | if ((serial->parent->port_spec & HSO_PORT_MASK) != HSO_PORT_MODEM) | ||
1728 | return -EINVAL; | ||
1729 | |||
1703 | if_num = serial->parent->interface->altsetting->desc.bInterfaceNumber; | 1730 | if_num = serial->parent->interface->altsetting->desc.bInterfaceNumber; |
1704 | 1731 | ||
1705 | spin_lock_irqsave(&serial->serial_lock, flags); | 1732 | spin_lock_irqsave(&serial->serial_lock, flags); |
@@ -1838,7 +1865,7 @@ static int mux_device_request(struct hso_serial *serial, u8 type, u16 port, | |||
1838 | result = usb_submit_urb(ctrl_urb, GFP_ATOMIC); | 1865 | result = usb_submit_urb(ctrl_urb, GFP_ATOMIC); |
1839 | if (result) { | 1866 | if (result) { |
1840 | dev_err(&ctrl_urb->dev->dev, | 1867 | dev_err(&ctrl_urb->dev->dev, |
1841 | "%s failed submit ctrl_urb %d type %d", __func__, | 1868 | "%s failed submit ctrl_urb %d type %d\n", __func__, |
1842 | result, type); | 1869 | result, type); |
1843 | return result; | 1870 | return result; |
1844 | } | 1871 | } |
@@ -1888,7 +1915,7 @@ static void intr_callback(struct urb *urb) | |||
1888 | 1915 | ||
1889 | /* status check */ | 1916 | /* status check */ |
1890 | if (status) { | 1917 | if (status) { |
1891 | log_usb_status(status, __func__); | 1918 | handle_usb_error(status, __func__, NULL); |
1892 | return; | 1919 | return; |
1893 | } | 1920 | } |
1894 | D4("\n--- Got intr callback 0x%02X ---", status); | 1921 | D4("\n--- Got intr callback 0x%02X ---", status); |
@@ -1905,18 +1932,18 @@ static void intr_callback(struct urb *urb) | |||
1905 | if (serial != NULL) { | 1932 | if (serial != NULL) { |
1906 | D1("Pending read interrupt on port %d\n", i); | 1933 | D1("Pending read interrupt on port %d\n", i); |
1907 | spin_lock(&serial->serial_lock); | 1934 | spin_lock(&serial->serial_lock); |
1908 | if (serial->rx_state == RX_IDLE) { | 1935 | if (serial->rx_state == RX_IDLE && |
1936 | serial->open_count > 0) { | ||
1909 | /* Setup and send a ctrl req read on | 1937 | /* Setup and send a ctrl req read on |
1910 | * port i */ | 1938 | * port i */ |
1911 | if (!serial->rx_urb_filled[0]) { | 1939 | if (!serial->rx_urb_filled[0]) { |
1912 | serial->rx_state = RX_SENT; | 1940 | serial->rx_state = RX_SENT; |
1913 | hso_mux_serial_read(serial); | 1941 | hso_mux_serial_read(serial); |
1914 | } else | 1942 | } else |
1915 | serial->rx_state = RX_PENDING; | 1943 | serial->rx_state = RX_PENDING; |
1916 | |||
1917 | } else { | 1944 | } else { |
1918 | D1("Already pending a read on " | 1945 | D1("Already a read pending on " |
1919 | "port %d\n", i); | 1946 | "port %d or port not open\n", i); |
1920 | } | 1947 | } |
1921 | spin_unlock(&serial->serial_lock); | 1948 | spin_unlock(&serial->serial_lock); |
1922 | } | 1949 | } |
@@ -1958,7 +1985,7 @@ static void hso_std_serial_write_bulk_callback(struct urb *urb) | |||
1958 | tty = tty_kref_get(serial->tty); | 1985 | tty = tty_kref_get(serial->tty); |
1959 | spin_unlock(&serial->serial_lock); | 1986 | spin_unlock(&serial->serial_lock); |
1960 | if (status) { | 1987 | if (status) { |
1961 | log_usb_status(status, __func__); | 1988 | handle_usb_error(status, __func__, serial->parent); |
1962 | tty_kref_put(tty); | 1989 | tty_kref_put(tty); |
1963 | return; | 1990 | return; |
1964 | } | 1991 | } |
@@ -2014,7 +2041,7 @@ static void ctrl_callback(struct urb *urb) | |||
2014 | tty = tty_kref_get(serial->tty); | 2041 | tty = tty_kref_get(serial->tty); |
2015 | spin_unlock(&serial->serial_lock); | 2042 | spin_unlock(&serial->serial_lock); |
2016 | if (status) { | 2043 | if (status) { |
2017 | log_usb_status(status, __func__); | 2044 | handle_usb_error(status, __func__, serial->parent); |
2018 | tty_kref_put(tty); | 2045 | tty_kref_put(tty); |
2019 | return; | 2046 | return; |
2020 | } | 2047 | } |
@@ -2358,12 +2385,12 @@ static int hso_serial_common_create(struct hso_serial *serial, int num_urbs, | |||
2358 | serial->tx_data_length = tx_size; | 2385 | serial->tx_data_length = tx_size; |
2359 | serial->tx_data = kzalloc(serial->tx_data_length, GFP_KERNEL); | 2386 | serial->tx_data = kzalloc(serial->tx_data_length, GFP_KERNEL); |
2360 | if (!serial->tx_data) { | 2387 | if (!serial->tx_data) { |
2361 | dev_err(dev, "%s - Out of memory", __func__); | 2388 | dev_err(dev, "%s - Out of memory\n", __func__); |
2362 | goto exit; | 2389 | goto exit; |
2363 | } | 2390 | } |
2364 | serial->tx_buffer = kzalloc(serial->tx_data_length, GFP_KERNEL); | 2391 | serial->tx_buffer = kzalloc(serial->tx_data_length, GFP_KERNEL); |
2365 | if (!serial->tx_buffer) { | 2392 | if (!serial->tx_buffer) { |
2366 | dev_err(dev, "%s - Out of memory", __func__); | 2393 | dev_err(dev, "%s - Out of memory\n", __func__); |
2367 | goto exit; | 2394 | goto exit; |
2368 | } | 2395 | } |
2369 | 2396 | ||
@@ -2391,6 +2418,7 @@ static struct hso_device *hso_create_device(struct usb_interface *intf, | |||
2391 | 2418 | ||
2392 | INIT_WORK(&hso_dev->async_get_intf, async_get_intf); | 2419 | INIT_WORK(&hso_dev->async_get_intf, async_get_intf); |
2393 | INIT_WORK(&hso_dev->async_put_intf, async_put_intf); | 2420 | INIT_WORK(&hso_dev->async_put_intf, async_put_intf); |
2421 | INIT_WORK(&hso_dev->reset_device, reset_device); | ||
2394 | 2422 | ||
2395 | return hso_dev; | 2423 | return hso_dev; |
2396 | } | 2424 | } |
@@ -2831,13 +2859,14 @@ struct hso_shared_int *hso_create_shared_int(struct usb_interface *interface) | |||
2831 | 2859 | ||
2832 | mux->shared_intr_urb = usb_alloc_urb(0, GFP_KERNEL); | 2860 | mux->shared_intr_urb = usb_alloc_urb(0, GFP_KERNEL); |
2833 | if (!mux->shared_intr_urb) { | 2861 | if (!mux->shared_intr_urb) { |
2834 | dev_err(&interface->dev, "Could not allocate intr urb?"); | 2862 | dev_err(&interface->dev, "Could not allocate intr urb?\n"); |
2835 | goto exit; | 2863 | goto exit; |
2836 | } | 2864 | } |
2837 | mux->shared_intr_buf = kzalloc(mux->intr_endp->wMaxPacketSize, | 2865 | mux->shared_intr_buf = |
2838 | GFP_KERNEL); | 2866 | kzalloc(le16_to_cpu(mux->intr_endp->wMaxPacketSize), |
2867 | GFP_KERNEL); | ||
2839 | if (!mux->shared_intr_buf) { | 2868 | if (!mux->shared_intr_buf) { |
2840 | dev_err(&interface->dev, "Could not allocate intr buf?"); | 2869 | dev_err(&interface->dev, "Could not allocate intr buf?\n"); |
2841 | goto exit; | 2870 | goto exit; |
2842 | } | 2871 | } |
2843 | 2872 | ||
@@ -3132,6 +3161,26 @@ out: | |||
3132 | return result; | 3161 | return result; |
3133 | } | 3162 | } |
3134 | 3163 | ||
3164 | static void reset_device(struct work_struct *data) | ||
3165 | { | ||
3166 | struct hso_device *hso_dev = | ||
3167 | container_of(data, struct hso_device, reset_device); | ||
3168 | struct usb_device *usb = hso_dev->usb; | ||
3169 | int result; | ||
3170 | |||
3171 | if (hso_dev->usb_gone) { | ||
3172 | D1("No reset during disconnect\n"); | ||
3173 | } else { | ||
3174 | result = usb_lock_device_for_reset(usb, hso_dev->interface); | ||
3175 | if (result < 0) | ||
3176 | D1("unable to lock device for reset: %d\n", result); | ||
3177 | else { | ||
3178 | usb_reset_device(usb); | ||
3179 | usb_unlock_device(usb); | ||
3180 | } | ||
3181 | } | ||
3182 | } | ||
3183 | |||
3135 | static void hso_serial_ref_free(struct kref *ref) | 3184 | static void hso_serial_ref_free(struct kref *ref) |
3136 | { | 3185 | { |
3137 | struct hso_device *hso_dev = container_of(ref, struct hso_device, ref); | 3186 | struct hso_device *hso_dev = container_of(ref, struct hso_device, ref); |
@@ -3232,13 +3281,13 @@ static int hso_mux_submit_intr_urb(struct hso_shared_int *shared_int, | |||
3232 | usb_rcvintpipe(usb, | 3281 | usb_rcvintpipe(usb, |
3233 | shared_int->intr_endp->bEndpointAddress & 0x7F), | 3282 | shared_int->intr_endp->bEndpointAddress & 0x7F), |
3234 | shared_int->shared_intr_buf, | 3283 | shared_int->shared_intr_buf, |
3235 | shared_int->intr_endp->wMaxPacketSize, | 3284 | 1, |
3236 | intr_callback, shared_int, | 3285 | intr_callback, shared_int, |
3237 | shared_int->intr_endp->bInterval); | 3286 | shared_int->intr_endp->bInterval); |
3238 | 3287 | ||
3239 | result = usb_submit_urb(shared_int->shared_intr_urb, gfp); | 3288 | result = usb_submit_urb(shared_int->shared_intr_urb, gfp); |
3240 | if (result) | 3289 | if (result) |
3241 | dev_warn(&usb->dev, "%s failed mux_intr_urb %d", __func__, | 3290 | dev_warn(&usb->dev, "%s failed mux_intr_urb %d\n", __func__, |
3242 | result); | 3291 | result); |
3243 | 3292 | ||
3244 | return result; | 3293 | return result; |
diff --git a/drivers/net/usb/rtl8150.c b/drivers/net/usb/rtl8150.c index f14d225404da..fd19db0d2504 100644 --- a/drivers/net/usb/rtl8150.c +++ b/drivers/net/usb/rtl8150.c | |||
@@ -270,7 +270,7 @@ static int read_mii_word(rtl8150_t * dev, u8 phy, __u8 indx, u16 * reg) | |||
270 | get_registers(dev, PHYCNT, 1, data); | 270 | get_registers(dev, PHYCNT, 1, data); |
271 | } while ((data[0] & PHY_GO) && (i++ < MII_TIMEOUT)); | 271 | } while ((data[0] & PHY_GO) && (i++ < MII_TIMEOUT)); |
272 | 272 | ||
273 | if (i < MII_TIMEOUT) { | 273 | if (i <= MII_TIMEOUT) { |
274 | get_registers(dev, PHYDAT, 2, data); | 274 | get_registers(dev, PHYDAT, 2, data); |
275 | *reg = data[0] | (data[1] << 8); | 275 | *reg = data[0] | (data[1] << 8); |
276 | return 0; | 276 | return 0; |
@@ -295,7 +295,7 @@ static int write_mii_word(rtl8150_t * dev, u8 phy, __u8 indx, u16 reg) | |||
295 | get_registers(dev, PHYCNT, 1, data); | 295 | get_registers(dev, PHYCNT, 1, data); |
296 | } while ((data[0] & PHY_GO) && (i++ < MII_TIMEOUT)); | 296 | } while ((data[0] & PHY_GO) && (i++ < MII_TIMEOUT)); |
297 | 297 | ||
298 | if (i < MII_TIMEOUT) | 298 | if (i <= MII_TIMEOUT) |
299 | return 0; | 299 | return 0; |
300 | else | 300 | else |
301 | return 1; | 301 | return 1; |
diff --git a/drivers/net/via-velocity.c b/drivers/net/via-velocity.c index 4ceb441f2687..c93f58f5c6f2 100644 --- a/drivers/net/via-velocity.c +++ b/drivers/net/via-velocity.c | |||
@@ -2237,8 +2237,6 @@ static int velocity_open(struct net_device *dev) | |||
2237 | /* Ensure chip is running */ | 2237 | /* Ensure chip is running */ |
2238 | pci_set_power_state(vptr->pdev, PCI_D0); | 2238 | pci_set_power_state(vptr->pdev, PCI_D0); |
2239 | 2239 | ||
2240 | velocity_give_many_rx_descs(vptr); | ||
2241 | |||
2242 | velocity_init_registers(vptr, VELOCITY_INIT_COLD); | 2240 | velocity_init_registers(vptr, VELOCITY_INIT_COLD); |
2243 | 2241 | ||
2244 | ret = request_irq(vptr->pdev->irq, velocity_intr, IRQF_SHARED, | 2242 | ret = request_irq(vptr->pdev->irq, velocity_intr, IRQF_SHARED, |
@@ -2250,6 +2248,8 @@ static int velocity_open(struct net_device *dev) | |||
2250 | goto out; | 2248 | goto out; |
2251 | } | 2249 | } |
2252 | 2250 | ||
2251 | velocity_give_many_rx_descs(vptr); | ||
2252 | |||
2253 | mac_enable_int(vptr->mac_regs); | 2253 | mac_enable_int(vptr->mac_regs); |
2254 | netif_start_queue(dev); | 2254 | netif_start_queue(dev); |
2255 | napi_enable(&vptr->napi); | 2255 | napi_enable(&vptr->napi); |
@@ -2339,10 +2339,10 @@ static int velocity_change_mtu(struct net_device *dev, int new_mtu) | |||
2339 | 2339 | ||
2340 | dev->mtu = new_mtu; | 2340 | dev->mtu = new_mtu; |
2341 | 2341 | ||
2342 | velocity_give_many_rx_descs(vptr); | ||
2343 | |||
2344 | velocity_init_registers(vptr, VELOCITY_INIT_COLD); | 2342 | velocity_init_registers(vptr, VELOCITY_INIT_COLD); |
2345 | 2343 | ||
2344 | velocity_give_many_rx_descs(vptr); | ||
2345 | |||
2346 | mac_enable_int(vptr->mac_regs); | 2346 | mac_enable_int(vptr->mac_regs); |
2347 | netif_start_queue(dev); | 2347 | netif_start_queue(dev); |
2348 | 2348 | ||
diff --git a/drivers/net/vxge/vxge-main.c b/drivers/net/vxge/vxge-main.c index 0fdfd58a35a1..b9685e82f7b6 100644 --- a/drivers/net/vxge/vxge-main.c +++ b/drivers/net/vxge/vxge-main.c | |||
@@ -310,7 +310,7 @@ static int vxge_rx_map(void *dtrh, struct vxge_ring *ring) | |||
310 | dma_addr = pci_map_single(ring->pdev, rx_priv->skb_data, | 310 | dma_addr = pci_map_single(ring->pdev, rx_priv->skb_data, |
311 | rx_priv->data_size, PCI_DMA_FROMDEVICE); | 311 | rx_priv->data_size, PCI_DMA_FROMDEVICE); |
312 | 312 | ||
313 | if (dma_addr == 0) { | 313 | if (unlikely(pci_dma_mapping_error(ring->pdev, dma_addr))) { |
314 | ring->stats.pci_map_fail++; | 314 | ring->stats.pci_map_fail++; |
315 | return -EIO; | 315 | return -EIO; |
316 | } | 316 | } |
diff --git a/drivers/net/wireless/ath/ath5k/eeprom.c b/drivers/net/wireless/ath/ath5k/eeprom.c index 5d1c8677f180..6a3f4da7fb48 100644 --- a/drivers/net/wireless/ath/ath5k/eeprom.c +++ b/drivers/net/wireless/ath/ath5k/eeprom.c | |||
@@ -97,7 +97,7 @@ ath5k_eeprom_init_header(struct ath5k_hw *ah) | |||
97 | struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom; | 97 | struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom; |
98 | int ret; | 98 | int ret; |
99 | u16 val; | 99 | u16 val; |
100 | u32 cksum, offset; | 100 | u32 cksum, offset, eep_max = AR5K_EEPROM_INFO_MAX; |
101 | 101 | ||
102 | /* | 102 | /* |
103 | * Read values from EEPROM and store them in the capability structure | 103 | * Read values from EEPROM and store them in the capability structure |
@@ -116,12 +116,38 @@ ath5k_eeprom_init_header(struct ath5k_hw *ah) | |||
116 | * Validate the checksum of the EEPROM date. There are some | 116 | * Validate the checksum of the EEPROM date. There are some |
117 | * devices with invalid EEPROMs. | 117 | * devices with invalid EEPROMs. |
118 | */ | 118 | */ |
119 | for (cksum = 0, offset = 0; offset < AR5K_EEPROM_INFO_MAX; offset++) { | 119 | AR5K_EEPROM_READ(AR5K_EEPROM_SIZE_UPPER, val); |
120 | if (val) { | ||
121 | eep_max = (val & AR5K_EEPROM_SIZE_UPPER_MASK) << | ||
122 | AR5K_EEPROM_SIZE_ENDLOC_SHIFT; | ||
123 | AR5K_EEPROM_READ(AR5K_EEPROM_SIZE_LOWER, val); | ||
124 | eep_max = (eep_max | val) - AR5K_EEPROM_INFO_BASE; | ||
125 | |||
126 | /* | ||
127 | * Fail safe check to prevent stupid loops due | ||
128 | * to busted EEPROMs. XXX: This value is likely too | ||
129 | * big still, waiting on a better value. | ||
130 | */ | ||
131 | if (eep_max > (3 * AR5K_EEPROM_INFO_MAX)) { | ||
132 | ATH5K_ERR(ah->ah_sc, "Invalid max custom EEPROM size: " | ||
133 | "%d (0x%04x) max expected: %d (0x%04x)\n", | ||
134 | eep_max, eep_max, | ||
135 | 3 * AR5K_EEPROM_INFO_MAX, | ||
136 | 3 * AR5K_EEPROM_INFO_MAX); | ||
137 | return -EIO; | ||
138 | } | ||
139 | } | ||
140 | |||
141 | for (cksum = 0, offset = 0; offset < eep_max; offset++) { | ||
120 | AR5K_EEPROM_READ(AR5K_EEPROM_INFO(offset), val); | 142 | AR5K_EEPROM_READ(AR5K_EEPROM_INFO(offset), val); |
121 | cksum ^= val; | 143 | cksum ^= val; |
122 | } | 144 | } |
123 | if (cksum != AR5K_EEPROM_INFO_CKSUM) { | 145 | if (cksum != AR5K_EEPROM_INFO_CKSUM) { |
124 | ATH5K_ERR(ah->ah_sc, "Invalid EEPROM checksum 0x%04x\n", cksum); | 146 | ATH5K_ERR(ah->ah_sc, "Invalid EEPROM " |
147 | "checksum: 0x%04x eep_max: 0x%04x (%s)\n", | ||
148 | cksum, eep_max, | ||
149 | eep_max == AR5K_EEPROM_INFO_MAX ? | ||
150 | "default size" : "custom size"); | ||
125 | return -EIO; | 151 | return -EIO; |
126 | } | 152 | } |
127 | 153 | ||
diff --git a/drivers/net/wireless/ath/ath5k/eeprom.h b/drivers/net/wireless/ath/ath5k/eeprom.h index 0123f3521a0b..473a483bb9c3 100644 --- a/drivers/net/wireless/ath/ath5k/eeprom.h +++ b/drivers/net/wireless/ath/ath5k/eeprom.h | |||
@@ -37,6 +37,14 @@ | |||
37 | #define AR5K_EEPROM_RFKILL_POLARITY_S 1 | 37 | #define AR5K_EEPROM_RFKILL_POLARITY_S 1 |
38 | 38 | ||
39 | #define AR5K_EEPROM_REG_DOMAIN 0x00bf /* EEPROM regdom */ | 39 | #define AR5K_EEPROM_REG_DOMAIN 0x00bf /* EEPROM regdom */ |
40 | |||
41 | /* FLASH(EEPROM) Defines for AR531X chips */ | ||
42 | #define AR5K_EEPROM_SIZE_LOWER 0x1b /* size info -- lower */ | ||
43 | #define AR5K_EEPROM_SIZE_UPPER 0x1c /* size info -- upper */ | ||
44 | #define AR5K_EEPROM_SIZE_UPPER_MASK 0xfff0 | ||
45 | #define AR5K_EEPROM_SIZE_UPPER_SHIFT 4 | ||
46 | #define AR5K_EEPROM_SIZE_ENDLOC_SHIFT 12 | ||
47 | |||
40 | #define AR5K_EEPROM_CHECKSUM 0x00c0 /* EEPROM checksum */ | 48 | #define AR5K_EEPROM_CHECKSUM 0x00c0 /* EEPROM checksum */ |
41 | #define AR5K_EEPROM_INFO_BASE 0x00c0 /* EEPROM header */ | 49 | #define AR5K_EEPROM_INFO_BASE 0x00c0 /* EEPROM header */ |
42 | #define AR5K_EEPROM_INFO_MAX (0x400 - AR5K_EEPROM_INFO_BASE) | 50 | #define AR5K_EEPROM_INFO_MAX (0x400 - AR5K_EEPROM_INFO_BASE) |
diff --git a/drivers/net/wireless/ath/ath9k/Kconfig b/drivers/net/wireless/ath/ath9k/Kconfig index 03a1106ad725..5774cea23a3b 100644 --- a/drivers/net/wireless/ath/ath9k/Kconfig +++ b/drivers/net/wireless/ath/ath9k/Kconfig | |||
@@ -25,7 +25,7 @@ config ATH9K | |||
25 | 25 | ||
26 | config ATH9K_DEBUGFS | 26 | config ATH9K_DEBUGFS |
27 | bool "Atheros ath9k debugging" | 27 | bool "Atheros ath9k debugging" |
28 | depends on ATH9K | 28 | depends on ATH9K && DEBUG_FS |
29 | ---help--- | 29 | ---help--- |
30 | Say Y, if you need access to ath9k's statistics for | 30 | Say Y, if you need access to ath9k's statistics for |
31 | interrupts, rate control, etc. | 31 | interrupts, rate control, etc. |
diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h index e2cef2ff5d8f..1597a42731ed 100644 --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h | |||
@@ -33,11 +33,11 @@ struct ath_node; | |||
33 | 33 | ||
34 | /* Macro to expand scalars to 64-bit objects */ | 34 | /* Macro to expand scalars to 64-bit objects */ |
35 | 35 | ||
36 | #define ito64(x) (sizeof(x) == 8) ? \ | 36 | #define ito64(x) (sizeof(x) == 1) ? \ |
37 | (((unsigned long long int)(x)) & (0xff)) : \ | 37 | (((unsigned long long int)(x)) & (0xff)) : \ |
38 | (sizeof(x) == 16) ? \ | 38 | (sizeof(x) == 2) ? \ |
39 | (((unsigned long long int)(x)) & 0xffff) : \ | 39 | (((unsigned long long int)(x)) & 0xffff) : \ |
40 | ((sizeof(x) == 32) ? \ | 40 | ((sizeof(x) == 4) ? \ |
41 | (((unsigned long long int)(x)) & 0xffffffff) : \ | 41 | (((unsigned long long int)(x)) & 0xffffffff) : \ |
42 | (unsigned long long int)(x)) | 42 | (unsigned long long int)(x)) |
43 | 43 | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c index 484c5fdf7c2a..9b4b8b5c7574 100644 --- a/drivers/net/wireless/iwlwifi/iwl-4965.c +++ b/drivers/net/wireless/iwlwifi/iwl-4965.c | |||
@@ -1961,7 +1961,7 @@ static void iwl4965_rx_reply_tx(struct iwl_priv *priv, | |||
1961 | struct ieee80211_tx_info *info; | 1961 | struct ieee80211_tx_info *info; |
1962 | struct iwl4965_tx_resp *tx_resp = (void *)&pkt->u.raw[0]; | 1962 | struct iwl4965_tx_resp *tx_resp = (void *)&pkt->u.raw[0]; |
1963 | u32 status = le32_to_cpu(tx_resp->u.status); | 1963 | u32 status = le32_to_cpu(tx_resp->u.status); |
1964 | int tid = MAX_TID_COUNT; | 1964 | int uninitialized_var(tid); |
1965 | int sta_id; | 1965 | int sta_id; |
1966 | int freed; | 1966 | int freed; |
1967 | u8 *qc = NULL; | 1967 | u8 *qc = NULL; |
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index 574d36658702..5461f105bd2d 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c | |||
@@ -2344,6 +2344,21 @@ static void iwl_ht_conf(struct iwl_priv *priv, | |||
2344 | IWL_DEBUG_MAC80211(priv, "leave\n"); | 2344 | IWL_DEBUG_MAC80211(priv, "leave\n"); |
2345 | } | 2345 | } |
2346 | 2346 | ||
2347 | static inline void iwl_set_no_assoc(struct iwl_priv *priv) | ||
2348 | { | ||
2349 | priv->assoc_id = 0; | ||
2350 | iwl_led_disassociate(priv); | ||
2351 | /* | ||
2352 | * inform the ucode that there is no longer an | ||
2353 | * association and that no more packets should be | ||
2354 | * sent | ||
2355 | */ | ||
2356 | priv->staging_rxon.filter_flags &= | ||
2357 | ~RXON_FILTER_ASSOC_MSK; | ||
2358 | priv->staging_rxon.assoc_id = 0; | ||
2359 | iwlcore_commit_rxon(priv); | ||
2360 | } | ||
2361 | |||
2347 | #define IWL_DELAY_NEXT_SCAN_AFTER_ASSOC (HZ*6) | 2362 | #define IWL_DELAY_NEXT_SCAN_AFTER_ASSOC (HZ*6) |
2348 | void iwl_bss_info_changed(struct ieee80211_hw *hw, | 2363 | void iwl_bss_info_changed(struct ieee80211_hw *hw, |
2349 | struct ieee80211_vif *vif, | 2364 | struct ieee80211_vif *vif, |
@@ -2475,20 +2490,8 @@ void iwl_bss_info_changed(struct ieee80211_hw *hw, | |||
2475 | IWL_DELAY_NEXT_SCAN_AFTER_ASSOC; | 2490 | IWL_DELAY_NEXT_SCAN_AFTER_ASSOC; |
2476 | if (!iwl_is_rfkill(priv)) | 2491 | if (!iwl_is_rfkill(priv)) |
2477 | priv->cfg->ops->lib->post_associate(priv); | 2492 | priv->cfg->ops->lib->post_associate(priv); |
2478 | } else { | 2493 | } else |
2479 | priv->assoc_id = 0; | 2494 | iwl_set_no_assoc(priv); |
2480 | iwl_led_disassociate(priv); | ||
2481 | |||
2482 | /* | ||
2483 | * inform the ucode that there is no longer an | ||
2484 | * association and that no more packets should be | ||
2485 | * send | ||
2486 | */ | ||
2487 | priv->staging_rxon.filter_flags &= | ||
2488 | ~RXON_FILTER_ASSOC_MSK; | ||
2489 | priv->staging_rxon.assoc_id = 0; | ||
2490 | iwlcore_commit_rxon(priv); | ||
2491 | } | ||
2492 | } | 2495 | } |
2493 | 2496 | ||
2494 | if (changes && iwl_is_associated(priv) && priv->assoc_id) { | 2497 | if (changes && iwl_is_associated(priv) && priv->assoc_id) { |
@@ -2503,12 +2506,14 @@ void iwl_bss_info_changed(struct ieee80211_hw *hw, | |||
2503 | } | 2506 | } |
2504 | } | 2507 | } |
2505 | 2508 | ||
2506 | if ((changes & BSS_CHANGED_BEACON_ENABLED) && | 2509 | if (changes & BSS_CHANGED_BEACON_ENABLED) { |
2507 | vif->bss_conf.enable_beacon) { | 2510 | if (vif->bss_conf.enable_beacon) { |
2508 | memcpy(priv->staging_rxon.bssid_addr, | 2511 | memcpy(priv->staging_rxon.bssid_addr, |
2509 | bss_conf->bssid, ETH_ALEN); | 2512 | bss_conf->bssid, ETH_ALEN); |
2510 | memcpy(priv->bssid, bss_conf->bssid, ETH_ALEN); | 2513 | memcpy(priv->bssid, bss_conf->bssid, ETH_ALEN); |
2511 | iwlcore_config_ap(priv); | 2514 | iwlcore_config_ap(priv); |
2515 | } else | ||
2516 | iwl_set_no_assoc(priv); | ||
2512 | } | 2517 | } |
2513 | 2518 | ||
2514 | mutex_unlock(&priv->mutex); | 2519 | mutex_unlock(&priv->mutex); |
diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h index 165d1f6e2dd9..3822cf53e368 100644 --- a/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/drivers/net/wireless/iwlwifi/iwl-dev.h | |||
@@ -711,7 +711,7 @@ extern void iwl_txq_ctx_stop(struct iwl_priv *priv); | |||
711 | extern int iwl_queue_space(const struct iwl_queue *q); | 711 | extern int iwl_queue_space(const struct iwl_queue *q); |
712 | static inline int iwl_queue_used(const struct iwl_queue *q, int i) | 712 | static inline int iwl_queue_used(const struct iwl_queue *q, int i) |
713 | { | 713 | { |
714 | return q->write_ptr > q->read_ptr ? | 714 | return q->write_ptr >= q->read_ptr ? |
715 | (i >= q->read_ptr && i < q->write_ptr) : | 715 | (i >= q->read_ptr && i < q->write_ptr) : |
716 | !(i < q->read_ptr && i >= q->write_ptr); | 716 | !(i < q->read_ptr && i >= q->write_ptr); |
717 | } | 717 | } |
diff --git a/drivers/net/wireless/mwl8k.c b/drivers/net/wireless/mwl8k.c index 59d49159cf2a..59f92105b0c2 100644 --- a/drivers/net/wireless/mwl8k.c +++ b/drivers/net/wireless/mwl8k.c | |||
@@ -3157,8 +3157,10 @@ static void mwl8k_configure_filter(struct ieee80211_hw *hw, | |||
3157 | /* Clear unsupported feature flags */ | 3157 | /* Clear unsupported feature flags */ |
3158 | *total_flags &= FIF_ALLMULTI | FIF_BCN_PRBRESP_PROMISC; | 3158 | *total_flags &= FIF_ALLMULTI | FIF_BCN_PRBRESP_PROMISC; |
3159 | 3159 | ||
3160 | if (mwl8k_fw_lock(hw)) | 3160 | if (mwl8k_fw_lock(hw)) { |
3161 | kfree(cmd); | ||
3161 | return; | 3162 | return; |
3163 | } | ||
3162 | 3164 | ||
3163 | if (priv->sniffer_enabled) { | 3165 | if (priv->sniffer_enabled) { |
3164 | mwl8k_enable_sniffer(hw, 0); | 3166 | mwl8k_enable_sniffer(hw, 0); |
diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c index 27bf887f1453..9deae41cb784 100644 --- a/drivers/net/wireless/rt2x00/rt2800lib.c +++ b/drivers/net/wireless/rt2x00/rt2800lib.c | |||
@@ -340,7 +340,7 @@ static int rt2800_blink_set(struct led_classdev *led_cdev, | |||
340 | rt2x00_set_field32(®, LED_CFG_OFF_PERIOD, *delay_off); | 340 | rt2x00_set_field32(®, LED_CFG_OFF_PERIOD, *delay_off); |
341 | rt2x00_set_field32(®, LED_CFG_SLOW_BLINK_PERIOD, 3); | 341 | rt2x00_set_field32(®, LED_CFG_SLOW_BLINK_PERIOD, 3); |
342 | rt2x00_set_field32(®, LED_CFG_R_LED_MODE, 3); | 342 | rt2x00_set_field32(®, LED_CFG_R_LED_MODE, 3); |
343 | rt2x00_set_field32(®, LED_CFG_G_LED_MODE, 12); | 343 | rt2x00_set_field32(®, LED_CFG_G_LED_MODE, 3); |
344 | rt2x00_set_field32(®, LED_CFG_Y_LED_MODE, 3); | 344 | rt2x00_set_field32(®, LED_CFG_Y_LED_MODE, 3); |
345 | rt2x00_set_field32(®, LED_CFG_LED_POLAR, 1); | 345 | rt2x00_set_field32(®, LED_CFG_LED_POLAR, 1); |
346 | rt2800_register_write(led->rt2x00dev, LED_CFG, reg); | 346 | rt2800_register_write(led->rt2x00dev, LED_CFG, reg); |
diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h index 4d841c07c970..dcfc8c25d1a7 100644 --- a/drivers/net/wireless/rt2x00/rt2x00.h +++ b/drivers/net/wireless/rt2x00/rt2x00.h | |||
@@ -113,6 +113,12 @@ | |||
113 | ( ((unsigned long)((__skb)->data + (__header))) & 3 ) | 113 | ( ((unsigned long)((__skb)->data + (__header))) & 3 ) |
114 | 114 | ||
115 | /* | 115 | /* |
116 | * Constants for extra TX headroom for alignment purposes. | ||
117 | */ | ||
118 | #define RT2X00_ALIGN_SIZE 4 /* Only whole frame needs alignment */ | ||
119 | #define RT2X00_L2PAD_SIZE 8 /* Both header & payload need alignment */ | ||
120 | |||
121 | /* | ||
116 | * Standard timing and size defines. | 122 | * Standard timing and size defines. |
117 | * These values should follow the ieee80211 specifications. | 123 | * These values should follow the ieee80211 specifications. |
118 | */ | 124 | */ |
diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c index 06c43ca39bf8..265e66dba552 100644 --- a/drivers/net/wireless/rt2x00/rt2x00dev.c +++ b/drivers/net/wireless/rt2x00/rt2x00dev.c | |||
@@ -686,7 +686,17 @@ static int rt2x00lib_probe_hw(struct rt2x00_dev *rt2x00dev) | |||
686 | /* | 686 | /* |
687 | * Initialize extra TX headroom required. | 687 | * Initialize extra TX headroom required. |
688 | */ | 688 | */ |
689 | rt2x00dev->hw->extra_tx_headroom = rt2x00dev->ops->extra_tx_headroom; | 689 | rt2x00dev->hw->extra_tx_headroom = |
690 | max_t(unsigned int, IEEE80211_TX_STATUS_HEADROOM, | ||
691 | rt2x00dev->ops->extra_tx_headroom); | ||
692 | |||
693 | /* | ||
694 | * Take TX headroom required for alignment into account. | ||
695 | */ | ||
696 | if (test_bit(DRIVER_REQUIRE_L2PAD, &rt2x00dev->flags)) | ||
697 | rt2x00dev->hw->extra_tx_headroom += RT2X00_L2PAD_SIZE; | ||
698 | else if (test_bit(DRIVER_REQUIRE_DMA, &rt2x00dev->flags)) | ||
699 | rt2x00dev->hw->extra_tx_headroom += RT2X00_ALIGN_SIZE; | ||
690 | 700 | ||
691 | /* | 701 | /* |
692 | * Register HW. | 702 | * Register HW. |
diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.c b/drivers/net/wireless/rt2x00/rt2x00queue.c index 239afc7a9c0b..9915a09141ef 100644 --- a/drivers/net/wireless/rt2x00/rt2x00queue.c +++ b/drivers/net/wireless/rt2x00/rt2x00queue.c | |||
@@ -104,7 +104,7 @@ void rt2x00queue_map_txskb(struct rt2x00_dev *rt2x00dev, struct sk_buff *skb) | |||
104 | * is also mapped to the DMA so it can be used for transfering | 104 | * is also mapped to the DMA so it can be used for transfering |
105 | * additional descriptor information to the hardware. | 105 | * additional descriptor information to the hardware. |
106 | */ | 106 | */ |
107 | skb_push(skb, rt2x00dev->hw->extra_tx_headroom); | 107 | skb_push(skb, rt2x00dev->ops->extra_tx_headroom); |
108 | 108 | ||
109 | skbdesc->skb_dma = | 109 | skbdesc->skb_dma = |
110 | dma_map_single(rt2x00dev->dev, skb->data, skb->len, DMA_TO_DEVICE); | 110 | dma_map_single(rt2x00dev->dev, skb->data, skb->len, DMA_TO_DEVICE); |
@@ -112,7 +112,7 @@ void rt2x00queue_map_txskb(struct rt2x00_dev *rt2x00dev, struct sk_buff *skb) | |||
112 | /* | 112 | /* |
113 | * Restore data pointer to original location again. | 113 | * Restore data pointer to original location again. |
114 | */ | 114 | */ |
115 | skb_pull(skb, rt2x00dev->hw->extra_tx_headroom); | 115 | skb_pull(skb, rt2x00dev->ops->extra_tx_headroom); |
116 | 116 | ||
117 | skbdesc->flags |= SKBDESC_DMA_MAPPED_TX; | 117 | skbdesc->flags |= SKBDESC_DMA_MAPPED_TX; |
118 | } | 118 | } |
@@ -134,7 +134,7 @@ void rt2x00queue_unmap_skb(struct rt2x00_dev *rt2x00dev, struct sk_buff *skb) | |||
134 | * by the driver, but it was actually mapped to DMA. | 134 | * by the driver, but it was actually mapped to DMA. |
135 | */ | 135 | */ |
136 | dma_unmap_single(rt2x00dev->dev, skbdesc->skb_dma, | 136 | dma_unmap_single(rt2x00dev->dev, skbdesc->skb_dma, |
137 | skb->len + rt2x00dev->hw->extra_tx_headroom, | 137 | skb->len + rt2x00dev->ops->extra_tx_headroom, |
138 | DMA_TO_DEVICE); | 138 | DMA_TO_DEVICE); |
139 | skbdesc->flags &= ~SKBDESC_DMA_MAPPED_TX; | 139 | skbdesc->flags &= ~SKBDESC_DMA_MAPPED_TX; |
140 | } | 140 | } |
diff --git a/drivers/net/wireless/zd1211rw/zd_mac.c b/drivers/net/wireless/zd1211rw/zd_mac.c index 8ebf5c33955d..f14deb0c8514 100644 --- a/drivers/net/wireless/zd1211rw/zd_mac.c +++ b/drivers/net/wireless/zd1211rw/zd_mac.c | |||
@@ -987,12 +987,13 @@ static void zd_op_configure_filter(struct ieee80211_hw *hw, | |||
987 | changed_flags &= SUPPORTED_FIF_FLAGS; | 987 | changed_flags &= SUPPORTED_FIF_FLAGS; |
988 | *new_flags &= SUPPORTED_FIF_FLAGS; | 988 | *new_flags &= SUPPORTED_FIF_FLAGS; |
989 | 989 | ||
990 | /* changed_flags is always populated but this driver | 990 | /* |
991 | * doesn't support all FIF flags so its possible we don't | 991 | * If multicast parameter (as returned by zd_op_prepare_multicast) |
992 | * need to do anything */ | 992 | * has changed, no bit in changed_flags is set. To handle this |
993 | if (!changed_flags) | 993 | * situation, we do not return if changed_flags is 0. If we do so, |
994 | return; | 994 | * we will have some issue with IPv6 which uses multicast for link |
995 | 995 | * layer address resolution. | |
996 | */ | ||
996 | if (*new_flags & (FIF_PROMISC_IN_BSS | FIF_ALLMULTI)) | 997 | if (*new_flags & (FIF_PROMISC_IN_BSS | FIF_ALLMULTI)) |
997 | zd_mc_add_all(&hash); | 998 | zd_mc_add_all(&hash); |
998 | 999 | ||
diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c index c5df94e86678..807224ec8351 100644 --- a/drivers/pci/pci-sysfs.c +++ b/drivers/pci/pci-sysfs.c | |||
@@ -75,7 +75,8 @@ static ssize_t local_cpus_show(struct device *dev, | |||
75 | int len; | 75 | int len; |
76 | 76 | ||
77 | #ifdef CONFIG_NUMA | 77 | #ifdef CONFIG_NUMA |
78 | mask = cpumask_of_node(dev_to_node(dev)); | 78 | mask = (dev_to_node(dev) == -1) ? cpu_online_mask : |
79 | cpumask_of_node(dev_to_node(dev)); | ||
79 | #else | 80 | #else |
80 | mask = cpumask_of_pcibus(to_pci_dev(dev)->bus); | 81 | mask = cpumask_of_pcibus(to_pci_dev(dev)->bus); |
81 | #endif | 82 | #endif |
@@ -93,7 +94,8 @@ static ssize_t local_cpulist_show(struct device *dev, | |||
93 | int len; | 94 | int len; |
94 | 95 | ||
95 | #ifdef CONFIG_NUMA | 96 | #ifdef CONFIG_NUMA |
96 | mask = cpumask_of_node(dev_to_node(dev)); | 97 | mask = (dev_to_node(dev) == -1) ? cpu_online_mask : |
98 | cpumask_of_node(dev_to_node(dev)); | ||
97 | #else | 99 | #else |
98 | mask = cpumask_of_pcibus(to_pci_dev(dev)->bus); | 100 | mask = cpumask_of_pcibus(to_pci_dev(dev)->bus); |
99 | #endif | 101 | #endif |
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 0906599ebfde..315fea47e784 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c | |||
@@ -29,7 +29,17 @@ const char *pci_power_names[] = { | |||
29 | }; | 29 | }; |
30 | EXPORT_SYMBOL_GPL(pci_power_names); | 30 | EXPORT_SYMBOL_GPL(pci_power_names); |
31 | 31 | ||
32 | unsigned int pci_pm_d3_delay = PCI_PM_D3_WAIT; | 32 | unsigned int pci_pm_d3_delay; |
33 | |||
34 | static void pci_dev_d3_sleep(struct pci_dev *dev) | ||
35 | { | ||
36 | unsigned int delay = dev->d3_delay; | ||
37 | |||
38 | if (delay < pci_pm_d3_delay) | ||
39 | delay = pci_pm_d3_delay; | ||
40 | |||
41 | msleep(delay); | ||
42 | } | ||
33 | 43 | ||
34 | #ifdef CONFIG_PCI_DOMAINS | 44 | #ifdef CONFIG_PCI_DOMAINS |
35 | int pci_domains_supported = 1; | 45 | int pci_domains_supported = 1; |
@@ -522,7 +532,7 @@ static int pci_raw_set_power_state(struct pci_dev *dev, pci_power_t state) | |||
522 | /* Mandatory power management transition delays */ | 532 | /* Mandatory power management transition delays */ |
523 | /* see PCI PM 1.1 5.6.1 table 18 */ | 533 | /* see PCI PM 1.1 5.6.1 table 18 */ |
524 | if (state == PCI_D3hot || dev->current_state == PCI_D3hot) | 534 | if (state == PCI_D3hot || dev->current_state == PCI_D3hot) |
525 | msleep(pci_pm_d3_delay); | 535 | pci_dev_d3_sleep(dev); |
526 | else if (state == PCI_D2 || dev->current_state == PCI_D2) | 536 | else if (state == PCI_D2 || dev->current_state == PCI_D2) |
527 | udelay(PCI_PM_D2_DELAY); | 537 | udelay(PCI_PM_D2_DELAY); |
528 | 538 | ||
@@ -1409,6 +1419,7 @@ void pci_pm_init(struct pci_dev *dev) | |||
1409 | } | 1419 | } |
1410 | 1420 | ||
1411 | dev->pm_cap = pm; | 1421 | dev->pm_cap = pm; |
1422 | dev->d3_delay = PCI_PM_D3_WAIT; | ||
1412 | 1423 | ||
1413 | dev->d1_support = false; | 1424 | dev->d1_support = false; |
1414 | dev->d2_support = false; | 1425 | dev->d2_support = false; |
@@ -2247,12 +2258,12 @@ static int pci_pm_reset(struct pci_dev *dev, int probe) | |||
2247 | csr &= ~PCI_PM_CTRL_STATE_MASK; | 2258 | csr &= ~PCI_PM_CTRL_STATE_MASK; |
2248 | csr |= PCI_D3hot; | 2259 | csr |= PCI_D3hot; |
2249 | pci_write_config_word(dev, dev->pm_cap + PCI_PM_CTRL, csr); | 2260 | pci_write_config_word(dev, dev->pm_cap + PCI_PM_CTRL, csr); |
2250 | msleep(pci_pm_d3_delay); | 2261 | pci_dev_d3_sleep(dev); |
2251 | 2262 | ||
2252 | csr &= ~PCI_PM_CTRL_STATE_MASK; | 2263 | csr &= ~PCI_PM_CTRL_STATE_MASK; |
2253 | csr |= PCI_D0; | 2264 | csr |= PCI_D0; |
2254 | pci_write_config_word(dev, dev->pm_cap + PCI_PM_CTRL, csr); | 2265 | pci_write_config_word(dev, dev->pm_cap + PCI_PM_CTRL, csr); |
2255 | msleep(pci_pm_d3_delay); | 2266 | pci_dev_d3_sleep(dev); |
2256 | 2267 | ||
2257 | return 0; | 2268 | return 0; |
2258 | } | 2269 | } |
diff --git a/drivers/pci/pcie/aer/aer_inject.c b/drivers/pci/pcie/aer/aer_inject.c index 797d47809f7a..8c30a9544d61 100644 --- a/drivers/pci/pcie/aer/aer_inject.c +++ b/drivers/pci/pcie/aer/aer_inject.c | |||
@@ -321,7 +321,7 @@ static int aer_inject(struct aer_error_inj *einj) | |||
321 | unsigned long flags; | 321 | unsigned long flags; |
322 | unsigned int devfn = PCI_DEVFN(einj->dev, einj->fn); | 322 | unsigned int devfn = PCI_DEVFN(einj->dev, einj->fn); |
323 | int pos_cap_err, rp_pos_cap_err; | 323 | int pos_cap_err, rp_pos_cap_err; |
324 | u32 sever; | 324 | u32 sever, mask; |
325 | int ret = 0; | 325 | int ret = 0; |
326 | 326 | ||
327 | dev = pci_get_domain_bus_and_slot((int)einj->domain, einj->bus, devfn); | 327 | dev = pci_get_domain_bus_and_slot((int)einj->domain, einj->bus, devfn); |
@@ -374,6 +374,24 @@ static int aer_inject(struct aer_error_inj *einj) | |||
374 | err->header_log2 = einj->header_log2; | 374 | err->header_log2 = einj->header_log2; |
375 | err->header_log3 = einj->header_log3; | 375 | err->header_log3 = einj->header_log3; |
376 | 376 | ||
377 | pci_read_config_dword(dev, pos_cap_err + PCI_ERR_COR_MASK, &mask); | ||
378 | if (einj->cor_status && !(einj->cor_status & ~mask)) { | ||
379 | ret = -EINVAL; | ||
380 | printk(KERN_WARNING "The correctable error(s) is masked " | ||
381 | "by device\n"); | ||
382 | spin_unlock_irqrestore(&inject_lock, flags); | ||
383 | goto out_put; | ||
384 | } | ||
385 | |||
386 | pci_read_config_dword(dev, pos_cap_err + PCI_ERR_UNCOR_MASK, &mask); | ||
387 | if (einj->uncor_status && !(einj->uncor_status & ~mask)) { | ||
388 | ret = -EINVAL; | ||
389 | printk(KERN_WARNING "The uncorrectable error(s) is masked " | ||
390 | "by device\n"); | ||
391 | spin_unlock_irqrestore(&inject_lock, flags); | ||
392 | goto out_put; | ||
393 | } | ||
394 | |||
377 | rperr = __find_aer_error_by_dev(rpdev); | 395 | rperr = __find_aer_error_by_dev(rpdev); |
378 | if (!rperr) { | 396 | if (!rperr) { |
379 | rperr = rperr_alloc; | 397 | rperr = rperr_alloc; |
@@ -413,8 +431,14 @@ static int aer_inject(struct aer_error_inj *einj) | |||
413 | if (ret) | 431 | if (ret) |
414 | goto out_put; | 432 | goto out_put; |
415 | 433 | ||
416 | if (find_aer_device(rpdev, &edev)) | 434 | if (find_aer_device(rpdev, &edev)) { |
435 | if (!get_service_data(edev)) { | ||
436 | printk(KERN_WARNING "AER service is not initialized\n"); | ||
437 | ret = -EINVAL; | ||
438 | goto out_put; | ||
439 | } | ||
417 | aer_irq(-1, edev); | 440 | aer_irq(-1, edev); |
441 | } | ||
418 | else | 442 | else |
419 | ret = -EINVAL; | 443 | ret = -EINVAL; |
420 | out_put: | 444 | out_put: |
diff --git a/drivers/pci/pcie/portdrv_core.c b/drivers/pci/pcie/portdrv_core.c index 413262eb95b7..b174188ac121 100644 --- a/drivers/pci/pcie/portdrv_core.c +++ b/drivers/pci/pcie/portdrv_core.c | |||
@@ -27,7 +27,7 @@ | |||
27 | */ | 27 | */ |
28 | static void release_pcie_device(struct device *dev) | 28 | static void release_pcie_device(struct device *dev) |
29 | { | 29 | { |
30 | kfree(to_pcie_device(dev)); | 30 | kfree(to_pcie_device(dev)); |
31 | } | 31 | } |
32 | 32 | ||
33 | /** | 33 | /** |
@@ -346,12 +346,11 @@ static int suspend_iter(struct device *dev, void *data) | |||
346 | { | 346 | { |
347 | struct pcie_port_service_driver *service_driver; | 347 | struct pcie_port_service_driver *service_driver; |
348 | 348 | ||
349 | if ((dev->bus == &pcie_port_bus_type) && | 349 | if ((dev->bus == &pcie_port_bus_type) && dev->driver) { |
350 | (dev->driver)) { | 350 | service_driver = to_service_driver(dev->driver); |
351 | service_driver = to_service_driver(dev->driver); | 351 | if (service_driver->suspend) |
352 | if (service_driver->suspend) | 352 | service_driver->suspend(to_pcie_device(dev)); |
353 | service_driver->suspend(to_pcie_device(dev)); | 353 | } |
354 | } | ||
355 | return 0; | 354 | return 0; |
356 | } | 355 | } |
357 | 356 | ||
@@ -494,6 +493,7 @@ int pcie_port_service_register(struct pcie_port_service_driver *new) | |||
494 | 493 | ||
495 | return driver_register(&new->driver); | 494 | return driver_register(&new->driver); |
496 | } | 495 | } |
496 | EXPORT_SYMBOL(pcie_port_service_register); | ||
497 | 497 | ||
498 | /** | 498 | /** |
499 | * pcie_port_service_unregister - unregister PCI Express port service driver | 499 | * pcie_port_service_unregister - unregister PCI Express port service driver |
@@ -503,6 +503,4 @@ void pcie_port_service_unregister(struct pcie_port_service_driver *drv) | |||
503 | { | 503 | { |
504 | driver_unregister(&drv->driver); | 504 | driver_unregister(&drv->driver); |
505 | } | 505 | } |
506 | |||
507 | EXPORT_SYMBOL(pcie_port_service_register); | ||
508 | EXPORT_SYMBOL(pcie_port_service_unregister); | 506 | EXPORT_SYMBOL(pcie_port_service_unregister); |
diff --git a/drivers/pci/pcie/portdrv_pci.c b/drivers/pci/pcie/portdrv_pci.c index 34d65172a4d7..13c8972886e6 100644 --- a/drivers/pci/pcie/portdrv_pci.c +++ b/drivers/pci/pcie/portdrv_pci.c | |||
@@ -63,7 +63,7 @@ static const struct dev_pm_ops pcie_portdrv_pm_ops = { | |||
63 | * pcie_portdrv_probe - Probe PCI-Express port devices | 63 | * pcie_portdrv_probe - Probe PCI-Express port devices |
64 | * @dev: PCI-Express port device being probed | 64 | * @dev: PCI-Express port device being probed |
65 | * | 65 | * |
66 | * If detected invokes the pcie_port_device_register() method for | 66 | * If detected invokes the pcie_port_device_register() method for |
67 | * this port device. | 67 | * this port device. |
68 | * | 68 | * |
69 | */ | 69 | */ |
@@ -78,7 +78,7 @@ static int __devinit pcie_portdrv_probe(struct pci_dev *dev, | |||
78 | (dev->pcie_type != PCI_EXP_TYPE_DOWNSTREAM))) | 78 | (dev->pcie_type != PCI_EXP_TYPE_DOWNSTREAM))) |
79 | return -ENODEV; | 79 | return -ENODEV; |
80 | 80 | ||
81 | if (!dev->irq && dev->pin) { | 81 | if (!dev->irq && dev->pin) { |
82 | dev_warn(&dev->dev, "device [%04x:%04x] has invalid IRQ; " | 82 | dev_warn(&dev->dev, "device [%04x:%04x] has invalid IRQ; " |
83 | "check vendor BIOS\n", dev->vendor, dev->device); | 83 | "check vendor BIOS\n", dev->vendor, dev->device); |
84 | } | 84 | } |
@@ -91,7 +91,7 @@ static int __devinit pcie_portdrv_probe(struct pci_dev *dev, | |||
91 | return 0; | 91 | return 0; |
92 | } | 92 | } |
93 | 93 | ||
94 | static void pcie_portdrv_remove (struct pci_dev *dev) | 94 | static void pcie_portdrv_remove(struct pci_dev *dev) |
95 | { | 95 | { |
96 | pcie_port_device_remove(dev); | 96 | pcie_port_device_remove(dev); |
97 | pci_disable_device(dev); | 97 | pci_disable_device(dev); |
@@ -129,14 +129,13 @@ static int error_detected_iter(struct device *device, void *data) | |||
129 | static pci_ers_result_t pcie_portdrv_error_detected(struct pci_dev *dev, | 129 | static pci_ers_result_t pcie_portdrv_error_detected(struct pci_dev *dev, |
130 | enum pci_channel_state error) | 130 | enum pci_channel_state error) |
131 | { | 131 | { |
132 | struct aer_broadcast_data result_data = | 132 | struct aer_broadcast_data data = {error, PCI_ERS_RESULT_CAN_RECOVER}; |
133 | {error, PCI_ERS_RESULT_CAN_RECOVER}; | 133 | int ret; |
134 | int retval; | ||
135 | 134 | ||
136 | /* can not fail */ | 135 | /* can not fail */ |
137 | retval = device_for_each_child(&dev->dev, &result_data, error_detected_iter); | 136 | ret = device_for_each_child(&dev->dev, &data, error_detected_iter); |
138 | 137 | ||
139 | return result_data.result; | 138 | return data.result; |
140 | } | 139 | } |
141 | 140 | ||
142 | static int mmio_enabled_iter(struct device *device, void *data) | 141 | static int mmio_enabled_iter(struct device *device, void *data) |
@@ -290,7 +289,7 @@ static int __init pcie_portdrv_init(void) | |||
290 | return retval; | 289 | return retval; |
291 | } | 290 | } |
292 | 291 | ||
293 | static void __exit pcie_portdrv_exit(void) | 292 | static void __exit pcie_portdrv_exit(void) |
294 | { | 293 | { |
295 | pci_unregister_driver(&pcie_portdriver); | 294 | pci_unregister_driver(&pcie_portdriver); |
296 | pcie_port_bus_unregister(); | 295 | pcie_port_bus_unregister(); |
diff --git a/drivers/platform/x86/hp-wmi.c b/drivers/platform/x86/hp-wmi.c index 5b648f0c6075..ad4c414dbfbc 100644 --- a/drivers/platform/x86/hp-wmi.c +++ b/drivers/platform/x86/hp-wmi.c | |||
@@ -393,8 +393,6 @@ static void hp_wmi_notify(u32 value, void *context) | |||
393 | } else | 393 | } else |
394 | printk(KERN_INFO "HP WMI: Unknown key pressed - %x\n", | 394 | printk(KERN_INFO "HP WMI: Unknown key pressed - %x\n", |
395 | eventcode); | 395 | eventcode); |
396 | |||
397 | kfree(obj); | ||
398 | } | 396 | } |
399 | 397 | ||
400 | static int __init hp_wmi_input_setup(void) | 398 | static int __init hp_wmi_input_setup(void) |
diff --git a/drivers/power/pmu_battery.c b/drivers/power/pmu_battery.c index 9346a862f1f2..9c87ad564803 100644 --- a/drivers/power/pmu_battery.c +++ b/drivers/power/pmu_battery.c | |||
@@ -89,6 +89,8 @@ static int pmu_bat_get_property(struct power_supply *psy, | |||
89 | case POWER_SUPPLY_PROP_STATUS: | 89 | case POWER_SUPPLY_PROP_STATUS: |
90 | if (pbi->flags & PMU_BATT_CHARGING) | 90 | if (pbi->flags & PMU_BATT_CHARGING) |
91 | val->intval = POWER_SUPPLY_STATUS_CHARGING; | 91 | val->intval = POWER_SUPPLY_STATUS_CHARGING; |
92 | else if (pmu_power_flags & PMU_PWR_AC_PRESENT) | ||
93 | val->intval = POWER_SUPPLY_STATUS_FULL; | ||
92 | else | 94 | else |
93 | val->intval = POWER_SUPPLY_STATUS_DISCHARGING; | 95 | val->intval = POWER_SUPPLY_STATUS_DISCHARGING; |
94 | break; | 96 | break; |
diff --git a/drivers/rtc/rtc-cmos.c b/drivers/rtc/rtc-cmos.c index c8c12325e69b..e9aa814ddd23 100644 --- a/drivers/rtc/rtc-cmos.c +++ b/drivers/rtc/rtc-cmos.c | |||
@@ -1096,9 +1096,9 @@ static int cmos_pnp_resume(struct pnp_dev *pnp) | |||
1096 | #define cmos_pnp_resume NULL | 1096 | #define cmos_pnp_resume NULL |
1097 | #endif | 1097 | #endif |
1098 | 1098 | ||
1099 | static void cmos_pnp_shutdown(struct device *pdev) | 1099 | static void cmos_pnp_shutdown(struct pnp_dev *pnp) |
1100 | { | 1100 | { |
1101 | if (system_state == SYSTEM_POWER_OFF && !cmos_poweroff(pdev)) | 1101 | if (system_state == SYSTEM_POWER_OFF && !cmos_poweroff(&pnp->dev)) |
1102 | return; | 1102 | return; |
1103 | 1103 | ||
1104 | cmos_do_shutdown(); | 1104 | cmos_do_shutdown(); |
@@ -1117,15 +1117,12 @@ static struct pnp_driver cmos_pnp_driver = { | |||
1117 | .id_table = rtc_ids, | 1117 | .id_table = rtc_ids, |
1118 | .probe = cmos_pnp_probe, | 1118 | .probe = cmos_pnp_probe, |
1119 | .remove = __exit_p(cmos_pnp_remove), | 1119 | .remove = __exit_p(cmos_pnp_remove), |
1120 | .shutdown = cmos_pnp_shutdown, | ||
1120 | 1121 | ||
1121 | /* flag ensures resume() gets called, and stops syslog spam */ | 1122 | /* flag ensures resume() gets called, and stops syslog spam */ |
1122 | .flags = PNP_DRIVER_RES_DO_NOT_CHANGE, | 1123 | .flags = PNP_DRIVER_RES_DO_NOT_CHANGE, |
1123 | .suspend = cmos_pnp_suspend, | 1124 | .suspend = cmos_pnp_suspend, |
1124 | .resume = cmos_pnp_resume, | 1125 | .resume = cmos_pnp_resume, |
1125 | .driver = { | ||
1126 | .name = (char *)driver_name, | ||
1127 | .shutdown = cmos_pnp_shutdown, | ||
1128 | } | ||
1129 | }; | 1126 | }; |
1130 | 1127 | ||
1131 | #endif /* CONFIG_PNP */ | 1128 | #endif /* CONFIG_PNP */ |
diff --git a/drivers/rtc/rtc-pl031.c b/drivers/rtc/rtc-pl031.c index 0264b117893b..c256aacfa954 100644 --- a/drivers/rtc/rtc-pl031.c +++ b/drivers/rtc/rtc-pl031.c | |||
@@ -7,6 +7,9 @@ | |||
7 | * | 7 | * |
8 | * Copyright 2006 (c) MontaVista Software, Inc. | 8 | * Copyright 2006 (c) MontaVista Software, Inc. |
9 | * | 9 | * |
10 | * Author: Mian Yousaf Kaukab <mian.yousaf.kaukab@stericsson.com> | ||
11 | * Copyright 2010 (c) ST-Ericsson AB | ||
12 | * | ||
10 | * This program is free software; you can redistribute it and/or | 13 | * This program is free software; you can redistribute it and/or |
11 | * modify it under the terms of the GNU General Public License | 14 | * modify it under the terms of the GNU General Public License |
12 | * as published by the Free Software Foundation; either version | 15 | * as published by the Free Software Foundation; either version |
@@ -18,6 +21,9 @@ | |||
18 | #include <linux/interrupt.h> | 21 | #include <linux/interrupt.h> |
19 | #include <linux/amba/bus.h> | 22 | #include <linux/amba/bus.h> |
20 | #include <linux/io.h> | 23 | #include <linux/io.h> |
24 | #include <linux/bcd.h> | ||
25 | #include <linux/delay.h> | ||
26 | #include <linux/version.h> | ||
21 | 27 | ||
22 | /* | 28 | /* |
23 | * Register definitions | 29 | * Register definitions |
@@ -30,35 +36,207 @@ | |||
30 | #define RTC_RIS 0x14 /* Raw interrupt status register */ | 36 | #define RTC_RIS 0x14 /* Raw interrupt status register */ |
31 | #define RTC_MIS 0x18 /* Masked interrupt status register */ | 37 | #define RTC_MIS 0x18 /* Masked interrupt status register */ |
32 | #define RTC_ICR 0x1c /* Interrupt clear register */ | 38 | #define RTC_ICR 0x1c /* Interrupt clear register */ |
39 | /* ST variants have additional timer functionality */ | ||
40 | #define RTC_TDR 0x20 /* Timer data read register */ | ||
41 | #define RTC_TLR 0x24 /* Timer data load register */ | ||
42 | #define RTC_TCR 0x28 /* Timer control register */ | ||
43 | #define RTC_YDR 0x30 /* Year data read register */ | ||
44 | #define RTC_YMR 0x34 /* Year match register */ | ||
45 | #define RTC_YLR 0x38 /* Year data load register */ | ||
46 | |||
47 | #define RTC_CR_CWEN (1 << 26) /* Clockwatch enable bit */ | ||
48 | |||
49 | #define RTC_TCR_EN (1 << 1) /* Periodic timer enable bit */ | ||
50 | |||
51 | /* Common bit definitions for Interrupt status and control registers */ | ||
52 | #define RTC_BIT_AI (1 << 0) /* Alarm interrupt bit */ | ||
53 | #define RTC_BIT_PI (1 << 1) /* Periodic interrupt bit. ST variants only. */ | ||
54 | |||
55 | /* Common bit definations for ST v2 for reading/writing time */ | ||
56 | #define RTC_SEC_SHIFT 0 | ||
57 | #define RTC_SEC_MASK (0x3F << RTC_SEC_SHIFT) /* Second [0-59] */ | ||
58 | #define RTC_MIN_SHIFT 6 | ||
59 | #define RTC_MIN_MASK (0x3F << RTC_MIN_SHIFT) /* Minute [0-59] */ | ||
60 | #define RTC_HOUR_SHIFT 12 | ||
61 | #define RTC_HOUR_MASK (0x1F << RTC_HOUR_SHIFT) /* Hour [0-23] */ | ||
62 | #define RTC_WDAY_SHIFT 17 | ||
63 | #define RTC_WDAY_MASK (0x7 << RTC_WDAY_SHIFT) /* Day of Week [1-7] 1=Sunday */ | ||
64 | #define RTC_MDAY_SHIFT 20 | ||
65 | #define RTC_MDAY_MASK (0x1F << RTC_MDAY_SHIFT) /* Day of Month [1-31] */ | ||
66 | #define RTC_MON_SHIFT 25 | ||
67 | #define RTC_MON_MASK (0xF << RTC_MON_SHIFT) /* Month [1-12] 1=January */ | ||
68 | |||
69 | #define RTC_TIMER_FREQ 32768 | ||
33 | 70 | ||
34 | struct pl031_local { | 71 | struct pl031_local { |
35 | struct rtc_device *rtc; | 72 | struct rtc_device *rtc; |
36 | void __iomem *base; | 73 | void __iomem *base; |
74 | u8 hw_designer; | ||
75 | u8 hw_revision:4; | ||
37 | }; | 76 | }; |
38 | 77 | ||
39 | static irqreturn_t pl031_interrupt(int irq, void *dev_id) | 78 | static int pl031_alarm_irq_enable(struct device *dev, |
79 | unsigned int enabled) | ||
80 | { | ||
81 | struct pl031_local *ldata = dev_get_drvdata(dev); | ||
82 | unsigned long imsc; | ||
83 | |||
84 | /* Clear any pending alarm interrupts. */ | ||
85 | writel(RTC_BIT_AI, ldata->base + RTC_ICR); | ||
86 | |||
87 | imsc = readl(ldata->base + RTC_IMSC); | ||
88 | |||
89 | if (enabled == 1) | ||
90 | writel(imsc | RTC_BIT_AI, ldata->base + RTC_IMSC); | ||
91 | else | ||
92 | writel(imsc & ~RTC_BIT_AI, ldata->base + RTC_IMSC); | ||
93 | |||
94 | return 0; | ||
95 | } | ||
96 | |||
97 | /* | ||
98 | * Convert Gregorian date to ST v2 RTC format. | ||
99 | */ | ||
100 | static int pl031_stv2_tm_to_time(struct device *dev, | ||
101 | struct rtc_time *tm, unsigned long *st_time, | ||
102 | unsigned long *bcd_year) | ||
103 | { | ||
104 | int year = tm->tm_year + 1900; | ||
105 | int wday = tm->tm_wday; | ||
106 | |||
107 | /* wday masking is not working in hardware so wday must be valid */ | ||
108 | if (wday < -1 || wday > 6) { | ||
109 | dev_err(dev, "invalid wday value %d\n", tm->tm_wday); | ||
110 | return -EINVAL; | ||
111 | } else if (wday == -1) { | ||
112 | /* wday is not provided, calculate it here */ | ||
113 | unsigned long time; | ||
114 | struct rtc_time calc_tm; | ||
115 | |||
116 | rtc_tm_to_time(tm, &time); | ||
117 | rtc_time_to_tm(time, &calc_tm); | ||
118 | wday = calc_tm.tm_wday; | ||
119 | } | ||
120 | |||
121 | *bcd_year = (bin2bcd(year % 100) | bin2bcd(year / 100) << 8); | ||
122 | |||
123 | *st_time = ((tm->tm_mon + 1) << RTC_MON_SHIFT) | ||
124 | | (tm->tm_mday << RTC_MDAY_SHIFT) | ||
125 | | ((wday + 1) << RTC_WDAY_SHIFT) | ||
126 | | (tm->tm_hour << RTC_HOUR_SHIFT) | ||
127 | | (tm->tm_min << RTC_MIN_SHIFT) | ||
128 | | (tm->tm_sec << RTC_SEC_SHIFT); | ||
129 | |||
130 | return 0; | ||
131 | } | ||
132 | |||
133 | /* | ||
134 | * Convert ST v2 RTC format to Gregorian date. | ||
135 | */ | ||
136 | static int pl031_stv2_time_to_tm(unsigned long st_time, unsigned long bcd_year, | ||
137 | struct rtc_time *tm) | ||
138 | { | ||
139 | tm->tm_year = bcd2bin(bcd_year) + (bcd2bin(bcd_year >> 8) * 100); | ||
140 | tm->tm_mon = ((st_time & RTC_MON_MASK) >> RTC_MON_SHIFT) - 1; | ||
141 | tm->tm_mday = ((st_time & RTC_MDAY_MASK) >> RTC_MDAY_SHIFT); | ||
142 | tm->tm_wday = ((st_time & RTC_WDAY_MASK) >> RTC_WDAY_SHIFT) - 1; | ||
143 | tm->tm_hour = ((st_time & RTC_HOUR_MASK) >> RTC_HOUR_SHIFT); | ||
144 | tm->tm_min = ((st_time & RTC_MIN_MASK) >> RTC_MIN_SHIFT); | ||
145 | tm->tm_sec = ((st_time & RTC_SEC_MASK) >> RTC_SEC_SHIFT); | ||
146 | |||
147 | tm->tm_yday = rtc_year_days(tm->tm_mday, tm->tm_mon, tm->tm_year); | ||
148 | tm->tm_year -= 1900; | ||
149 | |||
150 | return 0; | ||
151 | } | ||
152 | |||
153 | static int pl031_stv2_read_time(struct device *dev, struct rtc_time *tm) | ||
154 | { | ||
155 | struct pl031_local *ldata = dev_get_drvdata(dev); | ||
156 | |||
157 | pl031_stv2_time_to_tm(readl(ldata->base + RTC_DR), | ||
158 | readl(ldata->base + RTC_YDR), tm); | ||
159 | |||
160 | return 0; | ||
161 | } | ||
162 | |||
163 | static int pl031_stv2_set_time(struct device *dev, struct rtc_time *tm) | ||
164 | { | ||
165 | unsigned long time; | ||
166 | unsigned long bcd_year; | ||
167 | struct pl031_local *ldata = dev_get_drvdata(dev); | ||
168 | int ret; | ||
169 | |||
170 | ret = pl031_stv2_tm_to_time(dev, tm, &time, &bcd_year); | ||
171 | if (ret == 0) { | ||
172 | writel(bcd_year, ldata->base + RTC_YLR); | ||
173 | writel(time, ldata->base + RTC_LR); | ||
174 | } | ||
175 | |||
176 | return ret; | ||
177 | } | ||
178 | |||
179 | static int pl031_stv2_read_alarm(struct device *dev, struct rtc_wkalrm *alarm) | ||
40 | { | 180 | { |
41 | struct rtc_device *rtc = dev_id; | 181 | struct pl031_local *ldata = dev_get_drvdata(dev); |
182 | int ret; | ||
42 | 183 | ||
43 | rtc_update_irq(rtc, 1, RTC_AF); | 184 | ret = pl031_stv2_time_to_tm(readl(ldata->base + RTC_MR), |
185 | readl(ldata->base + RTC_YMR), &alarm->time); | ||
44 | 186 | ||
45 | return IRQ_HANDLED; | 187 | alarm->pending = readl(ldata->base + RTC_RIS) & RTC_BIT_AI; |
188 | alarm->enabled = readl(ldata->base + RTC_IMSC) & RTC_BIT_AI; | ||
189 | |||
190 | return ret; | ||
46 | } | 191 | } |
47 | 192 | ||
48 | static int pl031_ioctl(struct device *dev, unsigned int cmd, unsigned long arg) | 193 | static int pl031_stv2_set_alarm(struct device *dev, struct rtc_wkalrm *alarm) |
49 | { | 194 | { |
50 | struct pl031_local *ldata = dev_get_drvdata(dev); | 195 | struct pl031_local *ldata = dev_get_drvdata(dev); |
196 | unsigned long time; | ||
197 | unsigned long bcd_year; | ||
198 | int ret; | ||
199 | |||
200 | /* At the moment, we can only deal with non-wildcarded alarm times. */ | ||
201 | ret = rtc_valid_tm(&alarm->time); | ||
202 | if (ret == 0) { | ||
203 | ret = pl031_stv2_tm_to_time(dev, &alarm->time, | ||
204 | &time, &bcd_year); | ||
205 | if (ret == 0) { | ||
206 | writel(bcd_year, ldata->base + RTC_YMR); | ||
207 | writel(time, ldata->base + RTC_MR); | ||
208 | |||
209 | pl031_alarm_irq_enable(dev, alarm->enabled); | ||
210 | } | ||
211 | } | ||
212 | |||
213 | return ret; | ||
214 | } | ||
215 | |||
216 | static irqreturn_t pl031_interrupt(int irq, void *dev_id) | ||
217 | { | ||
218 | struct pl031_local *ldata = dev_id; | ||
219 | unsigned long rtcmis; | ||
220 | unsigned long events = 0; | ||
221 | |||
222 | rtcmis = readl(ldata->base + RTC_MIS); | ||
223 | if (rtcmis) { | ||
224 | writel(rtcmis, ldata->base + RTC_ICR); | ||
225 | |||
226 | if (rtcmis & RTC_BIT_AI) | ||
227 | events |= (RTC_AF | RTC_IRQF); | ||
228 | |||
229 | /* Timer interrupt is only available in ST variants */ | ||
230 | if ((rtcmis & RTC_BIT_PI) && | ||
231 | (ldata->hw_designer == AMBA_VENDOR_ST)) | ||
232 | events |= (RTC_PF | RTC_IRQF); | ||
233 | |||
234 | rtc_update_irq(ldata->rtc, 1, events); | ||
51 | 235 | ||
52 | switch (cmd) { | 236 | return IRQ_HANDLED; |
53 | case RTC_AIE_OFF: | ||
54 | writel(1, ldata->base + RTC_MIS); | ||
55 | return 0; | ||
56 | case RTC_AIE_ON: | ||
57 | writel(0, ldata->base + RTC_MIS); | ||
58 | return 0; | ||
59 | } | 237 | } |
60 | 238 | ||
61 | return -ENOIOCTLCMD; | 239 | return IRQ_NONE; |
62 | } | 240 | } |
63 | 241 | ||
64 | static int pl031_read_time(struct device *dev, struct rtc_time *tm) | 242 | static int pl031_read_time(struct device *dev, struct rtc_time *tm) |
@@ -74,11 +252,14 @@ static int pl031_set_time(struct device *dev, struct rtc_time *tm) | |||
74 | { | 252 | { |
75 | unsigned long time; | 253 | unsigned long time; |
76 | struct pl031_local *ldata = dev_get_drvdata(dev); | 254 | struct pl031_local *ldata = dev_get_drvdata(dev); |
255 | int ret; | ||
77 | 256 | ||
78 | rtc_tm_to_time(tm, &time); | 257 | ret = rtc_tm_to_time(tm, &time); |
79 | writel(time, ldata->base + RTC_LR); | ||
80 | 258 | ||
81 | return 0; | 259 | if (ret == 0) |
260 | writel(time, ldata->base + RTC_LR); | ||
261 | |||
262 | return ret; | ||
82 | } | 263 | } |
83 | 264 | ||
84 | static int pl031_read_alarm(struct device *dev, struct rtc_wkalrm *alarm) | 265 | static int pl031_read_alarm(struct device *dev, struct rtc_wkalrm *alarm) |
@@ -86,8 +267,9 @@ static int pl031_read_alarm(struct device *dev, struct rtc_wkalrm *alarm) | |||
86 | struct pl031_local *ldata = dev_get_drvdata(dev); | 267 | struct pl031_local *ldata = dev_get_drvdata(dev); |
87 | 268 | ||
88 | rtc_time_to_tm(readl(ldata->base + RTC_MR), &alarm->time); | 269 | rtc_time_to_tm(readl(ldata->base + RTC_MR), &alarm->time); |
89 | alarm->pending = readl(ldata->base + RTC_RIS); | 270 | |
90 | alarm->enabled = readl(ldata->base + RTC_IMSC); | 271 | alarm->pending = readl(ldata->base + RTC_RIS) & RTC_BIT_AI; |
272 | alarm->enabled = readl(ldata->base + RTC_IMSC) & RTC_BIT_AI; | ||
91 | 273 | ||
92 | return 0; | 274 | return 0; |
93 | } | 275 | } |
@@ -96,22 +278,71 @@ static int pl031_set_alarm(struct device *dev, struct rtc_wkalrm *alarm) | |||
96 | { | 278 | { |
97 | struct pl031_local *ldata = dev_get_drvdata(dev); | 279 | struct pl031_local *ldata = dev_get_drvdata(dev); |
98 | unsigned long time; | 280 | unsigned long time; |
281 | int ret; | ||
282 | |||
283 | /* At the moment, we can only deal with non-wildcarded alarm times. */ | ||
284 | ret = rtc_valid_tm(&alarm->time); | ||
285 | if (ret == 0) { | ||
286 | ret = rtc_tm_to_time(&alarm->time, &time); | ||
287 | if (ret == 0) { | ||
288 | writel(time, ldata->base + RTC_MR); | ||
289 | pl031_alarm_irq_enable(dev, alarm->enabled); | ||
290 | } | ||
291 | } | ||
292 | |||
293 | return ret; | ||
294 | } | ||
295 | |||
296 | /* Periodic interrupt is only available in ST variants. */ | ||
297 | static int pl031_irq_set_state(struct device *dev, int enabled) | ||
298 | { | ||
299 | struct pl031_local *ldata = dev_get_drvdata(dev); | ||
300 | |||
301 | if (enabled == 1) { | ||
302 | /* Clear any pending timer interrupt. */ | ||
303 | writel(RTC_BIT_PI, ldata->base + RTC_ICR); | ||
304 | |||
305 | writel(readl(ldata->base + RTC_IMSC) | RTC_BIT_PI, | ||
306 | ldata->base + RTC_IMSC); | ||
99 | 307 | ||
100 | rtc_tm_to_time(&alarm->time, &time); | 308 | /* Now start the timer */ |
309 | writel(readl(ldata->base + RTC_TCR) | RTC_TCR_EN, | ||
310 | ldata->base + RTC_TCR); | ||
101 | 311 | ||
102 | writel(time, ldata->base + RTC_MR); | 312 | } else { |
103 | writel(!alarm->enabled, ldata->base + RTC_MIS); | 313 | writel(readl(ldata->base + RTC_IMSC) & (~RTC_BIT_PI), |
314 | ldata->base + RTC_IMSC); | ||
315 | |||
316 | /* Also stop the timer */ | ||
317 | writel(readl(ldata->base + RTC_TCR) & (~RTC_TCR_EN), | ||
318 | ldata->base + RTC_TCR); | ||
319 | } | ||
320 | /* Wait at least 1 RTC32 clock cycle to ensure next access | ||
321 | * to RTC_TCR will succeed. | ||
322 | */ | ||
323 | udelay(40); | ||
104 | 324 | ||
105 | return 0; | 325 | return 0; |
106 | } | 326 | } |
107 | 327 | ||
108 | static const struct rtc_class_ops pl031_ops = { | 328 | static int pl031_irq_set_freq(struct device *dev, int freq) |
109 | .ioctl = pl031_ioctl, | 329 | { |
110 | .read_time = pl031_read_time, | 330 | struct pl031_local *ldata = dev_get_drvdata(dev); |
111 | .set_time = pl031_set_time, | 331 | |
112 | .read_alarm = pl031_read_alarm, | 332 | /* Cant set timer if it is already enabled */ |
113 | .set_alarm = pl031_set_alarm, | 333 | if (readl(ldata->base + RTC_TCR) & RTC_TCR_EN) { |
114 | }; | 334 | dev_err(dev, "can't change frequency while timer enabled\n"); |
335 | return -EINVAL; | ||
336 | } | ||
337 | |||
338 | /* If self start bit in RTC_TCR is set timer will start here, | ||
339 | * but we never set that bit. Instead we start the timer when | ||
340 | * set_state is called with enabled == 1. | ||
341 | */ | ||
342 | writel(RTC_TIMER_FREQ / freq, ldata->base + RTC_TLR); | ||
343 | |||
344 | return 0; | ||
345 | } | ||
115 | 346 | ||
116 | static int pl031_remove(struct amba_device *adev) | 347 | static int pl031_remove(struct amba_device *adev) |
117 | { | 348 | { |
@@ -131,18 +362,20 @@ static int pl031_probe(struct amba_device *adev, struct amba_id *id) | |||
131 | { | 362 | { |
132 | int ret; | 363 | int ret; |
133 | struct pl031_local *ldata; | 364 | struct pl031_local *ldata; |
365 | struct rtc_class_ops *ops = id->data; | ||
134 | 366 | ||
135 | ret = amba_request_regions(adev, NULL); | 367 | ret = amba_request_regions(adev, NULL); |
136 | if (ret) | 368 | if (ret) |
137 | goto err_req; | 369 | goto err_req; |
138 | 370 | ||
139 | ldata = kmalloc(sizeof(struct pl031_local), GFP_KERNEL); | 371 | ldata = kzalloc(sizeof(struct pl031_local), GFP_KERNEL); |
140 | if (!ldata) { | 372 | if (!ldata) { |
141 | ret = -ENOMEM; | 373 | ret = -ENOMEM; |
142 | goto out; | 374 | goto out; |
143 | } | 375 | } |
144 | 376 | ||
145 | ldata->base = ioremap(adev->res.start, resource_size(&adev->res)); | 377 | ldata->base = ioremap(adev->res.start, resource_size(&adev->res)); |
378 | |||
146 | if (!ldata->base) { | 379 | if (!ldata->base) { |
147 | ret = -ENOMEM; | 380 | ret = -ENOMEM; |
148 | goto out_no_remap; | 381 | goto out_no_remap; |
@@ -150,24 +383,36 @@ static int pl031_probe(struct amba_device *adev, struct amba_id *id) | |||
150 | 383 | ||
151 | amba_set_drvdata(adev, ldata); | 384 | amba_set_drvdata(adev, ldata); |
152 | 385 | ||
153 | if (request_irq(adev->irq[0], pl031_interrupt, IRQF_DISABLED, | 386 | ldata->hw_designer = amba_manf(adev); |
154 | "rtc-pl031", ldata->rtc)) { | 387 | ldata->hw_revision = amba_rev(adev); |
155 | ret = -EIO; | 388 | |
156 | goto out_no_irq; | 389 | dev_dbg(&adev->dev, "designer ID = 0x%02x\n", ldata->hw_designer); |
157 | } | 390 | dev_dbg(&adev->dev, "revision = 0x%01x\n", ldata->hw_revision); |
158 | 391 | ||
159 | ldata->rtc = rtc_device_register("pl031", &adev->dev, &pl031_ops, | 392 | /* Enable the clockwatch on ST Variants */ |
160 | THIS_MODULE); | 393 | if ((ldata->hw_designer == AMBA_VENDOR_ST) && |
394 | (ldata->hw_revision > 1)) | ||
395 | writel(readl(ldata->base + RTC_CR) | RTC_CR_CWEN, | ||
396 | ldata->base + RTC_CR); | ||
397 | |||
398 | ldata->rtc = rtc_device_register("pl031", &adev->dev, ops, | ||
399 | THIS_MODULE); | ||
161 | if (IS_ERR(ldata->rtc)) { | 400 | if (IS_ERR(ldata->rtc)) { |
162 | ret = PTR_ERR(ldata->rtc); | 401 | ret = PTR_ERR(ldata->rtc); |
163 | goto out_no_rtc; | 402 | goto out_no_rtc; |
164 | } | 403 | } |
165 | 404 | ||
405 | if (request_irq(adev->irq[0], pl031_interrupt, | ||
406 | IRQF_DISABLED | IRQF_SHARED, "rtc-pl031", ldata)) { | ||
407 | ret = -EIO; | ||
408 | goto out_no_irq; | ||
409 | } | ||
410 | |||
166 | return 0; | 411 | return 0; |
167 | 412 | ||
168 | out_no_rtc: | ||
169 | free_irq(adev->irq[0], ldata->rtc); | ||
170 | out_no_irq: | 413 | out_no_irq: |
414 | rtc_device_unregister(ldata->rtc); | ||
415 | out_no_rtc: | ||
171 | iounmap(ldata->base); | 416 | iounmap(ldata->base); |
172 | amba_set_drvdata(adev, NULL); | 417 | amba_set_drvdata(adev, NULL); |
173 | out_no_remap: | 418 | out_no_remap: |
@@ -175,13 +420,57 @@ out_no_remap: | |||
175 | out: | 420 | out: |
176 | amba_release_regions(adev); | 421 | amba_release_regions(adev); |
177 | err_req: | 422 | err_req: |
423 | |||
178 | return ret; | 424 | return ret; |
179 | } | 425 | } |
180 | 426 | ||
427 | /* Operations for the original ARM version */ | ||
428 | static struct rtc_class_ops arm_pl031_ops = { | ||
429 | .read_time = pl031_read_time, | ||
430 | .set_time = pl031_set_time, | ||
431 | .read_alarm = pl031_read_alarm, | ||
432 | .set_alarm = pl031_set_alarm, | ||
433 | .alarm_irq_enable = pl031_alarm_irq_enable, | ||
434 | }; | ||
435 | |||
436 | /* The First ST derivative */ | ||
437 | static struct rtc_class_ops stv1_pl031_ops = { | ||
438 | .read_time = pl031_read_time, | ||
439 | .set_time = pl031_set_time, | ||
440 | .read_alarm = pl031_read_alarm, | ||
441 | .set_alarm = pl031_set_alarm, | ||
442 | .alarm_irq_enable = pl031_alarm_irq_enable, | ||
443 | .irq_set_state = pl031_irq_set_state, | ||
444 | .irq_set_freq = pl031_irq_set_freq, | ||
445 | }; | ||
446 | |||
447 | /* And the second ST derivative */ | ||
448 | static struct rtc_class_ops stv2_pl031_ops = { | ||
449 | .read_time = pl031_stv2_read_time, | ||
450 | .set_time = pl031_stv2_set_time, | ||
451 | .read_alarm = pl031_stv2_read_alarm, | ||
452 | .set_alarm = pl031_stv2_set_alarm, | ||
453 | .alarm_irq_enable = pl031_alarm_irq_enable, | ||
454 | .irq_set_state = pl031_irq_set_state, | ||
455 | .irq_set_freq = pl031_irq_set_freq, | ||
456 | }; | ||
457 | |||
181 | static struct amba_id pl031_ids[] __initdata = { | 458 | static struct amba_id pl031_ids[] __initdata = { |
182 | { | 459 | { |
183 | .id = 0x00041031, | 460 | .id = 0x00041031, |
184 | .mask = 0x000fffff, | 461 | .mask = 0x000fffff, |
462 | .data = &arm_pl031_ops, | ||
463 | }, | ||
464 | /* ST Micro variants */ | ||
465 | { | ||
466 | .id = 0x00180031, | ||
467 | .mask = 0x00ffffff, | ||
468 | .data = &stv1_pl031_ops, | ||
469 | }, | ||
470 | { | ||
471 | .id = 0x00280031, | ||
472 | .mask = 0x00ffffff, | ||
473 | .data = &stv2_pl031_ops, | ||
185 | }, | 474 | }, |
186 | {0, 0}, | 475 | {0, 0}, |
187 | }; | 476 | }; |
diff --git a/drivers/s390/block/dasd_eckd.c b/drivers/s390/block/dasd_eckd.c index 5819dc02a143..1c500c462225 100644 --- a/drivers/s390/block/dasd_eckd.c +++ b/drivers/s390/block/dasd_eckd.c | |||
@@ -23,6 +23,7 @@ | |||
23 | #include <asm/debug.h> | 23 | #include <asm/debug.h> |
24 | #include <asm/idals.h> | 24 | #include <asm/idals.h> |
25 | #include <asm/ebcdic.h> | 25 | #include <asm/ebcdic.h> |
26 | #include <asm/compat.h> | ||
26 | #include <asm/io.h> | 27 | #include <asm/io.h> |
27 | #include <asm/uaccess.h> | 28 | #include <asm/uaccess.h> |
28 | #include <asm/cio.h> | 29 | #include <asm/cio.h> |
@@ -2844,13 +2845,16 @@ static int dasd_symm_io(struct dasd_device *device, void __user *argp) | |||
2844 | rc = -EFAULT; | 2845 | rc = -EFAULT; |
2845 | if (copy_from_user(&usrparm, argp, sizeof(usrparm))) | 2846 | if (copy_from_user(&usrparm, argp, sizeof(usrparm))) |
2846 | goto out; | 2847 | goto out; |
2847 | #ifndef CONFIG_64BIT | 2848 | if (is_compat_task() || sizeof(long) == 4) { |
2848 | /* Make sure pointers are sane even on 31 bit. */ | 2849 | /* Make sure pointers are sane even on 31 bit. */ |
2849 | if ((usrparm.psf_data >> 32) != 0 || (usrparm.rssd_result >> 32) != 0) { | ||
2850 | rc = -EINVAL; | 2850 | rc = -EINVAL; |
2851 | goto out; | 2851 | if ((usrparm.psf_data >> 32) != 0) |
2852 | goto out; | ||
2853 | if ((usrparm.rssd_result >> 32) != 0) | ||
2854 | goto out; | ||
2855 | usrparm.psf_data &= 0x7fffffffULL; | ||
2856 | usrparm.rssd_result &= 0x7fffffffULL; | ||
2852 | } | 2857 | } |
2853 | #endif | ||
2854 | /* alloc I/O data area */ | 2858 | /* alloc I/O data area */ |
2855 | psf_data = kzalloc(usrparm.psf_data_len, GFP_KERNEL | GFP_DMA); | 2859 | psf_data = kzalloc(usrparm.psf_data_len, GFP_KERNEL | GFP_DMA); |
2856 | rssd_result = kzalloc(usrparm.rssd_result_len, GFP_KERNEL | GFP_DMA); | 2860 | rssd_result = kzalloc(usrparm.rssd_result_len, GFP_KERNEL | GFP_DMA); |
diff --git a/drivers/s390/block/dasd_ioctl.c b/drivers/s390/block/dasd_ioctl.c index 478bcdb90b6f..fc7b30b4a255 100644 --- a/drivers/s390/block/dasd_ioctl.c +++ b/drivers/s390/block/dasd_ioctl.c | |||
@@ -17,7 +17,7 @@ | |||
17 | #include <linux/fs.h> | 17 | #include <linux/fs.h> |
18 | #include <linux/blkpg.h> | 18 | #include <linux/blkpg.h> |
19 | #include <linux/smp_lock.h> | 19 | #include <linux/smp_lock.h> |
20 | 20 | #include <asm/compat.h> | |
21 | #include <asm/ccwdev.h> | 21 | #include <asm/ccwdev.h> |
22 | #include <asm/cmb.h> | 22 | #include <asm/cmb.h> |
23 | #include <asm/uaccess.h> | 23 | #include <asm/uaccess.h> |
@@ -358,9 +358,8 @@ dasd_ioctl_set_ro(struct block_device *bdev, void __user *argp) | |||
358 | } | 358 | } |
359 | 359 | ||
360 | static int dasd_ioctl_readall_cmb(struct dasd_block *block, unsigned int cmd, | 360 | static int dasd_ioctl_readall_cmb(struct dasd_block *block, unsigned int cmd, |
361 | unsigned long arg) | 361 | struct cmbdata __user *argp) |
362 | { | 362 | { |
363 | struct cmbdata __user *argp = (void __user *) arg; | ||
364 | size_t size = _IOC_SIZE(cmd); | 363 | size_t size = _IOC_SIZE(cmd); |
365 | struct cmbdata data; | 364 | struct cmbdata data; |
366 | int ret; | 365 | int ret; |
@@ -376,7 +375,12 @@ dasd_do_ioctl(struct block_device *bdev, fmode_t mode, | |||
376 | unsigned int cmd, unsigned long arg) | 375 | unsigned int cmd, unsigned long arg) |
377 | { | 376 | { |
378 | struct dasd_block *block = bdev->bd_disk->private_data; | 377 | struct dasd_block *block = bdev->bd_disk->private_data; |
379 | void __user *argp = (void __user *)arg; | 378 | void __user *argp; |
379 | |||
380 | if (is_compat_task()) | ||
381 | argp = compat_ptr(arg); | ||
382 | else | ||
383 | argp = (void __user *)arg; | ||
380 | 384 | ||
381 | if (!block) | 385 | if (!block) |
382 | return -ENODEV; | 386 | return -ENODEV; |
@@ -414,7 +418,7 @@ dasd_do_ioctl(struct block_device *bdev, fmode_t mode, | |||
414 | case BIODASDCMFDISABLE: | 418 | case BIODASDCMFDISABLE: |
415 | return disable_cmf(block->base->cdev); | 419 | return disable_cmf(block->base->cdev); |
416 | case BIODASDREADALLCMB: | 420 | case BIODASDREADALLCMB: |
417 | return dasd_ioctl_readall_cmb(block, cmd, arg); | 421 | return dasd_ioctl_readall_cmb(block, cmd, argp); |
418 | default: | 422 | default: |
419 | /* if the discipline has an ioctl method try it. */ | 423 | /* if the discipline has an ioctl method try it. */ |
420 | if (block->base->discipline->ioctl) { | 424 | if (block->base->discipline->ioctl) { |
diff --git a/drivers/s390/char/con3215.c b/drivers/s390/char/con3215.c index 9d61683b5633..59ec073724bf 100644 --- a/drivers/s390/char/con3215.c +++ b/drivers/s390/char/con3215.c | |||
@@ -1037,22 +1037,6 @@ static void tty3215_flush_buffer(struct tty_struct *tty) | |||
1037 | } | 1037 | } |
1038 | 1038 | ||
1039 | /* | 1039 | /* |
1040 | * Currently we don't have any io controls for 3215 ttys | ||
1041 | */ | ||
1042 | static int tty3215_ioctl(struct tty_struct *tty, struct file * file, | ||
1043 | unsigned int cmd, unsigned long arg) | ||
1044 | { | ||
1045 | if (tty->flags & (1 << TTY_IO_ERROR)) | ||
1046 | return -EIO; | ||
1047 | |||
1048 | switch (cmd) { | ||
1049 | default: | ||
1050 | return -ENOIOCTLCMD; | ||
1051 | } | ||
1052 | return 0; | ||
1053 | } | ||
1054 | |||
1055 | /* | ||
1056 | * Disable reading from a 3215 tty | 1040 | * Disable reading from a 3215 tty |
1057 | */ | 1041 | */ |
1058 | static void tty3215_throttle(struct tty_struct * tty) | 1042 | static void tty3215_throttle(struct tty_struct * tty) |
@@ -1117,7 +1101,6 @@ static const struct tty_operations tty3215_ops = { | |||
1117 | .write_room = tty3215_write_room, | 1101 | .write_room = tty3215_write_room, |
1118 | .chars_in_buffer = tty3215_chars_in_buffer, | 1102 | .chars_in_buffer = tty3215_chars_in_buffer, |
1119 | .flush_buffer = tty3215_flush_buffer, | 1103 | .flush_buffer = tty3215_flush_buffer, |
1120 | .ioctl = tty3215_ioctl, | ||
1121 | .throttle = tty3215_throttle, | 1104 | .throttle = tty3215_throttle, |
1122 | .unthrottle = tty3215_unthrottle, | 1105 | .unthrottle = tty3215_unthrottle, |
1123 | .stop = tty3215_stop, | 1106 | .stop = tty3215_stop, |
diff --git a/drivers/s390/char/fs3270.c b/drivers/s390/char/fs3270.c index 247b2b934728..31c59b0d6df0 100644 --- a/drivers/s390/char/fs3270.c +++ b/drivers/s390/char/fs3270.c | |||
@@ -15,6 +15,7 @@ | |||
15 | #include <linux/types.h> | 15 | #include <linux/types.h> |
16 | #include <linux/smp_lock.h> | 16 | #include <linux/smp_lock.h> |
17 | 17 | ||
18 | #include <asm/compat.h> | ||
18 | #include <asm/ccwdev.h> | 19 | #include <asm/ccwdev.h> |
19 | #include <asm/cio.h> | 20 | #include <asm/cio.h> |
20 | #include <asm/ebcdic.h> | 21 | #include <asm/ebcdic.h> |
@@ -322,6 +323,7 @@ fs3270_write(struct file *filp, const char __user *data, size_t count, loff_t *o | |||
322 | static long | 323 | static long |
323 | fs3270_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) | 324 | fs3270_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) |
324 | { | 325 | { |
326 | char __user *argp; | ||
325 | struct fs3270 *fp; | 327 | struct fs3270 *fp; |
326 | struct raw3270_iocb iocb; | 328 | struct raw3270_iocb iocb; |
327 | int rc; | 329 | int rc; |
@@ -329,6 +331,10 @@ fs3270_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) | |||
329 | fp = filp->private_data; | 331 | fp = filp->private_data; |
330 | if (!fp) | 332 | if (!fp) |
331 | return -ENODEV; | 333 | return -ENODEV; |
334 | if (is_compat_task()) | ||
335 | argp = compat_ptr(arg); | ||
336 | else | ||
337 | argp = (char __user *)arg; | ||
332 | rc = 0; | 338 | rc = 0; |
333 | mutex_lock(&fs3270_mutex); | 339 | mutex_lock(&fs3270_mutex); |
334 | switch (cmd) { | 340 | switch (cmd) { |
@@ -339,10 +345,10 @@ fs3270_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) | |||
339 | fp->write_command = arg; | 345 | fp->write_command = arg; |
340 | break; | 346 | break; |
341 | case TUBGETI: | 347 | case TUBGETI: |
342 | rc = put_user(fp->read_command, (char __user *) arg); | 348 | rc = put_user(fp->read_command, argp); |
343 | break; | 349 | break; |
344 | case TUBGETO: | 350 | case TUBGETO: |
345 | rc = put_user(fp->write_command,(char __user *) arg); | 351 | rc = put_user(fp->write_command, argp); |
346 | break; | 352 | break; |
347 | case TUBGETMOD: | 353 | case TUBGETMOD: |
348 | iocb.model = fp->view.model; | 354 | iocb.model = fp->view.model; |
@@ -351,8 +357,7 @@ fs3270_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) | |||
351 | iocb.pf_cnt = 24; | 357 | iocb.pf_cnt = 24; |
352 | iocb.re_cnt = 20; | 358 | iocb.re_cnt = 20; |
353 | iocb.map = 0; | 359 | iocb.map = 0; |
354 | if (copy_to_user((char __user *) arg, &iocb, | 360 | if (copy_to_user(argp, &iocb, sizeof(struct raw3270_iocb))) |
355 | sizeof(struct raw3270_iocb))) | ||
356 | rc = -EFAULT; | 361 | rc = -EFAULT; |
357 | break; | 362 | break; |
358 | } | 363 | } |
@@ -511,8 +516,8 @@ static const struct file_operations fs3270_fops = { | |||
511 | .write = fs3270_write, /* write */ | 516 | .write = fs3270_write, /* write */ |
512 | .unlocked_ioctl = fs3270_ioctl, /* ioctl */ | 517 | .unlocked_ioctl = fs3270_ioctl, /* ioctl */ |
513 | .compat_ioctl = fs3270_ioctl, /* ioctl */ | 518 | .compat_ioctl = fs3270_ioctl, /* ioctl */ |
514 | .open = fs3270_open, /* open */ | 519 | .open = fs3270_open, /* open */ |
515 | .release = fs3270_close, /* release */ | 520 | .release = fs3270_close, /* release */ |
516 | }; | 521 | }; |
517 | 522 | ||
518 | /* | 523 | /* |
diff --git a/drivers/s390/char/tape_block.c b/drivers/s390/char/tape_block.c index 96816149368a..8d3d720737da 100644 --- a/drivers/s390/char/tape_block.c +++ b/drivers/s390/char/tape_block.c | |||
@@ -46,8 +46,6 @@ | |||
46 | */ | 46 | */ |
47 | static int tapeblock_open(struct block_device *, fmode_t); | 47 | static int tapeblock_open(struct block_device *, fmode_t); |
48 | static int tapeblock_release(struct gendisk *, fmode_t); | 48 | static int tapeblock_release(struct gendisk *, fmode_t); |
49 | static int tapeblock_ioctl(struct block_device *, fmode_t, unsigned int, | ||
50 | unsigned long); | ||
51 | static int tapeblock_medium_changed(struct gendisk *); | 49 | static int tapeblock_medium_changed(struct gendisk *); |
52 | static int tapeblock_revalidate_disk(struct gendisk *); | 50 | static int tapeblock_revalidate_disk(struct gendisk *); |
53 | 51 | ||
@@ -55,7 +53,6 @@ static const struct block_device_operations tapeblock_fops = { | |||
55 | .owner = THIS_MODULE, | 53 | .owner = THIS_MODULE, |
56 | .open = tapeblock_open, | 54 | .open = tapeblock_open, |
57 | .release = tapeblock_release, | 55 | .release = tapeblock_release, |
58 | .ioctl = tapeblock_ioctl, | ||
59 | .media_changed = tapeblock_medium_changed, | 56 | .media_changed = tapeblock_medium_changed, |
60 | .revalidate_disk = tapeblock_revalidate_disk, | 57 | .revalidate_disk = tapeblock_revalidate_disk, |
61 | }; | 58 | }; |
@@ -416,42 +413,6 @@ tapeblock_release(struct gendisk *disk, fmode_t mode) | |||
416 | } | 413 | } |
417 | 414 | ||
418 | /* | 415 | /* |
419 | * Support of some generic block device IOCTLs. | ||
420 | */ | ||
421 | static int | ||
422 | tapeblock_ioctl( | ||
423 | struct block_device * bdev, | ||
424 | fmode_t mode, | ||
425 | unsigned int command, | ||
426 | unsigned long arg | ||
427 | ) { | ||
428 | int rc; | ||
429 | int minor; | ||
430 | struct gendisk *disk = bdev->bd_disk; | ||
431 | struct tape_device *device; | ||
432 | |||
433 | rc = 0; | ||
434 | BUG_ON(!disk); | ||
435 | device = disk->private_data; | ||
436 | BUG_ON(!device); | ||
437 | minor = MINOR(bdev->bd_dev); | ||
438 | |||
439 | DBF_LH(6, "tapeblock_ioctl(0x%0x)\n", command); | ||
440 | DBF_LH(6, "device = %d:%d\n", tapeblock_major, minor); | ||
441 | |||
442 | switch (command) { | ||
443 | /* Refuse some IOCTL calls without complaining (mount). */ | ||
444 | case 0x5310: /* CDROMMULTISESSION */ | ||
445 | rc = -EINVAL; | ||
446 | break; | ||
447 | default: | ||
448 | rc = -EINVAL; | ||
449 | } | ||
450 | |||
451 | return rc; | ||
452 | } | ||
453 | |||
454 | /* | ||
455 | * Initialize block device frontend. | 416 | * Initialize block device frontend. |
456 | */ | 417 | */ |
457 | int | 418 | int |
diff --git a/drivers/s390/char/tape_char.c b/drivers/s390/char/tape_char.c index 2125ec7d95f0..539045acaad4 100644 --- a/drivers/s390/char/tape_char.c +++ b/drivers/s390/char/tape_char.c | |||
@@ -18,6 +18,7 @@ | |||
18 | #include <linux/proc_fs.h> | 18 | #include <linux/proc_fs.h> |
19 | #include <linux/mtio.h> | 19 | #include <linux/mtio.h> |
20 | #include <linux/smp_lock.h> | 20 | #include <linux/smp_lock.h> |
21 | #include <linux/compat.h> | ||
21 | 22 | ||
22 | #include <asm/uaccess.h> | 23 | #include <asm/uaccess.h> |
23 | 24 | ||
@@ -37,8 +38,9 @@ static ssize_t tapechar_write(struct file *, const char __user *, size_t, loff_t | |||
37 | static int tapechar_open(struct inode *,struct file *); | 38 | static int tapechar_open(struct inode *,struct file *); |
38 | static int tapechar_release(struct inode *,struct file *); | 39 | static int tapechar_release(struct inode *,struct file *); |
39 | static long tapechar_ioctl(struct file *, unsigned int, unsigned long); | 40 | static long tapechar_ioctl(struct file *, unsigned int, unsigned long); |
40 | static long tapechar_compat_ioctl(struct file *, unsigned int, | 41 | #ifdef CONFIG_COMPAT |
41 | unsigned long); | 42 | static long tapechar_compat_ioctl(struct file *, unsigned int, unsigned long); |
43 | #endif | ||
42 | 44 | ||
43 | static const struct file_operations tape_fops = | 45 | static const struct file_operations tape_fops = |
44 | { | 46 | { |
@@ -46,7 +48,9 @@ static const struct file_operations tape_fops = | |||
46 | .read = tapechar_read, | 48 | .read = tapechar_read, |
47 | .write = tapechar_write, | 49 | .write = tapechar_write, |
48 | .unlocked_ioctl = tapechar_ioctl, | 50 | .unlocked_ioctl = tapechar_ioctl, |
51 | #ifdef CONFIG_COMPAT | ||
49 | .compat_ioctl = tapechar_compat_ioctl, | 52 | .compat_ioctl = tapechar_compat_ioctl, |
53 | #endif | ||
50 | .open = tapechar_open, | 54 | .open = tapechar_open, |
51 | .release = tapechar_release, | 55 | .release = tapechar_release, |
52 | }; | 56 | }; |
@@ -457,15 +461,22 @@ tapechar_ioctl(struct file *filp, unsigned int no, unsigned long data) | |||
457 | return rc; | 461 | return rc; |
458 | } | 462 | } |
459 | 463 | ||
464 | #ifdef CONFIG_COMPAT | ||
460 | static long | 465 | static long |
461 | tapechar_compat_ioctl(struct file *filp, unsigned int no, unsigned long data) | 466 | tapechar_compat_ioctl(struct file *filp, unsigned int no, unsigned long data) |
462 | { | 467 | { |
463 | struct tape_device *device = filp->private_data; | 468 | struct tape_device *device = filp->private_data; |
464 | int rval = -ENOIOCTLCMD; | 469 | int rval = -ENOIOCTLCMD; |
470 | unsigned long argp; | ||
465 | 471 | ||
472 | /* The 'arg' argument of any ioctl function may only be used for | ||
473 | * pointers because of the compat pointer conversion. | ||
474 | * Consider this when adding new ioctls. | ||
475 | */ | ||
476 | argp = (unsigned long) compat_ptr(data); | ||
466 | if (device->discipline->ioctl_fn) { | 477 | if (device->discipline->ioctl_fn) { |
467 | mutex_lock(&device->mutex); | 478 | mutex_lock(&device->mutex); |
468 | rval = device->discipline->ioctl_fn(device, no, data); | 479 | rval = device->discipline->ioctl_fn(device, no, argp); |
469 | mutex_unlock(&device->mutex); | 480 | mutex_unlock(&device->mutex); |
470 | if (rval == -EINVAL) | 481 | if (rval == -EINVAL) |
471 | rval = -ENOIOCTLCMD; | 482 | rval = -ENOIOCTLCMD; |
@@ -473,6 +484,7 @@ tapechar_compat_ioctl(struct file *filp, unsigned int no, unsigned long data) | |||
473 | 484 | ||
474 | return rval; | 485 | return rval; |
475 | } | 486 | } |
487 | #endif /* CONFIG_COMPAT */ | ||
476 | 488 | ||
477 | /* | 489 | /* |
478 | * Initialize character device frontend. | 490 | * Initialize character device frontend. |
diff --git a/drivers/s390/char/vmcp.c b/drivers/s390/char/vmcp.c index a6087cec55b4..921dcda77676 100644 --- a/drivers/s390/char/vmcp.c +++ b/drivers/s390/char/vmcp.c | |||
@@ -19,6 +19,7 @@ | |||
19 | #include <linux/kernel.h> | 19 | #include <linux/kernel.h> |
20 | #include <linux/miscdevice.h> | 20 | #include <linux/miscdevice.h> |
21 | #include <linux/module.h> | 21 | #include <linux/module.h> |
22 | #include <asm/compat.h> | ||
22 | #include <asm/cpcmd.h> | 23 | #include <asm/cpcmd.h> |
23 | #include <asm/debug.h> | 24 | #include <asm/debug.h> |
24 | #include <asm/uaccess.h> | 25 | #include <asm/uaccess.h> |
@@ -139,21 +140,26 @@ vmcp_write(struct file *file, const char __user *buff, size_t count, | |||
139 | static long vmcp_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | 140 | static long vmcp_ioctl(struct file *file, unsigned int cmd, unsigned long arg) |
140 | { | 141 | { |
141 | struct vmcp_session *session; | 142 | struct vmcp_session *session; |
143 | int __user *argp; | ||
142 | int temp; | 144 | int temp; |
143 | 145 | ||
144 | session = (struct vmcp_session *)file->private_data; | 146 | session = (struct vmcp_session *)file->private_data; |
147 | if (is_compat_task()) | ||
148 | argp = compat_ptr(arg); | ||
149 | else | ||
150 | argp = (int __user *)arg; | ||
145 | if (mutex_lock_interruptible(&session->mutex)) | 151 | if (mutex_lock_interruptible(&session->mutex)) |
146 | return -ERESTARTSYS; | 152 | return -ERESTARTSYS; |
147 | switch (cmd) { | 153 | switch (cmd) { |
148 | case VMCP_GETCODE: | 154 | case VMCP_GETCODE: |
149 | temp = session->resp_code; | 155 | temp = session->resp_code; |
150 | mutex_unlock(&session->mutex); | 156 | mutex_unlock(&session->mutex); |
151 | return put_user(temp, (int __user *)arg); | 157 | return put_user(temp, argp); |
152 | case VMCP_SETBUF: | 158 | case VMCP_SETBUF: |
153 | free_pages((unsigned long)session->response, | 159 | free_pages((unsigned long)session->response, |
154 | get_order(session->bufsize)); | 160 | get_order(session->bufsize)); |
155 | session->response=NULL; | 161 | session->response=NULL; |
156 | temp = get_user(session->bufsize, (int __user *)arg); | 162 | temp = get_user(session->bufsize, argp); |
157 | if (get_order(session->bufsize) > 8) { | 163 | if (get_order(session->bufsize) > 8) { |
158 | session->bufsize = PAGE_SIZE; | 164 | session->bufsize = PAGE_SIZE; |
159 | temp = -EINVAL; | 165 | temp = -EINVAL; |
@@ -163,7 +169,7 @@ static long vmcp_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | |||
163 | case VMCP_GETSIZE: | 169 | case VMCP_GETSIZE: |
164 | temp = session->resp_size; | 170 | temp = session->resp_size; |
165 | mutex_unlock(&session->mutex); | 171 | mutex_unlock(&session->mutex); |
166 | return put_user(temp, (int __user *)arg); | 172 | return put_user(temp, argp); |
167 | default: | 173 | default: |
168 | mutex_unlock(&session->mutex); | 174 | mutex_unlock(&session->mutex); |
169 | return -ENOIOCTLCMD; | 175 | return -ENOIOCTLCMD; |
diff --git a/drivers/s390/cio/chsc_sch.c b/drivers/s390/cio/chsc_sch.c index cc5144b6f9d9..c84ac9443079 100644 --- a/drivers/s390/cio/chsc_sch.c +++ b/drivers/s390/cio/chsc_sch.c | |||
@@ -12,6 +12,7 @@ | |||
12 | #include <linux/uaccess.h> | 12 | #include <linux/uaccess.h> |
13 | #include <linux/miscdevice.h> | 13 | #include <linux/miscdevice.h> |
14 | 14 | ||
15 | #include <asm/compat.h> | ||
15 | #include <asm/cio.h> | 16 | #include <asm/cio.h> |
16 | #include <asm/chsc.h> | 17 | #include <asm/chsc.h> |
17 | #include <asm/isc.h> | 18 | #include <asm/isc.h> |
@@ -770,24 +771,30 @@ out_free: | |||
770 | static long chsc_ioctl(struct file *filp, unsigned int cmd, | 771 | static long chsc_ioctl(struct file *filp, unsigned int cmd, |
771 | unsigned long arg) | 772 | unsigned long arg) |
772 | { | 773 | { |
774 | void __user *argp; | ||
775 | |||
773 | CHSC_MSG(2, "chsc_ioctl called, cmd=%x\n", cmd); | 776 | CHSC_MSG(2, "chsc_ioctl called, cmd=%x\n", cmd); |
777 | if (is_compat_task()) | ||
778 | argp = compat_ptr(arg); | ||
779 | else | ||
780 | argp = (void __user *)arg; | ||
774 | switch (cmd) { | 781 | switch (cmd) { |
775 | case CHSC_START: | 782 | case CHSC_START: |
776 | return chsc_ioctl_start((void __user *)arg); | 783 | return chsc_ioctl_start(argp); |
777 | case CHSC_INFO_CHANNEL_PATH: | 784 | case CHSC_INFO_CHANNEL_PATH: |
778 | return chsc_ioctl_info_channel_path((void __user *)arg); | 785 | return chsc_ioctl_info_channel_path(argp); |
779 | case CHSC_INFO_CU: | 786 | case CHSC_INFO_CU: |
780 | return chsc_ioctl_info_cu((void __user *)arg); | 787 | return chsc_ioctl_info_cu(argp); |
781 | case CHSC_INFO_SCH_CU: | 788 | case CHSC_INFO_SCH_CU: |
782 | return chsc_ioctl_info_sch_cu((void __user *)arg); | 789 | return chsc_ioctl_info_sch_cu(argp); |
783 | case CHSC_INFO_CI: | 790 | case CHSC_INFO_CI: |
784 | return chsc_ioctl_conf_info((void __user *)arg); | 791 | return chsc_ioctl_conf_info(argp); |
785 | case CHSC_INFO_CCL: | 792 | case CHSC_INFO_CCL: |
786 | return chsc_ioctl_conf_comp_list((void __user *)arg); | 793 | return chsc_ioctl_conf_comp_list(argp); |
787 | case CHSC_INFO_CPD: | 794 | case CHSC_INFO_CPD: |
788 | return chsc_ioctl_chpd((void __user *)arg); | 795 | return chsc_ioctl_chpd(argp); |
789 | case CHSC_INFO_DCAL: | 796 | case CHSC_INFO_DCAL: |
790 | return chsc_ioctl_dcal((void __user *)arg); | 797 | return chsc_ioctl_dcal(argp); |
791 | default: /* unknown ioctl number */ | 798 | default: /* unknown ioctl number */ |
792 | return -ENOIOCTLCMD; | 799 | return -ENOIOCTLCMD; |
793 | } | 800 | } |
diff --git a/drivers/s390/crypto/zcrypt_api.c b/drivers/s390/crypto/zcrypt_api.c index 0d4d18bdd45c..c68be24e27d9 100644 --- a/drivers/s390/crypto/zcrypt_api.c +++ b/drivers/s390/crypto/zcrypt_api.c | |||
@@ -393,10 +393,12 @@ static long zcrypt_rsa_crt(struct ica_rsa_modexpo_crt *crt) | |||
393 | * u_mult_inv > 128 bytes. | 393 | * u_mult_inv > 128 bytes. |
394 | */ | 394 | */ |
395 | if (copied == 0) { | 395 | if (copied == 0) { |
396 | int len; | 396 | unsigned int len; |
397 | spin_unlock_bh(&zcrypt_device_lock); | 397 | spin_unlock_bh(&zcrypt_device_lock); |
398 | /* len is max 256 / 2 - 120 = 8 */ | 398 | /* len is max 256 / 2 - 120 = 8 */ |
399 | len = crt->inputdatalength / 2 - 120; | 399 | len = crt->inputdatalength / 2 - 120; |
400 | if (len > sizeof(z1)) | ||
401 | return -EFAULT; | ||
400 | z1 = z2 = z3 = 0; | 402 | z1 = z2 = z3 = 0; |
401 | if (copy_from_user(&z1, crt->np_prime, len) || | 403 | if (copy_from_user(&z1, crt->np_prime, len) || |
402 | copy_from_user(&z2, crt->bp_key, len) || | 404 | copy_from_user(&z2, crt->bp_key, len) || |
diff --git a/drivers/s390/net/claw.c b/drivers/s390/net/claw.c index 3c77bfe0764c..147bb1a69aba 100644 --- a/drivers/s390/net/claw.c +++ b/drivers/s390/net/claw.c | |||
@@ -3398,7 +3398,7 @@ claw_init(void) | |||
3398 | goto out_err; | 3398 | goto out_err; |
3399 | } | 3399 | } |
3400 | CLAW_DBF_TEXT(2, setup, "init_mod"); | 3400 | CLAW_DBF_TEXT(2, setup, "init_mod"); |
3401 | claw_root_dev = root_device_register("qeth"); | 3401 | claw_root_dev = root_device_register("claw"); |
3402 | ret = IS_ERR(claw_root_dev) ? PTR_ERR(claw_root_dev) : 0; | 3402 | ret = IS_ERR(claw_root_dev) ? PTR_ERR(claw_root_dev) : 0; |
3403 | if (ret) | 3403 | if (ret) |
3404 | goto register_err; | 3404 | goto register_err; |
diff --git a/drivers/scsi/cxgb3i/cxgb3i_offload.c b/drivers/scsi/cxgb3i/cxgb3i_offload.c index 26ffdcd5a437..15a00e8b7122 100644 --- a/drivers/scsi/cxgb3i/cxgb3i_offload.c +++ b/drivers/scsi/cxgb3i/cxgb3i_offload.c | |||
@@ -1440,6 +1440,10 @@ void cxgb3i_c3cn_release(struct s3_conn *c3cn) | |||
1440 | static int is_cxgb3_dev(struct net_device *dev) | 1440 | static int is_cxgb3_dev(struct net_device *dev) |
1441 | { | 1441 | { |
1442 | struct cxgb3i_sdev_data *cdata; | 1442 | struct cxgb3i_sdev_data *cdata; |
1443 | struct net_device *ndev = dev; | ||
1444 | |||
1445 | if (dev->priv_flags & IFF_802_1Q_VLAN) | ||
1446 | ndev = vlan_dev_real_dev(dev); | ||
1443 | 1447 | ||
1444 | write_lock(&cdata_rwlock); | 1448 | write_lock(&cdata_rwlock); |
1445 | list_for_each_entry(cdata, &cdata_list, list) { | 1449 | list_for_each_entry(cdata, &cdata_list, list) { |
@@ -1447,7 +1451,7 @@ static int is_cxgb3_dev(struct net_device *dev) | |||
1447 | int i; | 1451 | int i; |
1448 | 1452 | ||
1449 | for (i = 0; i < ports->nports; i++) | 1453 | for (i = 0; i < ports->nports; i++) |
1450 | if (dev == ports->lldevs[i]) { | 1454 | if (ndev == ports->lldevs[i]) { |
1451 | write_unlock(&cdata_rwlock); | 1455 | write_unlock(&cdata_rwlock); |
1452 | return 1; | 1456 | return 1; |
1453 | } | 1457 | } |
@@ -1566,6 +1570,26 @@ out_err: | |||
1566 | return -EINVAL; | 1570 | return -EINVAL; |
1567 | } | 1571 | } |
1568 | 1572 | ||
1573 | /** | ||
1574 | * cxgb3i_find_dev - find the interface associated with the given address | ||
1575 | * @ipaddr: ip address | ||
1576 | */ | ||
1577 | static struct net_device * | ||
1578 | cxgb3i_find_dev(struct net_device *dev, __be32 ipaddr) | ||
1579 | { | ||
1580 | struct flowi fl; | ||
1581 | int err; | ||
1582 | struct rtable *rt; | ||
1583 | |||
1584 | memset(&fl, 0, sizeof(fl)); | ||
1585 | fl.nl_u.ip4_u.daddr = ipaddr; | ||
1586 | |||
1587 | err = ip_route_output_key(dev ? dev_net(dev) : &init_net, &rt, &fl); | ||
1588 | if (!err) | ||
1589 | return (&rt->u.dst)->dev; | ||
1590 | |||
1591 | return NULL; | ||
1592 | } | ||
1569 | 1593 | ||
1570 | /** | 1594 | /** |
1571 | * cxgb3i_c3cn_connect - initiates an iscsi tcp connection to a given address | 1595 | * cxgb3i_c3cn_connect - initiates an iscsi tcp connection to a given address |
@@ -1581,6 +1605,7 @@ int cxgb3i_c3cn_connect(struct net_device *dev, struct s3_conn *c3cn, | |||
1581 | struct cxgb3i_sdev_data *cdata; | 1605 | struct cxgb3i_sdev_data *cdata; |
1582 | struct t3cdev *cdev; | 1606 | struct t3cdev *cdev; |
1583 | __be32 sipv4; | 1607 | __be32 sipv4; |
1608 | struct net_device *dstdev; | ||
1584 | int err; | 1609 | int err; |
1585 | 1610 | ||
1586 | c3cn_conn_debug("c3cn 0x%p, dev 0x%p.\n", c3cn, dev); | 1611 | c3cn_conn_debug("c3cn 0x%p, dev 0x%p.\n", c3cn, dev); |
@@ -1591,6 +1616,13 @@ int cxgb3i_c3cn_connect(struct net_device *dev, struct s3_conn *c3cn, | |||
1591 | c3cn->daddr.sin_port = usin->sin_port; | 1616 | c3cn->daddr.sin_port = usin->sin_port; |
1592 | c3cn->daddr.sin_addr.s_addr = usin->sin_addr.s_addr; | 1617 | c3cn->daddr.sin_addr.s_addr = usin->sin_addr.s_addr; |
1593 | 1618 | ||
1619 | dstdev = cxgb3i_find_dev(dev, usin->sin_addr.s_addr); | ||
1620 | if (!dstdev || !is_cxgb3_dev(dstdev)) | ||
1621 | return -ENETUNREACH; | ||
1622 | |||
1623 | if (dstdev->priv_flags & IFF_802_1Q_VLAN) | ||
1624 | dev = dstdev; | ||
1625 | |||
1594 | rt = find_route(dev, c3cn->saddr.sin_addr.s_addr, | 1626 | rt = find_route(dev, c3cn->saddr.sin_addr.s_addr, |
1595 | c3cn->daddr.sin_addr.s_addr, | 1627 | c3cn->daddr.sin_addr.s_addr, |
1596 | c3cn->saddr.sin_port, | 1628 | c3cn->saddr.sin_port, |
diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c index ce522702a6c1..2cc39684ce97 100644 --- a/drivers/scsi/lpfc/lpfc_els.c +++ b/drivers/scsi/lpfc/lpfc_els.c | |||
@@ -4142,8 +4142,8 @@ lpfc_els_rcv_rscn(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb, | |||
4142 | spin_lock_irq(shost->host_lock); | 4142 | spin_lock_irq(shost->host_lock); |
4143 | if (vport->fc_rscn_flush) { | 4143 | if (vport->fc_rscn_flush) { |
4144 | /* Another thread is walking fc_rscn_id_list on this vport */ | 4144 | /* Another thread is walking fc_rscn_id_list on this vport */ |
4145 | spin_unlock_irq(shost->host_lock); | ||
4146 | vport->fc_flag |= FC_RSCN_DISCOVERY; | 4145 | vport->fc_flag |= FC_RSCN_DISCOVERY; |
4146 | spin_unlock_irq(shost->host_lock); | ||
4147 | /* Send back ACC */ | 4147 | /* Send back ACC */ |
4148 | lpfc_els_rsp_acc(vport, ELS_CMD_ACC, cmdiocb, ndlp, NULL); | 4148 | lpfc_els_rsp_acc(vport, ELS_CMD_ACC, cmdiocb, ndlp, NULL); |
4149 | return 0; | 4149 | return 0; |
@@ -5948,8 +5948,8 @@ lpfc_cmpl_reg_new_vport(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) | |||
5948 | lpfc_initial_fdisc(vport); | 5948 | lpfc_initial_fdisc(vport); |
5949 | break; | 5949 | break; |
5950 | } | 5950 | } |
5951 | |||
5952 | } else { | 5951 | } else { |
5952 | vport->vpi_state |= LPFC_VPI_REGISTERED; | ||
5953 | if (vport == phba->pport) | 5953 | if (vport == phba->pport) |
5954 | if (phba->sli_rev < LPFC_SLI_REV4) | 5954 | if (phba->sli_rev < LPFC_SLI_REV4) |
5955 | lpfc_issue_fabric_reglogin(vport); | 5955 | lpfc_issue_fabric_reglogin(vport); |
diff --git a/drivers/scsi/lpfc/lpfc_hbadisc.c b/drivers/scsi/lpfc/lpfc_hbadisc.c index 3b9424427652..2445e399fd60 100755 --- a/drivers/scsi/lpfc/lpfc_hbadisc.c +++ b/drivers/scsi/lpfc/lpfc_hbadisc.c | |||
@@ -747,6 +747,10 @@ lpfc_linkdown(struct lpfc_hba *phba) | |||
747 | 747 | ||
748 | if (phba->link_state == LPFC_LINK_DOWN) | 748 | if (phba->link_state == LPFC_LINK_DOWN) |
749 | return 0; | 749 | return 0; |
750 | |||
751 | /* Block all SCSI stack I/Os */ | ||
752 | lpfc_scsi_dev_block(phba); | ||
753 | |||
750 | spin_lock_irq(&phba->hbalock); | 754 | spin_lock_irq(&phba->hbalock); |
751 | phba->fcf.fcf_flag &= ~(FCF_AVAILABLE | FCF_DISCOVERED); | 755 | phba->fcf.fcf_flag &= ~(FCF_AVAILABLE | FCF_DISCOVERED); |
752 | if (phba->link_state > LPFC_LINK_DOWN) { | 756 | if (phba->link_state > LPFC_LINK_DOWN) { |
@@ -1555,10 +1559,16 @@ lpfc_mbx_cmpl_read_fcf_record(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq) | |||
1555 | * to book keeping the FCFIs can be used. | 1559 | * to book keeping the FCFIs can be used. |
1556 | */ | 1560 | */ |
1557 | if (shdr_status || shdr_add_status) { | 1561 | if (shdr_status || shdr_add_status) { |
1558 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, | 1562 | if (shdr_status == STATUS_FCF_TABLE_EMPTY) { |
1559 | "2521 READ_FCF_RECORD mailbox failed " | 1563 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, |
1560 | "with status x%x add_status x%x, mbx\n", | 1564 | "2726 READ_FCF_RECORD Indicates empty " |
1561 | shdr_status, shdr_add_status); | 1565 | "FCF table.\n"); |
1566 | } else { | ||
1567 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, | ||
1568 | "2521 READ_FCF_RECORD mailbox failed " | ||
1569 | "with status x%x add_status x%x, mbx\n", | ||
1570 | shdr_status, shdr_add_status); | ||
1571 | } | ||
1562 | goto out; | 1572 | goto out; |
1563 | } | 1573 | } |
1564 | /* Interpreting the returned information of FCF records */ | 1574 | /* Interpreting the returned information of FCF records */ |
@@ -1698,7 +1708,9 @@ lpfc_init_vpi_cmpl(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq) | |||
1698 | lpfc_vport_set_state(vport, FC_VPORT_FAILED); | 1708 | lpfc_vport_set_state(vport, FC_VPORT_FAILED); |
1699 | return; | 1709 | return; |
1700 | } | 1710 | } |
1711 | spin_lock_irq(&phba->hbalock); | ||
1701 | vport->fc_flag &= ~FC_VPORT_NEEDS_INIT_VPI; | 1712 | vport->fc_flag &= ~FC_VPORT_NEEDS_INIT_VPI; |
1713 | spin_unlock_irq(&phba->hbalock); | ||
1702 | 1714 | ||
1703 | if (phba->link_flag & LS_NPIV_FAB_SUPPORTED) | 1715 | if (phba->link_flag & LS_NPIV_FAB_SUPPORTED) |
1704 | lpfc_initial_fdisc(vport); | 1716 | lpfc_initial_fdisc(vport); |
@@ -2259,7 +2271,10 @@ lpfc_mbx_cmpl_unreg_vpi(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) | |||
2259 | mb->mbxStatus); | 2271 | mb->mbxStatus); |
2260 | break; | 2272 | break; |
2261 | } | 2273 | } |
2274 | spin_lock_irq(&phba->hbalock); | ||
2262 | vport->vpi_state &= ~LPFC_VPI_REGISTERED; | 2275 | vport->vpi_state &= ~LPFC_VPI_REGISTERED; |
2276 | vport->fc_flag |= FC_VPORT_NEEDS_REG_VPI; | ||
2277 | spin_unlock_irq(&phba->hbalock); | ||
2263 | vport->unreg_vpi_cmpl = VPORT_OK; | 2278 | vport->unreg_vpi_cmpl = VPORT_OK; |
2264 | mempool_free(pmb, phba->mbox_mem_pool); | 2279 | mempool_free(pmb, phba->mbox_mem_pool); |
2265 | /* | 2280 | /* |
@@ -4475,8 +4490,10 @@ lpfc_unregister_unused_fcf(struct lpfc_hba *phba) | |||
4475 | (phba->sli3_options & LPFC_SLI3_NPIV_ENABLED)) | 4490 | (phba->sli3_options & LPFC_SLI3_NPIV_ENABLED)) |
4476 | for (i = 0; i <= phba->max_vports && vports[i] != NULL; i++) { | 4491 | for (i = 0; i <= phba->max_vports && vports[i] != NULL; i++) { |
4477 | lpfc_mbx_unreg_vpi(vports[i]); | 4492 | lpfc_mbx_unreg_vpi(vports[i]); |
4493 | spin_lock_irq(&phba->hbalock); | ||
4478 | vports[i]->fc_flag |= FC_VPORT_NEEDS_INIT_VPI; | 4494 | vports[i]->fc_flag |= FC_VPORT_NEEDS_INIT_VPI; |
4479 | vports[i]->vpi_state &= ~LPFC_VPI_REGISTERED; | 4495 | vports[i]->vpi_state &= ~LPFC_VPI_REGISTERED; |
4496 | spin_unlock_irq(&phba->hbalock); | ||
4480 | } | 4497 | } |
4481 | lpfc_destroy_vport_work_array(phba, vports); | 4498 | lpfc_destroy_vport_work_array(phba, vports); |
4482 | 4499 | ||
diff --git a/drivers/scsi/lpfc/lpfc_hw4.h b/drivers/scsi/lpfc/lpfc_hw4.h index 1585148a17e5..8a2a1c5935c6 100644..100755 --- a/drivers/scsi/lpfc/lpfc_hw4.h +++ b/drivers/scsi/lpfc/lpfc_hw4.h | |||
@@ -1013,7 +1013,7 @@ struct lpfc_mbx_wq_destroy { | |||
1013 | }; | 1013 | }; |
1014 | 1014 | ||
1015 | #define LPFC_HDR_BUF_SIZE 128 | 1015 | #define LPFC_HDR_BUF_SIZE 128 |
1016 | #define LPFC_DATA_BUF_SIZE 4096 | 1016 | #define LPFC_DATA_BUF_SIZE 2048 |
1017 | struct rq_context { | 1017 | struct rq_context { |
1018 | uint32_t word0; | 1018 | uint32_t word0; |
1019 | #define lpfc_rq_context_rq_size_SHIFT 16 | 1019 | #define lpfc_rq_context_rq_size_SHIFT 16 |
@@ -1371,6 +1371,7 @@ struct lpfc_mbx_query_fw_cfg { | |||
1371 | #define STATUS_ERROR_ACITMAIN 0x2a | 1371 | #define STATUS_ERROR_ACITMAIN 0x2a |
1372 | #define STATUS_REBOOT_REQUIRED 0x2c | 1372 | #define STATUS_REBOOT_REQUIRED 0x2c |
1373 | #define STATUS_FCF_IN_USE 0x3a | 1373 | #define STATUS_FCF_IN_USE 0x3a |
1374 | #define STATUS_FCF_TABLE_EMPTY 0x43 | ||
1374 | 1375 | ||
1375 | struct lpfc_mbx_sli4_config { | 1376 | struct lpfc_mbx_sli4_config { |
1376 | struct mbox_header header; | 1377 | struct mbox_header header; |
diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c index d4da6bdd0e73..b8eb1b6e5e77 100644 --- a/drivers/scsi/lpfc/lpfc_init.c +++ b/drivers/scsi/lpfc/lpfc_init.c | |||
@@ -3006,6 +3006,7 @@ lpfc_sli4_async_fcoe_evt(struct lpfc_hba *phba, | |||
3006 | struct lpfc_vport *vport; | 3006 | struct lpfc_vport *vport; |
3007 | struct lpfc_nodelist *ndlp; | 3007 | struct lpfc_nodelist *ndlp; |
3008 | struct Scsi_Host *shost; | 3008 | struct Scsi_Host *shost; |
3009 | uint32_t link_state; | ||
3009 | 3010 | ||
3010 | phba->fc_eventTag = acqe_fcoe->event_tag; | 3011 | phba->fc_eventTag = acqe_fcoe->event_tag; |
3011 | phba->fcoe_eventtag = acqe_fcoe->event_tag; | 3012 | phba->fcoe_eventtag = acqe_fcoe->event_tag; |
@@ -3052,9 +3053,12 @@ lpfc_sli4_async_fcoe_evt(struct lpfc_hba *phba, | |||
3052 | break; | 3053 | break; |
3053 | /* | 3054 | /* |
3054 | * Currently, driver support only one FCF - so treat this as | 3055 | * Currently, driver support only one FCF - so treat this as |
3055 | * a link down. | 3056 | * a link down, but save the link state because we don't want |
3057 | * it to be changed to Link Down unless it is already down. | ||
3056 | */ | 3058 | */ |
3059 | link_state = phba->link_state; | ||
3057 | lpfc_linkdown(phba); | 3060 | lpfc_linkdown(phba); |
3061 | phba->link_state = link_state; | ||
3058 | /* Unregister FCF if no devices connected to it */ | 3062 | /* Unregister FCF if no devices connected to it */ |
3059 | lpfc_unregister_unused_fcf(phba); | 3063 | lpfc_unregister_unused_fcf(phba); |
3060 | break; | 3064 | break; |
@@ -7226,8 +7230,6 @@ lpfc_prep_dev_for_perm_failure(struct lpfc_hba *phba) | |||
7226 | { | 7230 | { |
7227 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, | 7231 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, |
7228 | "2711 PCI channel permanent disable for failure\n"); | 7232 | "2711 PCI channel permanent disable for failure\n"); |
7229 | /* Block all SCSI devices' I/Os on the host */ | ||
7230 | lpfc_scsi_dev_block(phba); | ||
7231 | /* Clean up all driver's outstanding SCSI I/Os */ | 7233 | /* Clean up all driver's outstanding SCSI I/Os */ |
7232 | lpfc_sli_flush_fcp_rings(phba); | 7234 | lpfc_sli_flush_fcp_rings(phba); |
7233 | } | 7235 | } |
@@ -7256,6 +7258,9 @@ lpfc_io_error_detected_s3(struct pci_dev *pdev, pci_channel_state_t state) | |||
7256 | struct Scsi_Host *shost = pci_get_drvdata(pdev); | 7258 | struct Scsi_Host *shost = pci_get_drvdata(pdev); |
7257 | struct lpfc_hba *phba = ((struct lpfc_vport *)shost->hostdata)->phba; | 7259 | struct lpfc_hba *phba = ((struct lpfc_vport *)shost->hostdata)->phba; |
7258 | 7260 | ||
7261 | /* Block all SCSI devices' I/Os on the host */ | ||
7262 | lpfc_scsi_dev_block(phba); | ||
7263 | |||
7259 | switch (state) { | 7264 | switch (state) { |
7260 | case pci_channel_io_normal: | 7265 | case pci_channel_io_normal: |
7261 | /* Non-fatal error, prepare for recovery */ | 7266 | /* Non-fatal error, prepare for recovery */ |
@@ -7507,6 +7512,9 @@ lpfc_pci_probe_one_s4(struct pci_dev *pdev, const struct pci_device_id *pid) | |||
7507 | error = -ENODEV; | 7512 | error = -ENODEV; |
7508 | goto out_free_sysfs_attr; | 7513 | goto out_free_sysfs_attr; |
7509 | } | 7514 | } |
7515 | /* Default to single FCP EQ for non-MSI-X */ | ||
7516 | if (phba->intr_type != MSIX) | ||
7517 | phba->cfg_fcp_eq_count = 1; | ||
7510 | /* Set up SLI-4 HBA */ | 7518 | /* Set up SLI-4 HBA */ |
7511 | if (lpfc_sli4_hba_setup(phba)) { | 7519 | if (lpfc_sli4_hba_setup(phba)) { |
7512 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, | 7520 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, |
diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c index 7935667b81a5..589549b2bf0e 100644 --- a/drivers/scsi/lpfc/lpfc_sli.c +++ b/drivers/scsi/lpfc/lpfc_sli.c | |||
@@ -1383,7 +1383,7 @@ lpfc_sli_hbq_to_firmware_s4(struct lpfc_hba *phba, uint32_t hbqno, | |||
1383 | /* HBQ for ELS and CT traffic. */ | 1383 | /* HBQ for ELS and CT traffic. */ |
1384 | static struct lpfc_hbq_init lpfc_els_hbq = { | 1384 | static struct lpfc_hbq_init lpfc_els_hbq = { |
1385 | .rn = 1, | 1385 | .rn = 1, |
1386 | .entry_count = 200, | 1386 | .entry_count = 256, |
1387 | .mask_count = 0, | 1387 | .mask_count = 0, |
1388 | .profile = 0, | 1388 | .profile = 0, |
1389 | .ring_mask = (1 << LPFC_ELS_RING), | 1389 | .ring_mask = (1 << LPFC_ELS_RING), |
@@ -1482,8 +1482,11 @@ err: | |||
1482 | int | 1482 | int |
1483 | lpfc_sli_hbqbuf_add_hbqs(struct lpfc_hba *phba, uint32_t qno) | 1483 | lpfc_sli_hbqbuf_add_hbqs(struct lpfc_hba *phba, uint32_t qno) |
1484 | { | 1484 | { |
1485 | return(lpfc_sli_hbqbuf_fill_hbqs(phba, qno, | 1485 | if (phba->sli_rev == LPFC_SLI_REV4) |
1486 | lpfc_hbq_defs[qno]->add_count)); | 1486 | return 0; |
1487 | else | ||
1488 | return lpfc_sli_hbqbuf_fill_hbqs(phba, qno, | ||
1489 | lpfc_hbq_defs[qno]->add_count); | ||
1487 | } | 1490 | } |
1488 | 1491 | ||
1489 | /** | 1492 | /** |
@@ -1498,8 +1501,12 @@ lpfc_sli_hbqbuf_add_hbqs(struct lpfc_hba *phba, uint32_t qno) | |||
1498 | static int | 1501 | static int |
1499 | lpfc_sli_hbqbuf_init_hbqs(struct lpfc_hba *phba, uint32_t qno) | 1502 | lpfc_sli_hbqbuf_init_hbqs(struct lpfc_hba *phba, uint32_t qno) |
1500 | { | 1503 | { |
1501 | return(lpfc_sli_hbqbuf_fill_hbqs(phba, qno, | 1504 | if (phba->sli_rev == LPFC_SLI_REV4) |
1502 | lpfc_hbq_defs[qno]->init_count)); | 1505 | return lpfc_sli_hbqbuf_fill_hbqs(phba, qno, |
1506 | lpfc_hbq_defs[qno]->entry_count); | ||
1507 | else | ||
1508 | return lpfc_sli_hbqbuf_fill_hbqs(phba, qno, | ||
1509 | lpfc_hbq_defs[qno]->init_count); | ||
1503 | } | 1510 | } |
1504 | 1511 | ||
1505 | /** | 1512 | /** |
@@ -4110,6 +4117,7 @@ lpfc_sli4_read_rev(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq, | |||
4110 | if (rc) { | 4117 | if (rc) { |
4111 | dma_free_coherent(&phba->pcidev->dev, dma_size, | 4118 | dma_free_coherent(&phba->pcidev->dev, dma_size, |
4112 | dmabuf->virt, dmabuf->phys); | 4119 | dmabuf->virt, dmabuf->phys); |
4120 | kfree(dmabuf); | ||
4113 | return -EIO; | 4121 | return -EIO; |
4114 | } | 4122 | } |
4115 | 4123 | ||
@@ -5848,7 +5856,6 @@ lpfc_sli4_iocb2wqe(struct lpfc_hba *phba, struct lpfc_iocbq *iocbq, | |||
5848 | iocbq->iocb.un.ulpWord[3]); | 5856 | iocbq->iocb.un.ulpWord[3]); |
5849 | wqe->generic.word3 = 0; | 5857 | wqe->generic.word3 = 0; |
5850 | bf_set(wqe_rcvoxid, &wqe->generic, iocbq->iocb.ulpContext); | 5858 | bf_set(wqe_rcvoxid, &wqe->generic, iocbq->iocb.ulpContext); |
5851 | bf_set(wqe_xc, &wqe->generic, 1); | ||
5852 | /* The entire sequence is transmitted for this IOCB */ | 5859 | /* The entire sequence is transmitted for this IOCB */ |
5853 | xmit_len = total_len; | 5860 | xmit_len = total_len; |
5854 | cmnd = CMD_XMIT_SEQUENCE64_CR; | 5861 | cmnd = CMD_XMIT_SEQUENCE64_CR; |
@@ -10944,7 +10951,8 @@ lpfc_fc_frame_add(struct lpfc_vport *vport, struct hbq_dmabuf *dmabuf) | |||
10944 | return dmabuf; | 10951 | return dmabuf; |
10945 | } | 10952 | } |
10946 | temp_hdr = seq_dmabuf->hbuf.virt; | 10953 | temp_hdr = seq_dmabuf->hbuf.virt; |
10947 | if (new_hdr->fh_seq_cnt < temp_hdr->fh_seq_cnt) { | 10954 | if (be16_to_cpu(new_hdr->fh_seq_cnt) < |
10955 | be16_to_cpu(temp_hdr->fh_seq_cnt)) { | ||
10948 | list_del_init(&seq_dmabuf->hbuf.list); | 10956 | list_del_init(&seq_dmabuf->hbuf.list); |
10949 | list_add_tail(&dmabuf->hbuf.list, &vport->rcv_buffer_list); | 10957 | list_add_tail(&dmabuf->hbuf.list, &vport->rcv_buffer_list); |
10950 | list_add_tail(&dmabuf->dbuf.list, &seq_dmabuf->dbuf.list); | 10958 | list_add_tail(&dmabuf->dbuf.list, &seq_dmabuf->dbuf.list); |
@@ -10955,6 +10963,11 @@ lpfc_fc_frame_add(struct lpfc_vport *vport, struct hbq_dmabuf *dmabuf) | |||
10955 | list_move_tail(&seq_dmabuf->hbuf.list, &vport->rcv_buffer_list); | 10963 | list_move_tail(&seq_dmabuf->hbuf.list, &vport->rcv_buffer_list); |
10956 | seq_dmabuf->time_stamp = jiffies; | 10964 | seq_dmabuf->time_stamp = jiffies; |
10957 | lpfc_update_rcv_time_stamp(vport); | 10965 | lpfc_update_rcv_time_stamp(vport); |
10966 | if (list_empty(&seq_dmabuf->dbuf.list)) { | ||
10967 | temp_hdr = dmabuf->hbuf.virt; | ||
10968 | list_add_tail(&dmabuf->dbuf.list, &seq_dmabuf->dbuf.list); | ||
10969 | return seq_dmabuf; | ||
10970 | } | ||
10958 | /* find the correct place in the sequence to insert this frame */ | 10971 | /* find the correct place in the sequence to insert this frame */ |
10959 | list_for_each_entry_reverse(d_buf, &seq_dmabuf->dbuf.list, list) { | 10972 | list_for_each_entry_reverse(d_buf, &seq_dmabuf->dbuf.list, list) { |
10960 | temp_dmabuf = container_of(d_buf, struct hbq_dmabuf, dbuf); | 10973 | temp_dmabuf = container_of(d_buf, struct hbq_dmabuf, dbuf); |
@@ -10963,7 +10976,8 @@ lpfc_fc_frame_add(struct lpfc_vport *vport, struct hbq_dmabuf *dmabuf) | |||
10963 | * If the frame's sequence count is greater than the frame on | 10976 | * If the frame's sequence count is greater than the frame on |
10964 | * the list then insert the frame right after this frame | 10977 | * the list then insert the frame right after this frame |
10965 | */ | 10978 | */ |
10966 | if (new_hdr->fh_seq_cnt > temp_hdr->fh_seq_cnt) { | 10979 | if (be16_to_cpu(new_hdr->fh_seq_cnt) > |
10980 | be16_to_cpu(temp_hdr->fh_seq_cnt)) { | ||
10967 | list_add(&dmabuf->dbuf.list, &temp_dmabuf->dbuf.list); | 10981 | list_add(&dmabuf->dbuf.list, &temp_dmabuf->dbuf.list); |
10968 | return seq_dmabuf; | 10982 | return seq_dmabuf; |
10969 | } | 10983 | } |
@@ -11210,7 +11224,7 @@ lpfc_seq_complete(struct hbq_dmabuf *dmabuf) | |||
11210 | seq_dmabuf = container_of(d_buf, struct hbq_dmabuf, dbuf); | 11224 | seq_dmabuf = container_of(d_buf, struct hbq_dmabuf, dbuf); |
11211 | hdr = (struct fc_frame_header *)seq_dmabuf->hbuf.virt; | 11225 | hdr = (struct fc_frame_header *)seq_dmabuf->hbuf.virt; |
11212 | /* If there is a hole in the sequence count then fail. */ | 11226 | /* If there is a hole in the sequence count then fail. */ |
11213 | if (++seq_count != hdr->fh_seq_cnt) | 11227 | if (++seq_count != be16_to_cpu(hdr->fh_seq_cnt)) |
11214 | return 0; | 11228 | return 0; |
11215 | fctl = (hdr->fh_f_ctl[0] << 16 | | 11229 | fctl = (hdr->fh_f_ctl[0] << 16 | |
11216 | hdr->fh_f_ctl[1] << 8 | | 11230 | hdr->fh_f_ctl[1] << 8 | |
@@ -11242,6 +11256,7 @@ lpfc_prep_seq(struct lpfc_vport *vport, struct hbq_dmabuf *seq_dmabuf) | |||
11242 | struct lpfc_iocbq *first_iocbq, *iocbq; | 11256 | struct lpfc_iocbq *first_iocbq, *iocbq; |
11243 | struct fc_frame_header *fc_hdr; | 11257 | struct fc_frame_header *fc_hdr; |
11244 | uint32_t sid; | 11258 | uint32_t sid; |
11259 | struct ulp_bde64 *pbde; | ||
11245 | 11260 | ||
11246 | fc_hdr = (struct fc_frame_header *)seq_dmabuf->hbuf.virt; | 11261 | fc_hdr = (struct fc_frame_header *)seq_dmabuf->hbuf.virt; |
11247 | /* remove from receive buffer list */ | 11262 | /* remove from receive buffer list */ |
@@ -11283,8 +11298,9 @@ lpfc_prep_seq(struct lpfc_vport *vport, struct hbq_dmabuf *seq_dmabuf) | |||
11283 | if (!iocbq->context3) { | 11298 | if (!iocbq->context3) { |
11284 | iocbq->context3 = d_buf; | 11299 | iocbq->context3 = d_buf; |
11285 | iocbq->iocb.ulpBdeCount++; | 11300 | iocbq->iocb.ulpBdeCount++; |
11286 | iocbq->iocb.unsli3.rcvsli3.bde2.tus.f.bdeSize = | 11301 | pbde = (struct ulp_bde64 *) |
11287 | LPFC_DATA_BUF_SIZE; | 11302 | &iocbq->iocb.unsli3.sli3Words[4]; |
11303 | pbde->tus.f.bdeSize = LPFC_DATA_BUF_SIZE; | ||
11288 | first_iocbq->iocb.unsli3.rcvsli3.acc_len += | 11304 | first_iocbq->iocb.unsli3.rcvsli3.acc_len += |
11289 | bf_get(lpfc_rcqe_length, | 11305 | bf_get(lpfc_rcqe_length, |
11290 | &seq_dmabuf->cq_event.cqe.rcqe_cmpl); | 11306 | &seq_dmabuf->cq_event.cqe.rcqe_cmpl); |
@@ -11401,15 +11417,9 @@ lpfc_sli4_handle_received_buffer(struct lpfc_hba *phba, | |||
11401 | return; | 11417 | return; |
11402 | } | 11418 | } |
11403 | /* If not last frame in sequence continue processing frames. */ | 11419 | /* If not last frame in sequence continue processing frames. */ |
11404 | if (!lpfc_seq_complete(seq_dmabuf)) { | 11420 | if (!lpfc_seq_complete(seq_dmabuf)) |
11405 | /* | ||
11406 | * When saving off frames post a new one and mark this | ||
11407 | * frame to be freed when it is finished. | ||
11408 | **/ | ||
11409 | lpfc_sli_hbqbuf_fill_hbqs(phba, LPFC_ELS_HBQ, 1); | ||
11410 | dmabuf->tag = -1; | ||
11411 | return; | 11421 | return; |
11412 | } | 11422 | |
11413 | /* Send the complete sequence to the upper layer protocol */ | 11423 | /* Send the complete sequence to the upper layer protocol */ |
11414 | lpfc_sli4_send_seq_to_ulp(vport, seq_dmabuf); | 11424 | lpfc_sli4_send_seq_to_ulp(vport, seq_dmabuf); |
11415 | } | 11425 | } |
diff --git a/drivers/scsi/lpfc/lpfc_sli4.h b/drivers/scsi/lpfc/lpfc_sli4.h index 25d66d070cf8..44e5f574236b 100644 --- a/drivers/scsi/lpfc/lpfc_sli4.h +++ b/drivers/scsi/lpfc/lpfc_sli4.h | |||
@@ -28,7 +28,7 @@ | |||
28 | /* Multi-queue arrangement for fast-path FCP work queues */ | 28 | /* Multi-queue arrangement for fast-path FCP work queues */ |
29 | #define LPFC_FN_EQN_MAX 8 | 29 | #define LPFC_FN_EQN_MAX 8 |
30 | #define LPFC_SP_EQN_DEF 1 | 30 | #define LPFC_SP_EQN_DEF 1 |
31 | #define LPFC_FP_EQN_DEF 1 | 31 | #define LPFC_FP_EQN_DEF 4 |
32 | #define LPFC_FP_EQN_MIN 1 | 32 | #define LPFC_FP_EQN_MIN 1 |
33 | #define LPFC_FP_EQN_MAX (LPFC_FN_EQN_MAX - LPFC_SP_EQN_DEF) | 33 | #define LPFC_FP_EQN_MAX (LPFC_FN_EQN_MAX - LPFC_SP_EQN_DEF) |
34 | 34 | ||
diff --git a/drivers/scsi/lpfc/lpfc_version.h b/drivers/scsi/lpfc/lpfc_version.h index c7f3aed2aab8..792f72263f1a 100644 --- a/drivers/scsi/lpfc/lpfc_version.h +++ b/drivers/scsi/lpfc/lpfc_version.h | |||
@@ -18,7 +18,7 @@ | |||
18 | * included with this package. * | 18 | * included with this package. * |
19 | *******************************************************************/ | 19 | *******************************************************************/ |
20 | 20 | ||
21 | #define LPFC_DRIVER_VERSION "8.3.6" | 21 | #define LPFC_DRIVER_VERSION "8.3.7" |
22 | #define LPFC_DRIVER_NAME "lpfc" | 22 | #define LPFC_DRIVER_NAME "lpfc" |
23 | #define LPFC_SP_DRIVER_HANDLER_NAME "lpfc:sp" | 23 | #define LPFC_SP_DRIVER_HANDLER_NAME "lpfc:sp" |
24 | #define LPFC_FP_DRIVER_HANDLER_NAME "lpfc:fp" | 24 | #define LPFC_FP_DRIVER_HANDLER_NAME "lpfc:fp" |
diff --git a/drivers/scsi/lpfc/lpfc_vport.c b/drivers/scsi/lpfc/lpfc_vport.c index 7d6dd83d3592..e3c7fa642306 100644 --- a/drivers/scsi/lpfc/lpfc_vport.c +++ b/drivers/scsi/lpfc/lpfc_vport.c | |||
@@ -512,8 +512,10 @@ enable_vport(struct fc_vport *fc_vport) | |||
512 | return VPORT_OK; | 512 | return VPORT_OK; |
513 | } | 513 | } |
514 | 514 | ||
515 | spin_lock_irq(&phba->hbalock); | ||
515 | vport->load_flag |= FC_LOADING; | 516 | vport->load_flag |= FC_LOADING; |
516 | vport->fc_flag |= FC_VPORT_NEEDS_REG_VPI; | 517 | vport->fc_flag |= FC_VPORT_NEEDS_REG_VPI; |
518 | spin_unlock_irq(&phba->hbalock); | ||
517 | 519 | ||
518 | /* Use the Physical nodes Fabric NDLP to determine if the link is | 520 | /* Use the Physical nodes Fabric NDLP to determine if the link is |
519 | * up and ready to FDISC. | 521 | * up and ready to FDISC. |
@@ -700,7 +702,7 @@ lpfc_vport_delete(struct fc_vport *fc_vport) | |||
700 | } | 702 | } |
701 | spin_unlock_irq(&phba->ndlp_lock); | 703 | spin_unlock_irq(&phba->ndlp_lock); |
702 | } | 704 | } |
703 | if (vport->vpi_state != LPFC_VPI_REGISTERED) | 705 | if (!(vport->vpi_state & LPFC_VPI_REGISTERED)) |
704 | goto skip_logo; | 706 | goto skip_logo; |
705 | vport->unreg_vpi_cmpl = VPORT_INVAL; | 707 | vport->unreg_vpi_cmpl = VPORT_INVAL; |
706 | timeout = msecs_to_jiffies(phba->fc_ratov * 2000); | 708 | timeout = msecs_to_jiffies(phba->fc_ratov * 2000); |
diff --git a/drivers/scsi/megaraid/megaraid_sas.c b/drivers/scsi/megaraid/megaraid_sas.c index 99ff99e45bee..708ea3157b60 100644 --- a/drivers/scsi/megaraid/megaraid_sas.c +++ b/drivers/scsi/megaraid/megaraid_sas.c | |||
@@ -4046,7 +4046,7 @@ megasas_aen_polling(struct work_struct *work) | |||
4046 | } | 4046 | } |
4047 | 4047 | ||
4048 | 4048 | ||
4049 | static DRIVER_ATTR(poll_mode_io, S_IRUGO|S_IWUGO, | 4049 | static DRIVER_ATTR(poll_mode_io, S_IRUGO|S_IWUSR, |
4050 | megasas_sysfs_show_poll_mode_io, | 4050 | megasas_sysfs_show_poll_mode_io, |
4051 | megasas_sysfs_set_poll_mode_io); | 4051 | megasas_sysfs_set_poll_mode_io); |
4052 | 4052 | ||
diff --git a/drivers/scsi/pmcraid.c b/drivers/scsi/pmcraid.c index e7d2688fbeba..b6f1ef954af1 100644 --- a/drivers/scsi/pmcraid.c +++ b/drivers/scsi/pmcraid.c | |||
@@ -2483,14 +2483,12 @@ static int pmcraid_error_handler(struct pmcraid_cmd *cmd) | |||
2483 | sense_copied = 1; | 2483 | sense_copied = 1; |
2484 | } | 2484 | } |
2485 | 2485 | ||
2486 | if (RES_IS_GSCSI(res->cfg_entry)) { | 2486 | if (RES_IS_GSCSI(res->cfg_entry)) |
2487 | pmcraid_cancel_all(cmd, sense_copied); | 2487 | pmcraid_cancel_all(cmd, sense_copied); |
2488 | } else if (sense_copied) { | 2488 | else if (sense_copied) |
2489 | pmcraid_erp_done(cmd); | 2489 | pmcraid_erp_done(cmd); |
2490 | return 0; | 2490 | else |
2491 | } else { | ||
2492 | pmcraid_request_sense(cmd); | 2491 | pmcraid_request_sense(cmd); |
2493 | } | ||
2494 | 2492 | ||
2495 | return 1; | 2493 | return 1; |
2496 | 2494 | ||
diff --git a/drivers/scsi/qla2xxx/qla_attr.c b/drivers/scsi/qla2xxx/qla_attr.c index 21e2bc4d7401..3a9f5b288aee 100644 --- a/drivers/scsi/qla2xxx/qla_attr.c +++ b/drivers/scsi/qla2xxx/qla_attr.c | |||
@@ -232,6 +232,9 @@ qla2x00_sysfs_write_optrom_ctl(struct kobject *kobj, | |||
232 | if (off) | 232 | if (off) |
233 | return 0; | 233 | return 0; |
234 | 234 | ||
235 | if (unlikely(pci_channel_offline(ha->pdev))) | ||
236 | return 0; | ||
237 | |||
235 | if (sscanf(buf, "%d:%x:%x", &val, &start, &size) < 1) | 238 | if (sscanf(buf, "%d:%x:%x", &val, &start, &size) < 1) |
236 | return -EINVAL; | 239 | return -EINVAL; |
237 | if (start > ha->optrom_size) | 240 | if (start > ha->optrom_size) |
@@ -379,6 +382,9 @@ qla2x00_sysfs_read_vpd(struct kobject *kobj, | |||
379 | struct device, kobj))); | 382 | struct device, kobj))); |
380 | struct qla_hw_data *ha = vha->hw; | 383 | struct qla_hw_data *ha = vha->hw; |
381 | 384 | ||
385 | if (unlikely(pci_channel_offline(ha->pdev))) | ||
386 | return 0; | ||
387 | |||
382 | if (!capable(CAP_SYS_ADMIN)) | 388 | if (!capable(CAP_SYS_ADMIN)) |
383 | return 0; | 389 | return 0; |
384 | 390 | ||
@@ -398,6 +404,9 @@ qla2x00_sysfs_write_vpd(struct kobject *kobj, | |||
398 | struct qla_hw_data *ha = vha->hw; | 404 | struct qla_hw_data *ha = vha->hw; |
399 | uint8_t *tmp_data; | 405 | uint8_t *tmp_data; |
400 | 406 | ||
407 | if (unlikely(pci_channel_offline(ha->pdev))) | ||
408 | return 0; | ||
409 | |||
401 | if (!capable(CAP_SYS_ADMIN) || off != 0 || count != ha->vpd_size || | 410 | if (!capable(CAP_SYS_ADMIN) || off != 0 || count != ha->vpd_size || |
402 | !ha->isp_ops->write_nvram) | 411 | !ha->isp_ops->write_nvram) |
403 | return 0; | 412 | return 0; |
@@ -1238,10 +1247,11 @@ qla2x00_fw_state_show(struct device *dev, struct device_attribute *attr, | |||
1238 | char *buf) | 1247 | char *buf) |
1239 | { | 1248 | { |
1240 | scsi_qla_host_t *vha = shost_priv(class_to_shost(dev)); | 1249 | scsi_qla_host_t *vha = shost_priv(class_to_shost(dev)); |
1241 | int rval; | 1250 | int rval = QLA_FUNCTION_FAILED; |
1242 | uint16_t state[5]; | 1251 | uint16_t state[5]; |
1243 | 1252 | ||
1244 | rval = qla2x00_get_firmware_state(vha, state); | 1253 | if (!vha->hw->flags.eeh_busy) |
1254 | rval = qla2x00_get_firmware_state(vha, state); | ||
1245 | if (rval != QLA_SUCCESS) | 1255 | if (rval != QLA_SUCCESS) |
1246 | memset(state, -1, sizeof(state)); | 1256 | memset(state, -1, sizeof(state)); |
1247 | 1257 | ||
@@ -1452,10 +1462,13 @@ qla2x00_dev_loss_tmo_callbk(struct fc_rport *rport) | |||
1452 | if (!fcport) | 1462 | if (!fcport) |
1453 | return; | 1463 | return; |
1454 | 1464 | ||
1455 | if (unlikely(pci_channel_offline(fcport->vha->hw->pdev))) | 1465 | if (test_bit(ABORT_ISP_ACTIVE, &fcport->vha->dpc_flags)) |
1466 | return; | ||
1467 | |||
1468 | if (unlikely(pci_channel_offline(fcport->vha->hw->pdev))) { | ||
1456 | qla2x00_abort_all_cmds(fcport->vha, DID_NO_CONNECT << 16); | 1469 | qla2x00_abort_all_cmds(fcport->vha, DID_NO_CONNECT << 16); |
1457 | else | 1470 | return; |
1458 | qla2x00_abort_fcport_cmds(fcport); | 1471 | } |
1459 | 1472 | ||
1460 | /* | 1473 | /* |
1461 | * Transport has effectively 'deleted' the rport, clear | 1474 | * Transport has effectively 'deleted' the rport, clear |
@@ -1475,6 +1488,9 @@ qla2x00_terminate_rport_io(struct fc_rport *rport) | |||
1475 | if (!fcport) | 1488 | if (!fcport) |
1476 | return; | 1489 | return; |
1477 | 1490 | ||
1491 | if (test_bit(ABORT_ISP_ACTIVE, &fcport->vha->dpc_flags)) | ||
1492 | return; | ||
1493 | |||
1478 | if (unlikely(pci_channel_offline(fcport->vha->hw->pdev))) { | 1494 | if (unlikely(pci_channel_offline(fcport->vha->hw->pdev))) { |
1479 | qla2x00_abort_all_cmds(fcport->vha, DID_NO_CONNECT << 16); | 1495 | qla2x00_abort_all_cmds(fcport->vha, DID_NO_CONNECT << 16); |
1480 | return; | 1496 | return; |
@@ -1515,6 +1531,12 @@ qla2x00_get_fc_host_stats(struct Scsi_Host *shost) | |||
1515 | pfc_host_stat = &ha->fc_host_stat; | 1531 | pfc_host_stat = &ha->fc_host_stat; |
1516 | memset(pfc_host_stat, -1, sizeof(struct fc_host_statistics)); | 1532 | memset(pfc_host_stat, -1, sizeof(struct fc_host_statistics)); |
1517 | 1533 | ||
1534 | if (test_bit(UNLOADING, &vha->dpc_flags)) | ||
1535 | goto done; | ||
1536 | |||
1537 | if (unlikely(pci_channel_offline(ha->pdev))) | ||
1538 | goto done; | ||
1539 | |||
1518 | stats = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &stats_dma); | 1540 | stats = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &stats_dma); |
1519 | if (stats == NULL) { | 1541 | if (stats == NULL) { |
1520 | DEBUG2_3_11(printk("%s(%ld): Failed to allocate memory.\n", | 1542 | DEBUG2_3_11(printk("%s(%ld): Failed to allocate memory.\n", |
diff --git a/drivers/scsi/qla2xxx/qla_dbg.h b/drivers/scsi/qla2xxx/qla_dbg.h index f660dd70b72e..d6d9c86cb058 100644 --- a/drivers/scsi/qla2xxx/qla_dbg.h +++ b/drivers/scsi/qla2xxx/qla_dbg.h | |||
@@ -26,7 +26,7 @@ | |||
26 | /* #define QL_DEBUG_LEVEL_14 */ /* Output RSCN trace msgs */ | 26 | /* #define QL_DEBUG_LEVEL_14 */ /* Output RSCN trace msgs */ |
27 | /* #define QL_DEBUG_LEVEL_15 */ /* Output NPIV trace msgs */ | 27 | /* #define QL_DEBUG_LEVEL_15 */ /* Output NPIV trace msgs */ |
28 | /* #define QL_DEBUG_LEVEL_16 */ /* Output ISP84XX trace msgs */ | 28 | /* #define QL_DEBUG_LEVEL_16 */ /* Output ISP84XX trace msgs */ |
29 | /* #define QL_DEBUG_LEVEL_17 */ /* Output MULTI-Q trace messages */ | 29 | /* #define QL_DEBUG_LEVEL_17 */ /* Output EEH trace messages */ |
30 | 30 | ||
31 | /* | 31 | /* |
32 | * Macros use for debugging the driver. | 32 | * Macros use for debugging the driver. |
@@ -132,6 +132,13 @@ | |||
132 | #else | 132 | #else |
133 | #define DEBUG16(x) do {} while (0) | 133 | #define DEBUG16(x) do {} while (0) |
134 | #endif | 134 | #endif |
135 | |||
136 | #if defined(QL_DEBUG_LEVEL_17) | ||
137 | #define DEBUG17(x) do {x;} while (0) | ||
138 | #else | ||
139 | #define DEBUG17(x) do {} while (0) | ||
140 | #endif | ||
141 | |||
135 | /* | 142 | /* |
136 | * Firmware Dump structure definition | 143 | * Firmware Dump structure definition |
137 | */ | 144 | */ |
diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h index 384afda7dbe9..608e675f68c8 100644 --- a/drivers/scsi/qla2xxx/qla_def.h +++ b/drivers/scsi/qla2xxx/qla_def.h | |||
@@ -2256,11 +2256,13 @@ struct qla_hw_data { | |||
2256 | uint32_t disable_serdes :1; | 2256 | uint32_t disable_serdes :1; |
2257 | uint32_t gpsc_supported :1; | 2257 | uint32_t gpsc_supported :1; |
2258 | uint32_t npiv_supported :1; | 2258 | uint32_t npiv_supported :1; |
2259 | uint32_t pci_channel_io_perm_failure :1; | ||
2259 | uint32_t fce_enabled :1; | 2260 | uint32_t fce_enabled :1; |
2260 | uint32_t fac_supported :1; | 2261 | uint32_t fac_supported :1; |
2261 | uint32_t chip_reset_done :1; | 2262 | uint32_t chip_reset_done :1; |
2262 | uint32_t port0 :1; | 2263 | uint32_t port0 :1; |
2263 | uint32_t running_gold_fw :1; | 2264 | uint32_t running_gold_fw :1; |
2265 | uint32_t eeh_busy :1; | ||
2264 | uint32_t cpu_affinity_enabled :1; | 2266 | uint32_t cpu_affinity_enabled :1; |
2265 | uint32_t disable_msix_handshake :1; | 2267 | uint32_t disable_msix_handshake :1; |
2266 | } flags; | 2268 | } flags; |
diff --git a/drivers/scsi/qla2xxx/qla_gbl.h b/drivers/scsi/qla2xxx/qla_gbl.h index 0b6801fc6389..f61fb8d01330 100644 --- a/drivers/scsi/qla2xxx/qla_gbl.h +++ b/drivers/scsi/qla2xxx/qla_gbl.h | |||
@@ -324,6 +324,7 @@ qla2x00_read_ram_word(scsi_qla_host_t *, uint32_t, uint32_t *); | |||
324 | extern int | 324 | extern int |
325 | qla2x00_write_ram_word(scsi_qla_host_t *, uint32_t, uint32_t); | 325 | qla2x00_write_ram_word(scsi_qla_host_t *, uint32_t, uint32_t); |
326 | 326 | ||
327 | extern int qla2x00_get_data_rate(scsi_qla_host_t *); | ||
327 | /* | 328 | /* |
328 | * Global Function Prototypes in qla_isr.c source file. | 329 | * Global Function Prototypes in qla_isr.c source file. |
329 | */ | 330 | */ |
diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c index 73a793539d45..b4a0eac8f96d 100644 --- a/drivers/scsi/qla2xxx/qla_init.c +++ b/drivers/scsi/qla2xxx/qla_init.c | |||
@@ -269,6 +269,8 @@ qla2x00_initialize_adapter(scsi_qla_host_t *vha) | |||
269 | vha->flags.online = 0; | 269 | vha->flags.online = 0; |
270 | ha->flags.chip_reset_done = 0; | 270 | ha->flags.chip_reset_done = 0; |
271 | vha->flags.reset_active = 0; | 271 | vha->flags.reset_active = 0; |
272 | ha->flags.pci_channel_io_perm_failure = 0; | ||
273 | ha->flags.eeh_busy = 0; | ||
272 | atomic_set(&vha->loop_down_timer, LOOP_DOWN_TIME); | 274 | atomic_set(&vha->loop_down_timer, LOOP_DOWN_TIME); |
273 | atomic_set(&vha->loop_state, LOOP_DOWN); | 275 | atomic_set(&vha->loop_state, LOOP_DOWN); |
274 | vha->device_flags = DFLG_NO_CABLE; | 276 | vha->device_flags = DFLG_NO_CABLE; |
@@ -581,6 +583,9 @@ qla2x00_reset_chip(scsi_qla_host_t *vha) | |||
581 | uint32_t cnt; | 583 | uint32_t cnt; |
582 | uint16_t cmd; | 584 | uint16_t cmd; |
583 | 585 | ||
586 | if (unlikely(pci_channel_offline(ha->pdev))) | ||
587 | return; | ||
588 | |||
584 | ha->isp_ops->disable_intrs(ha); | 589 | ha->isp_ops->disable_intrs(ha); |
585 | 590 | ||
586 | spin_lock_irqsave(&ha->hardware_lock, flags); | 591 | spin_lock_irqsave(&ha->hardware_lock, flags); |
@@ -786,6 +791,12 @@ void | |||
786 | qla24xx_reset_chip(scsi_qla_host_t *vha) | 791 | qla24xx_reset_chip(scsi_qla_host_t *vha) |
787 | { | 792 | { |
788 | struct qla_hw_data *ha = vha->hw; | 793 | struct qla_hw_data *ha = vha->hw; |
794 | |||
795 | if (pci_channel_offline(ha->pdev) && | ||
796 | ha->flags.pci_channel_io_perm_failure) { | ||
797 | return; | ||
798 | } | ||
799 | |||
789 | ha->isp_ops->disable_intrs(ha); | 800 | ha->isp_ops->disable_intrs(ha); |
790 | 801 | ||
791 | /* Perform RISC reset. */ | 802 | /* Perform RISC reset. */ |
@@ -2266,6 +2277,8 @@ qla2x00_configure_loop(scsi_qla_host_t *vha) | |||
2266 | clear_bit(LOCAL_LOOP_UPDATE, &vha->dpc_flags); | 2277 | clear_bit(LOCAL_LOOP_UPDATE, &vha->dpc_flags); |
2267 | clear_bit(RSCN_UPDATE, &vha->dpc_flags); | 2278 | clear_bit(RSCN_UPDATE, &vha->dpc_flags); |
2268 | 2279 | ||
2280 | qla2x00_get_data_rate(vha); | ||
2281 | |||
2269 | /* Determine what we need to do */ | 2282 | /* Determine what we need to do */ |
2270 | if (ha->current_topology == ISP_CFG_FL && | 2283 | if (ha->current_topology == ISP_CFG_FL && |
2271 | (test_bit(LOCAL_LOOP_UPDATE, &flags))) { | 2284 | (test_bit(LOCAL_LOOP_UPDATE, &flags))) { |
@@ -3560,6 +3573,13 @@ qla2x00_abort_isp(scsi_qla_host_t *vha) | |||
3560 | /* Requeue all commands in outstanding command list. */ | 3573 | /* Requeue all commands in outstanding command list. */ |
3561 | qla2x00_abort_all_cmds(vha, DID_RESET << 16); | 3574 | qla2x00_abort_all_cmds(vha, DID_RESET << 16); |
3562 | 3575 | ||
3576 | if (unlikely(pci_channel_offline(ha->pdev) && | ||
3577 | ha->flags.pci_channel_io_perm_failure)) { | ||
3578 | clear_bit(ISP_ABORT_RETRY, &vha->dpc_flags); | ||
3579 | status = 0; | ||
3580 | return status; | ||
3581 | } | ||
3582 | |||
3563 | ha->isp_ops->get_flash_version(vha, req->ring); | 3583 | ha->isp_ops->get_flash_version(vha, req->ring); |
3564 | 3584 | ||
3565 | ha->isp_ops->nvram_config(vha); | 3585 | ha->isp_ops->nvram_config(vha); |
@@ -4458,6 +4478,8 @@ qla2x00_try_to_stop_firmware(scsi_qla_host_t *vha) | |||
4458 | int ret, retries; | 4478 | int ret, retries; |
4459 | struct qla_hw_data *ha = vha->hw; | 4479 | struct qla_hw_data *ha = vha->hw; |
4460 | 4480 | ||
4481 | if (ha->flags.pci_channel_io_perm_failure) | ||
4482 | return; | ||
4461 | if (!IS_FWI2_CAPABLE(ha)) | 4483 | if (!IS_FWI2_CAPABLE(ha)) |
4462 | return; | 4484 | return; |
4463 | if (!ha->fw_major_version) | 4485 | if (!ha->fw_major_version) |
diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c index 1692a883f4de..ffd0efdff40e 100644 --- a/drivers/scsi/qla2xxx/qla_isr.c +++ b/drivers/scsi/qla2xxx/qla_isr.c | |||
@@ -152,7 +152,7 @@ qla2300_intr_handler(int irq, void *dev_id) | |||
152 | for (iter = 50; iter--; ) { | 152 | for (iter = 50; iter--; ) { |
153 | stat = RD_REG_DWORD(®->u.isp2300.host_status); | 153 | stat = RD_REG_DWORD(®->u.isp2300.host_status); |
154 | if (stat & HSR_RISC_PAUSED) { | 154 | if (stat & HSR_RISC_PAUSED) { |
155 | if (pci_channel_offline(ha->pdev)) | 155 | if (unlikely(pci_channel_offline(ha->pdev))) |
156 | break; | 156 | break; |
157 | 157 | ||
158 | hccr = RD_REG_WORD(®->hccr); | 158 | hccr = RD_REG_WORD(®->hccr); |
@@ -1846,12 +1846,15 @@ qla24xx_intr_handler(int irq, void *dev_id) | |||
1846 | reg = &ha->iobase->isp24; | 1846 | reg = &ha->iobase->isp24; |
1847 | status = 0; | 1847 | status = 0; |
1848 | 1848 | ||
1849 | if (unlikely(pci_channel_offline(ha->pdev))) | ||
1850 | return IRQ_HANDLED; | ||
1851 | |||
1849 | spin_lock_irqsave(&ha->hardware_lock, flags); | 1852 | spin_lock_irqsave(&ha->hardware_lock, flags); |
1850 | vha = pci_get_drvdata(ha->pdev); | 1853 | vha = pci_get_drvdata(ha->pdev); |
1851 | for (iter = 50; iter--; ) { | 1854 | for (iter = 50; iter--; ) { |
1852 | stat = RD_REG_DWORD(®->host_status); | 1855 | stat = RD_REG_DWORD(®->host_status); |
1853 | if (stat & HSRX_RISC_PAUSED) { | 1856 | if (stat & HSRX_RISC_PAUSED) { |
1854 | if (pci_channel_offline(ha->pdev)) | 1857 | if (unlikely(pci_channel_offline(ha->pdev))) |
1855 | break; | 1858 | break; |
1856 | 1859 | ||
1857 | hccr = RD_REG_DWORD(®->hccr); | 1860 | hccr = RD_REG_DWORD(®->hccr); |
@@ -1992,7 +1995,7 @@ qla24xx_msix_default(int irq, void *dev_id) | |||
1992 | do { | 1995 | do { |
1993 | stat = RD_REG_DWORD(®->host_status); | 1996 | stat = RD_REG_DWORD(®->host_status); |
1994 | if (stat & HSRX_RISC_PAUSED) { | 1997 | if (stat & HSRX_RISC_PAUSED) { |
1995 | if (pci_channel_offline(ha->pdev)) | 1998 | if (unlikely(pci_channel_offline(ha->pdev))) |
1996 | break; | 1999 | break; |
1997 | 2000 | ||
1998 | hccr = RD_REG_DWORD(®->hccr); | 2001 | hccr = RD_REG_DWORD(®->hccr); |
diff --git a/drivers/scsi/qla2xxx/qla_mbx.c b/drivers/scsi/qla2xxx/qla_mbx.c index 05d595d9a7ef..056e4d4505f3 100644 --- a/drivers/scsi/qla2xxx/qla_mbx.c +++ b/drivers/scsi/qla2xxx/qla_mbx.c | |||
@@ -56,6 +56,12 @@ qla2x00_mailbox_command(scsi_qla_host_t *vha, mbx_cmd_t *mcp) | |||
56 | 56 | ||
57 | DEBUG11(printk("%s(%ld): entered.\n", __func__, base_vha->host_no)); | 57 | DEBUG11(printk("%s(%ld): entered.\n", __func__, base_vha->host_no)); |
58 | 58 | ||
59 | if (ha->flags.pci_channel_io_perm_failure) { | ||
60 | DEBUG(printk("%s(%ld): Perm failure on EEH, timeout MBX " | ||
61 | "Exiting.\n", __func__, vha->host_no)); | ||
62 | return QLA_FUNCTION_TIMEOUT; | ||
63 | } | ||
64 | |||
59 | /* | 65 | /* |
60 | * Wait for active mailbox commands to finish by waiting at most tov | 66 | * Wait for active mailbox commands to finish by waiting at most tov |
61 | * seconds. This is to serialize actual issuing of mailbox cmds during | 67 | * seconds. This is to serialize actual issuing of mailbox cmds during |
@@ -154,10 +160,14 @@ qla2x00_mailbox_command(scsi_qla_host_t *vha, mbx_cmd_t *mcp) | |||
154 | /* Check for pending interrupts. */ | 160 | /* Check for pending interrupts. */ |
155 | qla2x00_poll(ha->rsp_q_map[0]); | 161 | qla2x00_poll(ha->rsp_q_map[0]); |
156 | 162 | ||
157 | if (command != MBC_LOAD_RISC_RAM_EXTENDED && | 163 | if (!ha->flags.mbox_int && |
158 | !ha->flags.mbox_int) | 164 | !(IS_QLA2200(ha) && |
165 | command == MBC_LOAD_RISC_RAM_EXTENDED)) | ||
159 | msleep(10); | 166 | msleep(10); |
160 | } /* while */ | 167 | } /* while */ |
168 | DEBUG17(qla_printk(KERN_WARNING, ha, | ||
169 | "Waited %d sec\n", | ||
170 | (uint)((jiffies - (wait_time - (mcp->tov * HZ)))/HZ))); | ||
161 | } | 171 | } |
162 | 172 | ||
163 | /* Check whether we timed out */ | 173 | /* Check whether we timed out */ |
@@ -227,7 +237,8 @@ qla2x00_mailbox_command(scsi_qla_host_t *vha, mbx_cmd_t *mcp) | |||
227 | 237 | ||
228 | if (rval == QLA_FUNCTION_TIMEOUT && | 238 | if (rval == QLA_FUNCTION_TIMEOUT && |
229 | mcp->mb[0] != MBC_GEN_SYSTEM_ERROR) { | 239 | mcp->mb[0] != MBC_GEN_SYSTEM_ERROR) { |
230 | if (!io_lock_on || (mcp->flags & IOCTL_CMD)) { | 240 | if (!io_lock_on || (mcp->flags & IOCTL_CMD) || |
241 | ha->flags.eeh_busy) { | ||
231 | /* not in dpc. schedule it for dpc to take over. */ | 242 | /* not in dpc. schedule it for dpc to take over. */ |
232 | DEBUG(printk("%s(%ld): timeout schedule " | 243 | DEBUG(printk("%s(%ld): timeout schedule " |
233 | "isp_abort_needed.\n", __func__, | 244 | "isp_abort_needed.\n", __func__, |
@@ -237,7 +248,7 @@ qla2x00_mailbox_command(scsi_qla_host_t *vha, mbx_cmd_t *mcp) | |||
237 | base_vha->host_no)); | 248 | base_vha->host_no)); |
238 | qla_printk(KERN_WARNING, ha, | 249 | qla_printk(KERN_WARNING, ha, |
239 | "Mailbox command timeout occurred. Scheduling ISP " | 250 | "Mailbox command timeout occurred. Scheduling ISP " |
240 | "abort.\n"); | 251 | "abort. eeh_busy: 0x%x\n", ha->flags.eeh_busy); |
241 | set_bit(ISP_ABORT_NEEDED, &base_vha->dpc_flags); | 252 | set_bit(ISP_ABORT_NEEDED, &base_vha->dpc_flags); |
242 | qla2xxx_wake_dpc(vha); | 253 | qla2xxx_wake_dpc(vha); |
243 | } else if (!abort_active) { | 254 | } else if (!abort_active) { |
@@ -2530,6 +2541,9 @@ qla2x00_enable_eft_trace(scsi_qla_host_t *vha, dma_addr_t eft_dma, | |||
2530 | if (!IS_FWI2_CAPABLE(vha->hw)) | 2541 | if (!IS_FWI2_CAPABLE(vha->hw)) |
2531 | return QLA_FUNCTION_FAILED; | 2542 | return QLA_FUNCTION_FAILED; |
2532 | 2543 | ||
2544 | if (unlikely(pci_channel_offline(vha->hw->pdev))) | ||
2545 | return QLA_FUNCTION_FAILED; | ||
2546 | |||
2533 | DEBUG11(printk("%s(%ld): entered.\n", __func__, vha->host_no)); | 2547 | DEBUG11(printk("%s(%ld): entered.\n", __func__, vha->host_no)); |
2534 | 2548 | ||
2535 | mcp->mb[0] = MBC_TRACE_CONTROL; | 2549 | mcp->mb[0] = MBC_TRACE_CONTROL; |
@@ -2565,6 +2579,9 @@ qla2x00_disable_eft_trace(scsi_qla_host_t *vha) | |||
2565 | if (!IS_FWI2_CAPABLE(vha->hw)) | 2579 | if (!IS_FWI2_CAPABLE(vha->hw)) |
2566 | return QLA_FUNCTION_FAILED; | 2580 | return QLA_FUNCTION_FAILED; |
2567 | 2581 | ||
2582 | if (unlikely(pci_channel_offline(vha->hw->pdev))) | ||
2583 | return QLA_FUNCTION_FAILED; | ||
2584 | |||
2568 | DEBUG11(printk("%s(%ld): entered.\n", __func__, vha->host_no)); | 2585 | DEBUG11(printk("%s(%ld): entered.\n", __func__, vha->host_no)); |
2569 | 2586 | ||
2570 | mcp->mb[0] = MBC_TRACE_CONTROL; | 2587 | mcp->mb[0] = MBC_TRACE_CONTROL; |
@@ -2595,6 +2612,9 @@ qla2x00_enable_fce_trace(scsi_qla_host_t *vha, dma_addr_t fce_dma, | |||
2595 | if (!IS_QLA25XX(vha->hw) && !IS_QLA81XX(vha->hw)) | 2612 | if (!IS_QLA25XX(vha->hw) && !IS_QLA81XX(vha->hw)) |
2596 | return QLA_FUNCTION_FAILED; | 2613 | return QLA_FUNCTION_FAILED; |
2597 | 2614 | ||
2615 | if (unlikely(pci_channel_offline(vha->hw->pdev))) | ||
2616 | return QLA_FUNCTION_FAILED; | ||
2617 | |||
2598 | DEBUG11(printk("%s(%ld): entered.\n", __func__, vha->host_no)); | 2618 | DEBUG11(printk("%s(%ld): entered.\n", __func__, vha->host_no)); |
2599 | 2619 | ||
2600 | mcp->mb[0] = MBC_TRACE_CONTROL; | 2620 | mcp->mb[0] = MBC_TRACE_CONTROL; |
@@ -2639,6 +2659,9 @@ qla2x00_disable_fce_trace(scsi_qla_host_t *vha, uint64_t *wr, uint64_t *rd) | |||
2639 | if (!IS_FWI2_CAPABLE(vha->hw)) | 2659 | if (!IS_FWI2_CAPABLE(vha->hw)) |
2640 | return QLA_FUNCTION_FAILED; | 2660 | return QLA_FUNCTION_FAILED; |
2641 | 2661 | ||
2662 | if (unlikely(pci_channel_offline(vha->hw->pdev))) | ||
2663 | return QLA_FUNCTION_FAILED; | ||
2664 | |||
2642 | DEBUG11(printk("%s(%ld): entered.\n", __func__, vha->host_no)); | 2665 | DEBUG11(printk("%s(%ld): entered.\n", __func__, vha->host_no)); |
2643 | 2666 | ||
2644 | mcp->mb[0] = MBC_TRACE_CONTROL; | 2667 | mcp->mb[0] = MBC_TRACE_CONTROL; |
@@ -3643,3 +3666,36 @@ qla2x00_write_ram_word(scsi_qla_host_t *vha, uint32_t risc_addr, uint32_t data) | |||
3643 | 3666 | ||
3644 | return rval; | 3667 | return rval; |
3645 | } | 3668 | } |
3669 | |||
3670 | int | ||
3671 | qla2x00_get_data_rate(scsi_qla_host_t *vha) | ||
3672 | { | ||
3673 | int rval; | ||
3674 | mbx_cmd_t mc; | ||
3675 | mbx_cmd_t *mcp = &mc; | ||
3676 | struct qla_hw_data *ha = vha->hw; | ||
3677 | |||
3678 | if (!IS_FWI2_CAPABLE(ha)) | ||
3679 | return QLA_FUNCTION_FAILED; | ||
3680 | |||
3681 | DEBUG11(printk(KERN_INFO "%s(%ld): entered.\n", __func__, vha->host_no)); | ||
3682 | |||
3683 | mcp->mb[0] = MBC_DATA_RATE; | ||
3684 | mcp->mb[1] = 0; | ||
3685 | mcp->out_mb = MBX_1|MBX_0; | ||
3686 | mcp->in_mb = MBX_2|MBX_1|MBX_0; | ||
3687 | mcp->tov = MBX_TOV_SECONDS; | ||
3688 | mcp->flags = 0; | ||
3689 | rval = qla2x00_mailbox_command(vha, mcp); | ||
3690 | if (rval != QLA_SUCCESS) { | ||
3691 | DEBUG2_3_11(printk(KERN_INFO "%s(%ld): failed=%x mb[0]=%x.\n", | ||
3692 | __func__, vha->host_no, rval, mcp->mb[0])); | ||
3693 | } else { | ||
3694 | DEBUG11(printk(KERN_INFO | ||
3695 | "%s(%ld): done.\n", __func__, vha->host_no)); | ||
3696 | if (mcp->mb[1] != 0x7) | ||
3697 | ha->link_data_rate = mcp->mb[1]; | ||
3698 | } | ||
3699 | |||
3700 | return rval; | ||
3701 | } | ||
diff --git a/drivers/scsi/qla2xxx/qla_mid.c b/drivers/scsi/qla2xxx/qla_mid.c index 2a4c7f4e7b69..b901aa267e7d 100644 --- a/drivers/scsi/qla2xxx/qla_mid.c +++ b/drivers/scsi/qla2xxx/qla_mid.c | |||
@@ -639,8 +639,10 @@ static void qla_do_work(struct work_struct *work) | |||
639 | struct rsp_que *rsp = container_of(work, struct rsp_que, q_work); | 639 | struct rsp_que *rsp = container_of(work, struct rsp_que, q_work); |
640 | struct scsi_qla_host *vha; | 640 | struct scsi_qla_host *vha; |
641 | 641 | ||
642 | spin_lock_irq(&rsp->hw->hardware_lock); | ||
642 | vha = qla25xx_get_host(rsp); | 643 | vha = qla25xx_get_host(rsp); |
643 | qla24xx_process_response_queue(vha, rsp); | 644 | qla24xx_process_response_queue(vha, rsp); |
645 | spin_unlock_irq(&rsp->hw->hardware_lock); | ||
644 | } | 646 | } |
645 | 647 | ||
646 | /* create response queue */ | 648 | /* create response queue */ |
diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c index 2f873d237325..209f50e788a1 100644 --- a/drivers/scsi/qla2xxx/qla_os.c +++ b/drivers/scsi/qla2xxx/qla_os.c | |||
@@ -475,11 +475,11 @@ qla2xxx_queuecommand(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *)) | |||
475 | srb_t *sp; | 475 | srb_t *sp; |
476 | int rval; | 476 | int rval; |
477 | 477 | ||
478 | if (unlikely(pci_channel_offline(ha->pdev))) { | 478 | if (ha->flags.eeh_busy) { |
479 | if (ha->pdev->error_state == pci_channel_io_frozen) | 479 | if (ha->flags.pci_channel_io_perm_failure) |
480 | cmd->result = DID_REQUEUE << 16; | ||
481 | else | ||
482 | cmd->result = DID_NO_CONNECT << 16; | 480 | cmd->result = DID_NO_CONNECT << 16; |
481 | else | ||
482 | cmd->result = DID_REQUEUE << 16; | ||
483 | goto qc24_fail_command; | 483 | goto qc24_fail_command; |
484 | } | 484 | } |
485 | 485 | ||
@@ -552,8 +552,15 @@ qla2x00_eh_wait_on_command(struct scsi_cmnd *cmd) | |||
552 | #define ABORT_POLLING_PERIOD 1000 | 552 | #define ABORT_POLLING_PERIOD 1000 |
553 | #define ABORT_WAIT_ITER ((10 * 1000) / (ABORT_POLLING_PERIOD)) | 553 | #define ABORT_WAIT_ITER ((10 * 1000) / (ABORT_POLLING_PERIOD)) |
554 | unsigned long wait_iter = ABORT_WAIT_ITER; | 554 | unsigned long wait_iter = ABORT_WAIT_ITER; |
555 | scsi_qla_host_t *vha = shost_priv(cmd->device->host); | ||
556 | struct qla_hw_data *ha = vha->hw; | ||
555 | int ret = QLA_SUCCESS; | 557 | int ret = QLA_SUCCESS; |
556 | 558 | ||
559 | if (unlikely(pci_channel_offline(ha->pdev)) || ha->flags.eeh_busy) { | ||
560 | DEBUG17(qla_printk(KERN_WARNING, ha, "return:eh_wait\n")); | ||
561 | return ret; | ||
562 | } | ||
563 | |||
557 | while (CMD_SP(cmd) && wait_iter--) { | 564 | while (CMD_SP(cmd) && wait_iter--) { |
558 | msleep(ABORT_POLLING_PERIOD); | 565 | msleep(ABORT_POLLING_PERIOD); |
559 | } | 566 | } |
@@ -1810,6 +1817,13 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) | |||
1810 | 1817 | ||
1811 | /* Set ISP-type information. */ | 1818 | /* Set ISP-type information. */ |
1812 | qla2x00_set_isp_flags(ha); | 1819 | qla2x00_set_isp_flags(ha); |
1820 | |||
1821 | /* Set EEH reset type to fundamental if required by hba */ | ||
1822 | if ( IS_QLA24XX(ha) || IS_QLA25XX(ha) || IS_QLA81XX(ha)) { | ||
1823 | pdev->needs_freset = 1; | ||
1824 | pci_save_state(pdev); | ||
1825 | } | ||
1826 | |||
1813 | /* Configure PCI I/O space */ | 1827 | /* Configure PCI I/O space */ |
1814 | ret = qla2x00_iospace_config(ha); | 1828 | ret = qla2x00_iospace_config(ha); |
1815 | if (ret) | 1829 | if (ret) |
@@ -2174,6 +2188,24 @@ qla2x00_free_device(scsi_qla_host_t *vha) | |||
2174 | { | 2188 | { |
2175 | struct qla_hw_data *ha = vha->hw; | 2189 | struct qla_hw_data *ha = vha->hw; |
2176 | 2190 | ||
2191 | qla2x00_abort_all_cmds(vha, DID_NO_CONNECT << 16); | ||
2192 | |||
2193 | /* Disable timer */ | ||
2194 | if (vha->timer_active) | ||
2195 | qla2x00_stop_timer(vha); | ||
2196 | |||
2197 | /* Kill the kernel thread for this host */ | ||
2198 | if (ha->dpc_thread) { | ||
2199 | struct task_struct *t = ha->dpc_thread; | ||
2200 | |||
2201 | /* | ||
2202 | * qla2xxx_wake_dpc checks for ->dpc_thread | ||
2203 | * so we need to zero it out. | ||
2204 | */ | ||
2205 | ha->dpc_thread = NULL; | ||
2206 | kthread_stop(t); | ||
2207 | } | ||
2208 | |||
2177 | qla25xx_delete_queues(vha); | 2209 | qla25xx_delete_queues(vha); |
2178 | 2210 | ||
2179 | if (ha->flags.fce_enabled) | 2211 | if (ha->flags.fce_enabled) |
@@ -2185,6 +2217,8 @@ qla2x00_free_device(scsi_qla_host_t *vha) | |||
2185 | /* Stop currently executing firmware. */ | 2217 | /* Stop currently executing firmware. */ |
2186 | qla2x00_try_to_stop_firmware(vha); | 2218 | qla2x00_try_to_stop_firmware(vha); |
2187 | 2219 | ||
2220 | vha->flags.online = 0; | ||
2221 | |||
2188 | /* turn-off interrupts on the card */ | 2222 | /* turn-off interrupts on the card */ |
2189 | if (ha->interrupts_on) | 2223 | if (ha->interrupts_on) |
2190 | ha->isp_ops->disable_intrs(ha); | 2224 | ha->isp_ops->disable_intrs(ha); |
@@ -2859,6 +2893,13 @@ qla2x00_do_dpc(void *data) | |||
2859 | if (!base_vha->flags.init_done) | 2893 | if (!base_vha->flags.init_done) |
2860 | continue; | 2894 | continue; |
2861 | 2895 | ||
2896 | if (ha->flags.eeh_busy) { | ||
2897 | DEBUG17(qla_printk(KERN_WARNING, ha, | ||
2898 | "qla2x00_do_dpc: dpc_flags: %lx\n", | ||
2899 | base_vha->dpc_flags)); | ||
2900 | continue; | ||
2901 | } | ||
2902 | |||
2862 | DEBUG3(printk("scsi(%ld): DPC handler\n", base_vha->host_no)); | 2903 | DEBUG3(printk("scsi(%ld): DPC handler\n", base_vha->host_no)); |
2863 | 2904 | ||
2864 | ha->dpc_active = 1; | 2905 | ha->dpc_active = 1; |
@@ -3049,8 +3090,13 @@ qla2x00_timer(scsi_qla_host_t *vha) | |||
3049 | int index; | 3090 | int index; |
3050 | srb_t *sp; | 3091 | srb_t *sp; |
3051 | int t; | 3092 | int t; |
3093 | uint16_t w; | ||
3052 | struct qla_hw_data *ha = vha->hw; | 3094 | struct qla_hw_data *ha = vha->hw; |
3053 | struct req_que *req; | 3095 | struct req_que *req; |
3096 | |||
3097 | /* Hardware read to raise pending EEH errors during mailbox waits. */ | ||
3098 | if (!pci_channel_offline(ha->pdev)) | ||
3099 | pci_read_config_word(ha->pdev, PCI_VENDOR_ID, &w); | ||
3054 | /* | 3100 | /* |
3055 | * Ports - Port down timer. | 3101 | * Ports - Port down timer. |
3056 | * | 3102 | * |
@@ -3252,16 +3298,23 @@ qla2x00_release_firmware(void) | |||
3252 | static pci_ers_result_t | 3298 | static pci_ers_result_t |
3253 | qla2xxx_pci_error_detected(struct pci_dev *pdev, pci_channel_state_t state) | 3299 | qla2xxx_pci_error_detected(struct pci_dev *pdev, pci_channel_state_t state) |
3254 | { | 3300 | { |
3255 | scsi_qla_host_t *base_vha = pci_get_drvdata(pdev); | 3301 | scsi_qla_host_t *vha = pci_get_drvdata(pdev); |
3302 | struct qla_hw_data *ha = vha->hw; | ||
3303 | |||
3304 | DEBUG2(qla_printk(KERN_WARNING, ha, "error_detected:state %x\n", | ||
3305 | state)); | ||
3256 | 3306 | ||
3257 | switch (state) { | 3307 | switch (state) { |
3258 | case pci_channel_io_normal: | 3308 | case pci_channel_io_normal: |
3309 | ha->flags.eeh_busy = 0; | ||
3259 | return PCI_ERS_RESULT_CAN_RECOVER; | 3310 | return PCI_ERS_RESULT_CAN_RECOVER; |
3260 | case pci_channel_io_frozen: | 3311 | case pci_channel_io_frozen: |
3312 | ha->flags.eeh_busy = 1; | ||
3261 | pci_disable_device(pdev); | 3313 | pci_disable_device(pdev); |
3262 | return PCI_ERS_RESULT_NEED_RESET; | 3314 | return PCI_ERS_RESULT_NEED_RESET; |
3263 | case pci_channel_io_perm_failure: | 3315 | case pci_channel_io_perm_failure: |
3264 | qla2x00_abort_all_cmds(base_vha, DID_NO_CONNECT << 16); | 3316 | ha->flags.pci_channel_io_perm_failure = 1; |
3317 | qla2x00_abort_all_cmds(vha, DID_NO_CONNECT << 16); | ||
3265 | return PCI_ERS_RESULT_DISCONNECT; | 3318 | return PCI_ERS_RESULT_DISCONNECT; |
3266 | } | 3319 | } |
3267 | return PCI_ERS_RESULT_NEED_RESET; | 3320 | return PCI_ERS_RESULT_NEED_RESET; |
@@ -3312,6 +3365,8 @@ qla2xxx_pci_slot_reset(struct pci_dev *pdev) | |||
3312 | struct qla_hw_data *ha = base_vha->hw; | 3365 | struct qla_hw_data *ha = base_vha->hw; |
3313 | int rc; | 3366 | int rc; |
3314 | 3367 | ||
3368 | DEBUG17(qla_printk(KERN_WARNING, ha, "slot_reset\n")); | ||
3369 | |||
3315 | if (ha->mem_only) | 3370 | if (ha->mem_only) |
3316 | rc = pci_enable_device_mem(pdev); | 3371 | rc = pci_enable_device_mem(pdev); |
3317 | else | 3372 | else |
@@ -3320,19 +3375,33 @@ qla2xxx_pci_slot_reset(struct pci_dev *pdev) | |||
3320 | if (rc) { | 3375 | if (rc) { |
3321 | qla_printk(KERN_WARNING, ha, | 3376 | qla_printk(KERN_WARNING, ha, |
3322 | "Can't re-enable PCI device after reset.\n"); | 3377 | "Can't re-enable PCI device after reset.\n"); |
3323 | |||
3324 | return ret; | 3378 | return ret; |
3325 | } | 3379 | } |
3326 | pci_set_master(pdev); | ||
3327 | 3380 | ||
3328 | if (ha->isp_ops->pci_config(base_vha)) | 3381 | if (ha->isp_ops->pci_config(base_vha)) |
3329 | return ret; | 3382 | return ret; |
3330 | 3383 | ||
3384 | #ifdef QL_DEBUG_LEVEL_17 | ||
3385 | { | ||
3386 | uint8_t b; | ||
3387 | uint32_t i; | ||
3388 | |||
3389 | printk("slot_reset_1: "); | ||
3390 | for (i = 0; i < 256; i++) { | ||
3391 | pci_read_config_byte(ha->pdev, i, &b); | ||
3392 | printk("%s%02x", (i%16) ? " " : "\n", b); | ||
3393 | } | ||
3394 | printk("\n"); | ||
3395 | } | ||
3396 | #endif | ||
3331 | set_bit(ABORT_ISP_ACTIVE, &base_vha->dpc_flags); | 3397 | set_bit(ABORT_ISP_ACTIVE, &base_vha->dpc_flags); |
3332 | if (qla2x00_abort_isp(base_vha) == QLA_SUCCESS) | 3398 | if (qla2x00_abort_isp(base_vha) == QLA_SUCCESS) |
3333 | ret = PCI_ERS_RESULT_RECOVERED; | 3399 | ret = PCI_ERS_RESULT_RECOVERED; |
3334 | clear_bit(ABORT_ISP_ACTIVE, &base_vha->dpc_flags); | 3400 | clear_bit(ABORT_ISP_ACTIVE, &base_vha->dpc_flags); |
3335 | 3401 | ||
3402 | DEBUG17(qla_printk(KERN_WARNING, ha, | ||
3403 | "slot_reset-return:ret=%x\n", ret)); | ||
3404 | |||
3336 | return ret; | 3405 | return ret; |
3337 | } | 3406 | } |
3338 | 3407 | ||
@@ -3343,12 +3412,17 @@ qla2xxx_pci_resume(struct pci_dev *pdev) | |||
3343 | struct qla_hw_data *ha = base_vha->hw; | 3412 | struct qla_hw_data *ha = base_vha->hw; |
3344 | int ret; | 3413 | int ret; |
3345 | 3414 | ||
3415 | DEBUG17(qla_printk(KERN_WARNING, ha, "pci_resume\n")); | ||
3416 | |||
3346 | ret = qla2x00_wait_for_hba_online(base_vha); | 3417 | ret = qla2x00_wait_for_hba_online(base_vha); |
3347 | if (ret != QLA_SUCCESS) { | 3418 | if (ret != QLA_SUCCESS) { |
3348 | qla_printk(KERN_ERR, ha, | 3419 | qla_printk(KERN_ERR, ha, |
3349 | "the device failed to resume I/O " | 3420 | "the device failed to resume I/O " |
3350 | "from slot/link_reset"); | 3421 | "from slot/link_reset"); |
3351 | } | 3422 | } |
3423 | |||
3424 | ha->flags.eeh_busy = 0; | ||
3425 | |||
3352 | pci_cleanup_aer_uncorrect_error_status(pdev); | 3426 | pci_cleanup_aer_uncorrect_error_status(pdev); |
3353 | } | 3427 | } |
3354 | 3428 | ||
diff --git a/drivers/scsi/qla2xxx/qla_version.h b/drivers/scsi/qla2xxx/qla_version.h index c482220f7eed..a65dd95507c6 100644 --- a/drivers/scsi/qla2xxx/qla_version.h +++ b/drivers/scsi/qla2xxx/qla_version.h | |||
@@ -7,7 +7,7 @@ | |||
7 | /* | 7 | /* |
8 | * Driver version | 8 | * Driver version |
9 | */ | 9 | */ |
10 | #define QLA2XXX_VERSION "8.03.01-k8" | 10 | #define QLA2XXX_VERSION "8.03.01-k9" |
11 | 11 | ||
12 | #define QLA_DRIVER_MAJOR_VER 8 | 12 | #define QLA_DRIVER_MAJOR_VER 8 |
13 | #define QLA_DRIVER_MINOR_VER 3 | 13 | #define QLA_DRIVER_MINOR_VER 3 |
diff --git a/drivers/scsi/stex.c b/drivers/scsi/stex.c index 3058bb1aff95..fd7b15be7640 100644 --- a/drivers/scsi/stex.c +++ b/drivers/scsi/stex.c | |||
@@ -623,6 +623,11 @@ stex_queuecommand(struct scsi_cmnd *cmd, void (* done)(struct scsi_cmnd *)) | |||
623 | } | 623 | } |
624 | break; | 624 | break; |
625 | case INQUIRY: | 625 | case INQUIRY: |
626 | if (lun >= host->max_lun) { | ||
627 | cmd->result = DID_NO_CONNECT << 16; | ||
628 | done(cmd); | ||
629 | return 0; | ||
630 | } | ||
626 | if (id != host->max_id - 1) | 631 | if (id != host->max_id - 1) |
627 | break; | 632 | break; |
628 | if (!lun && !cmd->device->channel && | 633 | if (!lun && !cmd->device->channel && |
diff --git a/drivers/serial/21285.c b/drivers/serial/21285.c index 1e3d19397a59..8681f1345056 100644 --- a/drivers/serial/21285.c +++ b/drivers/serial/21285.c | |||
@@ -58,7 +58,7 @@ static const char serial21285_name[] = "Footbridge UART"; | |||
58 | static void serial21285_stop_tx(struct uart_port *port) | 58 | static void serial21285_stop_tx(struct uart_port *port) |
59 | { | 59 | { |
60 | if (tx_enabled(port)) { | 60 | if (tx_enabled(port)) { |
61 | disable_irq(IRQ_CONTX); | 61 | disable_irq_nosync(IRQ_CONTX); |
62 | tx_enabled(port) = 0; | 62 | tx_enabled(port) = 0; |
63 | } | 63 | } |
64 | } | 64 | } |
@@ -74,7 +74,7 @@ static void serial21285_start_tx(struct uart_port *port) | |||
74 | static void serial21285_stop_rx(struct uart_port *port) | 74 | static void serial21285_stop_rx(struct uart_port *port) |
75 | { | 75 | { |
76 | if (rx_enabled(port)) { | 76 | if (rx_enabled(port)) { |
77 | disable_irq(IRQ_CONRX); | 77 | disable_irq_nosync(IRQ_CONRX); |
78 | rx_enabled(port) = 0; | 78 | rx_enabled(port) = 0; |
79 | } | 79 | } |
80 | } | 80 | } |
diff --git a/drivers/serial/8250_pnp.c b/drivers/serial/8250_pnp.c index 36ede02ceacf..b5496a19d967 100644 --- a/drivers/serial/8250_pnp.c +++ b/drivers/serial/8250_pnp.c | |||
@@ -354,6 +354,8 @@ static const struct pnp_device_id pnp_dev_table[] = { | |||
354 | { "FUJ02E5", 0 }, | 354 | { "FUJ02E5", 0 }, |
355 | /* Fujitsu P-series tablet PC device */ | 355 | /* Fujitsu P-series tablet PC device */ |
356 | { "FUJ02E6", 0 }, | 356 | { "FUJ02E6", 0 }, |
357 | /* Fujitsu Wacom 2FGT Tablet PC device */ | ||
358 | { "FUJ02E7", 0 }, | ||
357 | /* | 359 | /* |
358 | * LG C1 EXPRESS DUAL (C1-PB11A3) touch screen (actually a FUJ02E6 in | 360 | * LG C1 EXPRESS DUAL (C1-PB11A3) touch screen (actually a FUJ02E6 in |
359 | * disguise) | 361 | * disguise) |
diff --git a/drivers/serial/pmac_zilog.c b/drivers/serial/pmac_zilog.c index 0700cd10b97c..683e66f18e8c 100644 --- a/drivers/serial/pmac_zilog.c +++ b/drivers/serial/pmac_zilog.c | |||
@@ -411,6 +411,17 @@ static void pmz_transmit_chars(struct uart_pmac_port *uap) | |||
411 | goto ack_tx_int; | 411 | goto ack_tx_int; |
412 | } | 412 | } |
413 | 413 | ||
414 | /* Under some circumstances, we see interrupts reported for | ||
415 | * a closed channel. The interrupt mask in R1 is clear, but | ||
416 | * R3 still signals the interrupts and we see them when taking | ||
417 | * an interrupt for the other channel (this could be a qemu | ||
418 | * bug but since the ESCC doc doesn't specify precsiely whether | ||
419 | * R3 interrup status bits are masked by R1 interrupt enable | ||
420 | * bits, better safe than sorry). --BenH. | ||
421 | */ | ||
422 | if (!ZS_IS_OPEN(uap)) | ||
423 | goto ack_tx_int; | ||
424 | |||
414 | if (uap->port.x_char) { | 425 | if (uap->port.x_char) { |
415 | uap->flags |= PMACZILOG_FLAG_TX_ACTIVE; | 426 | uap->flags |= PMACZILOG_FLAG_TX_ACTIVE; |
416 | write_zsdata(uap, uap->port.x_char); | 427 | write_zsdata(uap, uap->port.x_char); |
diff --git a/drivers/serial/serial_cs.c b/drivers/serial/serial_cs.c index fc413f0f8dd2..0ee7239c5d69 100644 --- a/drivers/serial/serial_cs.c +++ b/drivers/serial/serial_cs.c | |||
@@ -819,6 +819,7 @@ static struct pcmcia_device_id serial_ids[] = { | |||
819 | PCMCIA_MFC_DEVICE_CIS_MANF_CARD(1, 0x0101, 0x0035, "cis/3CXEM556.cis"), | 819 | PCMCIA_MFC_DEVICE_CIS_MANF_CARD(1, 0x0101, 0x0035, "cis/3CXEM556.cis"), |
820 | PCMCIA_MFC_DEVICE_CIS_MANF_CARD(1, 0x0101, 0x003d, "cis/3CXEM556.cis"), | 820 | PCMCIA_MFC_DEVICE_CIS_MANF_CARD(1, 0x0101, 0x003d, "cis/3CXEM556.cis"), |
821 | PCMCIA_DEVICE_CIS_PROD_ID12("Sierra Wireless", "AC850", 0xd85f6206, 0x42a2c018, "cis/SW_8xx_SER.cis"), /* Sierra Wireless AC850 3G Network Adapter R1 */ | 821 | PCMCIA_DEVICE_CIS_PROD_ID12("Sierra Wireless", "AC850", 0xd85f6206, 0x42a2c018, "cis/SW_8xx_SER.cis"), /* Sierra Wireless AC850 3G Network Adapter R1 */ |
822 | PCMCIA_DEVICE_CIS_PROD_ID12("Sierra Wireless", "AC860", 0xd85f6206, 0x698f93db, "cis/SW_8xx_SER.cis"), /* Sierra Wireless AC860 3G Network Adapter R1 */ | ||
822 | PCMCIA_DEVICE_CIS_PROD_ID12("Sierra Wireless", "AC710/AC750", 0xd85f6206, 0x761b11e0, "cis/SW_7xx_SER.cis"), /* Sierra Wireless AC710/AC750 GPRS Network Adapter R1 */ | 823 | PCMCIA_DEVICE_CIS_PROD_ID12("Sierra Wireless", "AC710/AC750", 0xd85f6206, 0x761b11e0, "cis/SW_7xx_SER.cis"), /* Sierra Wireless AC710/AC750 GPRS Network Adapter R1 */ |
823 | PCMCIA_DEVICE_CIS_MANF_CARD(0x0192, 0xa555, "cis/SW_555_SER.cis"), /* Sierra Aircard 555 CDMA 1xrtt Modem -- pre update */ | 824 | PCMCIA_DEVICE_CIS_MANF_CARD(0x0192, 0xa555, "cis/SW_555_SER.cis"), /* Sierra Aircard 555 CDMA 1xrtt Modem -- pre update */ |
824 | PCMCIA_DEVICE_CIS_MANF_CARD(0x013f, 0xa555, "cis/SW_555_SER.cis"), /* Sierra Aircard 555 CDMA 1xrtt Modem -- post update */ | 825 | PCMCIA_DEVICE_CIS_MANF_CARD(0x013f, 0xa555, "cis/SW_555_SER.cis"), /* Sierra Aircard 555 CDMA 1xrtt Modem -- post update */ |
@@ -827,7 +828,7 @@ static struct pcmcia_device_id serial_ids[] = { | |||
827 | PCMCIA_DEVICE_CIS_PROD_ID12("ADVANTECH", "COMpad-32/85B-4", 0x96913a85, 0xcec8f102, "cis/COMpad4.cis"), | 828 | PCMCIA_DEVICE_CIS_PROD_ID12("ADVANTECH", "COMpad-32/85B-4", 0x96913a85, 0xcec8f102, "cis/COMpad4.cis"), |
828 | PCMCIA_DEVICE_CIS_PROD_ID123("ADVANTECH", "COMpad-32/85", "1.0", 0x96913a85, 0x8fbe92ae, 0x0877b627, "cis/COMpad2.cis"), | 829 | PCMCIA_DEVICE_CIS_PROD_ID123("ADVANTECH", "COMpad-32/85", "1.0", 0x96913a85, 0x8fbe92ae, 0x0877b627, "cis/COMpad2.cis"), |
829 | PCMCIA_DEVICE_CIS_PROD_ID2("RS-COM 2P", 0xad20b156, "cis/RS-COM-2P.cis"), | 830 | PCMCIA_DEVICE_CIS_PROD_ID2("RS-COM 2P", 0xad20b156, "cis/RS-COM-2P.cis"), |
830 | PCMCIA_DEVICE_CIS_MANF_CARD(0x0013, 0x0000, "GLOBETROTTER.cis"), | 831 | PCMCIA_DEVICE_CIS_MANF_CARD(0x0013, 0x0000, "cis/GLOBETROTTER.cis"), |
831 | PCMCIA_DEVICE_PROD_ID12("ELAN DIGITAL SYSTEMS LTD, c1997.","SERIAL CARD: SL100 1.00.",0x19ca78af,0xf964f42b), | 832 | PCMCIA_DEVICE_PROD_ID12("ELAN DIGITAL SYSTEMS LTD, c1997.","SERIAL CARD: SL100 1.00.",0x19ca78af,0xf964f42b), |
832 | PCMCIA_DEVICE_PROD_ID12("ELAN DIGITAL SYSTEMS LTD, c1997.","SERIAL CARD: SL100",0x19ca78af,0x71d98e83), | 833 | PCMCIA_DEVICE_PROD_ID12("ELAN DIGITAL SYSTEMS LTD, c1997.","SERIAL CARD: SL100",0x19ca78af,0x71d98e83), |
833 | PCMCIA_DEVICE_PROD_ID12("ELAN DIGITAL SYSTEMS LTD, c1997.","SERIAL CARD: SL232 1.00.",0x19ca78af,0x69fb7490), | 834 | PCMCIA_DEVICE_PROD_ID12("ELAN DIGITAL SYSTEMS LTD, c1997.","SERIAL CARD: SL232 1.00.",0x19ca78af,0x69fb7490), |
@@ -861,6 +862,18 @@ static struct pcmcia_device_id serial_ids[] = { | |||
861 | }; | 862 | }; |
862 | MODULE_DEVICE_TABLE(pcmcia, serial_ids); | 863 | MODULE_DEVICE_TABLE(pcmcia, serial_ids); |
863 | 864 | ||
865 | MODULE_FIRMWARE("cis/PCMLM28.cis"); | ||
866 | MODULE_FIRMWARE("cis/DP83903.cis"); | ||
867 | MODULE_FIRMWARE("cis/3CCFEM556.cis"); | ||
868 | MODULE_FIRMWARE("cis/3CXEM556.cis"); | ||
869 | MODULE_FIRMWARE("cis/SW_8xx_SER.cis"); | ||
870 | MODULE_FIRMWARE("cis/SW_7xx_SER.cis"); | ||
871 | MODULE_FIRMWARE("cis/SW_555_SER.cis"); | ||
872 | MODULE_FIRMWARE("cis/MT5634ZLX.cis"); | ||
873 | MODULE_FIRMWARE("cis/COMpad2.cis"); | ||
874 | MODULE_FIRMWARE("cis/COMpad4.cis"); | ||
875 | MODULE_FIRMWARE("cis/RS-COM-2P.cis"); | ||
876 | |||
864 | static struct pcmcia_driver serial_cs_driver = { | 877 | static struct pcmcia_driver serial_cs_driver = { |
865 | .owner = THIS_MODULE, | 878 | .owner = THIS_MODULE, |
866 | .drv = { | 879 | .drv = { |
diff --git a/drivers/serial/sh-sci.c b/drivers/serial/sh-sci.c index 37f0de9dd9ce..42f3333c4ad0 100644 --- a/drivers/serial/sh-sci.c +++ b/drivers/serial/sh-sci.c | |||
@@ -1052,7 +1052,18 @@ static void __devinit sci_init_single(struct platform_device *dev, | |||
1052 | sci_port->port.ops = &sci_uart_ops; | 1052 | sci_port->port.ops = &sci_uart_ops; |
1053 | sci_port->port.iotype = UPIO_MEM; | 1053 | sci_port->port.iotype = UPIO_MEM; |
1054 | sci_port->port.line = index; | 1054 | sci_port->port.line = index; |
1055 | sci_port->port.fifosize = 1; | 1055 | |
1056 | switch (p->type) { | ||
1057 | case PORT_SCIFA: | ||
1058 | sci_port->port.fifosize = 64; | ||
1059 | break; | ||
1060 | case PORT_SCIF: | ||
1061 | sci_port->port.fifosize = 16; | ||
1062 | break; | ||
1063 | default: | ||
1064 | sci_port->port.fifosize = 1; | ||
1065 | break; | ||
1066 | } | ||
1056 | 1067 | ||
1057 | if (dev) { | 1068 | if (dev) { |
1058 | sci_port->iclk = p->clk ? clk_get(&dev->dev, p->clk) : NULL; | 1069 | sci_port->iclk = p->clk ? clk_get(&dev->dev, p->clk) : NULL; |
diff --git a/drivers/spi/amba-pl022.c b/drivers/spi/amba-pl022.c index ff5bbb9c43c9..9aeb68113100 100644 --- a/drivers/spi/amba-pl022.c +++ b/drivers/spi/amba-pl022.c | |||
@@ -363,6 +363,7 @@ struct pl022 { | |||
363 | void *rx_end; | 363 | void *rx_end; |
364 | enum ssp_reading read; | 364 | enum ssp_reading read; |
365 | enum ssp_writing write; | 365 | enum ssp_writing write; |
366 | u32 exp_fifo_level; | ||
366 | }; | 367 | }; |
367 | 368 | ||
368 | /** | 369 | /** |
@@ -501,6 +502,9 @@ static int flush(struct pl022 *pl022) | |||
501 | while (readw(SSP_SR(pl022->virtbase)) & SSP_SR_MASK_RNE) | 502 | while (readw(SSP_SR(pl022->virtbase)) & SSP_SR_MASK_RNE) |
502 | readw(SSP_DR(pl022->virtbase)); | 503 | readw(SSP_DR(pl022->virtbase)); |
503 | } while ((readw(SSP_SR(pl022->virtbase)) & SSP_SR_MASK_BSY) && limit--); | 504 | } while ((readw(SSP_SR(pl022->virtbase)) & SSP_SR_MASK_BSY) && limit--); |
505 | |||
506 | pl022->exp_fifo_level = 0; | ||
507 | |||
504 | return limit; | 508 | return limit; |
505 | } | 509 | } |
506 | 510 | ||
@@ -583,10 +587,9 @@ static void readwriter(struct pl022 *pl022) | |||
583 | * errons in 8bit wide transfers on ARM variants (just 8 words | 587 | * errons in 8bit wide transfers on ARM variants (just 8 words |
584 | * FIFO, means only 8x8 = 64 bits in FIFO) at least. | 588 | * FIFO, means only 8x8 = 64 bits in FIFO) at least. |
585 | * | 589 | * |
586 | * FIXME: currently we have no logic to account for this. | 590 | * To prevent this issue, the TX FIFO is only filled to the |
587 | * perhaps there is even something broken in HW regarding | 591 | * unused RX FIFO fill length, regardless of what the TX |
588 | * 8bit transfers (it doesn't fail on 16bit) so this needs | 592 | * FIFO status flag indicates. |
589 | * more investigation... | ||
590 | */ | 593 | */ |
591 | dev_dbg(&pl022->adev->dev, | 594 | dev_dbg(&pl022->adev->dev, |
592 | "%s, rx: %p, rxend: %p, tx: %p, txend: %p\n", | 595 | "%s, rx: %p, rxend: %p, tx: %p, txend: %p\n", |
@@ -613,11 +616,12 @@ static void readwriter(struct pl022 *pl022) | |||
613 | break; | 616 | break; |
614 | } | 617 | } |
615 | pl022->rx += (pl022->cur_chip->n_bytes); | 618 | pl022->rx += (pl022->cur_chip->n_bytes); |
619 | pl022->exp_fifo_level--; | ||
616 | } | 620 | } |
617 | /* | 621 | /* |
618 | * Write as much as you can, while keeping an eye on the RX FIFO! | 622 | * Write as much as possible up to the RX FIFO size |
619 | */ | 623 | */ |
620 | while ((readw(SSP_SR(pl022->virtbase)) & SSP_SR_MASK_TNF) | 624 | while ((pl022->exp_fifo_level < pl022->vendor->fifodepth) |
621 | && (pl022->tx < pl022->tx_end)) { | 625 | && (pl022->tx < pl022->tx_end)) { |
622 | switch (pl022->write) { | 626 | switch (pl022->write) { |
623 | case WRITING_NULL: | 627 | case WRITING_NULL: |
@@ -634,6 +638,7 @@ static void readwriter(struct pl022 *pl022) | |||
634 | break; | 638 | break; |
635 | } | 639 | } |
636 | pl022->tx += (pl022->cur_chip->n_bytes); | 640 | pl022->tx += (pl022->cur_chip->n_bytes); |
641 | pl022->exp_fifo_level++; | ||
637 | /* | 642 | /* |
638 | * This inner reader takes care of things appearing in the RX | 643 | * This inner reader takes care of things appearing in the RX |
639 | * FIFO as we're transmitting. This will happen a lot since the | 644 | * FIFO as we're transmitting. This will happen a lot since the |
@@ -660,6 +665,7 @@ static void readwriter(struct pl022 *pl022) | |||
660 | break; | 665 | break; |
661 | } | 666 | } |
662 | pl022->rx += (pl022->cur_chip->n_bytes); | 667 | pl022->rx += (pl022->cur_chip->n_bytes); |
668 | pl022->exp_fifo_level--; | ||
663 | } | 669 | } |
664 | } | 670 | } |
665 | /* | 671 | /* |
diff --git a/drivers/staging/cx25821/cx25821-medusa-video.c b/drivers/staging/cx25821/cx25821-medusa-video.c index e4df8134f059..1eb079b3d429 100644 --- a/drivers/staging/cx25821/cx25821-medusa-video.c +++ b/drivers/staging/cx25821/cx25821-medusa-video.c | |||
@@ -860,10 +860,8 @@ int medusa_video_init(struct cx25821_dev *dev) | |||
860 | 860 | ||
861 | ret_val = medusa_set_videostandard(dev); | 861 | ret_val = medusa_set_videostandard(dev); |
862 | 862 | ||
863 | if (ret_val < 0) { | 863 | if (ret_val < 0) |
864 | mutex_unlock(&dev->lock); | ||
865 | return -EINVAL; | 864 | return -EINVAL; |
866 | } | ||
867 | 865 | ||
868 | return 1; | 866 | return 1; |
869 | } | 867 | } |
diff --git a/drivers/video/backlight/omap1_bl.c b/drivers/video/backlight/omap1_bl.c index 409ca9643528..a3a7f8938175 100644 --- a/drivers/video/backlight/omap1_bl.c +++ b/drivers/video/backlight/omap1_bl.c | |||
@@ -139,8 +139,6 @@ static int omapbl_probe(struct platform_device *pdev) | |||
139 | if (!pdata) | 139 | if (!pdata) |
140 | return -ENXIO; | 140 | return -ENXIO; |
141 | 141 | ||
142 | omapbl_ops.check_fb = pdata->check_fb; | ||
143 | |||
144 | bl = kzalloc(sizeof(struct omap_backlight), GFP_KERNEL); | 142 | bl = kzalloc(sizeof(struct omap_backlight), GFP_KERNEL); |
145 | if (unlikely(!bl)) | 143 | if (unlikely(!bl)) |
146 | return -ENOMEM; | 144 | return -ENOMEM; |
diff --git a/drivers/video/omap/dispc.c b/drivers/video/omap/dispc.c index c7c6455f1fa8..e192b058a688 100644 --- a/drivers/video/omap/dispc.c +++ b/drivers/video/omap/dispc.c | |||
@@ -189,11 +189,6 @@ static struct { | |||
189 | struct omapfb_color_key color_key; | 189 | struct omapfb_color_key color_key; |
190 | } dispc; | 190 | } dispc; |
191 | 191 | ||
192 | static struct platform_device omapdss_device = { | ||
193 | .name = "omapdss", | ||
194 | .id = -1, | ||
195 | }; | ||
196 | |||
197 | static void enable_lcd_clocks(int enable); | 192 | static void enable_lcd_clocks(int enable); |
198 | 193 | ||
199 | static void inline dispc_write_reg(int idx, u32 val) | 194 | static void inline dispc_write_reg(int idx, u32 val) |
@@ -920,20 +915,20 @@ static irqreturn_t omap_dispc_irq_handler(int irq, void *dev) | |||
920 | 915 | ||
921 | static int get_dss_clocks(void) | 916 | static int get_dss_clocks(void) |
922 | { | 917 | { |
923 | dispc.dss_ick = clk_get(&omapdss_device.dev, "ick"); | 918 | dispc.dss_ick = clk_get(&dispc.fbdev->dssdev->dev, "ick"); |
924 | if (IS_ERR(dispc.dss_ick)) { | 919 | if (IS_ERR(dispc.dss_ick)) { |
925 | dev_err(dispc.fbdev->dev, "can't get ick\n"); | 920 | dev_err(dispc.fbdev->dev, "can't get ick\n"); |
926 | return PTR_ERR(dispc.dss_ick); | 921 | return PTR_ERR(dispc.dss_ick); |
927 | } | 922 | } |
928 | 923 | ||
929 | dispc.dss1_fck = clk_get(&omapdss_device.dev, "dss1_fck"); | 924 | dispc.dss1_fck = clk_get(&dispc.fbdev->dssdev->dev, "dss1_fck"); |
930 | if (IS_ERR(dispc.dss1_fck)) { | 925 | if (IS_ERR(dispc.dss1_fck)) { |
931 | dev_err(dispc.fbdev->dev, "can't get dss1_fck\n"); | 926 | dev_err(dispc.fbdev->dev, "can't get dss1_fck\n"); |
932 | clk_put(dispc.dss_ick); | 927 | clk_put(dispc.dss_ick); |
933 | return PTR_ERR(dispc.dss1_fck); | 928 | return PTR_ERR(dispc.dss1_fck); |
934 | } | 929 | } |
935 | 930 | ||
936 | dispc.dss_54m_fck = clk_get(&omapdss_device.dev, "tv_fck"); | 931 | dispc.dss_54m_fck = clk_get(&dispc.fbdev->dssdev->dev, "tv_fck"); |
937 | if (IS_ERR(dispc.dss_54m_fck)) { | 932 | if (IS_ERR(dispc.dss_54m_fck)) { |
938 | dev_err(dispc.fbdev->dev, "can't get tv_fck\n"); | 933 | dev_err(dispc.fbdev->dev, "can't get tv_fck\n"); |
939 | clk_put(dispc.dss_ick); | 934 | clk_put(dispc.dss_ick); |
@@ -1385,12 +1380,6 @@ static int omap_dispc_init(struct omapfb_device *fbdev, int ext_mode, | |||
1385 | int skip_init = 0; | 1380 | int skip_init = 0; |
1386 | int i; | 1381 | int i; |
1387 | 1382 | ||
1388 | r = platform_device_register(&omapdss_device); | ||
1389 | if (r) { | ||
1390 | dev_err(fbdev->dev, "can't register omapdss device\n"); | ||
1391 | return r; | ||
1392 | } | ||
1393 | |||
1394 | memset(&dispc, 0, sizeof(dispc)); | 1383 | memset(&dispc, 0, sizeof(dispc)); |
1395 | 1384 | ||
1396 | dispc.base = ioremap(DISPC_BASE, SZ_1K); | 1385 | dispc.base = ioremap(DISPC_BASE, SZ_1K); |
@@ -1534,7 +1523,6 @@ static void omap_dispc_cleanup(void) | |||
1534 | free_irq(INT_24XX_DSS_IRQ, dispc.fbdev); | 1523 | free_irq(INT_24XX_DSS_IRQ, dispc.fbdev); |
1535 | put_dss_clocks(); | 1524 | put_dss_clocks(); |
1536 | iounmap(dispc.base); | 1525 | iounmap(dispc.base); |
1537 | platform_device_unregister(&omapdss_device); | ||
1538 | } | 1526 | } |
1539 | 1527 | ||
1540 | const struct lcd_ctrl omap2_int_ctrl = { | 1528 | const struct lcd_ctrl omap2_int_ctrl = { |
diff --git a/drivers/video/omap/lcd_htcherald.c b/drivers/video/omap/lcd_htcherald.c index a9007c5d1fad..4802419da83b 100644 --- a/drivers/video/omap/lcd_htcherald.c +++ b/drivers/video/omap/lcd_htcherald.c | |||
@@ -115,12 +115,12 @@ struct platform_driver htcherald_panel_driver = { | |||
115 | }, | 115 | }, |
116 | }; | 116 | }; |
117 | 117 | ||
118 | static int htcherald_panel_drv_init(void) | 118 | static int __init htcherald_panel_drv_init(void) |
119 | { | 119 | { |
120 | return platform_driver_register(&htcherald_panel_driver); | 120 | return platform_driver_register(&htcherald_panel_driver); |
121 | } | 121 | } |
122 | 122 | ||
123 | static void htcherald_panel_drv_cleanup(void) | 123 | static void __exit htcherald_panel_drv_cleanup(void) |
124 | { | 124 | { |
125 | platform_driver_unregister(&htcherald_panel_driver); | 125 | platform_driver_unregister(&htcherald_panel_driver); |
126 | } | 126 | } |
diff --git a/drivers/video/omap/omapfb.h b/drivers/video/omap/omapfb.h index 46e4714014e8..af3c9e571ec3 100644 --- a/drivers/video/omap/omapfb.h +++ b/drivers/video/omap/omapfb.h | |||
@@ -203,6 +203,8 @@ struct omapfb_device { | |||
203 | 203 | ||
204 | struct omapfb_mem_desc mem_desc; | 204 | struct omapfb_mem_desc mem_desc; |
205 | struct fb_info *fb_info[OMAPFB_PLANE_NUM]; | 205 | struct fb_info *fb_info[OMAPFB_PLANE_NUM]; |
206 | |||
207 | struct platform_device *dssdev; /* dummy dev for clocks */ | ||
206 | }; | 208 | }; |
207 | 209 | ||
208 | #ifdef CONFIG_ARCH_OMAP1 | 210 | #ifdef CONFIG_ARCH_OMAP1 |
diff --git a/drivers/video/omap/omapfb_main.c b/drivers/video/omap/omapfb_main.c index c7f59a5ccdbc..2c4f470fa086 100644 --- a/drivers/video/omap/omapfb_main.c +++ b/drivers/video/omap/omapfb_main.c | |||
@@ -83,6 +83,19 @@ static struct caps_table_struct color_caps[] = { | |||
83 | { 1 << OMAPFB_COLOR_YUY422, "YUY422", }, | 83 | { 1 << OMAPFB_COLOR_YUY422, "YUY422", }, |
84 | }; | 84 | }; |
85 | 85 | ||
86 | static void omapdss_release(struct device *dev) | ||
87 | { | ||
88 | } | ||
89 | |||
90 | /* dummy device for clocks */ | ||
91 | static struct platform_device omapdss_device = { | ||
92 | .name = "omapdss", | ||
93 | .id = -1, | ||
94 | .dev = { | ||
95 | .release = omapdss_release, | ||
96 | }, | ||
97 | }; | ||
98 | |||
86 | /* | 99 | /* |
87 | * --------------------------------------------------------------------------- | 100 | * --------------------------------------------------------------------------- |
88 | * LCD panel | 101 | * LCD panel |
@@ -1700,6 +1713,7 @@ static int omapfb_do_probe(struct platform_device *pdev, | |||
1700 | 1713 | ||
1701 | fbdev->dev = &pdev->dev; | 1714 | fbdev->dev = &pdev->dev; |
1702 | fbdev->panel = panel; | 1715 | fbdev->panel = panel; |
1716 | fbdev->dssdev = &omapdss_device; | ||
1703 | platform_set_drvdata(pdev, fbdev); | 1717 | platform_set_drvdata(pdev, fbdev); |
1704 | 1718 | ||
1705 | mutex_init(&fbdev->rqueue_mutex); | 1719 | mutex_init(&fbdev->rqueue_mutex); |
@@ -1814,8 +1828,16 @@ cleanup: | |||
1814 | 1828 | ||
1815 | static int omapfb_probe(struct platform_device *pdev) | 1829 | static int omapfb_probe(struct platform_device *pdev) |
1816 | { | 1830 | { |
1831 | int r; | ||
1832 | |||
1817 | BUG_ON(fbdev_pdev != NULL); | 1833 | BUG_ON(fbdev_pdev != NULL); |
1818 | 1834 | ||
1835 | r = platform_device_register(&omapdss_device); | ||
1836 | if (r) { | ||
1837 | dev_err(&pdev->dev, "can't register omapdss device\n"); | ||
1838 | return r; | ||
1839 | } | ||
1840 | |||
1819 | /* Delay actual initialization until the LCD is registered */ | 1841 | /* Delay actual initialization until the LCD is registered */ |
1820 | fbdev_pdev = pdev; | 1842 | fbdev_pdev = pdev; |
1821 | if (fbdev_panel != NULL) | 1843 | if (fbdev_panel != NULL) |
@@ -1843,6 +1865,9 @@ static int omapfb_remove(struct platform_device *pdev) | |||
1843 | fbdev->state = OMAPFB_DISABLED; | 1865 | fbdev->state = OMAPFB_DISABLED; |
1844 | omapfb_free_resources(fbdev, saved_state); | 1866 | omapfb_free_resources(fbdev, saved_state); |
1845 | 1867 | ||
1868 | platform_device_unregister(&omapdss_device); | ||
1869 | fbdev->dssdev = NULL; | ||
1870 | |||
1846 | return 0; | 1871 | return 0; |
1847 | } | 1872 | } |
1848 | 1873 | ||
diff --git a/drivers/video/omap/rfbi.c b/drivers/video/omap/rfbi.c index fed7b1bda19c..1162603c72e5 100644 --- a/drivers/video/omap/rfbi.c +++ b/drivers/video/omap/rfbi.c | |||
@@ -83,13 +83,13 @@ static inline u32 rfbi_read_reg(int idx) | |||
83 | 83 | ||
84 | static int rfbi_get_clocks(void) | 84 | static int rfbi_get_clocks(void) |
85 | { | 85 | { |
86 | rfbi.dss_ick = clk_get(rfbi.fbdev->dev, "ick"); | 86 | rfbi.dss_ick = clk_get(&dispc.fbdev->dssdev->dev, "ick"); |
87 | if (IS_ERR(rfbi.dss_ick)) { | 87 | if (IS_ERR(rfbi.dss_ick)) { |
88 | dev_err(rfbi.fbdev->dev, "can't get ick\n"); | 88 | dev_err(rfbi.fbdev->dev, "can't get ick\n"); |
89 | return PTR_ERR(rfbi.dss_ick); | 89 | return PTR_ERR(rfbi.dss_ick); |
90 | } | 90 | } |
91 | 91 | ||
92 | rfbi.dss1_fck = clk_get(rfbi.fbdev->dev, "dss1_fck"); | 92 | rfbi.dss1_fck = clk_get(&dispc.fbdev->dssdev->dev, "dss1_fck"); |
93 | if (IS_ERR(rfbi.dss1_fck)) { | 93 | if (IS_ERR(rfbi.dss1_fck)) { |
94 | dev_err(rfbi.fbdev->dev, "can't get dss1_fck\n"); | 94 | dev_err(rfbi.fbdev->dev, "can't get dss1_fck\n"); |
95 | clk_put(rfbi.dss_ick); | 95 | clk_put(rfbi.dss_ick); |
diff --git a/drivers/video/omap2/dss/Kconfig b/drivers/video/omap2/dss/Kconfig index 71d8dec30635..c63ce767b277 100644 --- a/drivers/video/omap2/dss/Kconfig +++ b/drivers/video/omap2/dss/Kconfig | |||
@@ -25,6 +25,13 @@ config OMAP2_DSS_DEBUG_SUPPORT | |||
25 | This enables debug messages. You need to enable printing | 25 | This enables debug messages. You need to enable printing |
26 | with 'debug' module parameter. | 26 | with 'debug' module parameter. |
27 | 27 | ||
28 | config OMAP2_DSS_COLLECT_IRQ_STATS | ||
29 | bool "Collect DSS IRQ statistics" | ||
30 | depends on OMAP2_DSS_DEBUG_SUPPORT | ||
31 | default n | ||
32 | help | ||
33 | Collect DSS IRQ statistics, printable via debugfs | ||
34 | |||
28 | config OMAP2_DSS_RFBI | 35 | config OMAP2_DSS_RFBI |
29 | bool "RFBI support" | 36 | bool "RFBI support" |
30 | default n | 37 | default n |
diff --git a/drivers/video/omap2/dss/core.c b/drivers/video/omap2/dss/core.c index 29497a0c9a91..82918eec6d2e 100644 --- a/drivers/video/omap2/dss/core.c +++ b/drivers/video/omap2/dss/core.c | |||
@@ -124,6 +124,7 @@ static void restore_all_ctx(void) | |||
124 | dss_clk_disable_all_no_ctx(); | 124 | dss_clk_disable_all_no_ctx(); |
125 | } | 125 | } |
126 | 126 | ||
127 | #if defined(CONFIG_DEBUG_FS) && defined(CONFIG_OMAP2_DSS_DEBUG_SUPPORT) | ||
127 | /* CLOCKS */ | 128 | /* CLOCKS */ |
128 | static void core_dump_clocks(struct seq_file *s) | 129 | static void core_dump_clocks(struct seq_file *s) |
129 | { | 130 | { |
@@ -149,6 +150,7 @@ static void core_dump_clocks(struct seq_file *s) | |||
149 | clocks[i]->usecount); | 150 | clocks[i]->usecount); |
150 | } | 151 | } |
151 | } | 152 | } |
153 | #endif /* defined(CONFIG_DEBUG_FS) && defined(CONFIG_OMAP2_DSS_DEBUG_SUPPORT) */ | ||
152 | 154 | ||
153 | static int dss_get_clock(struct clk **clock, const char *clk_name) | 155 | static int dss_get_clock(struct clk **clock, const char *clk_name) |
154 | { | 156 | { |
@@ -395,6 +397,14 @@ static int dss_initialize_debugfs(void) | |||
395 | debugfs_create_file("clk", S_IRUGO, dss_debugfs_dir, | 397 | debugfs_create_file("clk", S_IRUGO, dss_debugfs_dir, |
396 | &dss_debug_dump_clocks, &dss_debug_fops); | 398 | &dss_debug_dump_clocks, &dss_debug_fops); |
397 | 399 | ||
400 | debugfs_create_file("dispc_irq", S_IRUGO, dss_debugfs_dir, | ||
401 | &dispc_dump_irqs, &dss_debug_fops); | ||
402 | |||
403 | #ifdef CONFIG_OMAP2_DSS_DSI | ||
404 | debugfs_create_file("dsi_irq", S_IRUGO, dss_debugfs_dir, | ||
405 | &dsi_dump_irqs, &dss_debug_fops); | ||
406 | #endif | ||
407 | |||
398 | debugfs_create_file("dss", S_IRUGO, dss_debugfs_dir, | 408 | debugfs_create_file("dss", S_IRUGO, dss_debugfs_dir, |
399 | &dss_dump_regs, &dss_debug_fops); | 409 | &dss_dump_regs, &dss_debug_fops); |
400 | debugfs_create_file("dispc", S_IRUGO, dss_debugfs_dir, | 410 | debugfs_create_file("dispc", S_IRUGO, dss_debugfs_dir, |
diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c index 6dabf4b2f005..de8bfbac9e26 100644 --- a/drivers/video/omap2/dss/dispc.c +++ b/drivers/video/omap2/dss/dispc.c | |||
@@ -148,6 +148,12 @@ static const struct dispc_reg dispc_reg_att[] = { DISPC_GFX_ATTRIBUTES, | |||
148 | DISPC_VID_ATTRIBUTES(0), | 148 | DISPC_VID_ATTRIBUTES(0), |
149 | DISPC_VID_ATTRIBUTES(1) }; | 149 | DISPC_VID_ATTRIBUTES(1) }; |
150 | 150 | ||
151 | struct dispc_irq_stats { | ||
152 | unsigned long last_reset; | ||
153 | unsigned irq_count; | ||
154 | unsigned irqs[32]; | ||
155 | }; | ||
156 | |||
151 | static struct { | 157 | static struct { |
152 | void __iomem *base; | 158 | void __iomem *base; |
153 | 159 | ||
@@ -160,6 +166,11 @@ static struct { | |||
160 | struct work_struct error_work; | 166 | struct work_struct error_work; |
161 | 167 | ||
162 | u32 ctx[DISPC_SZ_REGS / sizeof(u32)]; | 168 | u32 ctx[DISPC_SZ_REGS / sizeof(u32)]; |
169 | |||
170 | #ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS | ||
171 | spinlock_t irq_stats_lock; | ||
172 | struct dispc_irq_stats irq_stats; | ||
173 | #endif | ||
163 | } dispc; | 174 | } dispc; |
164 | 175 | ||
165 | static void _omap_dispc_set_irqs(void); | 176 | static void _omap_dispc_set_irqs(void); |
@@ -1443,7 +1454,10 @@ static unsigned long calc_fclk_five_taps(u16 width, u16 height, | |||
1443 | do_div(tmp, 2 * out_height * ppl); | 1454 | do_div(tmp, 2 * out_height * ppl); |
1444 | fclk = tmp; | 1455 | fclk = tmp; |
1445 | 1456 | ||
1446 | if (height > 2 * out_height && ppl != out_width) { | 1457 | if (height > 2 * out_height) { |
1458 | if (ppl == out_width) | ||
1459 | return 0; | ||
1460 | |||
1447 | tmp = pclk * (height - 2 * out_height) * out_width; | 1461 | tmp = pclk * (height - 2 * out_height) * out_width; |
1448 | do_div(tmp, 2 * out_height * (ppl - out_width)); | 1462 | do_div(tmp, 2 * out_height * (ppl - out_width)); |
1449 | fclk = max(fclk, (u32) tmp); | 1463 | fclk = max(fclk, (u32) tmp); |
@@ -1623,7 +1637,7 @@ static int _dispc_setup_plane(enum omap_plane plane, | |||
1623 | DSSDBG("required fclk rate = %lu Hz\n", fclk); | 1637 | DSSDBG("required fclk rate = %lu Hz\n", fclk); |
1624 | DSSDBG("current fclk rate = %lu Hz\n", dispc_fclk_rate()); | 1638 | DSSDBG("current fclk rate = %lu Hz\n", dispc_fclk_rate()); |
1625 | 1639 | ||
1626 | if (fclk > dispc_fclk_rate()) { | 1640 | if (!fclk || fclk > dispc_fclk_rate()) { |
1627 | DSSERR("failed to set up scaling, " | 1641 | DSSERR("failed to set up scaling, " |
1628 | "required fclk rate = %lu Hz, " | 1642 | "required fclk rate = %lu Hz, " |
1629 | "current fclk rate = %lu Hz\n", | 1643 | "current fclk rate = %lu Hz\n", |
@@ -2247,6 +2261,50 @@ void dispc_dump_clocks(struct seq_file *s) | |||
2247 | enable_clocks(0); | 2261 | enable_clocks(0); |
2248 | } | 2262 | } |
2249 | 2263 | ||
2264 | #ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS | ||
2265 | void dispc_dump_irqs(struct seq_file *s) | ||
2266 | { | ||
2267 | unsigned long flags; | ||
2268 | struct dispc_irq_stats stats; | ||
2269 | |||
2270 | spin_lock_irqsave(&dispc.irq_stats_lock, flags); | ||
2271 | |||
2272 | stats = dispc.irq_stats; | ||
2273 | memset(&dispc.irq_stats, 0, sizeof(dispc.irq_stats)); | ||
2274 | dispc.irq_stats.last_reset = jiffies; | ||
2275 | |||
2276 | spin_unlock_irqrestore(&dispc.irq_stats_lock, flags); | ||
2277 | |||
2278 | seq_printf(s, "period %u ms\n", | ||
2279 | jiffies_to_msecs(jiffies - stats.last_reset)); | ||
2280 | |||
2281 | seq_printf(s, "irqs %d\n", stats.irq_count); | ||
2282 | #define PIS(x) \ | ||
2283 | seq_printf(s, "%-20s %10d\n", #x, stats.irqs[ffs(DISPC_IRQ_##x)-1]); | ||
2284 | |||
2285 | PIS(FRAMEDONE); | ||
2286 | PIS(VSYNC); | ||
2287 | PIS(EVSYNC_EVEN); | ||
2288 | PIS(EVSYNC_ODD); | ||
2289 | PIS(ACBIAS_COUNT_STAT); | ||
2290 | PIS(PROG_LINE_NUM); | ||
2291 | PIS(GFX_FIFO_UNDERFLOW); | ||
2292 | PIS(GFX_END_WIN); | ||
2293 | PIS(PAL_GAMMA_MASK); | ||
2294 | PIS(OCP_ERR); | ||
2295 | PIS(VID1_FIFO_UNDERFLOW); | ||
2296 | PIS(VID1_END_WIN); | ||
2297 | PIS(VID2_FIFO_UNDERFLOW); | ||
2298 | PIS(VID2_END_WIN); | ||
2299 | PIS(SYNC_LOST); | ||
2300 | PIS(SYNC_LOST_DIGIT); | ||
2301 | PIS(WAKEUP); | ||
2302 | #undef PIS | ||
2303 | } | ||
2304 | #else | ||
2305 | void dispc_dump_irqs(struct seq_file *s) { } | ||
2306 | #endif | ||
2307 | |||
2250 | void dispc_dump_regs(struct seq_file *s) | 2308 | void dispc_dump_regs(struct seq_file *s) |
2251 | { | 2309 | { |
2252 | #define DUMPREG(r) seq_printf(s, "%-35s %08x\n", #r, dispc_read_reg(r)) | 2310 | #define DUMPREG(r) seq_printf(s, "%-35s %08x\n", #r, dispc_read_reg(r)) |
@@ -2665,6 +2723,13 @@ void dispc_irq_handler(void) | |||
2665 | 2723 | ||
2666 | irqstatus = dispc_read_reg(DISPC_IRQSTATUS); | 2724 | irqstatus = dispc_read_reg(DISPC_IRQSTATUS); |
2667 | 2725 | ||
2726 | #ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS | ||
2727 | spin_lock(&dispc.irq_stats_lock); | ||
2728 | dispc.irq_stats.irq_count++; | ||
2729 | dss_collect_irq_stats(irqstatus, dispc.irq_stats.irqs); | ||
2730 | spin_unlock(&dispc.irq_stats_lock); | ||
2731 | #endif | ||
2732 | |||
2668 | #ifdef DEBUG | 2733 | #ifdef DEBUG |
2669 | if (dss_debug) | 2734 | if (dss_debug) |
2670 | print_irq_status(irqstatus); | 2735 | print_irq_status(irqstatus); |
@@ -3012,6 +3077,11 @@ int dispc_init(void) | |||
3012 | 3077 | ||
3013 | spin_lock_init(&dispc.irq_lock); | 3078 | spin_lock_init(&dispc.irq_lock); |
3014 | 3079 | ||
3080 | #ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS | ||
3081 | spin_lock_init(&dispc.irq_stats_lock); | ||
3082 | dispc.irq_stats.last_reset = jiffies; | ||
3083 | #endif | ||
3084 | |||
3015 | INIT_WORK(&dispc.error_work, dispc_error_worker); | 3085 | INIT_WORK(&dispc.error_work, dispc_error_worker); |
3016 | 3086 | ||
3017 | dispc.base = ioremap(DISPC_BASE, DISPC_SZ_REGS); | 3087 | dispc.base = ioremap(DISPC_BASE, DISPC_SZ_REGS); |
diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c index 5936487b5def..6122178f5f85 100644 --- a/drivers/video/omap2/dss/dsi.c +++ b/drivers/video/omap2/dss/dsi.c | |||
@@ -204,6 +204,14 @@ struct dsi_update_region { | |||
204 | struct omap_dss_device *device; | 204 | struct omap_dss_device *device; |
205 | }; | 205 | }; |
206 | 206 | ||
207 | struct dsi_irq_stats { | ||
208 | unsigned long last_reset; | ||
209 | unsigned irq_count; | ||
210 | unsigned dsi_irqs[32]; | ||
211 | unsigned vc_irqs[4][32]; | ||
212 | unsigned cio_irqs[32]; | ||
213 | }; | ||
214 | |||
207 | static struct | 215 | static struct |
208 | { | 216 | { |
209 | void __iomem *base; | 217 | void __iomem *base; |
@@ -258,6 +266,11 @@ static struct | |||
258 | #endif | 266 | #endif |
259 | int debug_read; | 267 | int debug_read; |
260 | int debug_write; | 268 | int debug_write; |
269 | |||
270 | #ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS | ||
271 | spinlock_t irq_stats_lock; | ||
272 | struct dsi_irq_stats irq_stats; | ||
273 | #endif | ||
261 | } dsi; | 274 | } dsi; |
262 | 275 | ||
263 | #ifdef DEBUG | 276 | #ifdef DEBUG |
@@ -528,6 +541,12 @@ void dsi_irq_handler(void) | |||
528 | 541 | ||
529 | irqstatus = dsi_read_reg(DSI_IRQSTATUS); | 542 | irqstatus = dsi_read_reg(DSI_IRQSTATUS); |
530 | 543 | ||
544 | #ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS | ||
545 | spin_lock(&dsi.irq_stats_lock); | ||
546 | dsi.irq_stats.irq_count++; | ||
547 | dss_collect_irq_stats(irqstatus, dsi.irq_stats.dsi_irqs); | ||
548 | #endif | ||
549 | |||
531 | if (irqstatus & DSI_IRQ_ERROR_MASK) { | 550 | if (irqstatus & DSI_IRQ_ERROR_MASK) { |
532 | DSSERR("DSI error, irqstatus %x\n", irqstatus); | 551 | DSSERR("DSI error, irqstatus %x\n", irqstatus); |
533 | print_irq_status(irqstatus); | 552 | print_irq_status(irqstatus); |
@@ -549,6 +568,10 @@ void dsi_irq_handler(void) | |||
549 | 568 | ||
550 | vcstatus = dsi_read_reg(DSI_VC_IRQSTATUS(i)); | 569 | vcstatus = dsi_read_reg(DSI_VC_IRQSTATUS(i)); |
551 | 570 | ||
571 | #ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS | ||
572 | dss_collect_irq_stats(vcstatus, dsi.irq_stats.vc_irqs[i]); | ||
573 | #endif | ||
574 | |||
552 | if (vcstatus & DSI_VC_IRQ_BTA) | 575 | if (vcstatus & DSI_VC_IRQ_BTA) |
553 | complete(&dsi.bta_completion); | 576 | complete(&dsi.bta_completion); |
554 | 577 | ||
@@ -568,6 +591,10 @@ void dsi_irq_handler(void) | |||
568 | if (irqstatus & DSI_IRQ_COMPLEXIO_ERR) { | 591 | if (irqstatus & DSI_IRQ_COMPLEXIO_ERR) { |
569 | ciostatus = dsi_read_reg(DSI_COMPLEXIO_IRQ_STATUS); | 592 | ciostatus = dsi_read_reg(DSI_COMPLEXIO_IRQ_STATUS); |
570 | 593 | ||
594 | #ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS | ||
595 | dss_collect_irq_stats(ciostatus, dsi.irq_stats.cio_irqs); | ||
596 | #endif | ||
597 | |||
571 | dsi_write_reg(DSI_COMPLEXIO_IRQ_STATUS, ciostatus); | 598 | dsi_write_reg(DSI_COMPLEXIO_IRQ_STATUS, ciostatus); |
572 | /* flush posted write */ | 599 | /* flush posted write */ |
573 | dsi_read_reg(DSI_COMPLEXIO_IRQ_STATUS); | 600 | dsi_read_reg(DSI_COMPLEXIO_IRQ_STATUS); |
@@ -579,6 +606,10 @@ void dsi_irq_handler(void) | |||
579 | dsi_write_reg(DSI_IRQSTATUS, irqstatus & ~DSI_IRQ_CHANNEL_MASK); | 606 | dsi_write_reg(DSI_IRQSTATUS, irqstatus & ~DSI_IRQ_CHANNEL_MASK); |
580 | /* flush posted write */ | 607 | /* flush posted write */ |
581 | dsi_read_reg(DSI_IRQSTATUS); | 608 | dsi_read_reg(DSI_IRQSTATUS); |
609 | |||
610 | #ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS | ||
611 | spin_unlock(&dsi.irq_stats_lock); | ||
612 | #endif | ||
582 | } | 613 | } |
583 | 614 | ||
584 | 615 | ||
@@ -797,12 +828,12 @@ static int dsi_pll_power(enum dsi_pll_power_state state) | |||
797 | 828 | ||
798 | /* PLL_PWR_STATUS */ | 829 | /* PLL_PWR_STATUS */ |
799 | while (FLD_GET(dsi_read_reg(DSI_CLK_CTRL), 29, 28) != state) { | 830 | while (FLD_GET(dsi_read_reg(DSI_CLK_CTRL), 29, 28) != state) { |
800 | udelay(1); | 831 | if (++t > 1000) { |
801 | if (t++ > 1000) { | ||
802 | DSSERR("Failed to set DSI PLL power mode to %d\n", | 832 | DSSERR("Failed to set DSI PLL power mode to %d\n", |
803 | state); | 833 | state); |
804 | return -ENODEV; | 834 | return -ENODEV; |
805 | } | 835 | } |
836 | udelay(1); | ||
806 | } | 837 | } |
807 | 838 | ||
808 | return 0; | 839 | return 0; |
@@ -1226,6 +1257,95 @@ void dsi_dump_clocks(struct seq_file *s) | |||
1226 | enable_clocks(0); | 1257 | enable_clocks(0); |
1227 | } | 1258 | } |
1228 | 1259 | ||
1260 | #ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS | ||
1261 | void dsi_dump_irqs(struct seq_file *s) | ||
1262 | { | ||
1263 | unsigned long flags; | ||
1264 | struct dsi_irq_stats stats; | ||
1265 | |||
1266 | spin_lock_irqsave(&dsi.irq_stats_lock, flags); | ||
1267 | |||
1268 | stats = dsi.irq_stats; | ||
1269 | memset(&dsi.irq_stats, 0, sizeof(dsi.irq_stats)); | ||
1270 | dsi.irq_stats.last_reset = jiffies; | ||
1271 | |||
1272 | spin_unlock_irqrestore(&dsi.irq_stats_lock, flags); | ||
1273 | |||
1274 | seq_printf(s, "period %u ms\n", | ||
1275 | jiffies_to_msecs(jiffies - stats.last_reset)); | ||
1276 | |||
1277 | seq_printf(s, "irqs %d\n", stats.irq_count); | ||
1278 | #define PIS(x) \ | ||
1279 | seq_printf(s, "%-20s %10d\n", #x, stats.dsi_irqs[ffs(DSI_IRQ_##x)-1]); | ||
1280 | |||
1281 | seq_printf(s, "-- DSI interrupts --\n"); | ||
1282 | PIS(VC0); | ||
1283 | PIS(VC1); | ||
1284 | PIS(VC2); | ||
1285 | PIS(VC3); | ||
1286 | PIS(WAKEUP); | ||
1287 | PIS(RESYNC); | ||
1288 | PIS(PLL_LOCK); | ||
1289 | PIS(PLL_UNLOCK); | ||
1290 | PIS(PLL_RECALL); | ||
1291 | PIS(COMPLEXIO_ERR); | ||
1292 | PIS(HS_TX_TIMEOUT); | ||
1293 | PIS(LP_RX_TIMEOUT); | ||
1294 | PIS(TE_TRIGGER); | ||
1295 | PIS(ACK_TRIGGER); | ||
1296 | PIS(SYNC_LOST); | ||
1297 | PIS(LDO_POWER_GOOD); | ||
1298 | PIS(TA_TIMEOUT); | ||
1299 | #undef PIS | ||
1300 | |||
1301 | #define PIS(x) \ | ||
1302 | seq_printf(s, "%-20s %10d %10d %10d %10d\n", #x, \ | ||
1303 | stats.vc_irqs[0][ffs(DSI_VC_IRQ_##x)-1], \ | ||
1304 | stats.vc_irqs[1][ffs(DSI_VC_IRQ_##x)-1], \ | ||
1305 | stats.vc_irqs[2][ffs(DSI_VC_IRQ_##x)-1], \ | ||
1306 | stats.vc_irqs[3][ffs(DSI_VC_IRQ_##x)-1]); | ||
1307 | |||
1308 | seq_printf(s, "-- VC interrupts --\n"); | ||
1309 | PIS(CS); | ||
1310 | PIS(ECC_CORR); | ||
1311 | PIS(PACKET_SENT); | ||
1312 | PIS(FIFO_TX_OVF); | ||
1313 | PIS(FIFO_RX_OVF); | ||
1314 | PIS(BTA); | ||
1315 | PIS(ECC_NO_CORR); | ||
1316 | PIS(FIFO_TX_UDF); | ||
1317 | PIS(PP_BUSY_CHANGE); | ||
1318 | #undef PIS | ||
1319 | |||
1320 | #define PIS(x) \ | ||
1321 | seq_printf(s, "%-20s %10d\n", #x, \ | ||
1322 | stats.cio_irqs[ffs(DSI_CIO_IRQ_##x)-1]); | ||
1323 | |||
1324 | seq_printf(s, "-- CIO interrupts --\n"); | ||
1325 | PIS(ERRSYNCESC1); | ||
1326 | PIS(ERRSYNCESC2); | ||
1327 | PIS(ERRSYNCESC3); | ||
1328 | PIS(ERRESC1); | ||
1329 | PIS(ERRESC2); | ||
1330 | PIS(ERRESC3); | ||
1331 | PIS(ERRCONTROL1); | ||
1332 | PIS(ERRCONTROL2); | ||
1333 | PIS(ERRCONTROL3); | ||
1334 | PIS(STATEULPS1); | ||
1335 | PIS(STATEULPS2); | ||
1336 | PIS(STATEULPS3); | ||
1337 | PIS(ERRCONTENTIONLP0_1); | ||
1338 | PIS(ERRCONTENTIONLP1_1); | ||
1339 | PIS(ERRCONTENTIONLP0_2); | ||
1340 | PIS(ERRCONTENTIONLP1_2); | ||
1341 | PIS(ERRCONTENTIONLP0_3); | ||
1342 | PIS(ERRCONTENTIONLP1_3); | ||
1343 | PIS(ULPSACTIVENOT_ALL0); | ||
1344 | PIS(ULPSACTIVENOT_ALL1); | ||
1345 | #undef PIS | ||
1346 | } | ||
1347 | #endif | ||
1348 | |||
1229 | void dsi_dump_regs(struct seq_file *s) | 1349 | void dsi_dump_regs(struct seq_file *s) |
1230 | { | 1350 | { |
1231 | #define DUMPREG(r) seq_printf(s, "%-35s %08x\n", #r, dsi_read_reg(r)) | 1351 | #define DUMPREG(r) seq_printf(s, "%-35s %08x\n", #r, dsi_read_reg(r)) |
@@ -1321,12 +1441,12 @@ static int dsi_complexio_power(enum dsi_complexio_power_state state) | |||
1321 | 1441 | ||
1322 | /* PWR_STATUS */ | 1442 | /* PWR_STATUS */ |
1323 | while (FLD_GET(dsi_read_reg(DSI_COMPLEXIO_CFG1), 26, 25) != state) { | 1443 | while (FLD_GET(dsi_read_reg(DSI_COMPLEXIO_CFG1), 26, 25) != state) { |
1324 | udelay(1); | 1444 | if (++t > 1000) { |
1325 | if (t++ > 1000) { | ||
1326 | DSSERR("failed to set complexio power state to " | 1445 | DSSERR("failed to set complexio power state to " |
1327 | "%d\n", state); | 1446 | "%d\n", state); |
1328 | return -ENODEV; | 1447 | return -ENODEV; |
1329 | } | 1448 | } |
1449 | udelay(1); | ||
1330 | } | 1450 | } |
1331 | 1451 | ||
1332 | return 0; | 1452 | return 0; |
@@ -1526,10 +1646,10 @@ static void dsi_complexio_uninit(void) | |||
1526 | 1646 | ||
1527 | static int _dsi_wait_reset(void) | 1647 | static int _dsi_wait_reset(void) |
1528 | { | 1648 | { |
1529 | int i = 0; | 1649 | int t = 0; |
1530 | 1650 | ||
1531 | while (REG_GET(DSI_SYSSTATUS, 0, 0) == 0) { | 1651 | while (REG_GET(DSI_SYSSTATUS, 0, 0) == 0) { |
1532 | if (i++ > 5) { | 1652 | if (++t > 5) { |
1533 | DSSERR("soft reset failed\n"); | 1653 | DSSERR("soft reset failed\n"); |
1534 | return -ENODEV; | 1654 | return -ENODEV; |
1535 | } | 1655 | } |
@@ -1999,7 +2119,7 @@ static int dsi_vc_send_short(int channel, u8 data_type, u16 data, u8 ecc) | |||
1999 | return -EINVAL; | 2119 | return -EINVAL; |
2000 | } | 2120 | } |
2001 | 2121 | ||
2002 | data_id = data_type | channel << 6; | 2122 | data_id = data_type | dsi.vc[channel].dest_per << 6; |
2003 | 2123 | ||
2004 | r = (data_id << 0) | (data << 8) | (ecc << 24); | 2124 | r = (data_id << 0) | (data << 8) | (ecc << 24); |
2005 | 2125 | ||
@@ -2011,7 +2131,7 @@ static int dsi_vc_send_short(int channel, u8 data_type, u16 data, u8 ecc) | |||
2011 | int dsi_vc_send_null(int channel) | 2131 | int dsi_vc_send_null(int channel) |
2012 | { | 2132 | { |
2013 | u8 nullpkg[] = {0, 0, 0, 0}; | 2133 | u8 nullpkg[] = {0, 0, 0, 0}; |
2014 | return dsi_vc_send_long(0, DSI_DT_NULL_PACKET, nullpkg, 4, 0); | 2134 | return dsi_vc_send_long(channel, DSI_DT_NULL_PACKET, nullpkg, 4, 0); |
2015 | } | 2135 | } |
2016 | EXPORT_SYMBOL(dsi_vc_send_null); | 2136 | EXPORT_SYMBOL(dsi_vc_send_null); |
2017 | 2137 | ||
@@ -2058,7 +2178,7 @@ int dsi_vc_dcs_read(int channel, u8 dcs_cmd, u8 *buf, int buflen) | |||
2058 | int r; | 2178 | int r; |
2059 | 2179 | ||
2060 | if (dsi.debug_read) | 2180 | if (dsi.debug_read) |
2061 | DSSDBG("dsi_vc_dcs_read(ch%d, dcs_cmd %u)\n", channel, dcs_cmd); | 2181 | DSSDBG("dsi_vc_dcs_read(ch%d, dcs_cmd %x)\n", channel, dcs_cmd); |
2062 | 2182 | ||
2063 | r = dsi_vc_send_short(channel, DSI_DT_DCS_READ, dcs_cmd, 0); | 2183 | r = dsi_vc_send_short(channel, DSI_DT_DCS_READ, dcs_cmd, 0); |
2064 | if (r) | 2184 | if (r) |
@@ -2586,7 +2706,6 @@ static int dsi_update_screen_l4(struct omap_dss_device *dssdev, | |||
2586 | /* using fifo not empty */ | 2706 | /* using fifo not empty */ |
2587 | /* TX_FIFO_NOT_EMPTY */ | 2707 | /* TX_FIFO_NOT_EMPTY */ |
2588 | while (FLD_GET(dsi_read_reg(DSI_VC_CTRL(0)), 5, 5)) { | 2708 | while (FLD_GET(dsi_read_reg(DSI_VC_CTRL(0)), 5, 5)) { |
2589 | udelay(1); | ||
2590 | fifo_stalls++; | 2709 | fifo_stalls++; |
2591 | if (fifo_stalls > 0xfffff) { | 2710 | if (fifo_stalls > 0xfffff) { |
2592 | DSSERR("fifo stalls overflow, pixels left %d\n", | 2711 | DSSERR("fifo stalls overflow, pixels left %d\n", |
@@ -2594,6 +2713,7 @@ static int dsi_update_screen_l4(struct omap_dss_device *dssdev, | |||
2594 | dsi_if_enable(0); | 2713 | dsi_if_enable(0); |
2595 | return -EIO; | 2714 | return -EIO; |
2596 | } | 2715 | } |
2716 | udelay(1); | ||
2597 | } | 2717 | } |
2598 | #elif 1 | 2718 | #elif 1 |
2599 | /* using fifo emptiness */ | 2719 | /* using fifo emptiness */ |
@@ -2812,11 +2932,15 @@ static int dsi_set_update_mode(struct omap_dss_device *dssdev, | |||
2812 | 2932 | ||
2813 | static int dsi_set_te(struct omap_dss_device *dssdev, bool enable) | 2933 | static int dsi_set_te(struct omap_dss_device *dssdev, bool enable) |
2814 | { | 2934 | { |
2815 | int r; | 2935 | int r = 0; |
2816 | r = dssdev->driver->enable_te(dssdev, enable); | 2936 | |
2817 | /* XXX for some reason, DSI TE breaks if we don't wait here. | 2937 | if (dssdev->driver->enable_te) { |
2818 | * Panel bug? Needs more studying */ | 2938 | r = dssdev->driver->enable_te(dssdev, enable); |
2819 | msleep(100); | 2939 | /* XXX for some reason, DSI TE breaks if we don't wait here. |
2940 | * Panel bug? Needs more studying */ | ||
2941 | msleep(100); | ||
2942 | } | ||
2943 | |||
2820 | return r; | 2944 | return r; |
2821 | } | 2945 | } |
2822 | 2946 | ||
@@ -3637,6 +3761,11 @@ int dsi_init(struct platform_device *pdev) | |||
3637 | spin_lock_init(&dsi.errors_lock); | 3761 | spin_lock_init(&dsi.errors_lock); |
3638 | dsi.errors = 0; | 3762 | dsi.errors = 0; |
3639 | 3763 | ||
3764 | #ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS | ||
3765 | spin_lock_init(&dsi.irq_stats_lock); | ||
3766 | dsi.irq_stats.last_reset = jiffies; | ||
3767 | #endif | ||
3768 | |||
3640 | init_completion(&dsi.bta_completion); | 3769 | init_completion(&dsi.bta_completion); |
3641 | init_completion(&dsi.update_completion); | 3770 | init_completion(&dsi.update_completion); |
3642 | 3771 | ||
diff --git a/drivers/video/omap2/dss/dss.c b/drivers/video/omap2/dss/dss.c index 9b05ee65a15d..0a26b7d84d41 100644 --- a/drivers/video/omap2/dss/dss.c +++ b/drivers/video/omap2/dss/dss.c | |||
@@ -467,14 +467,14 @@ static irqreturn_t dss_irq_handler_omap3(int irq, void *arg) | |||
467 | 467 | ||
468 | static int _omap_dss_wait_reset(void) | 468 | static int _omap_dss_wait_reset(void) |
469 | { | 469 | { |
470 | unsigned timeout = 1000; | 470 | int t = 0; |
471 | 471 | ||
472 | while (REG_GET(DSS_SYSSTATUS, 0, 0) == 0) { | 472 | while (REG_GET(DSS_SYSSTATUS, 0, 0) == 0) { |
473 | udelay(1); | 473 | if (++t > 1000) { |
474 | if (!--timeout) { | ||
475 | DSSERR("soft reset failed\n"); | 474 | DSSERR("soft reset failed\n"); |
476 | return -ENODEV; | 475 | return -ENODEV; |
477 | } | 476 | } |
477 | udelay(1); | ||
478 | } | 478 | } |
479 | 479 | ||
480 | return 0; | 480 | return 0; |
diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h index 8da5ac42151b..2bcb1245d6c2 100644 --- a/drivers/video/omap2/dss/dss.h +++ b/drivers/video/omap2/dss/dss.h | |||
@@ -240,6 +240,7 @@ int dsi_init(struct platform_device *pdev); | |||
240 | void dsi_exit(void); | 240 | void dsi_exit(void); |
241 | 241 | ||
242 | void dsi_dump_clocks(struct seq_file *s); | 242 | void dsi_dump_clocks(struct seq_file *s); |
243 | void dsi_dump_irqs(struct seq_file *s); | ||
243 | void dsi_dump_regs(struct seq_file *s); | 244 | void dsi_dump_regs(struct seq_file *s); |
244 | 245 | ||
245 | void dsi_save_context(void); | 246 | void dsi_save_context(void); |
@@ -268,6 +269,7 @@ int dpi_init_display(struct omap_dss_device *dssdev); | |||
268 | int dispc_init(void); | 269 | int dispc_init(void); |
269 | void dispc_exit(void); | 270 | void dispc_exit(void); |
270 | void dispc_dump_clocks(struct seq_file *s); | 271 | void dispc_dump_clocks(struct seq_file *s); |
272 | void dispc_dump_irqs(struct seq_file *s); | ||
271 | void dispc_dump_regs(struct seq_file *s); | 273 | void dispc_dump_regs(struct seq_file *s); |
272 | void dispc_irq_handler(void); | 274 | void dispc_irq_handler(void); |
273 | void dispc_fake_vsync_irq(void); | 275 | void dispc_fake_vsync_irq(void); |
@@ -367,4 +369,16 @@ void rfbi_set_timings(int rfbi_module, struct rfbi_timings *t); | |||
367 | unsigned long rfbi_get_max_tx_rate(void); | 369 | unsigned long rfbi_get_max_tx_rate(void); |
368 | int rfbi_init_display(struct omap_dss_device *display); | 370 | int rfbi_init_display(struct omap_dss_device *display); |
369 | 371 | ||
372 | |||
373 | #ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS | ||
374 | static inline void dss_collect_irq_stats(u32 irqstatus, unsigned *irq_arr) | ||
375 | { | ||
376 | int b; | ||
377 | for (b = 0; b < 32; ++b) { | ||
378 | if (irqstatus & (1 << b)) | ||
379 | irq_arr[b]++; | ||
380 | } | ||
381 | } | ||
382 | #endif | ||
383 | |||
370 | #endif | 384 | #endif |
diff --git a/drivers/video/omap2/dss/rfbi.c b/drivers/video/omap2/dss/rfbi.c index d0b3006ad8a5..b936495c065d 100644 --- a/drivers/video/omap2/dss/rfbi.c +++ b/drivers/video/omap2/dss/rfbi.c | |||
@@ -120,7 +120,7 @@ static struct { | |||
120 | 120 | ||
121 | struct omap_dss_device *dssdev[2]; | 121 | struct omap_dss_device *dssdev[2]; |
122 | 122 | ||
123 | struct kfifo *cmd_fifo; | 123 | struct kfifo cmd_fifo; |
124 | spinlock_t cmd_lock; | 124 | spinlock_t cmd_lock; |
125 | struct completion cmd_done; | 125 | struct completion cmd_done; |
126 | atomic_t cmd_fifo_full; | 126 | atomic_t cmd_fifo_full; |
@@ -1011,20 +1011,20 @@ static void process_cmd_fifo(void) | |||
1011 | return; | 1011 | return; |
1012 | 1012 | ||
1013 | while (true) { | 1013 | while (true) { |
1014 | spin_lock_irqsave(rfbi.cmd_fifo->lock, flags); | 1014 | spin_lock_irqsave(&rfbi.cmd_lock, flags); |
1015 | 1015 | ||
1016 | len = __kfifo_get(rfbi.cmd_fifo, (unsigned char *)&p, | 1016 | len = kfifo_out(&rfbi.cmd_fifo, (unsigned char *)&p, |
1017 | sizeof(struct update_param)); | 1017 | sizeof(struct update_param)); |
1018 | if (len == 0) { | 1018 | if (len == 0) { |
1019 | DSSDBG("nothing more in fifo\n"); | 1019 | DSSDBG("nothing more in fifo\n"); |
1020 | atomic_set(&rfbi.cmd_pending, 0); | 1020 | atomic_set(&rfbi.cmd_pending, 0); |
1021 | spin_unlock_irqrestore(rfbi.cmd_fifo->lock, flags); | 1021 | spin_unlock_irqrestore(&rfbi.cmd_lock, flags); |
1022 | break; | 1022 | break; |
1023 | } | 1023 | } |
1024 | 1024 | ||
1025 | /* DSSDBG("fifo full %d\n", rfbi.cmd_fifo_full.counter);*/ | 1025 | /* DSSDBG("fifo full %d\n", rfbi.cmd_fifo_full.counter);*/ |
1026 | 1026 | ||
1027 | spin_unlock_irqrestore(rfbi.cmd_fifo->lock, flags); | 1027 | spin_unlock_irqrestore(&rfbi.cmd_lock, flags); |
1028 | 1028 | ||
1029 | BUG_ON(len != sizeof(struct update_param)); | 1029 | BUG_ON(len != sizeof(struct update_param)); |
1030 | BUG_ON(p.rfbi_module > 1); | 1030 | BUG_ON(p.rfbi_module > 1); |
@@ -1052,25 +1052,25 @@ static void rfbi_push_cmd(struct update_param *p) | |||
1052 | unsigned long flags; | 1052 | unsigned long flags; |
1053 | int available; | 1053 | int available; |
1054 | 1054 | ||
1055 | spin_lock_irqsave(rfbi.cmd_fifo->lock, flags); | 1055 | spin_lock_irqsave(&rfbi.cmd_lock, flags); |
1056 | available = RFBI_CMD_FIFO_LEN_BYTES - | 1056 | available = RFBI_CMD_FIFO_LEN_BYTES - |
1057 | __kfifo_len(rfbi.cmd_fifo); | 1057 | kfifo_len(&rfbi.cmd_fifo); |
1058 | 1058 | ||
1059 | /* DSSDBG("%d bytes left in fifo\n", available); */ | 1059 | /* DSSDBG("%d bytes left in fifo\n", available); */ |
1060 | if (available < sizeof(struct update_param)) { | 1060 | if (available < sizeof(struct update_param)) { |
1061 | DSSDBG("Going to wait because FIFO FULL..\n"); | 1061 | DSSDBG("Going to wait because FIFO FULL..\n"); |
1062 | spin_unlock_irqrestore(rfbi.cmd_fifo->lock, flags); | 1062 | spin_unlock_irqrestore(&rfbi.cmd_lock, flags); |
1063 | atomic_inc(&rfbi.cmd_fifo_full); | 1063 | atomic_inc(&rfbi.cmd_fifo_full); |
1064 | wait_for_completion(&rfbi.cmd_done); | 1064 | wait_for_completion(&rfbi.cmd_done); |
1065 | /*DSSDBG("Woke up because fifo not full anymore\n");*/ | 1065 | /*DSSDBG("Woke up because fifo not full anymore\n");*/ |
1066 | continue; | 1066 | continue; |
1067 | } | 1067 | } |
1068 | 1068 | ||
1069 | ret = __kfifo_put(rfbi.cmd_fifo, (unsigned char *)p, | 1069 | ret = kfifo_in(&rfbi.cmd_fifo, (unsigned char *)p, |
1070 | sizeof(struct update_param)); | 1070 | sizeof(struct update_param)); |
1071 | /* DSSDBG("pushed %d bytes\n", ret);*/ | 1071 | /* DSSDBG("pushed %d bytes\n", ret);*/ |
1072 | 1072 | ||
1073 | spin_unlock_irqrestore(rfbi.cmd_fifo->lock, flags); | 1073 | spin_unlock_irqrestore(&rfbi.cmd_lock, flags); |
1074 | 1074 | ||
1075 | BUG_ON(ret != sizeof(struct update_param)); | 1075 | BUG_ON(ret != sizeof(struct update_param)); |
1076 | 1076 | ||
@@ -1155,12 +1155,12 @@ int rfbi_init(void) | |||
1155 | { | 1155 | { |
1156 | u32 rev; | 1156 | u32 rev; |
1157 | u32 l; | 1157 | u32 l; |
1158 | int r; | ||
1158 | 1159 | ||
1159 | spin_lock_init(&rfbi.cmd_lock); | 1160 | spin_lock_init(&rfbi.cmd_lock); |
1160 | rfbi.cmd_fifo = kfifo_alloc(RFBI_CMD_FIFO_LEN_BYTES, GFP_KERNEL, | 1161 | r = kfifo_alloc(&rfbi.cmd_fifo, RFBI_CMD_FIFO_LEN_BYTES, GFP_KERNEL); |
1161 | &rfbi.cmd_lock); | 1162 | if (r) |
1162 | if (IS_ERR(rfbi.cmd_fifo)) | 1163 | return r; |
1163 | return -ENOMEM; | ||
1164 | 1164 | ||
1165 | init_completion(&rfbi.cmd_done); | 1165 | init_completion(&rfbi.cmd_done); |
1166 | atomic_set(&rfbi.cmd_fifo_full, 0); | 1166 | atomic_set(&rfbi.cmd_fifo_full, 0); |
@@ -1196,7 +1196,7 @@ void rfbi_exit(void) | |||
1196 | { | 1196 | { |
1197 | DSSDBG("rfbi_exit\n"); | 1197 | DSSDBG("rfbi_exit\n"); |
1198 | 1198 | ||
1199 | kfifo_free(rfbi.cmd_fifo); | 1199 | kfifo_free(&rfbi.cmd_fifo); |
1200 | 1200 | ||
1201 | iounmap(rfbi.base); | 1201 | iounmap(rfbi.base); |
1202 | } | 1202 | } |
diff --git a/drivers/video/omap2/omapfb/omapfb-main.c b/drivers/video/omap2/omapfb/omapfb-main.c index ef299839858a..d17caef6915a 100644 --- a/drivers/video/omap2/omapfb/omapfb-main.c +++ b/drivers/video/omap2/omapfb/omapfb-main.c | |||
@@ -1311,6 +1311,7 @@ static void omapfb_free_fbmem(struct fb_info *fbi) | |||
1311 | if (rg->vrfb.vaddr[0]) { | 1311 | if (rg->vrfb.vaddr[0]) { |
1312 | iounmap(rg->vrfb.vaddr[0]); | 1312 | iounmap(rg->vrfb.vaddr[0]); |
1313 | omap_vrfb_release_ctx(&rg->vrfb); | 1313 | omap_vrfb_release_ctx(&rg->vrfb); |
1314 | rg->vrfb.vaddr[0] = NULL; | ||
1314 | } | 1315 | } |
1315 | } | 1316 | } |
1316 | 1317 | ||
@@ -2114,6 +2115,11 @@ static int omapfb_probe(struct platform_device *pdev) | |||
2114 | dssdev = NULL; | 2115 | dssdev = NULL; |
2115 | for_each_dss_dev(dssdev) { | 2116 | for_each_dss_dev(dssdev) { |
2116 | omap_dss_get_device(dssdev); | 2117 | omap_dss_get_device(dssdev); |
2118 | if (!dssdev->driver) { | ||
2119 | dev_err(&pdev->dev, "no driver for display\n"); | ||
2120 | r = -EINVAL; | ||
2121 | goto cleanup; | ||
2122 | } | ||
2117 | fbdev->displays[fbdev->num_displays++] = dssdev; | 2123 | fbdev->displays[fbdev->num_displays++] = dssdev; |
2118 | } | 2124 | } |
2119 | 2125 | ||
diff --git a/drivers/video/pxafb.c b/drivers/video/pxafb.c index 415858b421b3..825b665245bb 100644 --- a/drivers/video/pxafb.c +++ b/drivers/video/pxafb.c | |||
@@ -1221,9 +1221,9 @@ static void setup_smart_timing(struct pxafb_info *fbi, | |||
1221 | static int pxafb_smart_thread(void *arg) | 1221 | static int pxafb_smart_thread(void *arg) |
1222 | { | 1222 | { |
1223 | struct pxafb_info *fbi = arg; | 1223 | struct pxafb_info *fbi = arg; |
1224 | struct pxafb_mach_info *inf; | 1224 | struct pxafb_mach_info *inf = fbi->dev->platform_data; |
1225 | 1225 | ||
1226 | if (!fbi || !fbi->dev->platform_data->smart_update) { | 1226 | if (!inf->smart_update) { |
1227 | pr_err("%s: not properly initialized, thread terminated\n", | 1227 | pr_err("%s: not properly initialized, thread terminated\n", |
1228 | __func__); | 1228 | __func__); |
1229 | return -EINVAL; | 1229 | return -EINVAL; |
diff --git a/drivers/video/s3c-fb.c b/drivers/video/s3c-fb.c index adf9632c6b1f..53cb722c45a0 100644 --- a/drivers/video/s3c-fb.c +++ b/drivers/video/s3c-fb.c | |||
@@ -211,21 +211,23 @@ static int s3c_fb_check_var(struct fb_var_screeninfo *var, | |||
211 | 211 | ||
212 | /** | 212 | /** |
213 | * s3c_fb_calc_pixclk() - calculate the divider to create the pixel clock. | 213 | * s3c_fb_calc_pixclk() - calculate the divider to create the pixel clock. |
214 | * @id: window id. | ||
215 | * @sfb: The hardware state. | 214 | * @sfb: The hardware state. |
216 | * @pixclock: The pixel clock wanted, in picoseconds. | 215 | * @pixclock: The pixel clock wanted, in picoseconds. |
217 | * | 216 | * |
218 | * Given the specified pixel clock, work out the necessary divider to get | 217 | * Given the specified pixel clock, work out the necessary divider to get |
219 | * close to the output frequency. | 218 | * close to the output frequency. |
220 | */ | 219 | */ |
221 | static int s3c_fb_calc_pixclk(unsigned char id, struct s3c_fb *sfb, unsigned int pixclk) | 220 | static int s3c_fb_calc_pixclk(struct s3c_fb *sfb, unsigned int pixclk) |
222 | { | 221 | { |
223 | struct s3c_fb_pd_win *win = sfb->pdata->win[id]; | ||
224 | unsigned long clk = clk_get_rate(sfb->bus_clk); | 222 | unsigned long clk = clk_get_rate(sfb->bus_clk); |
223 | unsigned long long tmp; | ||
225 | unsigned int result; | 224 | unsigned int result; |
226 | 225 | ||
227 | pixclk *= win->win_mode.refresh; | 226 | tmp = (unsigned long long)clk; |
228 | result = clk / pixclk; | 227 | tmp *= pixclk; |
228 | |||
229 | do_div(tmp, 1000000000UL); | ||
230 | result = (unsigned int)tmp / 1000; | ||
229 | 231 | ||
230 | dev_dbg(sfb->dev, "pixclk=%u, clk=%lu, div=%d (%lu)\n", | 232 | dev_dbg(sfb->dev, "pixclk=%u, clk=%lu, div=%d (%lu)\n", |
231 | pixclk, clk, result, clk / result); | 233 | pixclk, clk, result, clk / result); |
@@ -301,7 +303,7 @@ static int s3c_fb_set_par(struct fb_info *info) | |||
301 | /* use window 0 as the basis for the lcd output timings */ | 303 | /* use window 0 as the basis for the lcd output timings */ |
302 | 304 | ||
303 | if (win_no == 0) { | 305 | if (win_no == 0) { |
304 | clkdiv = s3c_fb_calc_pixclk(win_no, sfb, var->pixclock); | 306 | clkdiv = s3c_fb_calc_pixclk(sfb, var->pixclock); |
305 | 307 | ||
306 | data = sfb->pdata->vidcon0; | 308 | data = sfb->pdata->vidcon0; |
307 | data &= ~(VIDCON0_CLKVAL_F_MASK | VIDCON0_CLKDIR); | 309 | data &= ~(VIDCON0_CLKVAL_F_MASK | VIDCON0_CLKDIR); |
diff --git a/drivers/video/via/accel.c b/drivers/video/via/accel.c index 9d4f3a49ba4a..d5077dfa9e00 100644 --- a/drivers/video/via/accel.c +++ b/drivers/video/via/accel.c | |||
@@ -137,7 +137,7 @@ static int hw_bitblt_1(void __iomem *engine, u8 op, u32 width, u32 height, | |||
137 | tmp, dst_pitch); | 137 | tmp, dst_pitch); |
138 | return -EINVAL; | 138 | return -EINVAL; |
139 | } | 139 | } |
140 | tmp = (tmp >> 3) | (dst_pitch << (16 - 3)); | 140 | tmp = VIA_PITCH_ENABLE | (tmp >> 3) | (dst_pitch << (16 - 3)); |
141 | writel(tmp, engine + 0x38); | 141 | writel(tmp, engine + 0x38); |
142 | 142 | ||
143 | if (op == VIA_BITBLT_FILL) | 143 | if (op == VIA_BITBLT_FILL) |
@@ -352,6 +352,9 @@ int viafb_init_engine(struct fb_info *info) | |||
352 | viapar->shared->vq_vram_addr = viapar->fbmem_free; | 352 | viapar->shared->vq_vram_addr = viapar->fbmem_free; |
353 | viapar->fbmem_used += VQ_SIZE; | 353 | viapar->fbmem_used += VQ_SIZE; |
354 | 354 | ||
355 | /* Init 2D engine reg to reset 2D engine */ | ||
356 | writel(0x0, engine + VIA_REG_KEYCONTROL); | ||
357 | |||
355 | /* Init AGP and VQ regs */ | 358 | /* Init AGP and VQ regs */ |
356 | switch (chip_name) { | 359 | switch (chip_name) { |
357 | case UNICHROME_K8M890: | 360 | case UNICHROME_K8M890: |
diff --git a/drivers/video/via/viafbdev.c b/drivers/video/via/viafbdev.c index d8df17a7d5fc..3028e7ddc3b5 100644 --- a/drivers/video/via/viafbdev.c +++ b/drivers/video/via/viafbdev.c | |||
@@ -177,16 +177,15 @@ static int viafb_set_par(struct fb_info *info) | |||
177 | } | 177 | } |
178 | 178 | ||
179 | if (vmode_index != VIA_RES_INVALID) { | 179 | if (vmode_index != VIA_RES_INVALID) { |
180 | viafb_setmode(vmode_index, info->var.xres, info->var.yres, | ||
181 | info->var.bits_per_pixel, vmode_index1, | ||
182 | viafb_second_xres, viafb_second_yres, viafb_bpp1); | ||
183 | |||
184 | viafb_update_fix(info); | 180 | viafb_update_fix(info); |
185 | viafb_bpp = info->var.bits_per_pixel; | 181 | viafb_bpp = info->var.bits_per_pixel; |
186 | if (info->var.accel_flags & FB_ACCELF_TEXT) | 182 | if (info->var.accel_flags & FB_ACCELF_TEXT) |
187 | info->flags &= ~FBINFO_HWACCEL_DISABLED; | 183 | info->flags &= ~FBINFO_HWACCEL_DISABLED; |
188 | else | 184 | else |
189 | info->flags |= FBINFO_HWACCEL_DISABLED; | 185 | info->flags |= FBINFO_HWACCEL_DISABLED; |
186 | viafb_setmode(vmode_index, info->var.xres, info->var.yres, | ||
187 | info->var.bits_per_pixel, vmode_index1, | ||
188 | viafb_second_xres, viafb_second_yres, viafb_bpp1); | ||
190 | } | 189 | } |
191 | 190 | ||
192 | return 0; | 191 | return 0; |
@@ -872,7 +871,9 @@ static int viafb_cursor(struct fb_info *info, struct fb_cursor *cursor) | |||
872 | if (info->flags & FBINFO_HWACCEL_DISABLED || info != viafbinfo) | 871 | if (info->flags & FBINFO_HWACCEL_DISABLED || info != viafbinfo) |
873 | return -ENODEV; | 872 | return -ENODEV; |
874 | 873 | ||
875 | if (chip_name == UNICHROME_CLE266 && viapar->iga_path == IGA2) | 874 | /* LCD ouput does not support hw cursors (at least on VN896) */ |
875 | if ((chip_name == UNICHROME_CLE266 && viapar->iga_path == IGA2) || | ||
876 | viafb_LCD_ON) | ||
876 | return -ENODEV; | 877 | return -ENODEV; |
877 | 878 | ||
878 | viafb_show_hw_cursor(info, HW_Cursor_OFF); | 879 | viafb_show_hw_cursor(info, HW_Cursor_OFF); |
diff --git a/drivers/virtio/virtio_balloon.c b/drivers/virtio/virtio_balloon.c index 9dd588042880..505be88c82ae 100644 --- a/drivers/virtio/virtio_balloon.c +++ b/drivers/virtio/virtio_balloon.c | |||
@@ -266,7 +266,7 @@ static void __devexit virtballoon_remove(struct virtio_device *vdev) | |||
266 | 266 | ||
267 | static unsigned int features[] = { VIRTIO_BALLOON_F_MUST_TELL_HOST }; | 267 | static unsigned int features[] = { VIRTIO_BALLOON_F_MUST_TELL_HOST }; |
268 | 268 | ||
269 | static struct virtio_driver virtio_balloon = { | 269 | static struct virtio_driver virtio_balloon_driver = { |
270 | .feature_table = features, | 270 | .feature_table = features, |
271 | .feature_table_size = ARRAY_SIZE(features), | 271 | .feature_table_size = ARRAY_SIZE(features), |
272 | .driver.name = KBUILD_MODNAME, | 272 | .driver.name = KBUILD_MODNAME, |
@@ -279,12 +279,12 @@ static struct virtio_driver virtio_balloon = { | |||
279 | 279 | ||
280 | static int __init init(void) | 280 | static int __init init(void) |
281 | { | 281 | { |
282 | return register_virtio_driver(&virtio_balloon); | 282 | return register_virtio_driver(&virtio_balloon_driver); |
283 | } | 283 | } |
284 | 284 | ||
285 | static void __exit fini(void) | 285 | static void __exit fini(void) |
286 | { | 286 | { |
287 | unregister_virtio_driver(&virtio_balloon); | 287 | unregister_virtio_driver(&virtio_balloon_driver); |
288 | } | 288 | } |
289 | module_init(init); | 289 | module_init(init); |
290 | module_exit(fini); | 290 | module_exit(fini); |
diff --git a/drivers/watchdog/iTCO_wdt.c b/drivers/watchdog/iTCO_wdt.c index c8a3bec26830..4bdb7f1a9077 100644 --- a/drivers/watchdog/iTCO_wdt.c +++ b/drivers/watchdog/iTCO_wdt.c | |||
@@ -29,8 +29,9 @@ | |||
29 | * document number 313056-003, 313057-017: 82801H (ICH8) | 29 | * document number 313056-003, 313057-017: 82801H (ICH8) |
30 | * document number 316972-004, 316973-012: 82801I (ICH9) | 30 | * document number 316972-004, 316973-012: 82801I (ICH9) |
31 | * document number 319973-002, 319974-002: 82801J (ICH10) | 31 | * document number 319973-002, 319974-002: 82801J (ICH10) |
32 | * document number 322169-001, 322170-001: 5 Series, 3400 Series (PCH) | 32 | * document number 322169-001, 322170-003: 5 Series, 3400 Series (PCH) |
33 | * document number 320066-003, 320257-008: EP80597 (IICH) | 33 | * document number 320066-003, 320257-008: EP80597 (IICH) |
34 | * document number TBD : Cougar Point (CPT) | ||
34 | */ | 35 | */ |
35 | 36 | ||
36 | /* | 37 | /* |
@@ -100,8 +101,22 @@ enum iTCO_chipsets { | |||
100 | TCO_ICH10DO, /* ICH10DO */ | 101 | TCO_ICH10DO, /* ICH10DO */ |
101 | TCO_PCH, /* PCH Desktop Full Featured */ | 102 | TCO_PCH, /* PCH Desktop Full Featured */ |
102 | TCO_PCHM, /* PCH Mobile Full Featured */ | 103 | TCO_PCHM, /* PCH Mobile Full Featured */ |
104 | TCO_P55, /* P55 */ | ||
105 | TCO_PM55, /* PM55 */ | ||
106 | TCO_H55, /* H55 */ | ||
107 | TCO_QM57, /* QM57 */ | ||
108 | TCO_H57, /* H57 */ | ||
109 | TCO_HM55, /* HM55 */ | ||
110 | TCO_Q57, /* Q57 */ | ||
111 | TCO_HM57, /* HM57 */ | ||
103 | TCO_PCHMSFF, /* PCH Mobile SFF Full Featured */ | 112 | TCO_PCHMSFF, /* PCH Mobile SFF Full Featured */ |
113 | TCO_QS57, /* QS57 */ | ||
114 | TCO_3400, /* 3400 */ | ||
115 | TCO_3420, /* 3420 */ | ||
116 | TCO_3450, /* 3450 */ | ||
104 | TCO_EP80579, /* EP80579 */ | 117 | TCO_EP80579, /* EP80579 */ |
118 | TCO_CPTD, /* CPT Desktop */ | ||
119 | TCO_CPTM, /* CPT Mobile */ | ||
105 | }; | 120 | }; |
106 | 121 | ||
107 | static struct { | 122 | static struct { |
@@ -144,8 +159,22 @@ static struct { | |||
144 | {"ICH10DO", 2}, | 159 | {"ICH10DO", 2}, |
145 | {"PCH Desktop Full Featured", 2}, | 160 | {"PCH Desktop Full Featured", 2}, |
146 | {"PCH Mobile Full Featured", 2}, | 161 | {"PCH Mobile Full Featured", 2}, |
162 | {"P55", 2}, | ||
163 | {"PM55", 2}, | ||
164 | {"H55", 2}, | ||
165 | {"QM57", 2}, | ||
166 | {"H57", 2}, | ||
167 | {"HM55", 2}, | ||
168 | {"Q57", 2}, | ||
169 | {"HM57", 2}, | ||
147 | {"PCH Mobile SFF Full Featured", 2}, | 170 | {"PCH Mobile SFF Full Featured", 2}, |
171 | {"QS57", 2}, | ||
172 | {"3400", 2}, | ||
173 | {"3420", 2}, | ||
174 | {"3450", 2}, | ||
148 | {"EP80579", 2}, | 175 | {"EP80579", 2}, |
176 | {"CPT Desktop", 2}, | ||
177 | {"CPT Mobile", 2}, | ||
149 | {NULL, 0} | 178 | {NULL, 0} |
150 | }; | 179 | }; |
151 | 180 | ||
@@ -216,8 +245,22 @@ static struct pci_device_id iTCO_wdt_pci_tbl[] = { | |||
216 | { ITCO_PCI_DEVICE(0x3a14, TCO_ICH10DO)}, | 245 | { ITCO_PCI_DEVICE(0x3a14, TCO_ICH10DO)}, |
217 | { ITCO_PCI_DEVICE(0x3b00, TCO_PCH)}, | 246 | { ITCO_PCI_DEVICE(0x3b00, TCO_PCH)}, |
218 | { ITCO_PCI_DEVICE(0x3b01, TCO_PCHM)}, | 247 | { ITCO_PCI_DEVICE(0x3b01, TCO_PCHM)}, |
248 | { ITCO_PCI_DEVICE(0x3b02, TCO_P55)}, | ||
249 | { ITCO_PCI_DEVICE(0x3b03, TCO_PM55)}, | ||
250 | { ITCO_PCI_DEVICE(0x3b06, TCO_H55)}, | ||
251 | { ITCO_PCI_DEVICE(0x3b07, TCO_QM57)}, | ||
252 | { ITCO_PCI_DEVICE(0x3b08, TCO_H57)}, | ||
253 | { ITCO_PCI_DEVICE(0x3b09, TCO_HM55)}, | ||
254 | { ITCO_PCI_DEVICE(0x3b0a, TCO_Q57)}, | ||
255 | { ITCO_PCI_DEVICE(0x3b0b, TCO_HM57)}, | ||
219 | { ITCO_PCI_DEVICE(0x3b0d, TCO_PCHMSFF)}, | 256 | { ITCO_PCI_DEVICE(0x3b0d, TCO_PCHMSFF)}, |
257 | { ITCO_PCI_DEVICE(0x3b0f, TCO_QS57)}, | ||
258 | { ITCO_PCI_DEVICE(0x3b12, TCO_3400)}, | ||
259 | { ITCO_PCI_DEVICE(0x3b14, TCO_3420)}, | ||
260 | { ITCO_PCI_DEVICE(0x3b16, TCO_3450)}, | ||
220 | { ITCO_PCI_DEVICE(0x5031, TCO_EP80579)}, | 261 | { ITCO_PCI_DEVICE(0x5031, TCO_EP80579)}, |
262 | { ITCO_PCI_DEVICE(0x1c42, TCO_CPTD)}, | ||
263 | { ITCO_PCI_DEVICE(0x1c43, TCO_CPTM)}, | ||
221 | { 0, }, /* End of list */ | 264 | { 0, }, /* End of list */ |
222 | }; | 265 | }; |
223 | MODULE_DEVICE_TABLE(pci, iTCO_wdt_pci_tbl); | 266 | MODULE_DEVICE_TABLE(pci, iTCO_wdt_pci_tbl); |
diff --git a/drivers/xen/manage.c b/drivers/xen/manage.c index c4997930afc7..5d42d55e299b 100644 --- a/drivers/xen/manage.c +++ b/drivers/xen/manage.c | |||
@@ -102,15 +102,15 @@ static void do_suspend(void) | |||
102 | goto out_thaw; | 102 | goto out_thaw; |
103 | } | 103 | } |
104 | 104 | ||
105 | printk(KERN_DEBUG "suspending xenstore...\n"); | ||
106 | xs_suspend(); | ||
107 | |||
105 | err = dpm_suspend_noirq(PMSG_SUSPEND); | 108 | err = dpm_suspend_noirq(PMSG_SUSPEND); |
106 | if (err) { | 109 | if (err) { |
107 | printk(KERN_ERR "dpm_suspend_noirq failed: %d\n", err); | 110 | printk(KERN_ERR "dpm_suspend_noirq failed: %d\n", err); |
108 | goto out_resume; | 111 | goto out_resume; |
109 | } | 112 | } |
110 | 113 | ||
111 | printk(KERN_DEBUG "suspending xenstore...\n"); | ||
112 | xs_suspend(); | ||
113 | |||
114 | err = stop_machine(xen_suspend, &cancelled, cpumask_of(0)); | 114 | err = stop_machine(xen_suspend, &cancelled, cpumask_of(0)); |
115 | 115 | ||
116 | dpm_resume_noirq(PMSG_RESUME); | 116 | dpm_resume_noirq(PMSG_RESUME); |
@@ -120,13 +120,13 @@ static void do_suspend(void) | |||
120 | cancelled = 1; | 120 | cancelled = 1; |
121 | } | 121 | } |
122 | 122 | ||
123 | out_resume: | ||
123 | if (!cancelled) { | 124 | if (!cancelled) { |
124 | xen_arch_resume(); | 125 | xen_arch_resume(); |
125 | xs_resume(); | 126 | xs_resume(); |
126 | } else | 127 | } else |
127 | xs_suspend_cancel(); | 128 | xs_suspend_cancel(); |
128 | 129 | ||
129 | out_resume: | ||
130 | dpm_resume_end(PMSG_RESUME); | 130 | dpm_resume_end(PMSG_RESUME); |
131 | 131 | ||
132 | /* Make sure timer events get retriggered on all CPUs */ | 132 | /* Make sure timer events get retriggered on all CPUs */ |