diff options
author | David S. Miller <davem@davemloft.net> | 2011-12-02 13:49:21 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2011-12-02 13:49:21 -0500 |
commit | b3613118eb30a589d971e4eccbbb2a1314f5dfd4 (patch) | |
tree | 868c1ee59e1b5c19a4f2e43716400d0001a994e5 /drivers | |
parent | 7505afe28c16a8d386624930a018d0052c75d687 (diff) | |
parent | 5983fe2b29df5885880d7fa3b91aca306c7564ef (diff) |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net
Diffstat (limited to 'drivers')
163 files changed, 1989 insertions, 1705 deletions
diff --git a/drivers/acpi/apei/erst.c b/drivers/acpi/apei/erst.c index 127408069ca7..631b9477b99c 100644 --- a/drivers/acpi/apei/erst.c +++ b/drivers/acpi/apei/erst.c | |||
@@ -932,7 +932,8 @@ static int erst_check_table(struct acpi_table_erst *erst_tab) | |||
932 | static int erst_open_pstore(struct pstore_info *psi); | 932 | static int erst_open_pstore(struct pstore_info *psi); |
933 | static int erst_close_pstore(struct pstore_info *psi); | 933 | static int erst_close_pstore(struct pstore_info *psi); |
934 | static ssize_t erst_reader(u64 *id, enum pstore_type_id *type, | 934 | static ssize_t erst_reader(u64 *id, enum pstore_type_id *type, |
935 | struct timespec *time, struct pstore_info *psi); | 935 | struct timespec *time, char **buf, |
936 | struct pstore_info *psi); | ||
936 | static int erst_writer(enum pstore_type_id type, u64 *id, unsigned int part, | 937 | static int erst_writer(enum pstore_type_id type, u64 *id, unsigned int part, |
937 | size_t size, struct pstore_info *psi); | 938 | size_t size, struct pstore_info *psi); |
938 | static int erst_clearer(enum pstore_type_id type, u64 id, | 939 | static int erst_clearer(enum pstore_type_id type, u64 id, |
@@ -986,17 +987,23 @@ static int erst_close_pstore(struct pstore_info *psi) | |||
986 | } | 987 | } |
987 | 988 | ||
988 | static ssize_t erst_reader(u64 *id, enum pstore_type_id *type, | 989 | static ssize_t erst_reader(u64 *id, enum pstore_type_id *type, |
989 | struct timespec *time, struct pstore_info *psi) | 990 | struct timespec *time, char **buf, |
991 | struct pstore_info *psi) | ||
990 | { | 992 | { |
991 | int rc; | 993 | int rc; |
992 | ssize_t len = 0; | 994 | ssize_t len = 0; |
993 | u64 record_id; | 995 | u64 record_id; |
994 | struct cper_pstore_record *rcd = (struct cper_pstore_record *) | 996 | struct cper_pstore_record *rcd; |
995 | (erst_info.buf - sizeof(*rcd)); | 997 | size_t rcd_len = sizeof(*rcd) + erst_info.bufsize; |
996 | 998 | ||
997 | if (erst_disable) | 999 | if (erst_disable) |
998 | return -ENODEV; | 1000 | return -ENODEV; |
999 | 1001 | ||
1002 | rcd = kmalloc(rcd_len, GFP_KERNEL); | ||
1003 | if (!rcd) { | ||
1004 | rc = -ENOMEM; | ||
1005 | goto out; | ||
1006 | } | ||
1000 | skip: | 1007 | skip: |
1001 | rc = erst_get_record_id_next(&reader_pos, &record_id); | 1008 | rc = erst_get_record_id_next(&reader_pos, &record_id); |
1002 | if (rc) | 1009 | if (rc) |
@@ -1004,22 +1011,27 @@ skip: | |||
1004 | 1011 | ||
1005 | /* no more record */ | 1012 | /* no more record */ |
1006 | if (record_id == APEI_ERST_INVALID_RECORD_ID) { | 1013 | if (record_id == APEI_ERST_INVALID_RECORD_ID) { |
1007 | rc = -1; | 1014 | rc = -EINVAL; |
1008 | goto out; | 1015 | goto out; |
1009 | } | 1016 | } |
1010 | 1017 | ||
1011 | len = erst_read(record_id, &rcd->hdr, sizeof(*rcd) + | 1018 | len = erst_read(record_id, &rcd->hdr, rcd_len); |
1012 | erst_info.bufsize); | ||
1013 | /* The record may be cleared by others, try read next record */ | 1019 | /* The record may be cleared by others, try read next record */ |
1014 | if (len == -ENOENT) | 1020 | if (len == -ENOENT) |
1015 | goto skip; | 1021 | goto skip; |
1016 | else if (len < 0) { | 1022 | else if (len < sizeof(*rcd)) { |
1017 | rc = -1; | 1023 | rc = -EIO; |
1018 | goto out; | 1024 | goto out; |
1019 | } | 1025 | } |
1020 | if (uuid_le_cmp(rcd->hdr.creator_id, CPER_CREATOR_PSTORE) != 0) | 1026 | if (uuid_le_cmp(rcd->hdr.creator_id, CPER_CREATOR_PSTORE) != 0) |
1021 | goto skip; | 1027 | goto skip; |
1022 | 1028 | ||
1029 | *buf = kmalloc(len, GFP_KERNEL); | ||
1030 | if (*buf == NULL) { | ||
1031 | rc = -ENOMEM; | ||
1032 | goto out; | ||
1033 | } | ||
1034 | memcpy(*buf, rcd->data, len - sizeof(*rcd)); | ||
1023 | *id = record_id; | 1035 | *id = record_id; |
1024 | if (uuid_le_cmp(rcd->sec_hdr.section_type, | 1036 | if (uuid_le_cmp(rcd->sec_hdr.section_type, |
1025 | CPER_SECTION_TYPE_DMESG) == 0) | 1037 | CPER_SECTION_TYPE_DMESG) == 0) |
@@ -1037,6 +1049,7 @@ skip: | |||
1037 | time->tv_nsec = 0; | 1049 | time->tv_nsec = 0; |
1038 | 1050 | ||
1039 | out: | 1051 | out: |
1052 | kfree(rcd); | ||
1040 | return (rc < 0) ? rc : (len - sizeof(*rcd)); | 1053 | return (rc < 0) ? rc : (len - sizeof(*rcd)); |
1041 | } | 1054 | } |
1042 | 1055 | ||
diff --git a/drivers/ata/ahci_platform.c b/drivers/ata/ahci_platform.c index ec555951176e..43b875810d1b 100644 --- a/drivers/ata/ahci_platform.c +++ b/drivers/ata/ahci_platform.c | |||
@@ -67,7 +67,7 @@ static int __init ahci_probe(struct platform_device *pdev) | |||
67 | struct device *dev = &pdev->dev; | 67 | struct device *dev = &pdev->dev; |
68 | struct ahci_platform_data *pdata = dev_get_platdata(dev); | 68 | struct ahci_platform_data *pdata = dev_get_platdata(dev); |
69 | const struct platform_device_id *id = platform_get_device_id(pdev); | 69 | const struct platform_device_id *id = platform_get_device_id(pdev); |
70 | struct ata_port_info pi = ahci_port_info[id->driver_data]; | 70 | struct ata_port_info pi = ahci_port_info[id ? id->driver_data : 0]; |
71 | const struct ata_port_info *ppi[] = { &pi, NULL }; | 71 | const struct ata_port_info *ppi[] = { &pi, NULL }; |
72 | struct ahci_host_priv *hpriv; | 72 | struct ahci_host_priv *hpriv; |
73 | struct ata_host *host; | 73 | struct ata_host *host; |
diff --git a/drivers/ata/libata-sff.c b/drivers/ata/libata-sff.c index 63d53277d6a9..4cadfa28f940 100644 --- a/drivers/ata/libata-sff.c +++ b/drivers/ata/libata-sff.c | |||
@@ -2533,10 +2533,12 @@ static int ata_pci_init_one(struct pci_dev *pdev, | |||
2533 | if (rc) | 2533 | if (rc) |
2534 | goto out; | 2534 | goto out; |
2535 | 2535 | ||
2536 | #ifdef CONFIG_ATA_BMDMA | ||
2536 | if (bmdma) | 2537 | if (bmdma) |
2537 | /* prepare and activate BMDMA host */ | 2538 | /* prepare and activate BMDMA host */ |
2538 | rc = ata_pci_bmdma_prepare_host(pdev, ppi, &host); | 2539 | rc = ata_pci_bmdma_prepare_host(pdev, ppi, &host); |
2539 | else | 2540 | else |
2541 | #endif | ||
2540 | /* prepare and activate SFF host */ | 2542 | /* prepare and activate SFF host */ |
2541 | rc = ata_pci_sff_prepare_host(pdev, ppi, &host); | 2543 | rc = ata_pci_sff_prepare_host(pdev, ppi, &host); |
2542 | if (rc) | 2544 | if (rc) |
@@ -2544,10 +2546,12 @@ static int ata_pci_init_one(struct pci_dev *pdev, | |||
2544 | host->private_data = host_priv; | 2546 | host->private_data = host_priv; |
2545 | host->flags |= hflags; | 2547 | host->flags |= hflags; |
2546 | 2548 | ||
2549 | #ifdef CONFIG_ATA_BMDMA | ||
2547 | if (bmdma) { | 2550 | if (bmdma) { |
2548 | pci_set_master(pdev); | 2551 | pci_set_master(pdev); |
2549 | rc = ata_pci_sff_activate_host(host, ata_bmdma_interrupt, sht); | 2552 | rc = ata_pci_sff_activate_host(host, ata_bmdma_interrupt, sht); |
2550 | } else | 2553 | } else |
2554 | #endif | ||
2551 | rc = ata_pci_sff_activate_host(host, ata_sff_interrupt, sht); | 2555 | rc = ata_pci_sff_activate_host(host, ata_sff_interrupt, sht); |
2552 | out: | 2556 | out: |
2553 | if (rc == 0) | 2557 | if (rc == 0) |
diff --git a/drivers/base/node.c b/drivers/base/node.c index 793f796c4da3..5693ecee9a40 100644 --- a/drivers/base/node.c +++ b/drivers/base/node.c | |||
@@ -127,12 +127,13 @@ static ssize_t node_read_meminfo(struct sys_device * dev, | |||
127 | nid, K(node_page_state(nid, NR_WRITEBACK)), | 127 | nid, K(node_page_state(nid, NR_WRITEBACK)), |
128 | nid, K(node_page_state(nid, NR_FILE_PAGES)), | 128 | nid, K(node_page_state(nid, NR_FILE_PAGES)), |
129 | nid, K(node_page_state(nid, NR_FILE_MAPPED)), | 129 | nid, K(node_page_state(nid, NR_FILE_MAPPED)), |
130 | nid, K(node_page_state(nid, NR_ANON_PAGES) | ||
131 | #ifdef CONFIG_TRANSPARENT_HUGEPAGE | 130 | #ifdef CONFIG_TRANSPARENT_HUGEPAGE |
131 | nid, K(node_page_state(nid, NR_ANON_PAGES) | ||
132 | + node_page_state(nid, NR_ANON_TRANSPARENT_HUGEPAGES) * | 132 | + node_page_state(nid, NR_ANON_TRANSPARENT_HUGEPAGES) * |
133 | HPAGE_PMD_NR | 133 | HPAGE_PMD_NR), |
134 | #else | ||
135 | nid, K(node_page_state(nid, NR_ANON_PAGES)), | ||
134 | #endif | 136 | #endif |
135 | ), | ||
136 | nid, K(node_page_state(nid, NR_SHMEM)), | 137 | nid, K(node_page_state(nid, NR_SHMEM)), |
137 | nid, node_page_state(nid, NR_KERNEL_STACK) * | 138 | nid, node_page_state(nid, NR_KERNEL_STACK) * |
138 | THREAD_SIZE / 1024, | 139 | THREAD_SIZE / 1024, |
@@ -143,13 +144,14 @@ static ssize_t node_read_meminfo(struct sys_device * dev, | |||
143 | nid, K(node_page_state(nid, NR_SLAB_RECLAIMABLE) + | 144 | nid, K(node_page_state(nid, NR_SLAB_RECLAIMABLE) + |
144 | node_page_state(nid, NR_SLAB_UNRECLAIMABLE)), | 145 | node_page_state(nid, NR_SLAB_UNRECLAIMABLE)), |
145 | nid, K(node_page_state(nid, NR_SLAB_RECLAIMABLE)), | 146 | nid, K(node_page_state(nid, NR_SLAB_RECLAIMABLE)), |
146 | nid, K(node_page_state(nid, NR_SLAB_UNRECLAIMABLE)) | ||
147 | #ifdef CONFIG_TRANSPARENT_HUGEPAGE | 147 | #ifdef CONFIG_TRANSPARENT_HUGEPAGE |
148 | nid, K(node_page_state(nid, NR_SLAB_UNRECLAIMABLE)) | ||
148 | , nid, | 149 | , nid, |
149 | K(node_page_state(nid, NR_ANON_TRANSPARENT_HUGEPAGES) * | 150 | K(node_page_state(nid, NR_ANON_TRANSPARENT_HUGEPAGES) * |
150 | HPAGE_PMD_NR) | 151 | HPAGE_PMD_NR)); |
152 | #else | ||
153 | nid, K(node_page_state(nid, NR_SLAB_UNRECLAIMABLE))); | ||
151 | #endif | 154 | #endif |
152 | ); | ||
153 | n += hugetlb_report_node_meminfo(nid, buf + n); | 155 | n += hugetlb_report_node_meminfo(nid, buf + n); |
154 | return n; | 156 | return n; |
155 | } | 157 | } |
diff --git a/drivers/crypto/mv_cesa.c b/drivers/crypto/mv_cesa.c index 5c6f56f21443..dcd8babae9eb 100644 --- a/drivers/crypto/mv_cesa.c +++ b/drivers/crypto/mv_cesa.c | |||
@@ -343,11 +343,13 @@ static void mv_process_hash_current(int first_block) | |||
343 | else | 343 | else |
344 | op.config |= CFG_MID_FRAG; | 344 | op.config |= CFG_MID_FRAG; |
345 | 345 | ||
346 | writel(req_ctx->state[0], cpg->reg + DIGEST_INITIAL_VAL_A); | 346 | if (first_block) { |
347 | writel(req_ctx->state[1], cpg->reg + DIGEST_INITIAL_VAL_B); | 347 | writel(req_ctx->state[0], cpg->reg + DIGEST_INITIAL_VAL_A); |
348 | writel(req_ctx->state[2], cpg->reg + DIGEST_INITIAL_VAL_C); | 348 | writel(req_ctx->state[1], cpg->reg + DIGEST_INITIAL_VAL_B); |
349 | writel(req_ctx->state[3], cpg->reg + DIGEST_INITIAL_VAL_D); | 349 | writel(req_ctx->state[2], cpg->reg + DIGEST_INITIAL_VAL_C); |
350 | writel(req_ctx->state[4], cpg->reg + DIGEST_INITIAL_VAL_E); | 350 | writel(req_ctx->state[3], cpg->reg + DIGEST_INITIAL_VAL_D); |
351 | writel(req_ctx->state[4], cpg->reg + DIGEST_INITIAL_VAL_E); | ||
352 | } | ||
351 | } | 353 | } |
352 | 354 | ||
353 | memcpy(cpg->sram + SRAM_CONFIG, &op, sizeof(struct sec_accel_config)); | 355 | memcpy(cpg->sram + SRAM_CONFIG, &op, sizeof(struct sec_accel_config)); |
diff --git a/drivers/edac/mpc85xx_edac.c b/drivers/edac/mpc85xx_edac.c index 8af8e864a9cf..73464a62adf7 100644 --- a/drivers/edac/mpc85xx_edac.c +++ b/drivers/edac/mpc85xx_edac.c | |||
@@ -1128,7 +1128,7 @@ static struct of_device_id mpc85xx_mc_err_of_match[] = { | |||
1128 | { .compatible = "fsl,p1020-memory-controller", }, | 1128 | { .compatible = "fsl,p1020-memory-controller", }, |
1129 | { .compatible = "fsl,p1021-memory-controller", }, | 1129 | { .compatible = "fsl,p1021-memory-controller", }, |
1130 | { .compatible = "fsl,p2020-memory-controller", }, | 1130 | { .compatible = "fsl,p2020-memory-controller", }, |
1131 | { .compatible = "fsl,p4080-memory-controller", }, | 1131 | { .compatible = "fsl,qoriq-memory-controller", }, |
1132 | {}, | 1132 | {}, |
1133 | }; | 1133 | }; |
1134 | MODULE_DEVICE_TABLE(of, mpc85xx_mc_err_of_match); | 1134 | MODULE_DEVICE_TABLE(of, mpc85xx_mc_err_of_match); |
diff --git a/drivers/firmware/efivars.c b/drivers/firmware/efivars.c index 8370f72d87ff..b0a81173a268 100644 --- a/drivers/firmware/efivars.c +++ b/drivers/firmware/efivars.c | |||
@@ -457,7 +457,8 @@ static int efi_pstore_close(struct pstore_info *psi) | |||
457 | } | 457 | } |
458 | 458 | ||
459 | static ssize_t efi_pstore_read(u64 *id, enum pstore_type_id *type, | 459 | static ssize_t efi_pstore_read(u64 *id, enum pstore_type_id *type, |
460 | struct timespec *timespec, struct pstore_info *psi) | 460 | struct timespec *timespec, |
461 | char **buf, struct pstore_info *psi) | ||
461 | { | 462 | { |
462 | efi_guid_t vendor = LINUX_EFI_CRASH_GUID; | 463 | efi_guid_t vendor = LINUX_EFI_CRASH_GUID; |
463 | struct efivars *efivars = psi->data; | 464 | struct efivars *efivars = psi->data; |
@@ -478,7 +479,11 @@ static ssize_t efi_pstore_read(u64 *id, enum pstore_type_id *type, | |||
478 | timespec->tv_nsec = 0; | 479 | timespec->tv_nsec = 0; |
479 | get_var_data_locked(efivars, &efivars->walk_entry->var); | 480 | get_var_data_locked(efivars, &efivars->walk_entry->var); |
480 | size = efivars->walk_entry->var.DataSize; | 481 | size = efivars->walk_entry->var.DataSize; |
481 | memcpy(psi->buf, efivars->walk_entry->var.Data, size); | 482 | *buf = kmalloc(size, GFP_KERNEL); |
483 | if (*buf == NULL) | ||
484 | return -ENOMEM; | ||
485 | memcpy(*buf, efivars->walk_entry->var.Data, | ||
486 | size); | ||
482 | efivars->walk_entry = list_entry(efivars->walk_entry->list.next, | 487 | efivars->walk_entry = list_entry(efivars->walk_entry->list.next, |
483 | struct efivar_entry, list); | 488 | struct efivar_entry, list); |
484 | return size; | 489 | return size; |
@@ -576,7 +581,8 @@ static int efi_pstore_close(struct pstore_info *psi) | |||
576 | } | 581 | } |
577 | 582 | ||
578 | static ssize_t efi_pstore_read(u64 *id, enum pstore_type_id *type, | 583 | static ssize_t efi_pstore_read(u64 *id, enum pstore_type_id *type, |
579 | struct timespec *time, struct pstore_info *psi) | 584 | struct timespec *timespec, |
585 | char **buf, struct pstore_info *psi) | ||
580 | { | 586 | { |
581 | return -1; | 587 | return -1; |
582 | } | 588 | } |
diff --git a/drivers/gpio/gpio-pca953x.c b/drivers/gpio/gpio-pca953x.c index 147df8ae79db..d3f3e8f54561 100644 --- a/drivers/gpio/gpio-pca953x.c +++ b/drivers/gpio/gpio-pca953x.c | |||
@@ -546,7 +546,7 @@ static void pca953x_irq_teardown(struct pca953x_chip *chip) | |||
546 | * Translate OpenFirmware node properties into platform_data | 546 | * Translate OpenFirmware node properties into platform_data |
547 | * WARNING: This is DEPRECATED and will be removed eventually! | 547 | * WARNING: This is DEPRECATED and will be removed eventually! |
548 | */ | 548 | */ |
549 | void | 549 | static void |
550 | pca953x_get_alt_pdata(struct i2c_client *client, int *gpio_base, int *invert) | 550 | pca953x_get_alt_pdata(struct i2c_client *client, int *gpio_base, int *invert) |
551 | { | 551 | { |
552 | struct device_node *node; | 552 | struct device_node *node; |
@@ -574,7 +574,7 @@ pca953x_get_alt_pdata(struct i2c_client *client, int *gpio_base, int *invert) | |||
574 | *invert = *val; | 574 | *invert = *val; |
575 | } | 575 | } |
576 | #else | 576 | #else |
577 | void | 577 | static void |
578 | pca953x_get_alt_pdata(struct i2c_client *client, int *gpio_base, int *invert) | 578 | pca953x_get_alt_pdata(struct i2c_client *client, int *gpio_base, int *invert) |
579 | { | 579 | { |
580 | *gpio_base = -1; | 580 | *gpio_base = -1; |
diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c index 405c63b9d539..8323fc389840 100644 --- a/drivers/gpu/drm/drm_crtc.c +++ b/drivers/gpu/drm/drm_crtc.c | |||
@@ -1873,6 +1873,10 @@ int drm_mode_dirtyfb_ioctl(struct drm_device *dev, | |||
1873 | } | 1873 | } |
1874 | 1874 | ||
1875 | if (num_clips && clips_ptr) { | 1875 | if (num_clips && clips_ptr) { |
1876 | if (num_clips < 0 || num_clips > DRM_MODE_FB_DIRTY_MAX_CLIPS) { | ||
1877 | ret = -EINVAL; | ||
1878 | goto out_err1; | ||
1879 | } | ||
1876 | clips = kzalloc(num_clips * sizeof(*clips), GFP_KERNEL); | 1880 | clips = kzalloc(num_clips * sizeof(*clips), GFP_KERNEL); |
1877 | if (!clips) { | 1881 | if (!clips) { |
1878 | ret = -ENOMEM; | 1882 | ret = -ENOMEM; |
diff --git a/drivers/gpu/drm/exynos/exynos_drm_buf.c b/drivers/gpu/drm/exynos/exynos_drm_buf.c index 6f8afea94fc9..2bb07bca511a 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_buf.c +++ b/drivers/gpu/drm/exynos/exynos_drm_buf.c | |||
@@ -27,82 +27,84 @@ | |||
27 | #include "drm.h" | 27 | #include "drm.h" |
28 | 28 | ||
29 | #include "exynos_drm_drv.h" | 29 | #include "exynos_drm_drv.h" |
30 | #include "exynos_drm_gem.h" | ||
30 | #include "exynos_drm_buf.h" | 31 | #include "exynos_drm_buf.h" |
31 | 32 | ||
32 | static DEFINE_MUTEX(exynos_drm_buf_lock); | ||
33 | |||
34 | static int lowlevel_buffer_allocate(struct drm_device *dev, | 33 | static int lowlevel_buffer_allocate(struct drm_device *dev, |
35 | struct exynos_drm_buf_entry *entry) | 34 | struct exynos_drm_gem_buf *buffer) |
36 | { | 35 | { |
37 | DRM_DEBUG_KMS("%s\n", __FILE__); | 36 | DRM_DEBUG_KMS("%s\n", __FILE__); |
38 | 37 | ||
39 | entry->vaddr = dma_alloc_writecombine(dev->dev, entry->size, | 38 | buffer->kvaddr = dma_alloc_writecombine(dev->dev, buffer->size, |
40 | (dma_addr_t *)&entry->paddr, GFP_KERNEL); | 39 | &buffer->dma_addr, GFP_KERNEL); |
41 | if (!entry->paddr) { | 40 | if (!buffer->kvaddr) { |
42 | DRM_ERROR("failed to allocate buffer.\n"); | 41 | DRM_ERROR("failed to allocate buffer.\n"); |
43 | return -ENOMEM; | 42 | return -ENOMEM; |
44 | } | 43 | } |
45 | 44 | ||
46 | DRM_DEBUG_KMS("allocated : vaddr(0x%x), paddr(0x%x), size(0x%x)\n", | 45 | DRM_DEBUG_KMS("vaddr(0x%lx), dma_addr(0x%lx), size(0x%lx)\n", |
47 | (unsigned int)entry->vaddr, entry->paddr, entry->size); | 46 | (unsigned long)buffer->kvaddr, |
47 | (unsigned long)buffer->dma_addr, | ||
48 | buffer->size); | ||
48 | 49 | ||
49 | return 0; | 50 | return 0; |
50 | } | 51 | } |
51 | 52 | ||
52 | static void lowlevel_buffer_deallocate(struct drm_device *dev, | 53 | static void lowlevel_buffer_deallocate(struct drm_device *dev, |
53 | struct exynos_drm_buf_entry *entry) | 54 | struct exynos_drm_gem_buf *buffer) |
54 | { | 55 | { |
55 | DRM_DEBUG_KMS("%s.\n", __FILE__); | 56 | DRM_DEBUG_KMS("%s.\n", __FILE__); |
56 | 57 | ||
57 | if (entry->paddr && entry->vaddr && entry->size) | 58 | if (buffer->dma_addr && buffer->size) |
58 | dma_free_writecombine(dev->dev, entry->size, entry->vaddr, | 59 | dma_free_writecombine(dev->dev, buffer->size, buffer->kvaddr, |
59 | entry->paddr); | 60 | (dma_addr_t)buffer->dma_addr); |
60 | else | 61 | else |
61 | DRM_DEBUG_KMS("entry data is null.\n"); | 62 | DRM_DEBUG_KMS("buffer data are invalid.\n"); |
62 | } | 63 | } |
63 | 64 | ||
64 | struct exynos_drm_buf_entry *exynos_drm_buf_create(struct drm_device *dev, | 65 | struct exynos_drm_gem_buf *exynos_drm_buf_create(struct drm_device *dev, |
65 | unsigned int size) | 66 | unsigned int size) |
66 | { | 67 | { |
67 | struct exynos_drm_buf_entry *entry; | 68 | struct exynos_drm_gem_buf *buffer; |
68 | 69 | ||
69 | DRM_DEBUG_KMS("%s.\n", __FILE__); | 70 | DRM_DEBUG_KMS("%s.\n", __FILE__); |
71 | DRM_DEBUG_KMS("desired size = 0x%x\n", size); | ||
70 | 72 | ||
71 | entry = kzalloc(sizeof(*entry), GFP_KERNEL); | 73 | buffer = kzalloc(sizeof(*buffer), GFP_KERNEL); |
72 | if (!entry) { | 74 | if (!buffer) { |
73 | DRM_ERROR("failed to allocate exynos_drm_buf_entry.\n"); | 75 | DRM_ERROR("failed to allocate exynos_drm_gem_buf.\n"); |
74 | return ERR_PTR(-ENOMEM); | 76 | return ERR_PTR(-ENOMEM); |
75 | } | 77 | } |
76 | 78 | ||
77 | entry->size = size; | 79 | buffer->size = size; |
78 | 80 | ||
79 | /* | 81 | /* |
80 | * allocate memory region with size and set the memory information | 82 | * allocate memory region with size and set the memory information |
81 | * to vaddr and paddr of a entry object. | 83 | * to vaddr and dma_addr of a buffer object. |
82 | */ | 84 | */ |
83 | if (lowlevel_buffer_allocate(dev, entry) < 0) { | 85 | if (lowlevel_buffer_allocate(dev, buffer) < 0) { |
84 | kfree(entry); | 86 | kfree(buffer); |
85 | entry = NULL; | 87 | buffer = NULL; |
86 | return ERR_PTR(-ENOMEM); | 88 | return ERR_PTR(-ENOMEM); |
87 | } | 89 | } |
88 | 90 | ||
89 | return entry; | 91 | return buffer; |
90 | } | 92 | } |
91 | 93 | ||
92 | void exynos_drm_buf_destroy(struct drm_device *dev, | 94 | void exynos_drm_buf_destroy(struct drm_device *dev, |
93 | struct exynos_drm_buf_entry *entry) | 95 | struct exynos_drm_gem_buf *buffer) |
94 | { | 96 | { |
95 | DRM_DEBUG_KMS("%s.\n", __FILE__); | 97 | DRM_DEBUG_KMS("%s.\n", __FILE__); |
96 | 98 | ||
97 | if (!entry) { | 99 | if (!buffer) { |
98 | DRM_DEBUG_KMS("entry is null.\n"); | 100 | DRM_DEBUG_KMS("buffer is null.\n"); |
99 | return; | 101 | return; |
100 | } | 102 | } |
101 | 103 | ||
102 | lowlevel_buffer_deallocate(dev, entry); | 104 | lowlevel_buffer_deallocate(dev, buffer); |
103 | 105 | ||
104 | kfree(entry); | 106 | kfree(buffer); |
105 | entry = NULL; | 107 | buffer = NULL; |
106 | } | 108 | } |
107 | 109 | ||
108 | MODULE_AUTHOR("Inki Dae <inki.dae@samsung.com>"); | 110 | MODULE_AUTHOR("Inki Dae <inki.dae@samsung.com>"); |
diff --git a/drivers/gpu/drm/exynos/exynos_drm_buf.h b/drivers/gpu/drm/exynos/exynos_drm_buf.h index 045d59eab01a..6e91f9caa5db 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_buf.h +++ b/drivers/gpu/drm/exynos/exynos_drm_buf.h | |||
@@ -26,28 +26,15 @@ | |||
26 | #ifndef _EXYNOS_DRM_BUF_H_ | 26 | #ifndef _EXYNOS_DRM_BUF_H_ |
27 | #define _EXYNOS_DRM_BUF_H_ | 27 | #define _EXYNOS_DRM_BUF_H_ |
28 | 28 | ||
29 | /* | ||
30 | * exynos drm buffer entry structure. | ||
31 | * | ||
32 | * @paddr: physical address of allocated memory. | ||
33 | * @vaddr: kernel virtual address of allocated memory. | ||
34 | * @size: size of allocated memory. | ||
35 | */ | ||
36 | struct exynos_drm_buf_entry { | ||
37 | dma_addr_t paddr; | ||
38 | void __iomem *vaddr; | ||
39 | unsigned int size; | ||
40 | }; | ||
41 | |||
42 | /* allocate physical memory. */ | 29 | /* allocate physical memory. */ |
43 | struct exynos_drm_buf_entry *exynos_drm_buf_create(struct drm_device *dev, | 30 | struct exynos_drm_gem_buf *exynos_drm_buf_create(struct drm_device *dev, |
44 | unsigned int size); | 31 | unsigned int size); |
45 | 32 | ||
46 | /* get physical memory information of a drm framebuffer. */ | 33 | /* get memory information of a drm framebuffer. */ |
47 | struct exynos_drm_buf_entry *exynos_drm_fb_get_buf(struct drm_framebuffer *fb); | 34 | struct exynos_drm_gem_buf *exynos_drm_fb_get_buf(struct drm_framebuffer *fb); |
48 | 35 | ||
49 | /* remove allocated physical memory. */ | 36 | /* remove allocated physical memory. */ |
50 | void exynos_drm_buf_destroy(struct drm_device *dev, | 37 | void exynos_drm_buf_destroy(struct drm_device *dev, |
51 | struct exynos_drm_buf_entry *entry); | 38 | struct exynos_drm_gem_buf *buffer); |
52 | 39 | ||
53 | #endif | 40 | #endif |
diff --git a/drivers/gpu/drm/exynos/exynos_drm_connector.c b/drivers/gpu/drm/exynos/exynos_drm_connector.c index 985d9e768728..d620b0784257 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_connector.c +++ b/drivers/gpu/drm/exynos/exynos_drm_connector.c | |||
@@ -37,6 +37,8 @@ | |||
37 | 37 | ||
38 | struct exynos_drm_connector { | 38 | struct exynos_drm_connector { |
39 | struct drm_connector drm_connector; | 39 | struct drm_connector drm_connector; |
40 | uint32_t encoder_id; | ||
41 | struct exynos_drm_manager *manager; | ||
40 | }; | 42 | }; |
41 | 43 | ||
42 | /* convert exynos_video_timings to drm_display_mode */ | 44 | /* convert exynos_video_timings to drm_display_mode */ |
@@ -47,6 +49,7 @@ convert_to_display_mode(struct drm_display_mode *mode, | |||
47 | DRM_DEBUG_KMS("%s\n", __FILE__); | 49 | DRM_DEBUG_KMS("%s\n", __FILE__); |
48 | 50 | ||
49 | mode->clock = timing->pixclock / 1000; | 51 | mode->clock = timing->pixclock / 1000; |
52 | mode->vrefresh = timing->refresh; | ||
50 | 53 | ||
51 | mode->hdisplay = timing->xres; | 54 | mode->hdisplay = timing->xres; |
52 | mode->hsync_start = mode->hdisplay + timing->left_margin; | 55 | mode->hsync_start = mode->hdisplay + timing->left_margin; |
@@ -57,6 +60,12 @@ convert_to_display_mode(struct drm_display_mode *mode, | |||
57 | mode->vsync_start = mode->vdisplay + timing->upper_margin; | 60 | mode->vsync_start = mode->vdisplay + timing->upper_margin; |
58 | mode->vsync_end = mode->vsync_start + timing->vsync_len; | 61 | mode->vsync_end = mode->vsync_start + timing->vsync_len; |
59 | mode->vtotal = mode->vsync_end + timing->lower_margin; | 62 | mode->vtotal = mode->vsync_end + timing->lower_margin; |
63 | |||
64 | if (timing->vmode & FB_VMODE_INTERLACED) | ||
65 | mode->flags |= DRM_MODE_FLAG_INTERLACE; | ||
66 | |||
67 | if (timing->vmode & FB_VMODE_DOUBLE) | ||
68 | mode->flags |= DRM_MODE_FLAG_DBLSCAN; | ||
60 | } | 69 | } |
61 | 70 | ||
62 | /* convert drm_display_mode to exynos_video_timings */ | 71 | /* convert drm_display_mode to exynos_video_timings */ |
@@ -69,7 +78,7 @@ convert_to_video_timing(struct fb_videomode *timing, | |||
69 | memset(timing, 0, sizeof(*timing)); | 78 | memset(timing, 0, sizeof(*timing)); |
70 | 79 | ||
71 | timing->pixclock = mode->clock * 1000; | 80 | timing->pixclock = mode->clock * 1000; |
72 | timing->refresh = mode->vrefresh; | 81 | timing->refresh = drm_mode_vrefresh(mode); |
73 | 82 | ||
74 | timing->xres = mode->hdisplay; | 83 | timing->xres = mode->hdisplay; |
75 | timing->left_margin = mode->hsync_start - mode->hdisplay; | 84 | timing->left_margin = mode->hsync_start - mode->hdisplay; |
@@ -92,15 +101,16 @@ convert_to_video_timing(struct fb_videomode *timing, | |||
92 | 101 | ||
93 | static int exynos_drm_connector_get_modes(struct drm_connector *connector) | 102 | static int exynos_drm_connector_get_modes(struct drm_connector *connector) |
94 | { | 103 | { |
95 | struct exynos_drm_manager *manager = | 104 | struct exynos_drm_connector *exynos_connector = |
96 | exynos_drm_get_manager(connector->encoder); | 105 | to_exynos_connector(connector); |
97 | struct exynos_drm_display *display = manager->display; | 106 | struct exynos_drm_manager *manager = exynos_connector->manager; |
107 | struct exynos_drm_display_ops *display_ops = manager->display_ops; | ||
98 | unsigned int count; | 108 | unsigned int count; |
99 | 109 | ||
100 | DRM_DEBUG_KMS("%s\n", __FILE__); | 110 | DRM_DEBUG_KMS("%s\n", __FILE__); |
101 | 111 | ||
102 | if (!display) { | 112 | if (!display_ops) { |
103 | DRM_DEBUG_KMS("display is null.\n"); | 113 | DRM_DEBUG_KMS("display_ops is null.\n"); |
104 | return 0; | 114 | return 0; |
105 | } | 115 | } |
106 | 116 | ||
@@ -112,7 +122,7 @@ static int exynos_drm_connector_get_modes(struct drm_connector *connector) | |||
112 | * P.S. in case of lcd panel, count is always 1 if success | 122 | * P.S. in case of lcd panel, count is always 1 if success |
113 | * because lcd panel has only one mode. | 123 | * because lcd panel has only one mode. |
114 | */ | 124 | */ |
115 | if (display->get_edid) { | 125 | if (display_ops->get_edid) { |
116 | int ret; | 126 | int ret; |
117 | void *edid; | 127 | void *edid; |
118 | 128 | ||
@@ -122,7 +132,7 @@ static int exynos_drm_connector_get_modes(struct drm_connector *connector) | |||
122 | return 0; | 132 | return 0; |
123 | } | 133 | } |
124 | 134 | ||
125 | ret = display->get_edid(manager->dev, connector, | 135 | ret = display_ops->get_edid(manager->dev, connector, |
126 | edid, MAX_EDID); | 136 | edid, MAX_EDID); |
127 | if (ret < 0) { | 137 | if (ret < 0) { |
128 | DRM_ERROR("failed to get edid data.\n"); | 138 | DRM_ERROR("failed to get edid data.\n"); |
@@ -140,8 +150,8 @@ static int exynos_drm_connector_get_modes(struct drm_connector *connector) | |||
140 | struct drm_display_mode *mode = drm_mode_create(connector->dev); | 150 | struct drm_display_mode *mode = drm_mode_create(connector->dev); |
141 | struct fb_videomode *timing; | 151 | struct fb_videomode *timing; |
142 | 152 | ||
143 | if (display->get_timing) | 153 | if (display_ops->get_timing) |
144 | timing = display->get_timing(manager->dev); | 154 | timing = display_ops->get_timing(manager->dev); |
145 | else { | 155 | else { |
146 | drm_mode_destroy(connector->dev, mode); | 156 | drm_mode_destroy(connector->dev, mode); |
147 | return 0; | 157 | return 0; |
@@ -162,9 +172,10 @@ static int exynos_drm_connector_get_modes(struct drm_connector *connector) | |||
162 | static int exynos_drm_connector_mode_valid(struct drm_connector *connector, | 172 | static int exynos_drm_connector_mode_valid(struct drm_connector *connector, |
163 | struct drm_display_mode *mode) | 173 | struct drm_display_mode *mode) |
164 | { | 174 | { |
165 | struct exynos_drm_manager *manager = | 175 | struct exynos_drm_connector *exynos_connector = |
166 | exynos_drm_get_manager(connector->encoder); | 176 | to_exynos_connector(connector); |
167 | struct exynos_drm_display *display = manager->display; | 177 | struct exynos_drm_manager *manager = exynos_connector->manager; |
178 | struct exynos_drm_display_ops *display_ops = manager->display_ops; | ||
168 | struct fb_videomode timing; | 179 | struct fb_videomode timing; |
169 | int ret = MODE_BAD; | 180 | int ret = MODE_BAD; |
170 | 181 | ||
@@ -172,8 +183,8 @@ static int exynos_drm_connector_mode_valid(struct drm_connector *connector, | |||
172 | 183 | ||
173 | convert_to_video_timing(&timing, mode); | 184 | convert_to_video_timing(&timing, mode); |
174 | 185 | ||
175 | if (display && display->check_timing) | 186 | if (display_ops && display_ops->check_timing) |
176 | if (!display->check_timing(manager->dev, (void *)&timing)) | 187 | if (!display_ops->check_timing(manager->dev, (void *)&timing)) |
177 | ret = MODE_OK; | 188 | ret = MODE_OK; |
178 | 189 | ||
179 | return ret; | 190 | return ret; |
@@ -181,9 +192,25 @@ static int exynos_drm_connector_mode_valid(struct drm_connector *connector, | |||
181 | 192 | ||
182 | struct drm_encoder *exynos_drm_best_encoder(struct drm_connector *connector) | 193 | struct drm_encoder *exynos_drm_best_encoder(struct drm_connector *connector) |
183 | { | 194 | { |
195 | struct drm_device *dev = connector->dev; | ||
196 | struct exynos_drm_connector *exynos_connector = | ||
197 | to_exynos_connector(connector); | ||
198 | struct drm_mode_object *obj; | ||
199 | struct drm_encoder *encoder; | ||
200 | |||
184 | DRM_DEBUG_KMS("%s\n", __FILE__); | 201 | DRM_DEBUG_KMS("%s\n", __FILE__); |
185 | 202 | ||
186 | return connector->encoder; | 203 | obj = drm_mode_object_find(dev, exynos_connector->encoder_id, |
204 | DRM_MODE_OBJECT_ENCODER); | ||
205 | if (!obj) { | ||
206 | DRM_DEBUG_KMS("Unknown ENCODER ID %d\n", | ||
207 | exynos_connector->encoder_id); | ||
208 | return NULL; | ||
209 | } | ||
210 | |||
211 | encoder = obj_to_encoder(obj); | ||
212 | |||
213 | return encoder; | ||
187 | } | 214 | } |
188 | 215 | ||
189 | static struct drm_connector_helper_funcs exynos_connector_helper_funcs = { | 216 | static struct drm_connector_helper_funcs exynos_connector_helper_funcs = { |
@@ -196,15 +223,17 @@ static struct drm_connector_helper_funcs exynos_connector_helper_funcs = { | |||
196 | static enum drm_connector_status | 223 | static enum drm_connector_status |
197 | exynos_drm_connector_detect(struct drm_connector *connector, bool force) | 224 | exynos_drm_connector_detect(struct drm_connector *connector, bool force) |
198 | { | 225 | { |
199 | struct exynos_drm_manager *manager = | 226 | struct exynos_drm_connector *exynos_connector = |
200 | exynos_drm_get_manager(connector->encoder); | 227 | to_exynos_connector(connector); |
201 | struct exynos_drm_display *display = manager->display; | 228 | struct exynos_drm_manager *manager = exynos_connector->manager; |
229 | struct exynos_drm_display_ops *display_ops = | ||
230 | manager->display_ops; | ||
202 | enum drm_connector_status status = connector_status_disconnected; | 231 | enum drm_connector_status status = connector_status_disconnected; |
203 | 232 | ||
204 | DRM_DEBUG_KMS("%s\n", __FILE__); | 233 | DRM_DEBUG_KMS("%s\n", __FILE__); |
205 | 234 | ||
206 | if (display && display->is_connected) { | 235 | if (display_ops && display_ops->is_connected) { |
207 | if (display->is_connected(manager->dev)) | 236 | if (display_ops->is_connected(manager->dev)) |
208 | status = connector_status_connected; | 237 | status = connector_status_connected; |
209 | else | 238 | else |
210 | status = connector_status_disconnected; | 239 | status = connector_status_disconnected; |
@@ -251,9 +280,11 @@ struct drm_connector *exynos_drm_connector_create(struct drm_device *dev, | |||
251 | 280 | ||
252 | connector = &exynos_connector->drm_connector; | 281 | connector = &exynos_connector->drm_connector; |
253 | 282 | ||
254 | switch (manager->display->type) { | 283 | switch (manager->display_ops->type) { |
255 | case EXYNOS_DISPLAY_TYPE_HDMI: | 284 | case EXYNOS_DISPLAY_TYPE_HDMI: |
256 | type = DRM_MODE_CONNECTOR_HDMIA; | 285 | type = DRM_MODE_CONNECTOR_HDMIA; |
286 | connector->interlace_allowed = true; | ||
287 | connector->polled = DRM_CONNECTOR_POLL_HPD; | ||
257 | break; | 288 | break; |
258 | default: | 289 | default: |
259 | type = DRM_MODE_CONNECTOR_Unknown; | 290 | type = DRM_MODE_CONNECTOR_Unknown; |
@@ -267,7 +298,10 @@ struct drm_connector *exynos_drm_connector_create(struct drm_device *dev, | |||
267 | if (err) | 298 | if (err) |
268 | goto err_connector; | 299 | goto err_connector; |
269 | 300 | ||
301 | exynos_connector->encoder_id = encoder->base.id; | ||
302 | exynos_connector->manager = manager; | ||
270 | connector->encoder = encoder; | 303 | connector->encoder = encoder; |
304 | |||
271 | err = drm_mode_connector_attach_encoder(connector, encoder); | 305 | err = drm_mode_connector_attach_encoder(connector, encoder); |
272 | if (err) { | 306 | if (err) { |
273 | DRM_ERROR("failed to attach a connector to a encoder\n"); | 307 | DRM_ERROR("failed to attach a connector to a encoder\n"); |
diff --git a/drivers/gpu/drm/exynos/exynos_drm_crtc.c b/drivers/gpu/drm/exynos/exynos_drm_crtc.c index 9337e5e2dbb6..ee43cc220853 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_crtc.c +++ b/drivers/gpu/drm/exynos/exynos_drm_crtc.c | |||
@@ -29,36 +29,17 @@ | |||
29 | #include "drmP.h" | 29 | #include "drmP.h" |
30 | #include "drm_crtc_helper.h" | 30 | #include "drm_crtc_helper.h" |
31 | 31 | ||
32 | #include "exynos_drm_crtc.h" | ||
32 | #include "exynos_drm_drv.h" | 33 | #include "exynos_drm_drv.h" |
33 | #include "exynos_drm_fb.h" | 34 | #include "exynos_drm_fb.h" |
34 | #include "exynos_drm_encoder.h" | 35 | #include "exynos_drm_encoder.h" |
36 | #include "exynos_drm_gem.h" | ||
35 | #include "exynos_drm_buf.h" | 37 | #include "exynos_drm_buf.h" |
36 | 38 | ||
37 | #define to_exynos_crtc(x) container_of(x, struct exynos_drm_crtc,\ | 39 | #define to_exynos_crtc(x) container_of(x, struct exynos_drm_crtc,\ |
38 | drm_crtc) | 40 | drm_crtc) |
39 | 41 | ||
40 | /* | 42 | /* |
41 | * Exynos specific crtc postion structure. | ||
42 | * | ||
43 | * @fb_x: offset x on a framebuffer to be displyed | ||
44 | * - the unit is screen coordinates. | ||
45 | * @fb_y: offset y on a framebuffer to be displayed | ||
46 | * - the unit is screen coordinates. | ||
47 | * @crtc_x: offset x on hardware screen. | ||
48 | * @crtc_y: offset y on hardware screen. | ||
49 | * @crtc_w: width of hardware screen. | ||
50 | * @crtc_h: height of hardware screen. | ||
51 | */ | ||
52 | struct exynos_drm_crtc_pos { | ||
53 | unsigned int fb_x; | ||
54 | unsigned int fb_y; | ||
55 | unsigned int crtc_x; | ||
56 | unsigned int crtc_y; | ||
57 | unsigned int crtc_w; | ||
58 | unsigned int crtc_h; | ||
59 | }; | ||
60 | |||
61 | /* | ||
62 | * Exynos specific crtc structure. | 43 | * Exynos specific crtc structure. |
63 | * | 44 | * |
64 | * @drm_crtc: crtc object. | 45 | * @drm_crtc: crtc object. |
@@ -85,30 +66,31 @@ static void exynos_drm_crtc_apply(struct drm_crtc *crtc) | |||
85 | 66 | ||
86 | exynos_drm_fn_encoder(crtc, overlay, | 67 | exynos_drm_fn_encoder(crtc, overlay, |
87 | exynos_drm_encoder_crtc_mode_set); | 68 | exynos_drm_encoder_crtc_mode_set); |
88 | exynos_drm_fn_encoder(crtc, NULL, exynos_drm_encoder_crtc_commit); | 69 | exynos_drm_fn_encoder(crtc, &exynos_crtc->pipe, |
70 | exynos_drm_encoder_crtc_commit); | ||
89 | } | 71 | } |
90 | 72 | ||
91 | static int exynos_drm_overlay_update(struct exynos_drm_overlay *overlay, | 73 | int exynos_drm_overlay_update(struct exynos_drm_overlay *overlay, |
92 | struct drm_framebuffer *fb, | 74 | struct drm_framebuffer *fb, |
93 | struct drm_display_mode *mode, | 75 | struct drm_display_mode *mode, |
94 | struct exynos_drm_crtc_pos *pos) | 76 | struct exynos_drm_crtc_pos *pos) |
95 | { | 77 | { |
96 | struct exynos_drm_buf_entry *entry; | 78 | struct exynos_drm_gem_buf *buffer; |
97 | unsigned int actual_w; | 79 | unsigned int actual_w; |
98 | unsigned int actual_h; | 80 | unsigned int actual_h; |
99 | 81 | ||
100 | entry = exynos_drm_fb_get_buf(fb); | 82 | buffer = exynos_drm_fb_get_buf(fb); |
101 | if (!entry) { | 83 | if (!buffer) { |
102 | DRM_LOG_KMS("entry is null.\n"); | 84 | DRM_LOG_KMS("buffer is null.\n"); |
103 | return -EFAULT; | 85 | return -EFAULT; |
104 | } | 86 | } |
105 | 87 | ||
106 | overlay->paddr = entry->paddr; | 88 | overlay->dma_addr = buffer->dma_addr; |
107 | overlay->vaddr = entry->vaddr; | 89 | overlay->vaddr = buffer->kvaddr; |
108 | 90 | ||
109 | DRM_DEBUG_KMS("vaddr = 0x%lx, paddr = 0x%lx\n", | 91 | DRM_DEBUG_KMS("vaddr = 0x%lx, dma_addr = 0x%lx\n", |
110 | (unsigned long)overlay->vaddr, | 92 | (unsigned long)overlay->vaddr, |
111 | (unsigned long)overlay->paddr); | 93 | (unsigned long)overlay->dma_addr); |
112 | 94 | ||
113 | actual_w = min((mode->hdisplay - pos->crtc_x), pos->crtc_w); | 95 | actual_w = min((mode->hdisplay - pos->crtc_x), pos->crtc_w); |
114 | actual_h = min((mode->vdisplay - pos->crtc_y), pos->crtc_h); | 96 | actual_h = min((mode->vdisplay - pos->crtc_y), pos->crtc_h); |
@@ -171,9 +153,26 @@ static int exynos_drm_crtc_update(struct drm_crtc *crtc) | |||
171 | 153 | ||
172 | static void exynos_drm_crtc_dpms(struct drm_crtc *crtc, int mode) | 154 | static void exynos_drm_crtc_dpms(struct drm_crtc *crtc, int mode) |
173 | { | 155 | { |
174 | DRM_DEBUG_KMS("%s\n", __FILE__); | 156 | struct exynos_drm_crtc *exynos_crtc = to_exynos_crtc(crtc); |
175 | 157 | ||
176 | /* TODO */ | 158 | DRM_DEBUG_KMS("crtc[%d] mode[%d]\n", crtc->base.id, mode); |
159 | |||
160 | switch (mode) { | ||
161 | case DRM_MODE_DPMS_ON: | ||
162 | exynos_drm_fn_encoder(crtc, &exynos_crtc->pipe, | ||
163 | exynos_drm_encoder_crtc_commit); | ||
164 | break; | ||
165 | case DRM_MODE_DPMS_STANDBY: | ||
166 | case DRM_MODE_DPMS_SUSPEND: | ||
167 | case DRM_MODE_DPMS_OFF: | ||
168 | /* TODO */ | ||
169 | exynos_drm_fn_encoder(crtc, NULL, | ||
170 | exynos_drm_encoder_crtc_disable); | ||
171 | break; | ||
172 | default: | ||
173 | DRM_DEBUG_KMS("unspecified mode %d\n", mode); | ||
174 | break; | ||
175 | } | ||
177 | } | 176 | } |
178 | 177 | ||
179 | static void exynos_drm_crtc_prepare(struct drm_crtc *crtc) | 178 | static void exynos_drm_crtc_prepare(struct drm_crtc *crtc) |
@@ -185,9 +184,12 @@ static void exynos_drm_crtc_prepare(struct drm_crtc *crtc) | |||
185 | 184 | ||
186 | static void exynos_drm_crtc_commit(struct drm_crtc *crtc) | 185 | static void exynos_drm_crtc_commit(struct drm_crtc *crtc) |
187 | { | 186 | { |
187 | struct exynos_drm_crtc *exynos_crtc = to_exynos_crtc(crtc); | ||
188 | |||
188 | DRM_DEBUG_KMS("%s\n", __FILE__); | 189 | DRM_DEBUG_KMS("%s\n", __FILE__); |
189 | 190 | ||
190 | /* drm framework doesn't check NULL. */ | 191 | exynos_drm_fn_encoder(crtc, &exynos_crtc->pipe, |
192 | exynos_drm_encoder_crtc_commit); | ||
191 | } | 193 | } |
192 | 194 | ||
193 | static bool | 195 | static bool |
diff --git a/drivers/gpu/drm/exynos/exynos_drm_crtc.h b/drivers/gpu/drm/exynos/exynos_drm_crtc.h index c584042d6d2c..25f72a62cb88 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_crtc.h +++ b/drivers/gpu/drm/exynos/exynos_drm_crtc.h | |||
@@ -35,4 +35,29 @@ int exynos_drm_crtc_create(struct drm_device *dev, unsigned int nr); | |||
35 | int exynos_drm_crtc_enable_vblank(struct drm_device *dev, int crtc); | 35 | int exynos_drm_crtc_enable_vblank(struct drm_device *dev, int crtc); |
36 | void exynos_drm_crtc_disable_vblank(struct drm_device *dev, int crtc); | 36 | void exynos_drm_crtc_disable_vblank(struct drm_device *dev, int crtc); |
37 | 37 | ||
38 | /* | ||
39 | * Exynos specific crtc postion structure. | ||
40 | * | ||
41 | * @fb_x: offset x on a framebuffer to be displyed | ||
42 | * - the unit is screen coordinates. | ||
43 | * @fb_y: offset y on a framebuffer to be displayed | ||
44 | * - the unit is screen coordinates. | ||
45 | * @crtc_x: offset x on hardware screen. | ||
46 | * @crtc_y: offset y on hardware screen. | ||
47 | * @crtc_w: width of hardware screen. | ||
48 | * @crtc_h: height of hardware screen. | ||
49 | */ | ||
50 | struct exynos_drm_crtc_pos { | ||
51 | unsigned int fb_x; | ||
52 | unsigned int fb_y; | ||
53 | unsigned int crtc_x; | ||
54 | unsigned int crtc_y; | ||
55 | unsigned int crtc_w; | ||
56 | unsigned int crtc_h; | ||
57 | }; | ||
58 | |||
59 | int exynos_drm_overlay_update(struct exynos_drm_overlay *overlay, | ||
60 | struct drm_framebuffer *fb, | ||
61 | struct drm_display_mode *mode, | ||
62 | struct exynos_drm_crtc_pos *pos); | ||
38 | #endif | 63 | #endif |
diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.c b/drivers/gpu/drm/exynos/exynos_drm_drv.c index 83810cbe3c17..53e2216de61d 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_drv.c +++ b/drivers/gpu/drm/exynos/exynos_drm_drv.c | |||
@@ -27,6 +27,7 @@ | |||
27 | 27 | ||
28 | #include "drmP.h" | 28 | #include "drmP.h" |
29 | #include "drm.h" | 29 | #include "drm.h" |
30 | #include "drm_crtc_helper.h" | ||
30 | 31 | ||
31 | #include <drm/exynos_drm.h> | 32 | #include <drm/exynos_drm.h> |
32 | 33 | ||
@@ -61,6 +62,9 @@ static int exynos_drm_load(struct drm_device *dev, unsigned long flags) | |||
61 | 62 | ||
62 | drm_mode_config_init(dev); | 63 | drm_mode_config_init(dev); |
63 | 64 | ||
65 | /* init kms poll for handling hpd */ | ||
66 | drm_kms_helper_poll_init(dev); | ||
67 | |||
64 | exynos_drm_mode_config_init(dev); | 68 | exynos_drm_mode_config_init(dev); |
65 | 69 | ||
66 | /* | 70 | /* |
@@ -116,6 +120,7 @@ static int exynos_drm_unload(struct drm_device *dev) | |||
116 | exynos_drm_fbdev_fini(dev); | 120 | exynos_drm_fbdev_fini(dev); |
117 | exynos_drm_device_unregister(dev); | 121 | exynos_drm_device_unregister(dev); |
118 | drm_vblank_cleanup(dev); | 122 | drm_vblank_cleanup(dev); |
123 | drm_kms_helper_poll_fini(dev); | ||
119 | drm_mode_config_cleanup(dev); | 124 | drm_mode_config_cleanup(dev); |
120 | kfree(dev->dev_private); | 125 | kfree(dev->dev_private); |
121 | 126 | ||
diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.h b/drivers/gpu/drm/exynos/exynos_drm_drv.h index c03683f2ae72..5e02e6ecc2e0 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_drv.h +++ b/drivers/gpu/drm/exynos/exynos_drm_drv.h | |||
@@ -29,6 +29,7 @@ | |||
29 | #ifndef _EXYNOS_DRM_DRV_H_ | 29 | #ifndef _EXYNOS_DRM_DRV_H_ |
30 | #define _EXYNOS_DRM_DRV_H_ | 30 | #define _EXYNOS_DRM_DRV_H_ |
31 | 31 | ||
32 | #include <linux/module.h> | ||
32 | #include "drm.h" | 33 | #include "drm.h" |
33 | 34 | ||
34 | #define MAX_CRTC 2 | 35 | #define MAX_CRTC 2 |
@@ -79,8 +80,8 @@ struct exynos_drm_overlay_ops { | |||
79 | * @scan_flag: interlace or progressive way. | 80 | * @scan_flag: interlace or progressive way. |
80 | * (it could be DRM_MODE_FLAG_*) | 81 | * (it could be DRM_MODE_FLAG_*) |
81 | * @bpp: pixel size.(in bit) | 82 | * @bpp: pixel size.(in bit) |
82 | * @paddr: bus(accessed by dma) physical memory address to this overlay | 83 | * @dma_addr: bus(accessed by dma) address to the memory region allocated |
83 | * and this is physically continuous. | 84 | * for a overlay. |
84 | * @vaddr: virtual memory addresss to this overlay. | 85 | * @vaddr: virtual memory addresss to this overlay. |
85 | * @default_win: a window to be enabled. | 86 | * @default_win: a window to be enabled. |
86 | * @color_key: color key on or off. | 87 | * @color_key: color key on or off. |
@@ -108,7 +109,7 @@ struct exynos_drm_overlay { | |||
108 | unsigned int scan_flag; | 109 | unsigned int scan_flag; |
109 | unsigned int bpp; | 110 | unsigned int bpp; |
110 | unsigned int pitch; | 111 | unsigned int pitch; |
111 | dma_addr_t paddr; | 112 | dma_addr_t dma_addr; |
112 | void __iomem *vaddr; | 113 | void __iomem *vaddr; |
113 | 114 | ||
114 | bool default_win; | 115 | bool default_win; |
@@ -130,7 +131,7 @@ struct exynos_drm_overlay { | |||
130 | * @check_timing: check if timing is valid or not. | 131 | * @check_timing: check if timing is valid or not. |
131 | * @power_on: display device on or off. | 132 | * @power_on: display device on or off. |
132 | */ | 133 | */ |
133 | struct exynos_drm_display { | 134 | struct exynos_drm_display_ops { |
134 | enum exynos_drm_output_type type; | 135 | enum exynos_drm_output_type type; |
135 | bool (*is_connected)(struct device *dev); | 136 | bool (*is_connected)(struct device *dev); |
136 | int (*get_edid)(struct device *dev, struct drm_connector *connector, | 137 | int (*get_edid)(struct device *dev, struct drm_connector *connector, |
@@ -146,12 +147,14 @@ struct exynos_drm_display { | |||
146 | * @mode_set: convert drm_display_mode to hw specific display mode and | 147 | * @mode_set: convert drm_display_mode to hw specific display mode and |
147 | * would be called by encoder->mode_set(). | 148 | * would be called by encoder->mode_set(). |
148 | * @commit: set current hw specific display mode to hw. | 149 | * @commit: set current hw specific display mode to hw. |
150 | * @disable: disable hardware specific display mode. | ||
149 | * @enable_vblank: specific driver callback for enabling vblank interrupt. | 151 | * @enable_vblank: specific driver callback for enabling vblank interrupt. |
150 | * @disable_vblank: specific driver callback for disabling vblank interrupt. | 152 | * @disable_vblank: specific driver callback for disabling vblank interrupt. |
151 | */ | 153 | */ |
152 | struct exynos_drm_manager_ops { | 154 | struct exynos_drm_manager_ops { |
153 | void (*mode_set)(struct device *subdrv_dev, void *mode); | 155 | void (*mode_set)(struct device *subdrv_dev, void *mode); |
154 | void (*commit)(struct device *subdrv_dev); | 156 | void (*commit)(struct device *subdrv_dev); |
157 | void (*disable)(struct device *subdrv_dev); | ||
155 | int (*enable_vblank)(struct device *subdrv_dev); | 158 | int (*enable_vblank)(struct device *subdrv_dev); |
156 | void (*disable_vblank)(struct device *subdrv_dev); | 159 | void (*disable_vblank)(struct device *subdrv_dev); |
157 | }; | 160 | }; |
@@ -178,7 +181,7 @@ struct exynos_drm_manager { | |||
178 | int pipe; | 181 | int pipe; |
179 | struct exynos_drm_manager_ops *ops; | 182 | struct exynos_drm_manager_ops *ops; |
180 | struct exynos_drm_overlay_ops *overlay_ops; | 183 | struct exynos_drm_overlay_ops *overlay_ops; |
181 | struct exynos_drm_display *display; | 184 | struct exynos_drm_display_ops *display_ops; |
182 | }; | 185 | }; |
183 | 186 | ||
184 | /* | 187 | /* |
diff --git a/drivers/gpu/drm/exynos/exynos_drm_encoder.c b/drivers/gpu/drm/exynos/exynos_drm_encoder.c index 7cf6fa86a67e..153061415baf 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_encoder.c +++ b/drivers/gpu/drm/exynos/exynos_drm_encoder.c | |||
@@ -53,15 +53,36 @@ static void exynos_drm_encoder_dpms(struct drm_encoder *encoder, int mode) | |||
53 | struct drm_device *dev = encoder->dev; | 53 | struct drm_device *dev = encoder->dev; |
54 | struct drm_connector *connector; | 54 | struct drm_connector *connector; |
55 | struct exynos_drm_manager *manager = exynos_drm_get_manager(encoder); | 55 | struct exynos_drm_manager *manager = exynos_drm_get_manager(encoder); |
56 | struct exynos_drm_manager_ops *manager_ops = manager->ops; | ||
56 | 57 | ||
57 | DRM_DEBUG_KMS("%s, encoder dpms: %d\n", __FILE__, mode); | 58 | DRM_DEBUG_KMS("%s, encoder dpms: %d\n", __FILE__, mode); |
58 | 59 | ||
60 | switch (mode) { | ||
61 | case DRM_MODE_DPMS_ON: | ||
62 | if (manager_ops && manager_ops->commit) | ||
63 | manager_ops->commit(manager->dev); | ||
64 | break; | ||
65 | case DRM_MODE_DPMS_STANDBY: | ||
66 | case DRM_MODE_DPMS_SUSPEND: | ||
67 | case DRM_MODE_DPMS_OFF: | ||
68 | /* TODO */ | ||
69 | if (manager_ops && manager_ops->disable) | ||
70 | manager_ops->disable(manager->dev); | ||
71 | break; | ||
72 | default: | ||
73 | DRM_ERROR("unspecified mode %d\n", mode); | ||
74 | break; | ||
75 | } | ||
76 | |||
59 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) { | 77 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) { |
60 | if (connector->encoder == encoder) { | 78 | if (connector->encoder == encoder) { |
61 | struct exynos_drm_display *display = manager->display; | 79 | struct exynos_drm_display_ops *display_ops = |
80 | manager->display_ops; | ||
62 | 81 | ||
63 | if (display && display->power_on) | 82 | DRM_DEBUG_KMS("connector[%d] dpms[%d]\n", |
64 | display->power_on(manager->dev, mode); | 83 | connector->base.id, mode); |
84 | if (display_ops && display_ops->power_on) | ||
85 | display_ops->power_on(manager->dev, mode); | ||
65 | } | 86 | } |
66 | } | 87 | } |
67 | } | 88 | } |
@@ -116,15 +137,11 @@ static void exynos_drm_encoder_commit(struct drm_encoder *encoder) | |||
116 | { | 137 | { |
117 | struct exynos_drm_manager *manager = exynos_drm_get_manager(encoder); | 138 | struct exynos_drm_manager *manager = exynos_drm_get_manager(encoder); |
118 | struct exynos_drm_manager_ops *manager_ops = manager->ops; | 139 | struct exynos_drm_manager_ops *manager_ops = manager->ops; |
119 | struct exynos_drm_overlay_ops *overlay_ops = manager->overlay_ops; | ||
120 | 140 | ||
121 | DRM_DEBUG_KMS("%s\n", __FILE__); | 141 | DRM_DEBUG_KMS("%s\n", __FILE__); |
122 | 142 | ||
123 | if (manager_ops && manager_ops->commit) | 143 | if (manager_ops && manager_ops->commit) |
124 | manager_ops->commit(manager->dev); | 144 | manager_ops->commit(manager->dev); |
125 | |||
126 | if (overlay_ops && overlay_ops->commit) | ||
127 | overlay_ops->commit(manager->dev); | ||
128 | } | 145 | } |
129 | 146 | ||
130 | static struct drm_crtc * | 147 | static struct drm_crtc * |
@@ -208,10 +225,23 @@ void exynos_drm_fn_encoder(struct drm_crtc *crtc, void *data, | |||
208 | { | 225 | { |
209 | struct drm_device *dev = crtc->dev; | 226 | struct drm_device *dev = crtc->dev; |
210 | struct drm_encoder *encoder; | 227 | struct drm_encoder *encoder; |
228 | struct exynos_drm_private *private = dev->dev_private; | ||
229 | struct exynos_drm_manager *manager; | ||
211 | 230 | ||
212 | list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { | 231 | list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { |
213 | if (encoder->crtc != crtc) | 232 | /* |
214 | continue; | 233 | * if crtc is detached from encoder, check pipe, |
234 | * otherwise check crtc attached to encoder | ||
235 | */ | ||
236 | if (!encoder->crtc) { | ||
237 | manager = to_exynos_encoder(encoder)->manager; | ||
238 | if (manager->pipe < 0 || | ||
239 | private->crtc[manager->pipe] != crtc) | ||
240 | continue; | ||
241 | } else { | ||
242 | if (encoder->crtc != crtc) | ||
243 | continue; | ||
244 | } | ||
215 | 245 | ||
216 | fn(encoder, data); | 246 | fn(encoder, data); |
217 | } | 247 | } |
@@ -250,8 +280,18 @@ void exynos_drm_encoder_crtc_commit(struct drm_encoder *encoder, void *data) | |||
250 | struct exynos_drm_manager *manager = | 280 | struct exynos_drm_manager *manager = |
251 | to_exynos_encoder(encoder)->manager; | 281 | to_exynos_encoder(encoder)->manager; |
252 | struct exynos_drm_overlay_ops *overlay_ops = manager->overlay_ops; | 282 | struct exynos_drm_overlay_ops *overlay_ops = manager->overlay_ops; |
283 | int crtc = *(int *)data; | ||
284 | |||
285 | DRM_DEBUG_KMS("%s\n", __FILE__); | ||
286 | |||
287 | /* | ||
288 | * when crtc is detached from encoder, this pipe is used | ||
289 | * to select manager operation | ||
290 | */ | ||
291 | manager->pipe = crtc; | ||
253 | 292 | ||
254 | overlay_ops->commit(manager->dev); | 293 | if (overlay_ops && overlay_ops->commit) |
294 | overlay_ops->commit(manager->dev); | ||
255 | } | 295 | } |
256 | 296 | ||
257 | void exynos_drm_encoder_crtc_mode_set(struct drm_encoder *encoder, void *data) | 297 | void exynos_drm_encoder_crtc_mode_set(struct drm_encoder *encoder, void *data) |
@@ -261,7 +301,28 @@ void exynos_drm_encoder_crtc_mode_set(struct drm_encoder *encoder, void *data) | |||
261 | struct exynos_drm_overlay_ops *overlay_ops = manager->overlay_ops; | 301 | struct exynos_drm_overlay_ops *overlay_ops = manager->overlay_ops; |
262 | struct exynos_drm_overlay *overlay = data; | 302 | struct exynos_drm_overlay *overlay = data; |
263 | 303 | ||
264 | overlay_ops->mode_set(manager->dev, overlay); | 304 | if (overlay_ops && overlay_ops->mode_set) |
305 | overlay_ops->mode_set(manager->dev, overlay); | ||
306 | } | ||
307 | |||
308 | void exynos_drm_encoder_crtc_disable(struct drm_encoder *encoder, void *data) | ||
309 | { | ||
310 | struct exynos_drm_manager *manager = | ||
311 | to_exynos_encoder(encoder)->manager; | ||
312 | struct exynos_drm_overlay_ops *overlay_ops = manager->overlay_ops; | ||
313 | |||
314 | DRM_DEBUG_KMS("\n"); | ||
315 | |||
316 | if (overlay_ops && overlay_ops->disable) | ||
317 | overlay_ops->disable(manager->dev); | ||
318 | |||
319 | /* | ||
320 | * crtc is already detached from encoder and last | ||
321 | * function for detaching is properly done, so | ||
322 | * clear pipe from manager to prevent repeated call | ||
323 | */ | ||
324 | if (!encoder->crtc) | ||
325 | manager->pipe = -1; | ||
265 | } | 326 | } |
266 | 327 | ||
267 | MODULE_AUTHOR("Inki Dae <inki.dae@samsung.com>"); | 328 | MODULE_AUTHOR("Inki Dae <inki.dae@samsung.com>"); |
diff --git a/drivers/gpu/drm/exynos/exynos_drm_encoder.h b/drivers/gpu/drm/exynos/exynos_drm_encoder.h index 5ecd645d06a9..a22acfbf0e4e 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_encoder.h +++ b/drivers/gpu/drm/exynos/exynos_drm_encoder.h | |||
@@ -41,5 +41,6 @@ void exynos_drm_enable_vblank(struct drm_encoder *encoder, void *data); | |||
41 | void exynos_drm_disable_vblank(struct drm_encoder *encoder, void *data); | 41 | void exynos_drm_disable_vblank(struct drm_encoder *encoder, void *data); |
42 | void exynos_drm_encoder_crtc_commit(struct drm_encoder *encoder, void *data); | 42 | void exynos_drm_encoder_crtc_commit(struct drm_encoder *encoder, void *data); |
43 | void exynos_drm_encoder_crtc_mode_set(struct drm_encoder *encoder, void *data); | 43 | void exynos_drm_encoder_crtc_mode_set(struct drm_encoder *encoder, void *data); |
44 | void exynos_drm_encoder_crtc_disable(struct drm_encoder *encoder, void *data); | ||
44 | 45 | ||
45 | #endif | 46 | #endif |
diff --git a/drivers/gpu/drm/exynos/exynos_drm_fb.c b/drivers/gpu/drm/exynos/exynos_drm_fb.c index 48d29cfd5240..5bf4a1ac7f82 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_fb.c +++ b/drivers/gpu/drm/exynos/exynos_drm_fb.c | |||
@@ -29,7 +29,9 @@ | |||
29 | #include "drmP.h" | 29 | #include "drmP.h" |
30 | #include "drm_crtc.h" | 30 | #include "drm_crtc.h" |
31 | #include "drm_crtc_helper.h" | 31 | #include "drm_crtc_helper.h" |
32 | #include "drm_fb_helper.h" | ||
32 | 33 | ||
34 | #include "exynos_drm_drv.h" | ||
33 | #include "exynos_drm_fb.h" | 35 | #include "exynos_drm_fb.h" |
34 | #include "exynos_drm_buf.h" | 36 | #include "exynos_drm_buf.h" |
35 | #include "exynos_drm_gem.h" | 37 | #include "exynos_drm_gem.h" |
@@ -41,14 +43,14 @@ | |||
41 | * | 43 | * |
42 | * @fb: drm framebuffer obejct. | 44 | * @fb: drm framebuffer obejct. |
43 | * @exynos_gem_obj: exynos specific gem object containing a gem object. | 45 | * @exynos_gem_obj: exynos specific gem object containing a gem object. |
44 | * @entry: pointer to exynos drm buffer entry object. | 46 | * @buffer: pointer to exynos_drm_gem_buffer object. |
45 | * - containing only the information to physically continuous memory | 47 | * - contain the memory information to memory region allocated |
46 | * region allocated at default framebuffer creation. | 48 | * at default framebuffer creation. |
47 | */ | 49 | */ |
48 | struct exynos_drm_fb { | 50 | struct exynos_drm_fb { |
49 | struct drm_framebuffer fb; | 51 | struct drm_framebuffer fb; |
50 | struct exynos_drm_gem_obj *exynos_gem_obj; | 52 | struct exynos_drm_gem_obj *exynos_gem_obj; |
51 | struct exynos_drm_buf_entry *entry; | 53 | struct exynos_drm_gem_buf *buffer; |
52 | }; | 54 | }; |
53 | 55 | ||
54 | static void exynos_drm_fb_destroy(struct drm_framebuffer *fb) | 56 | static void exynos_drm_fb_destroy(struct drm_framebuffer *fb) |
@@ -63,8 +65,8 @@ static void exynos_drm_fb_destroy(struct drm_framebuffer *fb) | |||
63 | * default framebuffer has no gem object so | 65 | * default framebuffer has no gem object so |
64 | * a buffer of the default framebuffer should be released at here. | 66 | * a buffer of the default framebuffer should be released at here. |
65 | */ | 67 | */ |
66 | if (!exynos_fb->exynos_gem_obj && exynos_fb->entry) | 68 | if (!exynos_fb->exynos_gem_obj && exynos_fb->buffer) |
67 | exynos_drm_buf_destroy(fb->dev, exynos_fb->entry); | 69 | exynos_drm_buf_destroy(fb->dev, exynos_fb->buffer); |
68 | 70 | ||
69 | kfree(exynos_fb); | 71 | kfree(exynos_fb); |
70 | exynos_fb = NULL; | 72 | exynos_fb = NULL; |
@@ -143,29 +145,29 @@ exynos_drm_fb_init(struct drm_file *file_priv, struct drm_device *dev, | |||
143 | */ | 145 | */ |
144 | if (!mode_cmd->handle) { | 146 | if (!mode_cmd->handle) { |
145 | if (!file_priv) { | 147 | if (!file_priv) { |
146 | struct exynos_drm_buf_entry *entry; | 148 | struct exynos_drm_gem_buf *buffer; |
147 | 149 | ||
148 | /* | 150 | /* |
149 | * in case that file_priv is NULL, it allocates | 151 | * in case that file_priv is NULL, it allocates |
150 | * only buffer and this buffer would be used | 152 | * only buffer and this buffer would be used |
151 | * for default framebuffer. | 153 | * for default framebuffer. |
152 | */ | 154 | */ |
153 | entry = exynos_drm_buf_create(dev, size); | 155 | buffer = exynos_drm_buf_create(dev, size); |
154 | if (IS_ERR(entry)) { | 156 | if (IS_ERR(buffer)) { |
155 | ret = PTR_ERR(entry); | 157 | ret = PTR_ERR(buffer); |
156 | goto err_buffer; | 158 | goto err_buffer; |
157 | } | 159 | } |
158 | 160 | ||
159 | exynos_fb->entry = entry; | 161 | exynos_fb->buffer = buffer; |
160 | 162 | ||
161 | DRM_LOG_KMS("default fb: paddr = 0x%lx, size = 0x%x\n", | 163 | DRM_LOG_KMS("default: dma_addr = 0x%lx, size = 0x%x\n", |
162 | (unsigned long)entry->paddr, size); | 164 | (unsigned long)buffer->dma_addr, size); |
163 | 165 | ||
164 | goto out; | 166 | goto out; |
165 | } else { | 167 | } else { |
166 | exynos_gem_obj = exynos_drm_gem_create(file_priv, dev, | 168 | exynos_gem_obj = exynos_drm_gem_create(dev, file_priv, |
167 | size, | 169 | &mode_cmd->handle, |
168 | &mode_cmd->handle); | 170 | size); |
169 | if (IS_ERR(exynos_gem_obj)) { | 171 | if (IS_ERR(exynos_gem_obj)) { |
170 | ret = PTR_ERR(exynos_gem_obj); | 172 | ret = PTR_ERR(exynos_gem_obj); |
171 | goto err_buffer; | 173 | goto err_buffer; |
@@ -189,10 +191,10 @@ exynos_drm_fb_init(struct drm_file *file_priv, struct drm_device *dev, | |||
189 | * so that default framebuffer has no its own gem object, | 191 | * so that default framebuffer has no its own gem object, |
190 | * only its own buffer object. | 192 | * only its own buffer object. |
191 | */ | 193 | */ |
192 | exynos_fb->entry = exynos_gem_obj->entry; | 194 | exynos_fb->buffer = exynos_gem_obj->buffer; |
193 | 195 | ||
194 | DRM_LOG_KMS("paddr = 0x%lx, size = 0x%x, gem object = 0x%x\n", | 196 | DRM_LOG_KMS("dma_addr = 0x%lx, size = 0x%x, gem object = 0x%x\n", |
195 | (unsigned long)exynos_fb->entry->paddr, size, | 197 | (unsigned long)exynos_fb->buffer->dma_addr, size, |
196 | (unsigned int)&exynos_gem_obj->base); | 198 | (unsigned int)&exynos_gem_obj->base); |
197 | 199 | ||
198 | out: | 200 | out: |
@@ -220,26 +222,36 @@ struct drm_framebuffer *exynos_drm_fb_create(struct drm_device *dev, | |||
220 | return exynos_drm_fb_init(file_priv, dev, mode_cmd); | 222 | return exynos_drm_fb_init(file_priv, dev, mode_cmd); |
221 | } | 223 | } |
222 | 224 | ||
223 | struct exynos_drm_buf_entry *exynos_drm_fb_get_buf(struct drm_framebuffer *fb) | 225 | struct exynos_drm_gem_buf *exynos_drm_fb_get_buf(struct drm_framebuffer *fb) |
224 | { | 226 | { |
225 | struct exynos_drm_fb *exynos_fb = to_exynos_fb(fb); | 227 | struct exynos_drm_fb *exynos_fb = to_exynos_fb(fb); |
226 | struct exynos_drm_buf_entry *entry; | 228 | struct exynos_drm_gem_buf *buffer; |
227 | 229 | ||
228 | DRM_DEBUG_KMS("%s\n", __FILE__); | 230 | DRM_DEBUG_KMS("%s\n", __FILE__); |
229 | 231 | ||
230 | entry = exynos_fb->entry; | 232 | buffer = exynos_fb->buffer; |
231 | if (!entry) | 233 | if (!buffer) |
232 | return NULL; | 234 | return NULL; |
233 | 235 | ||
234 | DRM_DEBUG_KMS("vaddr = 0x%lx, paddr = 0x%lx\n", | 236 | DRM_DEBUG_KMS("vaddr = 0x%lx, dma_addr = 0x%lx\n", |
235 | (unsigned long)entry->vaddr, | 237 | (unsigned long)buffer->kvaddr, |
236 | (unsigned long)entry->paddr); | 238 | (unsigned long)buffer->dma_addr); |
237 | 239 | ||
238 | return entry; | 240 | return buffer; |
241 | } | ||
242 | |||
243 | static void exynos_drm_output_poll_changed(struct drm_device *dev) | ||
244 | { | ||
245 | struct exynos_drm_private *private = dev->dev_private; | ||
246 | struct drm_fb_helper *fb_helper = private->fb_helper; | ||
247 | |||
248 | if (fb_helper) | ||
249 | drm_fb_helper_hotplug_event(fb_helper); | ||
239 | } | 250 | } |
240 | 251 | ||
241 | static struct drm_mode_config_funcs exynos_drm_mode_config_funcs = { | 252 | static struct drm_mode_config_funcs exynos_drm_mode_config_funcs = { |
242 | .fb_create = exynos_drm_fb_create, | 253 | .fb_create = exynos_drm_fb_create, |
254 | .output_poll_changed = exynos_drm_output_poll_changed, | ||
243 | }; | 255 | }; |
244 | 256 | ||
245 | void exynos_drm_mode_config_init(struct drm_device *dev) | 257 | void exynos_drm_mode_config_init(struct drm_device *dev) |
diff --git a/drivers/gpu/drm/exynos/exynos_drm_fbdev.c b/drivers/gpu/drm/exynos/exynos_drm_fbdev.c index 1f4b3d1a7713..836f41008187 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_fbdev.c +++ b/drivers/gpu/drm/exynos/exynos_drm_fbdev.c | |||
@@ -33,6 +33,7 @@ | |||
33 | 33 | ||
34 | #include "exynos_drm_drv.h" | 34 | #include "exynos_drm_drv.h" |
35 | #include "exynos_drm_fb.h" | 35 | #include "exynos_drm_fb.h" |
36 | #include "exynos_drm_gem.h" | ||
36 | #include "exynos_drm_buf.h" | 37 | #include "exynos_drm_buf.h" |
37 | 38 | ||
38 | #define MAX_CONNECTOR 4 | 39 | #define MAX_CONNECTOR 4 |
@@ -85,15 +86,13 @@ static struct fb_ops exynos_drm_fb_ops = { | |||
85 | }; | 86 | }; |
86 | 87 | ||
87 | static int exynos_drm_fbdev_update(struct drm_fb_helper *helper, | 88 | static int exynos_drm_fbdev_update(struct drm_fb_helper *helper, |
88 | struct drm_framebuffer *fb, | 89 | struct drm_framebuffer *fb) |
89 | unsigned int fb_width, | ||
90 | unsigned int fb_height) | ||
91 | { | 90 | { |
92 | struct fb_info *fbi = helper->fbdev; | 91 | struct fb_info *fbi = helper->fbdev; |
93 | struct drm_device *dev = helper->dev; | 92 | struct drm_device *dev = helper->dev; |
94 | struct exynos_drm_fbdev *exynos_fb = to_exynos_fbdev(helper); | 93 | struct exynos_drm_fbdev *exynos_fb = to_exynos_fbdev(helper); |
95 | struct exynos_drm_buf_entry *entry; | 94 | struct exynos_drm_gem_buf *buffer; |
96 | unsigned int size = fb_width * fb_height * (fb->bits_per_pixel >> 3); | 95 | unsigned int size = fb->width * fb->height * (fb->bits_per_pixel >> 3); |
97 | unsigned long offset; | 96 | unsigned long offset; |
98 | 97 | ||
99 | DRM_DEBUG_KMS("%s\n", __FILE__); | 98 | DRM_DEBUG_KMS("%s\n", __FILE__); |
@@ -101,20 +100,20 @@ static int exynos_drm_fbdev_update(struct drm_fb_helper *helper, | |||
101 | exynos_fb->fb = fb; | 100 | exynos_fb->fb = fb; |
102 | 101 | ||
103 | drm_fb_helper_fill_fix(fbi, fb->pitch, fb->depth); | 102 | drm_fb_helper_fill_fix(fbi, fb->pitch, fb->depth); |
104 | drm_fb_helper_fill_var(fbi, helper, fb_width, fb_height); | 103 | drm_fb_helper_fill_var(fbi, helper, fb->width, fb->height); |
105 | 104 | ||
106 | entry = exynos_drm_fb_get_buf(fb); | 105 | buffer = exynos_drm_fb_get_buf(fb); |
107 | if (!entry) { | 106 | if (!buffer) { |
108 | DRM_LOG_KMS("entry is null.\n"); | 107 | DRM_LOG_KMS("buffer is null.\n"); |
109 | return -EFAULT; | 108 | return -EFAULT; |
110 | } | 109 | } |
111 | 110 | ||
112 | offset = fbi->var.xoffset * (fb->bits_per_pixel >> 3); | 111 | offset = fbi->var.xoffset * (fb->bits_per_pixel >> 3); |
113 | offset += fbi->var.yoffset * fb->pitch; | 112 | offset += fbi->var.yoffset * fb->pitch; |
114 | 113 | ||
115 | dev->mode_config.fb_base = entry->paddr; | 114 | dev->mode_config.fb_base = (resource_size_t)buffer->dma_addr; |
116 | fbi->screen_base = entry->vaddr + offset; | 115 | fbi->screen_base = buffer->kvaddr + offset; |
117 | fbi->fix.smem_start = entry->paddr + offset; | 116 | fbi->fix.smem_start = (unsigned long)(buffer->dma_addr + offset); |
118 | fbi->screen_size = size; | 117 | fbi->screen_size = size; |
119 | fbi->fix.smem_len = size; | 118 | fbi->fix.smem_len = size; |
120 | 119 | ||
@@ -171,8 +170,7 @@ static int exynos_drm_fbdev_create(struct drm_fb_helper *helper, | |||
171 | goto out; | 170 | goto out; |
172 | } | 171 | } |
173 | 172 | ||
174 | ret = exynos_drm_fbdev_update(helper, helper->fb, sizes->fb_width, | 173 | ret = exynos_drm_fbdev_update(helper, helper->fb); |
175 | sizes->fb_height); | ||
176 | if (ret < 0) | 174 | if (ret < 0) |
177 | fb_dealloc_cmap(&fbi->cmap); | 175 | fb_dealloc_cmap(&fbi->cmap); |
178 | 176 | ||
@@ -235,8 +233,7 @@ static int exynos_drm_fbdev_recreate(struct drm_fb_helper *helper, | |||
235 | } | 233 | } |
236 | 234 | ||
237 | helper->fb = exynos_fbdev->fb; | 235 | helper->fb = exynos_fbdev->fb; |
238 | return exynos_drm_fbdev_update(helper, helper->fb, sizes->fb_width, | 236 | return exynos_drm_fbdev_update(helper, helper->fb); |
239 | sizes->fb_height); | ||
240 | } | 237 | } |
241 | 238 | ||
242 | static int exynos_drm_fbdev_probe(struct drm_fb_helper *helper, | 239 | static int exynos_drm_fbdev_probe(struct drm_fb_helper *helper, |
@@ -405,6 +402,18 @@ int exynos_drm_fbdev_reinit(struct drm_device *dev) | |||
405 | fb_helper = private->fb_helper; | 402 | fb_helper = private->fb_helper; |
406 | 403 | ||
407 | if (fb_helper) { | 404 | if (fb_helper) { |
405 | struct list_head temp_list; | ||
406 | |||
407 | INIT_LIST_HEAD(&temp_list); | ||
408 | |||
409 | /* | ||
410 | * fb_helper is reintialized but kernel fb is reused | ||
411 | * so kernel_fb_list need to be backuped and restored | ||
412 | */ | ||
413 | if (!list_empty(&fb_helper->kernel_fb_list)) | ||
414 | list_replace_init(&fb_helper->kernel_fb_list, | ||
415 | &temp_list); | ||
416 | |||
408 | drm_fb_helper_fini(fb_helper); | 417 | drm_fb_helper_fini(fb_helper); |
409 | 418 | ||
410 | ret = drm_fb_helper_init(dev, fb_helper, | 419 | ret = drm_fb_helper_init(dev, fb_helper, |
@@ -414,6 +423,9 @@ int exynos_drm_fbdev_reinit(struct drm_device *dev) | |||
414 | return ret; | 423 | return ret; |
415 | } | 424 | } |
416 | 425 | ||
426 | if (!list_empty(&temp_list)) | ||
427 | list_replace(&temp_list, &fb_helper->kernel_fb_list); | ||
428 | |||
417 | ret = drm_fb_helper_single_add_all_connectors(fb_helper); | 429 | ret = drm_fb_helper_single_add_all_connectors(fb_helper); |
418 | if (ret < 0) { | 430 | if (ret < 0) { |
419 | DRM_ERROR("failed to add fb helper to connectors\n"); | 431 | DRM_ERROR("failed to add fb helper to connectors\n"); |
diff --git a/drivers/gpu/drm/exynos/exynos_drm_fimd.c b/drivers/gpu/drm/exynos/exynos_drm_fimd.c index 4659c88cdd9b..db3b3d9e731d 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_fimd.c +++ b/drivers/gpu/drm/exynos/exynos_drm_fimd.c | |||
@@ -64,7 +64,7 @@ struct fimd_win_data { | |||
64 | unsigned int fb_width; | 64 | unsigned int fb_width; |
65 | unsigned int fb_height; | 65 | unsigned int fb_height; |
66 | unsigned int bpp; | 66 | unsigned int bpp; |
67 | dma_addr_t paddr; | 67 | dma_addr_t dma_addr; |
68 | void __iomem *vaddr; | 68 | void __iomem *vaddr; |
69 | unsigned int buf_offsize; | 69 | unsigned int buf_offsize; |
70 | unsigned int line_size; /* bytes */ | 70 | unsigned int line_size; /* bytes */ |
@@ -124,7 +124,7 @@ static int fimd_display_power_on(struct device *dev, int mode) | |||
124 | return 0; | 124 | return 0; |
125 | } | 125 | } |
126 | 126 | ||
127 | static struct exynos_drm_display fimd_display = { | 127 | static struct exynos_drm_display_ops fimd_display_ops = { |
128 | .type = EXYNOS_DISPLAY_TYPE_LCD, | 128 | .type = EXYNOS_DISPLAY_TYPE_LCD, |
129 | .is_connected = fimd_display_is_connected, | 129 | .is_connected = fimd_display_is_connected, |
130 | .get_timing = fimd_get_timing, | 130 | .get_timing = fimd_get_timing, |
@@ -177,6 +177,40 @@ static void fimd_commit(struct device *dev) | |||
177 | writel(val, ctx->regs + VIDCON0); | 177 | writel(val, ctx->regs + VIDCON0); |
178 | } | 178 | } |
179 | 179 | ||
180 | static void fimd_disable(struct device *dev) | ||
181 | { | ||
182 | struct fimd_context *ctx = get_fimd_context(dev); | ||
183 | struct exynos_drm_subdrv *subdrv = &ctx->subdrv; | ||
184 | struct drm_device *drm_dev = subdrv->drm_dev; | ||
185 | struct exynos_drm_manager *manager = &subdrv->manager; | ||
186 | u32 val; | ||
187 | |||
188 | DRM_DEBUG_KMS("%s\n", __FILE__); | ||
189 | |||
190 | /* fimd dma off */ | ||
191 | val = readl(ctx->regs + VIDCON0); | ||
192 | val &= ~(VIDCON0_ENVID | VIDCON0_ENVID_F); | ||
193 | writel(val, ctx->regs + VIDCON0); | ||
194 | |||
195 | /* | ||
196 | * if vblank is enabled status with dma off then | ||
197 | * it disables vsync interrupt. | ||
198 | */ | ||
199 | if (drm_dev->vblank_enabled[manager->pipe] && | ||
200 | atomic_read(&drm_dev->vblank_refcount[manager->pipe])) { | ||
201 | drm_vblank_put(drm_dev, manager->pipe); | ||
202 | |||
203 | /* | ||
204 | * if vblank_disable_allowed is 0 then disable | ||
205 | * vsync interrupt right now else the vsync interrupt | ||
206 | * would be disabled by drm timer once a current process | ||
207 | * gives up ownershop of vblank event. | ||
208 | */ | ||
209 | if (!drm_dev->vblank_disable_allowed) | ||
210 | drm_vblank_off(drm_dev, manager->pipe); | ||
211 | } | ||
212 | } | ||
213 | |||
180 | static int fimd_enable_vblank(struct device *dev) | 214 | static int fimd_enable_vblank(struct device *dev) |
181 | { | 215 | { |
182 | struct fimd_context *ctx = get_fimd_context(dev); | 216 | struct fimd_context *ctx = get_fimd_context(dev); |
@@ -220,6 +254,7 @@ static void fimd_disable_vblank(struct device *dev) | |||
220 | 254 | ||
221 | static struct exynos_drm_manager_ops fimd_manager_ops = { | 255 | static struct exynos_drm_manager_ops fimd_manager_ops = { |
222 | .commit = fimd_commit, | 256 | .commit = fimd_commit, |
257 | .disable = fimd_disable, | ||
223 | .enable_vblank = fimd_enable_vblank, | 258 | .enable_vblank = fimd_enable_vblank, |
224 | .disable_vblank = fimd_disable_vblank, | 259 | .disable_vblank = fimd_disable_vblank, |
225 | }; | 260 | }; |
@@ -251,7 +286,7 @@ static void fimd_win_mode_set(struct device *dev, | |||
251 | win_data->ovl_height = overlay->crtc_height; | 286 | win_data->ovl_height = overlay->crtc_height; |
252 | win_data->fb_width = overlay->fb_width; | 287 | win_data->fb_width = overlay->fb_width; |
253 | win_data->fb_height = overlay->fb_height; | 288 | win_data->fb_height = overlay->fb_height; |
254 | win_data->paddr = overlay->paddr + offset; | 289 | win_data->dma_addr = overlay->dma_addr + offset; |
255 | win_data->vaddr = overlay->vaddr + offset; | 290 | win_data->vaddr = overlay->vaddr + offset; |
256 | win_data->bpp = overlay->bpp; | 291 | win_data->bpp = overlay->bpp; |
257 | win_data->buf_offsize = (overlay->fb_width - overlay->crtc_width) * | 292 | win_data->buf_offsize = (overlay->fb_width - overlay->crtc_width) * |
@@ -263,7 +298,7 @@ static void fimd_win_mode_set(struct device *dev, | |||
263 | DRM_DEBUG_KMS("ovl_width = %d, ovl_height = %d\n", | 298 | DRM_DEBUG_KMS("ovl_width = %d, ovl_height = %d\n", |
264 | win_data->ovl_width, win_data->ovl_height); | 299 | win_data->ovl_width, win_data->ovl_height); |
265 | DRM_DEBUG_KMS("paddr = 0x%lx, vaddr = 0x%lx\n", | 300 | DRM_DEBUG_KMS("paddr = 0x%lx, vaddr = 0x%lx\n", |
266 | (unsigned long)win_data->paddr, | 301 | (unsigned long)win_data->dma_addr, |
267 | (unsigned long)win_data->vaddr); | 302 | (unsigned long)win_data->vaddr); |
268 | DRM_DEBUG_KMS("fb_width = %d, crtc_width = %d\n", | 303 | DRM_DEBUG_KMS("fb_width = %d, crtc_width = %d\n", |
269 | overlay->fb_width, overlay->crtc_width); | 304 | overlay->fb_width, overlay->crtc_width); |
@@ -376,16 +411,16 @@ static void fimd_win_commit(struct device *dev) | |||
376 | writel(val, ctx->regs + SHADOWCON); | 411 | writel(val, ctx->regs + SHADOWCON); |
377 | 412 | ||
378 | /* buffer start address */ | 413 | /* buffer start address */ |
379 | val = win_data->paddr; | 414 | val = (unsigned long)win_data->dma_addr; |
380 | writel(val, ctx->regs + VIDWx_BUF_START(win, 0)); | 415 | writel(val, ctx->regs + VIDWx_BUF_START(win, 0)); |
381 | 416 | ||
382 | /* buffer end address */ | 417 | /* buffer end address */ |
383 | size = win_data->fb_width * win_data->ovl_height * (win_data->bpp >> 3); | 418 | size = win_data->fb_width * win_data->ovl_height * (win_data->bpp >> 3); |
384 | val = win_data->paddr + size; | 419 | val = (unsigned long)(win_data->dma_addr + size); |
385 | writel(val, ctx->regs + VIDWx_BUF_END(win, 0)); | 420 | writel(val, ctx->regs + VIDWx_BUF_END(win, 0)); |
386 | 421 | ||
387 | DRM_DEBUG_KMS("start addr = 0x%lx, end addr = 0x%lx, size = 0x%lx\n", | 422 | DRM_DEBUG_KMS("start addr = 0x%lx, end addr = 0x%lx, size = 0x%lx\n", |
388 | (unsigned long)win_data->paddr, val, size); | 423 | (unsigned long)win_data->dma_addr, val, size); |
389 | DRM_DEBUG_KMS("ovl_width = %d, ovl_height = %d\n", | 424 | DRM_DEBUG_KMS("ovl_width = %d, ovl_height = %d\n", |
390 | win_data->ovl_width, win_data->ovl_height); | 425 | win_data->ovl_width, win_data->ovl_height); |
391 | 426 | ||
@@ -447,7 +482,6 @@ static void fimd_win_commit(struct device *dev) | |||
447 | static void fimd_win_disable(struct device *dev) | 482 | static void fimd_win_disable(struct device *dev) |
448 | { | 483 | { |
449 | struct fimd_context *ctx = get_fimd_context(dev); | 484 | struct fimd_context *ctx = get_fimd_context(dev); |
450 | struct fimd_win_data *win_data; | ||
451 | int win = ctx->default_win; | 485 | int win = ctx->default_win; |
452 | u32 val; | 486 | u32 val; |
453 | 487 | ||
@@ -456,8 +490,6 @@ static void fimd_win_disable(struct device *dev) | |||
456 | if (win < 0 || win > WINDOWS_NR) | 490 | if (win < 0 || win > WINDOWS_NR) |
457 | return; | 491 | return; |
458 | 492 | ||
459 | win_data = &ctx->win_data[win]; | ||
460 | |||
461 | /* protect windows */ | 493 | /* protect windows */ |
462 | val = readl(ctx->regs + SHADOWCON); | 494 | val = readl(ctx->regs + SHADOWCON); |
463 | val |= SHADOWCON_WINx_PROTECT(win); | 495 | val |= SHADOWCON_WINx_PROTECT(win); |
@@ -528,6 +560,16 @@ static irqreturn_t fimd_irq_handler(int irq, void *dev_id) | |||
528 | /* VSYNC interrupt */ | 560 | /* VSYNC interrupt */ |
529 | writel(VIDINTCON1_INT_FRAME, ctx->regs + VIDINTCON1); | 561 | writel(VIDINTCON1_INT_FRAME, ctx->regs + VIDINTCON1); |
530 | 562 | ||
563 | /* | ||
564 | * in case that vblank_disable_allowed is 1, it could induce | ||
565 | * the problem that manager->pipe could be -1 because with | ||
566 | * disable callback, vsync interrupt isn't disabled and at this moment, | ||
567 | * vsync interrupt could occur. the vsync interrupt would be disabled | ||
568 | * by timer handler later. | ||
569 | */ | ||
570 | if (manager->pipe == -1) | ||
571 | return IRQ_HANDLED; | ||
572 | |||
531 | drm_handle_vblank(drm_dev, manager->pipe); | 573 | drm_handle_vblank(drm_dev, manager->pipe); |
532 | fimd_finish_pageflip(drm_dev, manager->pipe); | 574 | fimd_finish_pageflip(drm_dev, manager->pipe); |
533 | 575 | ||
@@ -548,13 +590,6 @@ static int fimd_subdrv_probe(struct drm_device *drm_dev, struct device *dev) | |||
548 | */ | 590 | */ |
549 | drm_dev->irq_enabled = 1; | 591 | drm_dev->irq_enabled = 1; |
550 | 592 | ||
551 | /* | ||
552 | * with vblank_disable_allowed = 1, vblank interrupt will be disabled | ||
553 | * by drm timer once a current process gives up ownership of | ||
554 | * vblank event.(drm_vblank_put function was called) | ||
555 | */ | ||
556 | drm_dev->vblank_disable_allowed = 1; | ||
557 | |||
558 | return 0; | 593 | return 0; |
559 | } | 594 | } |
560 | 595 | ||
@@ -731,7 +766,7 @@ static int __devinit fimd_probe(struct platform_device *pdev) | |||
731 | subdrv->manager.pipe = -1; | 766 | subdrv->manager.pipe = -1; |
732 | subdrv->manager.ops = &fimd_manager_ops; | 767 | subdrv->manager.ops = &fimd_manager_ops; |
733 | subdrv->manager.overlay_ops = &fimd_overlay_ops; | 768 | subdrv->manager.overlay_ops = &fimd_overlay_ops; |
734 | subdrv->manager.display = &fimd_display; | 769 | subdrv->manager.display_ops = &fimd_display_ops; |
735 | subdrv->manager.dev = dev; | 770 | subdrv->manager.dev = dev; |
736 | 771 | ||
737 | platform_set_drvdata(pdev, ctx); | 772 | platform_set_drvdata(pdev, ctx); |
diff --git a/drivers/gpu/drm/exynos/exynos_drm_gem.c b/drivers/gpu/drm/exynos/exynos_drm_gem.c index a8e7a88906ed..aba0fe47f7ea 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_gem.c +++ b/drivers/gpu/drm/exynos/exynos_drm_gem.c | |||
@@ -62,40 +62,28 @@ static unsigned int get_gem_mmap_offset(struct drm_gem_object *obj) | |||
62 | return (unsigned int)obj->map_list.hash.key << PAGE_SHIFT; | 62 | return (unsigned int)obj->map_list.hash.key << PAGE_SHIFT; |
63 | } | 63 | } |
64 | 64 | ||
65 | struct exynos_drm_gem_obj *exynos_drm_gem_create(struct drm_file *file_priv, | 65 | static struct exynos_drm_gem_obj |
66 | struct drm_device *dev, unsigned int size, | 66 | *exynos_drm_gem_init(struct drm_device *drm_dev, |
67 | unsigned int *handle) | 67 | struct drm_file *file_priv, unsigned int *handle, |
68 | unsigned int size) | ||
68 | { | 69 | { |
69 | struct exynos_drm_gem_obj *exynos_gem_obj; | 70 | struct exynos_drm_gem_obj *exynos_gem_obj; |
70 | struct exynos_drm_buf_entry *entry; | ||
71 | struct drm_gem_object *obj; | 71 | struct drm_gem_object *obj; |
72 | int ret; | 72 | int ret; |
73 | 73 | ||
74 | DRM_DEBUG_KMS("%s\n", __FILE__); | ||
75 | |||
76 | size = roundup(size, PAGE_SIZE); | ||
77 | |||
78 | exynos_gem_obj = kzalloc(sizeof(*exynos_gem_obj), GFP_KERNEL); | 74 | exynos_gem_obj = kzalloc(sizeof(*exynos_gem_obj), GFP_KERNEL); |
79 | if (!exynos_gem_obj) { | 75 | if (!exynos_gem_obj) { |
80 | DRM_ERROR("failed to allocate exynos gem object.\n"); | 76 | DRM_ERROR("failed to allocate exynos gem object.\n"); |
81 | return ERR_PTR(-ENOMEM); | 77 | return ERR_PTR(-ENOMEM); |
82 | } | 78 | } |
83 | 79 | ||
84 | /* allocate the new buffer object and memory region. */ | ||
85 | entry = exynos_drm_buf_create(dev, size); | ||
86 | if (!entry) { | ||
87 | kfree(exynos_gem_obj); | ||
88 | return ERR_PTR(-ENOMEM); | ||
89 | } | ||
90 | |||
91 | exynos_gem_obj->entry = entry; | ||
92 | |||
93 | obj = &exynos_gem_obj->base; | 80 | obj = &exynos_gem_obj->base; |
94 | 81 | ||
95 | ret = drm_gem_object_init(dev, obj, size); | 82 | ret = drm_gem_object_init(drm_dev, obj, size); |
96 | if (ret < 0) { | 83 | if (ret < 0) { |
97 | DRM_ERROR("failed to initailize gem object.\n"); | 84 | DRM_ERROR("failed to initialize gem object.\n"); |
98 | goto err_obj_init; | 85 | ret = -EINVAL; |
86 | goto err_object_init; | ||
99 | } | 87 | } |
100 | 88 | ||
101 | DRM_DEBUG_KMS("created file object = 0x%x\n", (unsigned int)obj->filp); | 89 | DRM_DEBUG_KMS("created file object = 0x%x\n", (unsigned int)obj->filp); |
@@ -127,24 +115,50 @@ err_handle_create: | |||
127 | err_create_mmap_offset: | 115 | err_create_mmap_offset: |
128 | drm_gem_object_release(obj); | 116 | drm_gem_object_release(obj); |
129 | 117 | ||
130 | err_obj_init: | 118 | err_object_init: |
131 | exynos_drm_buf_destroy(dev, exynos_gem_obj->entry); | ||
132 | |||
133 | kfree(exynos_gem_obj); | 119 | kfree(exynos_gem_obj); |
134 | 120 | ||
135 | return ERR_PTR(ret); | 121 | return ERR_PTR(ret); |
136 | } | 122 | } |
137 | 123 | ||
124 | struct exynos_drm_gem_obj *exynos_drm_gem_create(struct drm_device *dev, | ||
125 | struct drm_file *file_priv, | ||
126 | unsigned int *handle, unsigned long size) | ||
127 | { | ||
128 | |||
129 | struct exynos_drm_gem_obj *exynos_gem_obj = NULL; | ||
130 | struct exynos_drm_gem_buf *buffer; | ||
131 | |||
132 | size = roundup(size, PAGE_SIZE); | ||
133 | |||
134 | DRM_DEBUG_KMS("%s: size = 0x%lx\n", __FILE__, size); | ||
135 | |||
136 | buffer = exynos_drm_buf_create(dev, size); | ||
137 | if (IS_ERR(buffer)) { | ||
138 | return ERR_CAST(buffer); | ||
139 | } | ||
140 | |||
141 | exynos_gem_obj = exynos_drm_gem_init(dev, file_priv, handle, size); | ||
142 | if (IS_ERR(exynos_gem_obj)) { | ||
143 | exynos_drm_buf_destroy(dev, buffer); | ||
144 | return exynos_gem_obj; | ||
145 | } | ||
146 | |||
147 | exynos_gem_obj->buffer = buffer; | ||
148 | |||
149 | return exynos_gem_obj; | ||
150 | } | ||
151 | |||
138 | int exynos_drm_gem_create_ioctl(struct drm_device *dev, void *data, | 152 | int exynos_drm_gem_create_ioctl(struct drm_device *dev, void *data, |
139 | struct drm_file *file_priv) | 153 | struct drm_file *file_priv) |
140 | { | 154 | { |
141 | struct drm_exynos_gem_create *args = data; | 155 | struct drm_exynos_gem_create *args = data; |
142 | struct exynos_drm_gem_obj *exynos_gem_obj; | 156 | struct exynos_drm_gem_obj *exynos_gem_obj = NULL; |
143 | 157 | ||
144 | DRM_DEBUG_KMS("%s : size = 0x%x\n", __FILE__, args->size); | 158 | DRM_DEBUG_KMS("%s\n", __FILE__); |
145 | 159 | ||
146 | exynos_gem_obj = exynos_drm_gem_create(file_priv, dev, args->size, | 160 | exynos_gem_obj = exynos_drm_gem_create(dev, file_priv, |
147 | &args->handle); | 161 | &args->handle, args->size); |
148 | if (IS_ERR(exynos_gem_obj)) | 162 | if (IS_ERR(exynos_gem_obj)) |
149 | return PTR_ERR(exynos_gem_obj); | 163 | return PTR_ERR(exynos_gem_obj); |
150 | 164 | ||
@@ -175,7 +189,7 @@ static int exynos_drm_gem_mmap_buffer(struct file *filp, | |||
175 | { | 189 | { |
176 | struct drm_gem_object *obj = filp->private_data; | 190 | struct drm_gem_object *obj = filp->private_data; |
177 | struct exynos_drm_gem_obj *exynos_gem_obj = to_exynos_gem_obj(obj); | 191 | struct exynos_drm_gem_obj *exynos_gem_obj = to_exynos_gem_obj(obj); |
178 | struct exynos_drm_buf_entry *entry; | 192 | struct exynos_drm_gem_buf *buffer; |
179 | unsigned long pfn, vm_size; | 193 | unsigned long pfn, vm_size; |
180 | 194 | ||
181 | DRM_DEBUG_KMS("%s\n", __FILE__); | 195 | DRM_DEBUG_KMS("%s\n", __FILE__); |
@@ -187,20 +201,20 @@ static int exynos_drm_gem_mmap_buffer(struct file *filp, | |||
187 | 201 | ||
188 | vm_size = vma->vm_end - vma->vm_start; | 202 | vm_size = vma->vm_end - vma->vm_start; |
189 | /* | 203 | /* |
190 | * a entry contains information to physically continuous memory | 204 | * a buffer contains information to physically continuous memory |
191 | * allocated by user request or at framebuffer creation. | 205 | * allocated by user request or at framebuffer creation. |
192 | */ | 206 | */ |
193 | entry = exynos_gem_obj->entry; | 207 | buffer = exynos_gem_obj->buffer; |
194 | 208 | ||
195 | /* check if user-requested size is valid. */ | 209 | /* check if user-requested size is valid. */ |
196 | if (vm_size > entry->size) | 210 | if (vm_size > buffer->size) |
197 | return -EINVAL; | 211 | return -EINVAL; |
198 | 212 | ||
199 | /* | 213 | /* |
200 | * get page frame number to physical memory to be mapped | 214 | * get page frame number to physical memory to be mapped |
201 | * to user space. | 215 | * to user space. |
202 | */ | 216 | */ |
203 | pfn = exynos_gem_obj->entry->paddr >> PAGE_SHIFT; | 217 | pfn = ((unsigned long)exynos_gem_obj->buffer->dma_addr) >> PAGE_SHIFT; |
204 | 218 | ||
205 | DRM_DEBUG_KMS("pfn = 0x%lx\n", pfn); | 219 | DRM_DEBUG_KMS("pfn = 0x%lx\n", pfn); |
206 | 220 | ||
@@ -281,7 +295,7 @@ void exynos_drm_gem_free_object(struct drm_gem_object *gem_obj) | |||
281 | 295 | ||
282 | exynos_gem_obj = to_exynos_gem_obj(gem_obj); | 296 | exynos_gem_obj = to_exynos_gem_obj(gem_obj); |
283 | 297 | ||
284 | exynos_drm_buf_destroy(gem_obj->dev, exynos_gem_obj->entry); | 298 | exynos_drm_buf_destroy(gem_obj->dev, exynos_gem_obj->buffer); |
285 | 299 | ||
286 | kfree(exynos_gem_obj); | 300 | kfree(exynos_gem_obj); |
287 | } | 301 | } |
@@ -302,8 +316,8 @@ int exynos_drm_gem_dumb_create(struct drm_file *file_priv, | |||
302 | args->pitch = args->width * args->bpp >> 3; | 316 | args->pitch = args->width * args->bpp >> 3; |
303 | args->size = args->pitch * args->height; | 317 | args->size = args->pitch * args->height; |
304 | 318 | ||
305 | exynos_gem_obj = exynos_drm_gem_create(file_priv, dev, args->size, | 319 | exynos_gem_obj = exynos_drm_gem_create(dev, file_priv, &args->handle, |
306 | &args->handle); | 320 | args->size); |
307 | if (IS_ERR(exynos_gem_obj)) | 321 | if (IS_ERR(exynos_gem_obj)) |
308 | return PTR_ERR(exynos_gem_obj); | 322 | return PTR_ERR(exynos_gem_obj); |
309 | 323 | ||
@@ -360,7 +374,8 @@ int exynos_drm_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf) | |||
360 | 374 | ||
361 | mutex_lock(&dev->struct_mutex); | 375 | mutex_lock(&dev->struct_mutex); |
362 | 376 | ||
363 | pfn = (exynos_gem_obj->entry->paddr >> PAGE_SHIFT) + page_offset; | 377 | pfn = (((unsigned long)exynos_gem_obj->buffer->dma_addr) >> |
378 | PAGE_SHIFT) + page_offset; | ||
364 | 379 | ||
365 | ret = vm_insert_mixed(vma, (unsigned long)vmf->virtual_address, pfn); | 380 | ret = vm_insert_mixed(vma, (unsigned long)vmf->virtual_address, pfn); |
366 | 381 | ||
diff --git a/drivers/gpu/drm/exynos/exynos_drm_gem.h b/drivers/gpu/drm/exynos/exynos_drm_gem.h index e5fc0148277b..ef8797334e6d 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_gem.h +++ b/drivers/gpu/drm/exynos/exynos_drm_gem.h | |||
@@ -30,13 +30,29 @@ | |||
30 | struct exynos_drm_gem_obj, base) | 30 | struct exynos_drm_gem_obj, base) |
31 | 31 | ||
32 | /* | 32 | /* |
33 | * exynos drm gem buffer structure. | ||
34 | * | ||
35 | * @kvaddr: kernel virtual address to allocated memory region. | ||
36 | * @dma_addr: bus address(accessed by dma) to allocated memory region. | ||
37 | * - this address could be physical address without IOMMU and | ||
38 | * device address with IOMMU. | ||
39 | * @size: size of allocated memory region. | ||
40 | */ | ||
41 | struct exynos_drm_gem_buf { | ||
42 | void __iomem *kvaddr; | ||
43 | dma_addr_t dma_addr; | ||
44 | unsigned long size; | ||
45 | }; | ||
46 | |||
47 | /* | ||
33 | * exynos drm buffer structure. | 48 | * exynos drm buffer structure. |
34 | * | 49 | * |
35 | * @base: a gem object. | 50 | * @base: a gem object. |
36 | * - a new handle to this gem object would be created | 51 | * - a new handle to this gem object would be created |
37 | * by drm_gem_handle_create(). | 52 | * by drm_gem_handle_create(). |
38 | * @entry: pointer to exynos drm buffer entry object. | 53 | * @buffer: a pointer to exynos_drm_gem_buffer object. |
39 | * - containing the information to physically | 54 | * - contain the information to memory region allocated |
55 | * by user request or at framebuffer creation. | ||
40 | * continuous memory region allocated by user request | 56 | * continuous memory region allocated by user request |
41 | * or at framebuffer creation. | 57 | * or at framebuffer creation. |
42 | * | 58 | * |
@@ -45,13 +61,13 @@ | |||
45 | */ | 61 | */ |
46 | struct exynos_drm_gem_obj { | 62 | struct exynos_drm_gem_obj { |
47 | struct drm_gem_object base; | 63 | struct drm_gem_object base; |
48 | struct exynos_drm_buf_entry *entry; | 64 | struct exynos_drm_gem_buf *buffer; |
49 | }; | 65 | }; |
50 | 66 | ||
51 | /* create a new buffer and get a new gem handle. */ | 67 | /* create a new buffer and get a new gem handle. */ |
52 | struct exynos_drm_gem_obj *exynos_drm_gem_create(struct drm_file *file_priv, | 68 | struct exynos_drm_gem_obj *exynos_drm_gem_create(struct drm_device *dev, |
53 | struct drm_device *dev, unsigned int size, | 69 | struct drm_file *file_priv, |
54 | unsigned int *handle); | 70 | unsigned int *handle, unsigned long size); |
55 | 71 | ||
56 | /* | 72 | /* |
57 | * request gem object creation and buffer allocation as the size | 73 | * request gem object creation and buffer allocation as the size |
diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index 4f40f1ce1d8e..d09a6e02dc95 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c | |||
@@ -636,11 +636,16 @@ static int i915_ringbuffer_info(struct seq_file *m, void *data) | |||
636 | struct drm_device *dev = node->minor->dev; | 636 | struct drm_device *dev = node->minor->dev; |
637 | drm_i915_private_t *dev_priv = dev->dev_private; | 637 | drm_i915_private_t *dev_priv = dev->dev_private; |
638 | struct intel_ring_buffer *ring; | 638 | struct intel_ring_buffer *ring; |
639 | int ret; | ||
639 | 640 | ||
640 | ring = &dev_priv->ring[(uintptr_t)node->info_ent->data]; | 641 | ring = &dev_priv->ring[(uintptr_t)node->info_ent->data]; |
641 | if (ring->size == 0) | 642 | if (ring->size == 0) |
642 | return 0; | 643 | return 0; |
643 | 644 | ||
645 | ret = mutex_lock_interruptible(&dev->struct_mutex); | ||
646 | if (ret) | ||
647 | return ret; | ||
648 | |||
644 | seq_printf(m, "Ring %s:\n", ring->name); | 649 | seq_printf(m, "Ring %s:\n", ring->name); |
645 | seq_printf(m, " Head : %08x\n", I915_READ_HEAD(ring) & HEAD_ADDR); | 650 | seq_printf(m, " Head : %08x\n", I915_READ_HEAD(ring) & HEAD_ADDR); |
646 | seq_printf(m, " Tail : %08x\n", I915_READ_TAIL(ring) & TAIL_ADDR); | 651 | seq_printf(m, " Tail : %08x\n", I915_READ_TAIL(ring) & TAIL_ADDR); |
@@ -654,6 +659,8 @@ static int i915_ringbuffer_info(struct seq_file *m, void *data) | |||
654 | seq_printf(m, " Control : %08x\n", I915_READ_CTL(ring)); | 659 | seq_printf(m, " Control : %08x\n", I915_READ_CTL(ring)); |
655 | seq_printf(m, " Start : %08x\n", I915_READ_START(ring)); | 660 | seq_printf(m, " Start : %08x\n", I915_READ_START(ring)); |
656 | 661 | ||
662 | mutex_unlock(&dev->struct_mutex); | ||
663 | |||
657 | return 0; | 664 | return 0; |
658 | } | 665 | } |
659 | 666 | ||
@@ -842,7 +849,16 @@ static int i915_rstdby_delays(struct seq_file *m, void *unused) | |||
842 | struct drm_info_node *node = (struct drm_info_node *) m->private; | 849 | struct drm_info_node *node = (struct drm_info_node *) m->private; |
843 | struct drm_device *dev = node->minor->dev; | 850 | struct drm_device *dev = node->minor->dev; |
844 | drm_i915_private_t *dev_priv = dev->dev_private; | 851 | drm_i915_private_t *dev_priv = dev->dev_private; |
845 | u16 crstanddelay = I915_READ16(CRSTANDVID); | 852 | u16 crstanddelay; |
853 | int ret; | ||
854 | |||
855 | ret = mutex_lock_interruptible(&dev->struct_mutex); | ||
856 | if (ret) | ||
857 | return ret; | ||
858 | |||
859 | crstanddelay = I915_READ16(CRSTANDVID); | ||
860 | |||
861 | mutex_unlock(&dev->struct_mutex); | ||
846 | 862 | ||
847 | seq_printf(m, "w/ctx: %d, w/o ctx: %d\n", (crstanddelay >> 8) & 0x3f, (crstanddelay & 0x3f)); | 863 | seq_printf(m, "w/ctx: %d, w/o ctx: %d\n", (crstanddelay >> 8) & 0x3f, (crstanddelay & 0x3f)); |
848 | 864 | ||
@@ -940,7 +956,11 @@ static int i915_delayfreq_table(struct seq_file *m, void *unused) | |||
940 | struct drm_device *dev = node->minor->dev; | 956 | struct drm_device *dev = node->minor->dev; |
941 | drm_i915_private_t *dev_priv = dev->dev_private; | 957 | drm_i915_private_t *dev_priv = dev->dev_private; |
942 | u32 delayfreq; | 958 | u32 delayfreq; |
943 | int i; | 959 | int ret, i; |
960 | |||
961 | ret = mutex_lock_interruptible(&dev->struct_mutex); | ||
962 | if (ret) | ||
963 | return ret; | ||
944 | 964 | ||
945 | for (i = 0; i < 16; i++) { | 965 | for (i = 0; i < 16; i++) { |
946 | delayfreq = I915_READ(PXVFREQ_BASE + i * 4); | 966 | delayfreq = I915_READ(PXVFREQ_BASE + i * 4); |
@@ -948,6 +968,8 @@ static int i915_delayfreq_table(struct seq_file *m, void *unused) | |||
948 | (delayfreq & PXVFREQ_PX_MASK) >> PXVFREQ_PX_SHIFT); | 968 | (delayfreq & PXVFREQ_PX_MASK) >> PXVFREQ_PX_SHIFT); |
949 | } | 969 | } |
950 | 970 | ||
971 | mutex_unlock(&dev->struct_mutex); | ||
972 | |||
951 | return 0; | 973 | return 0; |
952 | } | 974 | } |
953 | 975 | ||
@@ -962,13 +984,19 @@ static int i915_inttoext_table(struct seq_file *m, void *unused) | |||
962 | struct drm_device *dev = node->minor->dev; | 984 | struct drm_device *dev = node->minor->dev; |
963 | drm_i915_private_t *dev_priv = dev->dev_private; | 985 | drm_i915_private_t *dev_priv = dev->dev_private; |
964 | u32 inttoext; | 986 | u32 inttoext; |
965 | int i; | 987 | int ret, i; |
988 | |||
989 | ret = mutex_lock_interruptible(&dev->struct_mutex); | ||
990 | if (ret) | ||
991 | return ret; | ||
966 | 992 | ||
967 | for (i = 1; i <= 32; i++) { | 993 | for (i = 1; i <= 32; i++) { |
968 | inttoext = I915_READ(INTTOEXT_BASE_ILK + i * 4); | 994 | inttoext = I915_READ(INTTOEXT_BASE_ILK + i * 4); |
969 | seq_printf(m, "INTTOEXT%02d: 0x%08x\n", i, inttoext); | 995 | seq_printf(m, "INTTOEXT%02d: 0x%08x\n", i, inttoext); |
970 | } | 996 | } |
971 | 997 | ||
998 | mutex_unlock(&dev->struct_mutex); | ||
999 | |||
972 | return 0; | 1000 | return 0; |
973 | } | 1001 | } |
974 | 1002 | ||
@@ -977,9 +1005,19 @@ static int i915_drpc_info(struct seq_file *m, void *unused) | |||
977 | struct drm_info_node *node = (struct drm_info_node *) m->private; | 1005 | struct drm_info_node *node = (struct drm_info_node *) m->private; |
978 | struct drm_device *dev = node->minor->dev; | 1006 | struct drm_device *dev = node->minor->dev; |
979 | drm_i915_private_t *dev_priv = dev->dev_private; | 1007 | drm_i915_private_t *dev_priv = dev->dev_private; |
980 | u32 rgvmodectl = I915_READ(MEMMODECTL); | 1008 | u32 rgvmodectl, rstdbyctl; |
981 | u32 rstdbyctl = I915_READ(RSTDBYCTL); | 1009 | u16 crstandvid; |
982 | u16 crstandvid = I915_READ16(CRSTANDVID); | 1010 | int ret; |
1011 | |||
1012 | ret = mutex_lock_interruptible(&dev->struct_mutex); | ||
1013 | if (ret) | ||
1014 | return ret; | ||
1015 | |||
1016 | rgvmodectl = I915_READ(MEMMODECTL); | ||
1017 | rstdbyctl = I915_READ(RSTDBYCTL); | ||
1018 | crstandvid = I915_READ16(CRSTANDVID); | ||
1019 | |||
1020 | mutex_unlock(&dev->struct_mutex); | ||
983 | 1021 | ||
984 | seq_printf(m, "HD boost: %s\n", (rgvmodectl & MEMMODE_BOOST_EN) ? | 1022 | seq_printf(m, "HD boost: %s\n", (rgvmodectl & MEMMODE_BOOST_EN) ? |
985 | "yes" : "no"); | 1023 | "yes" : "no"); |
@@ -1167,9 +1205,16 @@ static int i915_gfxec(struct seq_file *m, void *unused) | |||
1167 | struct drm_info_node *node = (struct drm_info_node *) m->private; | 1205 | struct drm_info_node *node = (struct drm_info_node *) m->private; |
1168 | struct drm_device *dev = node->minor->dev; | 1206 | struct drm_device *dev = node->minor->dev; |
1169 | drm_i915_private_t *dev_priv = dev->dev_private; | 1207 | drm_i915_private_t *dev_priv = dev->dev_private; |
1208 | int ret; | ||
1209 | |||
1210 | ret = mutex_lock_interruptible(&dev->struct_mutex); | ||
1211 | if (ret) | ||
1212 | return ret; | ||
1170 | 1213 | ||
1171 | seq_printf(m, "GFXEC: %ld\n", (unsigned long)I915_READ(0x112f4)); | 1214 | seq_printf(m, "GFXEC: %ld\n", (unsigned long)I915_READ(0x112f4)); |
1172 | 1215 | ||
1216 | mutex_unlock(&dev->struct_mutex); | ||
1217 | |||
1173 | return 0; | 1218 | return 0; |
1174 | } | 1219 | } |
1175 | 1220 | ||
diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index e9c2cfe45daa..15bfa9145d2b 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c | |||
@@ -68,7 +68,7 @@ module_param_named(i915_enable_rc6, i915_enable_rc6, int, 0600); | |||
68 | MODULE_PARM_DESC(i915_enable_rc6, | 68 | MODULE_PARM_DESC(i915_enable_rc6, |
69 | "Enable power-saving render C-state 6 (default: true)"); | 69 | "Enable power-saving render C-state 6 (default: true)"); |
70 | 70 | ||
71 | unsigned int i915_enable_fbc __read_mostly = -1; | 71 | int i915_enable_fbc __read_mostly = -1; |
72 | module_param_named(i915_enable_fbc, i915_enable_fbc, int, 0600); | 72 | module_param_named(i915_enable_fbc, i915_enable_fbc, int, 0600); |
73 | MODULE_PARM_DESC(i915_enable_fbc, | 73 | MODULE_PARM_DESC(i915_enable_fbc, |
74 | "Enable frame buffer compression for power savings " | 74 | "Enable frame buffer compression for power savings " |
@@ -80,7 +80,7 @@ MODULE_PARM_DESC(lvds_downclock, | |||
80 | "Use panel (LVDS/eDP) downclocking for power savings " | 80 | "Use panel (LVDS/eDP) downclocking for power savings " |
81 | "(default: false)"); | 81 | "(default: false)"); |
82 | 82 | ||
83 | unsigned int i915_panel_use_ssc __read_mostly = -1; | 83 | int i915_panel_use_ssc __read_mostly = -1; |
84 | module_param_named(lvds_use_ssc, i915_panel_use_ssc, int, 0600); | 84 | module_param_named(lvds_use_ssc, i915_panel_use_ssc, int, 0600); |
85 | MODULE_PARM_DESC(lvds_use_ssc, | 85 | MODULE_PARM_DESC(lvds_use_ssc, |
86 | "Use Spread Spectrum Clock with panels [LVDS/eDP] " | 86 | "Use Spread Spectrum Clock with panels [LVDS/eDP] " |
@@ -107,7 +107,7 @@ static struct drm_driver driver; | |||
107 | extern int intel_agp_enabled; | 107 | extern int intel_agp_enabled; |
108 | 108 | ||
109 | #define INTEL_VGA_DEVICE(id, info) { \ | 109 | #define INTEL_VGA_DEVICE(id, info) { \ |
110 | .class = PCI_CLASS_DISPLAY_VGA << 8, \ | 110 | .class = PCI_BASE_CLASS_DISPLAY << 16, \ |
111 | .class_mask = 0xff0000, \ | 111 | .class_mask = 0xff0000, \ |
112 | .vendor = 0x8086, \ | 112 | .vendor = 0x8086, \ |
113 | .device = id, \ | 113 | .device = id, \ |
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 06a37f4fd74b..4a9c1b979804 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h | |||
@@ -126,6 +126,9 @@ struct drm_i915_master_private { | |||
126 | struct _drm_i915_sarea *sarea_priv; | 126 | struct _drm_i915_sarea *sarea_priv; |
127 | }; | 127 | }; |
128 | #define I915_FENCE_REG_NONE -1 | 128 | #define I915_FENCE_REG_NONE -1 |
129 | #define I915_MAX_NUM_FENCES 16 | ||
130 | /* 16 fences + sign bit for FENCE_REG_NONE */ | ||
131 | #define I915_MAX_NUM_FENCE_BITS 5 | ||
129 | 132 | ||
130 | struct drm_i915_fence_reg { | 133 | struct drm_i915_fence_reg { |
131 | struct list_head lru_list; | 134 | struct list_head lru_list; |
@@ -168,7 +171,7 @@ struct drm_i915_error_state { | |||
168 | u32 instdone1; | 171 | u32 instdone1; |
169 | u32 seqno; | 172 | u32 seqno; |
170 | u64 bbaddr; | 173 | u64 bbaddr; |
171 | u64 fence[16]; | 174 | u64 fence[I915_MAX_NUM_FENCES]; |
172 | struct timeval time; | 175 | struct timeval time; |
173 | struct drm_i915_error_object { | 176 | struct drm_i915_error_object { |
174 | int page_count; | 177 | int page_count; |
@@ -182,7 +185,7 @@ struct drm_i915_error_state { | |||
182 | u32 gtt_offset; | 185 | u32 gtt_offset; |
183 | u32 read_domains; | 186 | u32 read_domains; |
184 | u32 write_domain; | 187 | u32 write_domain; |
185 | s32 fence_reg:5; | 188 | s32 fence_reg:I915_MAX_NUM_FENCE_BITS; |
186 | s32 pinned:2; | 189 | s32 pinned:2; |
187 | u32 tiling:2; | 190 | u32 tiling:2; |
188 | u32 dirty:1; | 191 | u32 dirty:1; |
@@ -375,7 +378,7 @@ typedef struct drm_i915_private { | |||
375 | struct notifier_block lid_notifier; | 378 | struct notifier_block lid_notifier; |
376 | 379 | ||
377 | int crt_ddc_pin; | 380 | int crt_ddc_pin; |
378 | struct drm_i915_fence_reg fence_regs[16]; /* assume 965 */ | 381 | struct drm_i915_fence_reg fence_regs[I915_MAX_NUM_FENCES]; /* assume 965 */ |
379 | int fence_reg_start; /* 4 if userland hasn't ioctl'd us yet */ | 382 | int fence_reg_start; /* 4 if userland hasn't ioctl'd us yet */ |
380 | int num_fence_regs; /* 8 on pre-965, 16 otherwise */ | 383 | int num_fence_regs; /* 8 on pre-965, 16 otherwise */ |
381 | 384 | ||
@@ -506,7 +509,7 @@ typedef struct drm_i915_private { | |||
506 | u8 saveAR[21]; | 509 | u8 saveAR[21]; |
507 | u8 saveDACMASK; | 510 | u8 saveDACMASK; |
508 | u8 saveCR[37]; | 511 | u8 saveCR[37]; |
509 | uint64_t saveFENCE[16]; | 512 | uint64_t saveFENCE[I915_MAX_NUM_FENCES]; |
510 | u32 saveCURACNTR; | 513 | u32 saveCURACNTR; |
511 | u32 saveCURAPOS; | 514 | u32 saveCURAPOS; |
512 | u32 saveCURABASE; | 515 | u32 saveCURABASE; |
@@ -777,10 +780,8 @@ struct drm_i915_gem_object { | |||
777 | * Fence register bits (if any) for this object. Will be set | 780 | * Fence register bits (if any) for this object. Will be set |
778 | * as needed when mapped into the GTT. | 781 | * as needed when mapped into the GTT. |
779 | * Protected by dev->struct_mutex. | 782 | * Protected by dev->struct_mutex. |
780 | * | ||
781 | * Size: 4 bits for 16 fences + sign (for FENCE_REG_NONE) | ||
782 | */ | 783 | */ |
783 | signed int fence_reg:5; | 784 | signed int fence_reg:I915_MAX_NUM_FENCE_BITS; |
784 | 785 | ||
785 | /** | 786 | /** |
786 | * Advice: are the backing pages purgeable? | 787 | * Advice: are the backing pages purgeable? |
@@ -999,10 +1000,10 @@ extern int i915_panel_ignore_lid __read_mostly; | |||
999 | extern unsigned int i915_powersave __read_mostly; | 1000 | extern unsigned int i915_powersave __read_mostly; |
1000 | extern unsigned int i915_semaphores __read_mostly; | 1001 | extern unsigned int i915_semaphores __read_mostly; |
1001 | extern unsigned int i915_lvds_downclock __read_mostly; | 1002 | extern unsigned int i915_lvds_downclock __read_mostly; |
1002 | extern unsigned int i915_panel_use_ssc __read_mostly; | 1003 | extern int i915_panel_use_ssc __read_mostly; |
1003 | extern int i915_vbt_sdvo_panel_type __read_mostly; | 1004 | extern int i915_vbt_sdvo_panel_type __read_mostly; |
1004 | extern unsigned int i915_enable_rc6 __read_mostly; | 1005 | extern unsigned int i915_enable_rc6 __read_mostly; |
1005 | extern unsigned int i915_enable_fbc __read_mostly; | 1006 | extern int i915_enable_fbc __read_mostly; |
1006 | extern bool i915_enable_hangcheck __read_mostly; | 1007 | extern bool i915_enable_hangcheck __read_mostly; |
1007 | 1008 | ||
1008 | extern int i915_suspend(struct drm_device *dev, pm_message_t state); | 1009 | extern int i915_suspend(struct drm_device *dev, pm_message_t state); |
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index d18b07adcffa..8359dc777041 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c | |||
@@ -1745,7 +1745,7 @@ static void i915_gem_reset_fences(struct drm_device *dev) | |||
1745 | struct drm_i915_private *dev_priv = dev->dev_private; | 1745 | struct drm_i915_private *dev_priv = dev->dev_private; |
1746 | int i; | 1746 | int i; |
1747 | 1747 | ||
1748 | for (i = 0; i < 16; i++) { | 1748 | for (i = 0; i < dev_priv->num_fence_regs; i++) { |
1749 | struct drm_i915_fence_reg *reg = &dev_priv->fence_regs[i]; | 1749 | struct drm_i915_fence_reg *reg = &dev_priv->fence_regs[i]; |
1750 | struct drm_i915_gem_object *obj = reg->obj; | 1750 | struct drm_i915_gem_object *obj = reg->obj; |
1751 | 1751 | ||
@@ -3512,9 +3512,11 @@ i915_gem_busy_ioctl(struct drm_device *dev, void *data, | |||
3512 | * so emit a request to do so. | 3512 | * so emit a request to do so. |
3513 | */ | 3513 | */ |
3514 | request = kzalloc(sizeof(*request), GFP_KERNEL); | 3514 | request = kzalloc(sizeof(*request), GFP_KERNEL); |
3515 | if (request) | 3515 | if (request) { |
3516 | ret = i915_add_request(obj->ring, NULL, request); | 3516 | ret = i915_add_request(obj->ring, NULL, request); |
3517 | else | 3517 | if (ret) |
3518 | kfree(request); | ||
3519 | } else | ||
3518 | ret = -ENOMEM; | 3520 | ret = -ENOMEM; |
3519 | } | 3521 | } |
3520 | 3522 | ||
@@ -3613,7 +3615,7 @@ struct drm_i915_gem_object *i915_gem_alloc_object(struct drm_device *dev, | |||
3613 | obj->base.write_domain = I915_GEM_DOMAIN_CPU; | 3615 | obj->base.write_domain = I915_GEM_DOMAIN_CPU; |
3614 | obj->base.read_domains = I915_GEM_DOMAIN_CPU; | 3616 | obj->base.read_domains = I915_GEM_DOMAIN_CPU; |
3615 | 3617 | ||
3616 | if (IS_GEN6(dev)) { | 3618 | if (IS_GEN6(dev) || IS_GEN7(dev)) { |
3617 | /* On Gen6, we can have the GPU use the LLC (the CPU | 3619 | /* On Gen6, we can have the GPU use the LLC (the CPU |
3618 | * cache) for about a 10% performance improvement | 3620 | * cache) for about a 10% performance improvement |
3619 | * compared to uncached. Graphics requests other than | 3621 | * compared to uncached. Graphics requests other than |
@@ -3877,7 +3879,7 @@ i915_gem_load(struct drm_device *dev) | |||
3877 | INIT_LIST_HEAD(&dev_priv->mm.gtt_list); | 3879 | INIT_LIST_HEAD(&dev_priv->mm.gtt_list); |
3878 | for (i = 0; i < I915_NUM_RINGS; i++) | 3880 | for (i = 0; i < I915_NUM_RINGS; i++) |
3879 | init_ring_lists(&dev_priv->ring[i]); | 3881 | init_ring_lists(&dev_priv->ring[i]); |
3880 | for (i = 0; i < 16; i++) | 3882 | for (i = 0; i < I915_MAX_NUM_FENCES; i++) |
3881 | INIT_LIST_HEAD(&dev_priv->fence_regs[i].lru_list); | 3883 | INIT_LIST_HEAD(&dev_priv->fence_regs[i].lru_list); |
3882 | INIT_DELAYED_WORK(&dev_priv->mm.retire_work, | 3884 | INIT_DELAYED_WORK(&dev_priv->mm.retire_work, |
3883 | i915_gem_retire_work_handler); | 3885 | i915_gem_retire_work_handler); |
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 9ee2729fe5c6..b40004b55977 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c | |||
@@ -824,6 +824,7 @@ static void i915_gem_record_fences(struct drm_device *dev, | |||
824 | 824 | ||
825 | /* Fences */ | 825 | /* Fences */ |
826 | switch (INTEL_INFO(dev)->gen) { | 826 | switch (INTEL_INFO(dev)->gen) { |
827 | case 7: | ||
827 | case 6: | 828 | case 6: |
828 | for (i = 0; i < 16; i++) | 829 | for (i = 0; i < 16; i++) |
829 | error->fence[i] = I915_READ64(FENCE_REG_SANDYBRIDGE_0 + (i * 8)); | 830 | error->fence[i] = I915_READ64(FENCE_REG_SANDYBRIDGE_0 + (i * 8)); |
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 5a09416e611f..b080cc824001 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h | |||
@@ -1553,12 +1553,21 @@ | |||
1553 | */ | 1553 | */ |
1554 | #define PP_READY (1 << 30) | 1554 | #define PP_READY (1 << 30) |
1555 | #define PP_SEQUENCE_NONE (0 << 28) | 1555 | #define PP_SEQUENCE_NONE (0 << 28) |
1556 | #define PP_SEQUENCE_ON (1 << 28) | 1556 | #define PP_SEQUENCE_POWER_UP (1 << 28) |
1557 | #define PP_SEQUENCE_OFF (2 << 28) | 1557 | #define PP_SEQUENCE_POWER_DOWN (2 << 28) |
1558 | #define PP_SEQUENCE_MASK 0x30000000 | 1558 | #define PP_SEQUENCE_MASK (3 << 28) |
1559 | #define PP_SEQUENCE_SHIFT 28 | ||
1559 | #define PP_CYCLE_DELAY_ACTIVE (1 << 27) | 1560 | #define PP_CYCLE_DELAY_ACTIVE (1 << 27) |
1560 | #define PP_SEQUENCE_STATE_ON_IDLE (1 << 3) | ||
1561 | #define PP_SEQUENCE_STATE_MASK 0x0000000f | 1561 | #define PP_SEQUENCE_STATE_MASK 0x0000000f |
1562 | #define PP_SEQUENCE_STATE_OFF_IDLE (0x0 << 0) | ||
1563 | #define PP_SEQUENCE_STATE_OFF_S0_1 (0x1 << 0) | ||
1564 | #define PP_SEQUENCE_STATE_OFF_S0_2 (0x2 << 0) | ||
1565 | #define PP_SEQUENCE_STATE_OFF_S0_3 (0x3 << 0) | ||
1566 | #define PP_SEQUENCE_STATE_ON_IDLE (0x8 << 0) | ||
1567 | #define PP_SEQUENCE_STATE_ON_S1_0 (0x9 << 0) | ||
1568 | #define PP_SEQUENCE_STATE_ON_S1_2 (0xa << 0) | ||
1569 | #define PP_SEQUENCE_STATE_ON_S1_3 (0xb << 0) | ||
1570 | #define PP_SEQUENCE_STATE_RESET (0xf << 0) | ||
1562 | #define PP_CONTROL 0x61204 | 1571 | #define PP_CONTROL 0x61204 |
1563 | #define POWER_TARGET_ON (1 << 0) | 1572 | #define POWER_TARGET_ON (1 << 0) |
1564 | #define PP_ON_DELAYS 0x61208 | 1573 | #define PP_ON_DELAYS 0x61208 |
@@ -3444,6 +3453,10 @@ | |||
3444 | #define GT_FIFO_FREE_ENTRIES 0x120008 | 3453 | #define GT_FIFO_FREE_ENTRIES 0x120008 |
3445 | #define GT_FIFO_NUM_RESERVED_ENTRIES 20 | 3454 | #define GT_FIFO_NUM_RESERVED_ENTRIES 20 |
3446 | 3455 | ||
3456 | #define GEN6_UCGCTL2 0x9404 | ||
3457 | # define GEN6_RCPBUNIT_CLOCK_GATE_DISABLE (1 << 12) | ||
3458 | # define GEN6_RCCUNIT_CLOCK_GATE_DISABLE (1 << 11) | ||
3459 | |||
3447 | #define GEN6_RPNSWREQ 0xA008 | 3460 | #define GEN6_RPNSWREQ 0xA008 |
3448 | #define GEN6_TURBO_DISABLE (1<<31) | 3461 | #define GEN6_TURBO_DISABLE (1<<31) |
3449 | #define GEN6_FREQUENCY(x) ((x)<<25) | 3462 | #define GEN6_FREQUENCY(x) ((x)<<25) |
diff --git a/drivers/gpu/drm/i915/i915_suspend.c b/drivers/gpu/drm/i915/i915_suspend.c index f8f602d76650..7886e4fb60e3 100644 --- a/drivers/gpu/drm/i915/i915_suspend.c +++ b/drivers/gpu/drm/i915/i915_suspend.c | |||
@@ -370,6 +370,7 @@ static void i915_save_modeset_reg(struct drm_device *dev) | |||
370 | 370 | ||
371 | /* Fences */ | 371 | /* Fences */ |
372 | switch (INTEL_INFO(dev)->gen) { | 372 | switch (INTEL_INFO(dev)->gen) { |
373 | case 7: | ||
373 | case 6: | 374 | case 6: |
374 | for (i = 0; i < 16; i++) | 375 | for (i = 0; i < 16; i++) |
375 | dev_priv->saveFENCE[i] = I915_READ64(FENCE_REG_SANDYBRIDGE_0 + (i * 8)); | 376 | dev_priv->saveFENCE[i] = I915_READ64(FENCE_REG_SANDYBRIDGE_0 + (i * 8)); |
@@ -404,6 +405,7 @@ static void i915_restore_modeset_reg(struct drm_device *dev) | |||
404 | 405 | ||
405 | /* Fences */ | 406 | /* Fences */ |
406 | switch (INTEL_INFO(dev)->gen) { | 407 | switch (INTEL_INFO(dev)->gen) { |
408 | case 7: | ||
407 | case 6: | 409 | case 6: |
408 | for (i = 0; i < 16; i++) | 410 | for (i = 0; i < 16; i++) |
409 | I915_WRITE64(FENCE_REG_SANDYBRIDGE_0 + (i * 8), dev_priv->saveFENCE[i]); | 411 | I915_WRITE64(FENCE_REG_SANDYBRIDGE_0 + (i * 8), dev_priv->saveFENCE[i]); |
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 981b1f1c04d8..e77a863a3833 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c | |||
@@ -2933,7 +2933,8 @@ static void ironlake_pch_enable(struct drm_crtc *crtc) | |||
2933 | 2933 | ||
2934 | /* For PCH DP, enable TRANS_DP_CTL */ | 2934 | /* For PCH DP, enable TRANS_DP_CTL */ |
2935 | if (HAS_PCH_CPT(dev) && | 2935 | if (HAS_PCH_CPT(dev) && |
2936 | intel_pipe_has_type(crtc, INTEL_OUTPUT_DISPLAYPORT)) { | 2936 | (intel_pipe_has_type(crtc, INTEL_OUTPUT_DISPLAYPORT) || |
2937 | intel_pipe_has_type(crtc, INTEL_OUTPUT_EDP))) { | ||
2937 | u32 bpc = (I915_READ(PIPECONF(pipe)) & PIPE_BPC_MASK) >> 5; | 2938 | u32 bpc = (I915_READ(PIPECONF(pipe)) & PIPE_BPC_MASK) >> 5; |
2938 | reg = TRANS_DP_CTL(pipe); | 2939 | reg = TRANS_DP_CTL(pipe); |
2939 | temp = I915_READ(reg); | 2940 | temp = I915_READ(reg); |
@@ -4711,7 +4712,7 @@ static bool intel_choose_pipe_bpp_dither(struct drm_crtc *crtc, | |||
4711 | lvds_bpc = 6; | 4712 | lvds_bpc = 6; |
4712 | 4713 | ||
4713 | if (lvds_bpc < display_bpc) { | 4714 | if (lvds_bpc < display_bpc) { |
4714 | DRM_DEBUG_DRIVER("clamping display bpc (was %d) to LVDS (%d)\n", display_bpc, lvds_bpc); | 4715 | DRM_DEBUG_KMS("clamping display bpc (was %d) to LVDS (%d)\n", display_bpc, lvds_bpc); |
4715 | display_bpc = lvds_bpc; | 4716 | display_bpc = lvds_bpc; |
4716 | } | 4717 | } |
4717 | continue; | 4718 | continue; |
@@ -4722,7 +4723,7 @@ static bool intel_choose_pipe_bpp_dither(struct drm_crtc *crtc, | |||
4722 | unsigned int edp_bpc = dev_priv->edp.bpp / 3; | 4723 | unsigned int edp_bpc = dev_priv->edp.bpp / 3; |
4723 | 4724 | ||
4724 | if (edp_bpc < display_bpc) { | 4725 | if (edp_bpc < display_bpc) { |
4725 | DRM_DEBUG_DRIVER("clamping display bpc (was %d) to eDP (%d)\n", display_bpc, edp_bpc); | 4726 | DRM_DEBUG_KMS("clamping display bpc (was %d) to eDP (%d)\n", display_bpc, edp_bpc); |
4726 | display_bpc = edp_bpc; | 4727 | display_bpc = edp_bpc; |
4727 | } | 4728 | } |
4728 | continue; | 4729 | continue; |
@@ -4737,7 +4738,7 @@ static bool intel_choose_pipe_bpp_dither(struct drm_crtc *crtc, | |||
4737 | /* Don't use an invalid EDID bpc value */ | 4738 | /* Don't use an invalid EDID bpc value */ |
4738 | if (connector->display_info.bpc && | 4739 | if (connector->display_info.bpc && |
4739 | connector->display_info.bpc < display_bpc) { | 4740 | connector->display_info.bpc < display_bpc) { |
4740 | DRM_DEBUG_DRIVER("clamping display bpc (was %d) to EDID reported max of %d\n", display_bpc, connector->display_info.bpc); | 4741 | DRM_DEBUG_KMS("clamping display bpc (was %d) to EDID reported max of %d\n", display_bpc, connector->display_info.bpc); |
4741 | display_bpc = connector->display_info.bpc; | 4742 | display_bpc = connector->display_info.bpc; |
4742 | } | 4743 | } |
4743 | } | 4744 | } |
@@ -4748,10 +4749,10 @@ static bool intel_choose_pipe_bpp_dither(struct drm_crtc *crtc, | |||
4748 | */ | 4749 | */ |
4749 | if (intel_encoder->type == INTEL_OUTPUT_HDMI) { | 4750 | if (intel_encoder->type == INTEL_OUTPUT_HDMI) { |
4750 | if (display_bpc > 8 && display_bpc < 12) { | 4751 | if (display_bpc > 8 && display_bpc < 12) { |
4751 | DRM_DEBUG_DRIVER("forcing bpc to 12 for HDMI\n"); | 4752 | DRM_DEBUG_KMS("forcing bpc to 12 for HDMI\n"); |
4752 | display_bpc = 12; | 4753 | display_bpc = 12; |
4753 | } else { | 4754 | } else { |
4754 | DRM_DEBUG_DRIVER("forcing bpc to 8 for HDMI\n"); | 4755 | DRM_DEBUG_KMS("forcing bpc to 8 for HDMI\n"); |
4755 | display_bpc = 8; | 4756 | display_bpc = 8; |
4756 | } | 4757 | } |
4757 | } | 4758 | } |
@@ -4789,8 +4790,8 @@ static bool intel_choose_pipe_bpp_dither(struct drm_crtc *crtc, | |||
4789 | 4790 | ||
4790 | display_bpc = min(display_bpc, bpc); | 4791 | display_bpc = min(display_bpc, bpc); |
4791 | 4792 | ||
4792 | DRM_DEBUG_DRIVER("setting pipe bpc to %d (max display bpc %d)\n", | 4793 | DRM_DEBUG_KMS("setting pipe bpc to %d (max display bpc %d)\n", |
4793 | bpc, display_bpc); | 4794 | bpc, display_bpc); |
4794 | 4795 | ||
4795 | *pipe_bpp = display_bpc * 3; | 4796 | *pipe_bpp = display_bpc * 3; |
4796 | 4797 | ||
@@ -5671,7 +5672,7 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc, | |||
5671 | pipeconf &= ~PIPECONF_DITHER_TYPE_MASK; | 5672 | pipeconf &= ~PIPECONF_DITHER_TYPE_MASK; |
5672 | if ((is_lvds && dev_priv->lvds_dither) || dither) { | 5673 | if ((is_lvds && dev_priv->lvds_dither) || dither) { |
5673 | pipeconf |= PIPECONF_DITHER_EN; | 5674 | pipeconf |= PIPECONF_DITHER_EN; |
5674 | pipeconf |= PIPECONF_DITHER_TYPE_ST1; | 5675 | pipeconf |= PIPECONF_DITHER_TYPE_SP; |
5675 | } | 5676 | } |
5676 | if (is_dp || intel_encoder_is_pch_edp(&has_edp_encoder->base)) { | 5677 | if (is_dp || intel_encoder_is_pch_edp(&has_edp_encoder->base)) { |
5677 | intel_dp_set_m_n(crtc, mode, adjusted_mode); | 5678 | intel_dp_set_m_n(crtc, mode, adjusted_mode); |
@@ -8148,6 +8149,20 @@ static void gen6_init_clock_gating(struct drm_device *dev) | |||
8148 | I915_WRITE(WM2_LP_ILK, 0); | 8149 | I915_WRITE(WM2_LP_ILK, 0); |
8149 | I915_WRITE(WM1_LP_ILK, 0); | 8150 | I915_WRITE(WM1_LP_ILK, 0); |
8150 | 8151 | ||
8152 | /* According to the BSpec vol1g, bit 12 (RCPBUNIT) clock | ||
8153 | * gating disable must be set. Failure to set it results in | ||
8154 | * flickering pixels due to Z write ordering failures after | ||
8155 | * some amount of runtime in the Mesa "fire" demo, and Unigine | ||
8156 | * Sanctuary and Tropics, and apparently anything else with | ||
8157 | * alpha test or pixel discard. | ||
8158 | * | ||
8159 | * According to the spec, bit 11 (RCCUNIT) must also be set, | ||
8160 | * but we didn't debug actual testcases to find it out. | ||
8161 | */ | ||
8162 | I915_WRITE(GEN6_UCGCTL2, | ||
8163 | GEN6_RCPBUNIT_CLOCK_GATE_DISABLE | | ||
8164 | GEN6_RCCUNIT_CLOCK_GATE_DISABLE); | ||
8165 | |||
8151 | /* | 8166 | /* |
8152 | * According to the spec the following bits should be | 8167 | * According to the spec the following bits should be |
8153 | * set in order to enable memory self-refresh and fbc: | 8168 | * set in order to enable memory self-refresh and fbc: |
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 09b318b0227f..4d0358fad937 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c | |||
@@ -59,7 +59,6 @@ struct intel_dp { | |||
59 | struct i2c_algo_dp_aux_data algo; | 59 | struct i2c_algo_dp_aux_data algo; |
60 | bool is_pch_edp; | 60 | bool is_pch_edp; |
61 | uint8_t train_set[4]; | 61 | uint8_t train_set[4]; |
62 | uint8_t link_status[DP_LINK_STATUS_SIZE]; | ||
63 | int panel_power_up_delay; | 62 | int panel_power_up_delay; |
64 | int panel_power_down_delay; | 63 | int panel_power_down_delay; |
65 | int panel_power_cycle_delay; | 64 | int panel_power_cycle_delay; |
@@ -68,7 +67,6 @@ struct intel_dp { | |||
68 | struct drm_display_mode *panel_fixed_mode; /* for eDP */ | 67 | struct drm_display_mode *panel_fixed_mode; /* for eDP */ |
69 | struct delayed_work panel_vdd_work; | 68 | struct delayed_work panel_vdd_work; |
70 | bool want_panel_vdd; | 69 | bool want_panel_vdd; |
71 | unsigned long panel_off_jiffies; | ||
72 | }; | 70 | }; |
73 | 71 | ||
74 | /** | 72 | /** |
@@ -157,16 +155,12 @@ intel_edp_link_config(struct intel_encoder *intel_encoder, | |||
157 | static int | 155 | static int |
158 | intel_dp_max_lane_count(struct intel_dp *intel_dp) | 156 | intel_dp_max_lane_count(struct intel_dp *intel_dp) |
159 | { | 157 | { |
160 | int max_lane_count = 4; | 158 | int max_lane_count = intel_dp->dpcd[DP_MAX_LANE_COUNT] & 0x1f; |
161 | 159 | switch (max_lane_count) { | |
162 | if (intel_dp->dpcd[DP_DPCD_REV] >= 0x11) { | 160 | case 1: case 2: case 4: |
163 | max_lane_count = intel_dp->dpcd[DP_MAX_LANE_COUNT] & 0x1f; | 161 | break; |
164 | switch (max_lane_count) { | 162 | default: |
165 | case 1: case 2: case 4: | 163 | max_lane_count = 4; |
166 | break; | ||
167 | default: | ||
168 | max_lane_count = 4; | ||
169 | } | ||
170 | } | 164 | } |
171 | return max_lane_count; | 165 | return max_lane_count; |
172 | } | 166 | } |
@@ -768,12 +762,11 @@ intel_dp_set_m_n(struct drm_crtc *crtc, struct drm_display_mode *mode, | |||
768 | continue; | 762 | continue; |
769 | 763 | ||
770 | intel_dp = enc_to_intel_dp(encoder); | 764 | intel_dp = enc_to_intel_dp(encoder); |
771 | if (intel_dp->base.type == INTEL_OUTPUT_DISPLAYPORT) { | 765 | if (intel_dp->base.type == INTEL_OUTPUT_DISPLAYPORT || |
766 | intel_dp->base.type == INTEL_OUTPUT_EDP) | ||
767 | { | ||
772 | lane_count = intel_dp->lane_count; | 768 | lane_count = intel_dp->lane_count; |
773 | break; | 769 | break; |
774 | } else if (is_edp(intel_dp)) { | ||
775 | lane_count = dev_priv->edp.lanes; | ||
776 | break; | ||
777 | } | 770 | } |
778 | } | 771 | } |
779 | 772 | ||
@@ -810,6 +803,7 @@ intel_dp_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode, | |||
810 | struct drm_display_mode *adjusted_mode) | 803 | struct drm_display_mode *adjusted_mode) |
811 | { | 804 | { |
812 | struct drm_device *dev = encoder->dev; | 805 | struct drm_device *dev = encoder->dev; |
806 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
813 | struct intel_dp *intel_dp = enc_to_intel_dp(encoder); | 807 | struct intel_dp *intel_dp = enc_to_intel_dp(encoder); |
814 | struct drm_crtc *crtc = intel_dp->base.base.crtc; | 808 | struct drm_crtc *crtc = intel_dp->base.base.crtc; |
815 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); | 809 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
@@ -822,18 +816,31 @@ intel_dp_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode, | |||
822 | ironlake_edp_pll_off(encoder); | 816 | ironlake_edp_pll_off(encoder); |
823 | } | 817 | } |
824 | 818 | ||
825 | intel_dp->DP = DP_VOLTAGE_0_4 | DP_PRE_EMPHASIS_0; | 819 | /* |
826 | intel_dp->DP |= intel_dp->color_range; | 820 | * There are three kinds of DP registers: |
821 | * | ||
822 | * IBX PCH | ||
823 | * CPU | ||
824 | * CPT PCH | ||
825 | * | ||
826 | * IBX PCH and CPU are the same for almost everything, | ||
827 | * except that the CPU DP PLL is configured in this | ||
828 | * register | ||
829 | * | ||
830 | * CPT PCH is quite different, having many bits moved | ||
831 | * to the TRANS_DP_CTL register instead. That | ||
832 | * configuration happens (oddly) in ironlake_pch_enable | ||
833 | */ | ||
827 | 834 | ||
828 | if (adjusted_mode->flags & DRM_MODE_FLAG_PHSYNC) | 835 | /* Preserve the BIOS-computed detected bit. This is |
829 | intel_dp->DP |= DP_SYNC_HS_HIGH; | 836 | * supposed to be read-only. |
830 | if (adjusted_mode->flags & DRM_MODE_FLAG_PVSYNC) | 837 | */ |
831 | intel_dp->DP |= DP_SYNC_VS_HIGH; | 838 | intel_dp->DP = I915_READ(intel_dp->output_reg) & DP_DETECTED; |
839 | intel_dp->DP |= DP_VOLTAGE_0_4 | DP_PRE_EMPHASIS_0; | ||
832 | 840 | ||
833 | if (HAS_PCH_CPT(dev) && !is_cpu_edp(intel_dp)) | 841 | /* Handle DP bits in common between all three register formats */ |
834 | intel_dp->DP |= DP_LINK_TRAIN_OFF_CPT; | 842 | |
835 | else | 843 | intel_dp->DP |= DP_VOLTAGE_0_4 | DP_PRE_EMPHASIS_0; |
836 | intel_dp->DP |= DP_LINK_TRAIN_OFF; | ||
837 | 844 | ||
838 | switch (intel_dp->lane_count) { | 845 | switch (intel_dp->lane_count) { |
839 | case 1: | 846 | case 1: |
@@ -852,59 +859,106 @@ intel_dp_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode, | |||
852 | intel_dp->DP |= DP_AUDIO_OUTPUT_ENABLE; | 859 | intel_dp->DP |= DP_AUDIO_OUTPUT_ENABLE; |
853 | intel_write_eld(encoder, adjusted_mode); | 860 | intel_write_eld(encoder, adjusted_mode); |
854 | } | 861 | } |
855 | |||
856 | memset(intel_dp->link_configuration, 0, DP_LINK_CONFIGURATION_SIZE); | 862 | memset(intel_dp->link_configuration, 0, DP_LINK_CONFIGURATION_SIZE); |
857 | intel_dp->link_configuration[0] = intel_dp->link_bw; | 863 | intel_dp->link_configuration[0] = intel_dp->link_bw; |
858 | intel_dp->link_configuration[1] = intel_dp->lane_count; | 864 | intel_dp->link_configuration[1] = intel_dp->lane_count; |
859 | intel_dp->link_configuration[8] = DP_SET_ANSI_8B10B; | 865 | intel_dp->link_configuration[8] = DP_SET_ANSI_8B10B; |
860 | |||
861 | /* | 866 | /* |
862 | * Check for DPCD version > 1.1 and enhanced framing support | 867 | * Check for DPCD version > 1.1 and enhanced framing support |
863 | */ | 868 | */ |
864 | if (intel_dp->dpcd[DP_DPCD_REV] >= 0x11 && | 869 | if (intel_dp->dpcd[DP_DPCD_REV] >= 0x11 && |
865 | (intel_dp->dpcd[DP_MAX_LANE_COUNT] & DP_ENHANCED_FRAME_CAP)) { | 870 | (intel_dp->dpcd[DP_MAX_LANE_COUNT] & DP_ENHANCED_FRAME_CAP)) { |
866 | intel_dp->link_configuration[1] |= DP_LANE_COUNT_ENHANCED_FRAME_EN; | 871 | intel_dp->link_configuration[1] |= DP_LANE_COUNT_ENHANCED_FRAME_EN; |
867 | intel_dp->DP |= DP_ENHANCED_FRAMING; | ||
868 | } | 872 | } |
869 | 873 | ||
870 | /* CPT DP's pipe select is decided in TRANS_DP_CTL */ | 874 | /* Split out the IBX/CPU vs CPT settings */ |
871 | if (intel_crtc->pipe == 1 && !HAS_PCH_CPT(dev)) | ||
872 | intel_dp->DP |= DP_PIPEB_SELECT; | ||
873 | 875 | ||
874 | if (is_cpu_edp(intel_dp)) { | 876 | if (!HAS_PCH_CPT(dev) || is_cpu_edp(intel_dp)) { |
875 | /* don't miss out required setting for eDP */ | 877 | intel_dp->DP |= intel_dp->color_range; |
876 | intel_dp->DP |= DP_PLL_ENABLE; | 878 | |
877 | if (adjusted_mode->clock < 200000) | 879 | if (adjusted_mode->flags & DRM_MODE_FLAG_PHSYNC) |
878 | intel_dp->DP |= DP_PLL_FREQ_160MHZ; | 880 | intel_dp->DP |= DP_SYNC_HS_HIGH; |
879 | else | 881 | if (adjusted_mode->flags & DRM_MODE_FLAG_PVSYNC) |
880 | intel_dp->DP |= DP_PLL_FREQ_270MHZ; | 882 | intel_dp->DP |= DP_SYNC_VS_HIGH; |
883 | intel_dp->DP |= DP_LINK_TRAIN_OFF; | ||
884 | |||
885 | if (intel_dp->link_configuration[1] & DP_LANE_COUNT_ENHANCED_FRAME_EN) | ||
886 | intel_dp->DP |= DP_ENHANCED_FRAMING; | ||
887 | |||
888 | if (intel_crtc->pipe == 1) | ||
889 | intel_dp->DP |= DP_PIPEB_SELECT; | ||
890 | |||
891 | if (is_cpu_edp(intel_dp)) { | ||
892 | /* don't miss out required setting for eDP */ | ||
893 | intel_dp->DP |= DP_PLL_ENABLE; | ||
894 | if (adjusted_mode->clock < 200000) | ||
895 | intel_dp->DP |= DP_PLL_FREQ_160MHZ; | ||
896 | else | ||
897 | intel_dp->DP |= DP_PLL_FREQ_270MHZ; | ||
898 | } | ||
899 | } else { | ||
900 | intel_dp->DP |= DP_LINK_TRAIN_OFF_CPT; | ||
881 | } | 901 | } |
882 | } | 902 | } |
883 | 903 | ||
884 | static void ironlake_wait_panel_off(struct intel_dp *intel_dp) | 904 | #define IDLE_ON_MASK (PP_ON | 0 | PP_SEQUENCE_MASK | 0 | PP_SEQUENCE_STATE_MASK) |
905 | #define IDLE_ON_VALUE (PP_ON | 0 | PP_SEQUENCE_NONE | 0 | PP_SEQUENCE_STATE_ON_IDLE) | ||
906 | |||
907 | #define IDLE_OFF_MASK (PP_ON | 0 | PP_SEQUENCE_MASK | 0 | PP_SEQUENCE_STATE_MASK) | ||
908 | #define IDLE_OFF_VALUE (0 | 0 | PP_SEQUENCE_NONE | 0 | PP_SEQUENCE_STATE_OFF_IDLE) | ||
909 | |||
910 | #define IDLE_CYCLE_MASK (PP_ON | 0 | PP_SEQUENCE_MASK | PP_CYCLE_DELAY_ACTIVE | PP_SEQUENCE_STATE_MASK) | ||
911 | #define IDLE_CYCLE_VALUE (0 | 0 | PP_SEQUENCE_NONE | 0 | PP_SEQUENCE_STATE_OFF_IDLE) | ||
912 | |||
913 | static void ironlake_wait_panel_status(struct intel_dp *intel_dp, | ||
914 | u32 mask, | ||
915 | u32 value) | ||
885 | { | 916 | { |
886 | unsigned long off_time; | 917 | struct drm_device *dev = intel_dp->base.base.dev; |
887 | unsigned long delay; | 918 | struct drm_i915_private *dev_priv = dev->dev_private; |
888 | 919 | ||
889 | DRM_DEBUG_KMS("Wait for panel power off time\n"); | 920 | DRM_DEBUG_KMS("mask %08x value %08x status %08x control %08x\n", |
921 | mask, value, | ||
922 | I915_READ(PCH_PP_STATUS), | ||
923 | I915_READ(PCH_PP_CONTROL)); | ||
890 | 924 | ||
891 | if (ironlake_edp_have_panel_power(intel_dp) || | 925 | if (_wait_for((I915_READ(PCH_PP_STATUS) & mask) == value, 5000, 10)) { |
892 | ironlake_edp_have_panel_vdd(intel_dp)) | 926 | DRM_ERROR("Panel status timeout: status %08x control %08x\n", |
893 | { | 927 | I915_READ(PCH_PP_STATUS), |
894 | DRM_DEBUG_KMS("Panel still on, no delay needed\n"); | 928 | I915_READ(PCH_PP_CONTROL)); |
895 | return; | ||
896 | } | 929 | } |
930 | } | ||
897 | 931 | ||
898 | off_time = intel_dp->panel_off_jiffies + msecs_to_jiffies(intel_dp->panel_power_down_delay); | 932 | static void ironlake_wait_panel_on(struct intel_dp *intel_dp) |
899 | if (time_after(jiffies, off_time)) { | 933 | { |
900 | DRM_DEBUG_KMS("Time already passed"); | 934 | DRM_DEBUG_KMS("Wait for panel power on\n"); |
901 | return; | 935 | ironlake_wait_panel_status(intel_dp, IDLE_ON_MASK, IDLE_ON_VALUE); |
902 | } | 936 | } |
903 | delay = jiffies_to_msecs(off_time - jiffies); | 937 | |
904 | if (delay > intel_dp->panel_power_down_delay) | 938 | static void ironlake_wait_panel_off(struct intel_dp *intel_dp) |
905 | delay = intel_dp->panel_power_down_delay; | 939 | { |
906 | DRM_DEBUG_KMS("Waiting an additional %ld ms\n", delay); | 940 | DRM_DEBUG_KMS("Wait for panel power off time\n"); |
907 | msleep(delay); | 941 | ironlake_wait_panel_status(intel_dp, IDLE_OFF_MASK, IDLE_OFF_VALUE); |
942 | } | ||
943 | |||
944 | static void ironlake_wait_panel_power_cycle(struct intel_dp *intel_dp) | ||
945 | { | ||
946 | DRM_DEBUG_KMS("Wait for panel power cycle\n"); | ||
947 | ironlake_wait_panel_status(intel_dp, IDLE_CYCLE_MASK, IDLE_CYCLE_VALUE); | ||
948 | } | ||
949 | |||
950 | |||
951 | /* Read the current pp_control value, unlocking the register if it | ||
952 | * is locked | ||
953 | */ | ||
954 | |||
955 | static u32 ironlake_get_pp_control(struct drm_i915_private *dev_priv) | ||
956 | { | ||
957 | u32 control = I915_READ(PCH_PP_CONTROL); | ||
958 | |||
959 | control &= ~PANEL_UNLOCK_MASK; | ||
960 | control |= PANEL_UNLOCK_REGS; | ||
961 | return control; | ||
908 | } | 962 | } |
909 | 963 | ||
910 | static void ironlake_edp_panel_vdd_on(struct intel_dp *intel_dp) | 964 | static void ironlake_edp_panel_vdd_on(struct intel_dp *intel_dp) |
@@ -921,15 +975,16 @@ static void ironlake_edp_panel_vdd_on(struct intel_dp *intel_dp) | |||
921 | "eDP VDD already requested on\n"); | 975 | "eDP VDD already requested on\n"); |
922 | 976 | ||
923 | intel_dp->want_panel_vdd = true; | 977 | intel_dp->want_panel_vdd = true; |
978 | |||
924 | if (ironlake_edp_have_panel_vdd(intel_dp)) { | 979 | if (ironlake_edp_have_panel_vdd(intel_dp)) { |
925 | DRM_DEBUG_KMS("eDP VDD already on\n"); | 980 | DRM_DEBUG_KMS("eDP VDD already on\n"); |
926 | return; | 981 | return; |
927 | } | 982 | } |
928 | 983 | ||
929 | ironlake_wait_panel_off(intel_dp); | 984 | if (!ironlake_edp_have_panel_power(intel_dp)) |
930 | pp = I915_READ(PCH_PP_CONTROL); | 985 | ironlake_wait_panel_power_cycle(intel_dp); |
931 | pp &= ~PANEL_UNLOCK_MASK; | 986 | |
932 | pp |= PANEL_UNLOCK_REGS; | 987 | pp = ironlake_get_pp_control(dev_priv); |
933 | pp |= EDP_FORCE_VDD; | 988 | pp |= EDP_FORCE_VDD; |
934 | I915_WRITE(PCH_PP_CONTROL, pp); | 989 | I915_WRITE(PCH_PP_CONTROL, pp); |
935 | POSTING_READ(PCH_PP_CONTROL); | 990 | POSTING_READ(PCH_PP_CONTROL); |
@@ -952,9 +1007,7 @@ static void ironlake_panel_vdd_off_sync(struct intel_dp *intel_dp) | |||
952 | u32 pp; | 1007 | u32 pp; |
953 | 1008 | ||
954 | if (!intel_dp->want_panel_vdd && ironlake_edp_have_panel_vdd(intel_dp)) { | 1009 | if (!intel_dp->want_panel_vdd && ironlake_edp_have_panel_vdd(intel_dp)) { |
955 | pp = I915_READ(PCH_PP_CONTROL); | 1010 | pp = ironlake_get_pp_control(dev_priv); |
956 | pp &= ~PANEL_UNLOCK_MASK; | ||
957 | pp |= PANEL_UNLOCK_REGS; | ||
958 | pp &= ~EDP_FORCE_VDD; | 1011 | pp &= ~EDP_FORCE_VDD; |
959 | I915_WRITE(PCH_PP_CONTROL, pp); | 1012 | I915_WRITE(PCH_PP_CONTROL, pp); |
960 | POSTING_READ(PCH_PP_CONTROL); | 1013 | POSTING_READ(PCH_PP_CONTROL); |
@@ -962,7 +1015,8 @@ static void ironlake_panel_vdd_off_sync(struct intel_dp *intel_dp) | |||
962 | /* Make sure sequencer is idle before allowing subsequent activity */ | 1015 | /* Make sure sequencer is idle before allowing subsequent activity */ |
963 | DRM_DEBUG_KMS("PCH_PP_STATUS: 0x%08x PCH_PP_CONTROL: 0x%08x\n", | 1016 | DRM_DEBUG_KMS("PCH_PP_STATUS: 0x%08x PCH_PP_CONTROL: 0x%08x\n", |
964 | I915_READ(PCH_PP_STATUS), I915_READ(PCH_PP_CONTROL)); | 1017 | I915_READ(PCH_PP_STATUS), I915_READ(PCH_PP_CONTROL)); |
965 | intel_dp->panel_off_jiffies = jiffies; | 1018 | |
1019 | msleep(intel_dp->panel_power_down_delay); | ||
966 | } | 1020 | } |
967 | } | 1021 | } |
968 | 1022 | ||
@@ -972,9 +1026,9 @@ static void ironlake_panel_vdd_work(struct work_struct *__work) | |||
972 | struct intel_dp, panel_vdd_work); | 1026 | struct intel_dp, panel_vdd_work); |
973 | struct drm_device *dev = intel_dp->base.base.dev; | 1027 | struct drm_device *dev = intel_dp->base.base.dev; |
974 | 1028 | ||
975 | mutex_lock(&dev->struct_mutex); | 1029 | mutex_lock(&dev->mode_config.mutex); |
976 | ironlake_panel_vdd_off_sync(intel_dp); | 1030 | ironlake_panel_vdd_off_sync(intel_dp); |
977 | mutex_unlock(&dev->struct_mutex); | 1031 | mutex_unlock(&dev->mode_config.mutex); |
978 | } | 1032 | } |
979 | 1033 | ||
980 | static void ironlake_edp_panel_vdd_off(struct intel_dp *intel_dp, bool sync) | 1034 | static void ironlake_edp_panel_vdd_off(struct intel_dp *intel_dp, bool sync) |
@@ -984,7 +1038,7 @@ static void ironlake_edp_panel_vdd_off(struct intel_dp *intel_dp, bool sync) | |||
984 | 1038 | ||
985 | DRM_DEBUG_KMS("Turn eDP VDD off %d\n", intel_dp->want_panel_vdd); | 1039 | DRM_DEBUG_KMS("Turn eDP VDD off %d\n", intel_dp->want_panel_vdd); |
986 | WARN(!intel_dp->want_panel_vdd, "eDP VDD not forced on"); | 1040 | WARN(!intel_dp->want_panel_vdd, "eDP VDD not forced on"); |
987 | 1041 | ||
988 | intel_dp->want_panel_vdd = false; | 1042 | intel_dp->want_panel_vdd = false; |
989 | 1043 | ||
990 | if (sync) { | 1044 | if (sync) { |
@@ -1000,23 +1054,25 @@ static void ironlake_edp_panel_vdd_off(struct intel_dp *intel_dp, bool sync) | |||
1000 | } | 1054 | } |
1001 | } | 1055 | } |
1002 | 1056 | ||
1003 | /* Returns true if the panel was already on when called */ | ||
1004 | static void ironlake_edp_panel_on(struct intel_dp *intel_dp) | 1057 | static void ironlake_edp_panel_on(struct intel_dp *intel_dp) |
1005 | { | 1058 | { |
1006 | struct drm_device *dev = intel_dp->base.base.dev; | 1059 | struct drm_device *dev = intel_dp->base.base.dev; |
1007 | struct drm_i915_private *dev_priv = dev->dev_private; | 1060 | struct drm_i915_private *dev_priv = dev->dev_private; |
1008 | u32 pp, idle_on_mask = PP_ON | PP_SEQUENCE_STATE_ON_IDLE; | 1061 | u32 pp; |
1009 | 1062 | ||
1010 | if (!is_edp(intel_dp)) | 1063 | if (!is_edp(intel_dp)) |
1011 | return; | 1064 | return; |
1012 | if (ironlake_edp_have_panel_power(intel_dp)) | 1065 | |
1066 | DRM_DEBUG_KMS("Turn eDP power on\n"); | ||
1067 | |||
1068 | if (ironlake_edp_have_panel_power(intel_dp)) { | ||
1069 | DRM_DEBUG_KMS("eDP power already on\n"); | ||
1013 | return; | 1070 | return; |
1071 | } | ||
1014 | 1072 | ||
1015 | ironlake_wait_panel_off(intel_dp); | 1073 | ironlake_wait_panel_power_cycle(intel_dp); |
1016 | pp = I915_READ(PCH_PP_CONTROL); | ||
1017 | pp &= ~PANEL_UNLOCK_MASK; | ||
1018 | pp |= PANEL_UNLOCK_REGS; | ||
1019 | 1074 | ||
1075 | pp = ironlake_get_pp_control(dev_priv); | ||
1020 | if (IS_GEN5(dev)) { | 1076 | if (IS_GEN5(dev)) { |
1021 | /* ILK workaround: disable reset around power sequence */ | 1077 | /* ILK workaround: disable reset around power sequence */ |
1022 | pp &= ~PANEL_POWER_RESET; | 1078 | pp &= ~PANEL_POWER_RESET; |
@@ -1025,13 +1081,13 @@ static void ironlake_edp_panel_on(struct intel_dp *intel_dp) | |||
1025 | } | 1081 | } |
1026 | 1082 | ||
1027 | pp |= POWER_TARGET_ON; | 1083 | pp |= POWER_TARGET_ON; |
1084 | if (!IS_GEN5(dev)) | ||
1085 | pp |= PANEL_POWER_RESET; | ||
1086 | |||
1028 | I915_WRITE(PCH_PP_CONTROL, pp); | 1087 | I915_WRITE(PCH_PP_CONTROL, pp); |
1029 | POSTING_READ(PCH_PP_CONTROL); | 1088 | POSTING_READ(PCH_PP_CONTROL); |
1030 | 1089 | ||
1031 | if (wait_for((I915_READ(PCH_PP_STATUS) & idle_on_mask) == idle_on_mask, | 1090 | ironlake_wait_panel_on(intel_dp); |
1032 | 5000)) | ||
1033 | DRM_ERROR("panel on wait timed out: 0x%08x\n", | ||
1034 | I915_READ(PCH_PP_STATUS)); | ||
1035 | 1091 | ||
1036 | if (IS_GEN5(dev)) { | 1092 | if (IS_GEN5(dev)) { |
1037 | pp |= PANEL_POWER_RESET; /* restore panel reset bit */ | 1093 | pp |= PANEL_POWER_RESET; /* restore panel reset bit */ |
@@ -1040,46 +1096,25 @@ static void ironlake_edp_panel_on(struct intel_dp *intel_dp) | |||
1040 | } | 1096 | } |
1041 | } | 1097 | } |
1042 | 1098 | ||
1043 | static void ironlake_edp_panel_off(struct drm_encoder *encoder) | 1099 | static void ironlake_edp_panel_off(struct intel_dp *intel_dp) |
1044 | { | 1100 | { |
1045 | struct intel_dp *intel_dp = enc_to_intel_dp(encoder); | 1101 | struct drm_device *dev = intel_dp->base.base.dev; |
1046 | struct drm_device *dev = encoder->dev; | ||
1047 | struct drm_i915_private *dev_priv = dev->dev_private; | 1102 | struct drm_i915_private *dev_priv = dev->dev_private; |
1048 | u32 pp, idle_off_mask = PP_ON | PP_SEQUENCE_MASK | | 1103 | u32 pp; |
1049 | PP_CYCLE_DELAY_ACTIVE | PP_SEQUENCE_STATE_MASK; | ||
1050 | 1104 | ||
1051 | if (!is_edp(intel_dp)) | 1105 | if (!is_edp(intel_dp)) |
1052 | return; | 1106 | return; |
1053 | pp = I915_READ(PCH_PP_CONTROL); | ||
1054 | pp &= ~PANEL_UNLOCK_MASK; | ||
1055 | pp |= PANEL_UNLOCK_REGS; | ||
1056 | 1107 | ||
1057 | if (IS_GEN5(dev)) { | 1108 | DRM_DEBUG_KMS("Turn eDP power off\n"); |
1058 | /* ILK workaround: disable reset around power sequence */ | ||
1059 | pp &= ~PANEL_POWER_RESET; | ||
1060 | I915_WRITE(PCH_PP_CONTROL, pp); | ||
1061 | POSTING_READ(PCH_PP_CONTROL); | ||
1062 | } | ||
1063 | 1109 | ||
1064 | intel_dp->panel_off_jiffies = jiffies; | 1110 | WARN(intel_dp->want_panel_vdd, "Cannot turn power off while VDD is on\n"); |
1065 | 1111 | ||
1066 | if (IS_GEN5(dev)) { | 1112 | pp = ironlake_get_pp_control(dev_priv); |
1067 | pp &= ~POWER_TARGET_ON; | 1113 | pp &= ~(POWER_TARGET_ON | EDP_FORCE_VDD | PANEL_POWER_RESET | EDP_BLC_ENABLE); |
1068 | I915_WRITE(PCH_PP_CONTROL, pp); | 1114 | I915_WRITE(PCH_PP_CONTROL, pp); |
1069 | POSTING_READ(PCH_PP_CONTROL); | 1115 | POSTING_READ(PCH_PP_CONTROL); |
1070 | pp &= ~POWER_TARGET_ON; | ||
1071 | I915_WRITE(PCH_PP_CONTROL, pp); | ||
1072 | POSTING_READ(PCH_PP_CONTROL); | ||
1073 | msleep(intel_dp->panel_power_cycle_delay); | ||
1074 | |||
1075 | if (wait_for((I915_READ(PCH_PP_STATUS) & idle_off_mask) == 0, 5000)) | ||
1076 | DRM_ERROR("panel off wait timed out: 0x%08x\n", | ||
1077 | I915_READ(PCH_PP_STATUS)); | ||
1078 | 1116 | ||
1079 | pp |= PANEL_POWER_RESET; /* restore panel reset bit */ | 1117 | ironlake_wait_panel_off(intel_dp); |
1080 | I915_WRITE(PCH_PP_CONTROL, pp); | ||
1081 | POSTING_READ(PCH_PP_CONTROL); | ||
1082 | } | ||
1083 | } | 1118 | } |
1084 | 1119 | ||
1085 | static void ironlake_edp_backlight_on(struct intel_dp *intel_dp) | 1120 | static void ironlake_edp_backlight_on(struct intel_dp *intel_dp) |
@@ -1099,9 +1134,7 @@ static void ironlake_edp_backlight_on(struct intel_dp *intel_dp) | |||
1099 | * allowing it to appear. | 1134 | * allowing it to appear. |
1100 | */ | 1135 | */ |
1101 | msleep(intel_dp->backlight_on_delay); | 1136 | msleep(intel_dp->backlight_on_delay); |
1102 | pp = I915_READ(PCH_PP_CONTROL); | 1137 | pp = ironlake_get_pp_control(dev_priv); |
1103 | pp &= ~PANEL_UNLOCK_MASK; | ||
1104 | pp |= PANEL_UNLOCK_REGS; | ||
1105 | pp |= EDP_BLC_ENABLE; | 1138 | pp |= EDP_BLC_ENABLE; |
1106 | I915_WRITE(PCH_PP_CONTROL, pp); | 1139 | I915_WRITE(PCH_PP_CONTROL, pp); |
1107 | POSTING_READ(PCH_PP_CONTROL); | 1140 | POSTING_READ(PCH_PP_CONTROL); |
@@ -1117,9 +1150,7 @@ static void ironlake_edp_backlight_off(struct intel_dp *intel_dp) | |||
1117 | return; | 1150 | return; |
1118 | 1151 | ||
1119 | DRM_DEBUG_KMS("\n"); | 1152 | DRM_DEBUG_KMS("\n"); |
1120 | pp = I915_READ(PCH_PP_CONTROL); | 1153 | pp = ironlake_get_pp_control(dev_priv); |
1121 | pp &= ~PANEL_UNLOCK_MASK; | ||
1122 | pp |= PANEL_UNLOCK_REGS; | ||
1123 | pp &= ~EDP_BLC_ENABLE; | 1154 | pp &= ~EDP_BLC_ENABLE; |
1124 | I915_WRITE(PCH_PP_CONTROL, pp); | 1155 | I915_WRITE(PCH_PP_CONTROL, pp); |
1125 | POSTING_READ(PCH_PP_CONTROL); | 1156 | POSTING_READ(PCH_PP_CONTROL); |
@@ -1187,17 +1218,18 @@ static void intel_dp_prepare(struct drm_encoder *encoder) | |||
1187 | { | 1218 | { |
1188 | struct intel_dp *intel_dp = enc_to_intel_dp(encoder); | 1219 | struct intel_dp *intel_dp = enc_to_intel_dp(encoder); |
1189 | 1220 | ||
1221 | ironlake_edp_backlight_off(intel_dp); | ||
1222 | ironlake_edp_panel_off(intel_dp); | ||
1223 | |||
1190 | /* Wake up the sink first */ | 1224 | /* Wake up the sink first */ |
1191 | ironlake_edp_panel_vdd_on(intel_dp); | 1225 | ironlake_edp_panel_vdd_on(intel_dp); |
1192 | intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_ON); | 1226 | intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_ON); |
1227 | intel_dp_link_down(intel_dp); | ||
1193 | ironlake_edp_panel_vdd_off(intel_dp, false); | 1228 | ironlake_edp_panel_vdd_off(intel_dp, false); |
1194 | 1229 | ||
1195 | /* Make sure the panel is off before trying to | 1230 | /* Make sure the panel is off before trying to |
1196 | * change the mode | 1231 | * change the mode |
1197 | */ | 1232 | */ |
1198 | ironlake_edp_backlight_off(intel_dp); | ||
1199 | intel_dp_link_down(intel_dp); | ||
1200 | ironlake_edp_panel_off(encoder); | ||
1201 | } | 1233 | } |
1202 | 1234 | ||
1203 | static void intel_dp_commit(struct drm_encoder *encoder) | 1235 | static void intel_dp_commit(struct drm_encoder *encoder) |
@@ -1211,7 +1243,6 @@ static void intel_dp_commit(struct drm_encoder *encoder) | |||
1211 | intel_dp_start_link_train(intel_dp); | 1243 | intel_dp_start_link_train(intel_dp); |
1212 | ironlake_edp_panel_on(intel_dp); | 1244 | ironlake_edp_panel_on(intel_dp); |
1213 | ironlake_edp_panel_vdd_off(intel_dp, true); | 1245 | ironlake_edp_panel_vdd_off(intel_dp, true); |
1214 | |||
1215 | intel_dp_complete_link_train(intel_dp); | 1246 | intel_dp_complete_link_train(intel_dp); |
1216 | ironlake_edp_backlight_on(intel_dp); | 1247 | ironlake_edp_backlight_on(intel_dp); |
1217 | 1248 | ||
@@ -1230,16 +1261,20 @@ intel_dp_dpms(struct drm_encoder *encoder, int mode) | |||
1230 | uint32_t dp_reg = I915_READ(intel_dp->output_reg); | 1261 | uint32_t dp_reg = I915_READ(intel_dp->output_reg); |
1231 | 1262 | ||
1232 | if (mode != DRM_MODE_DPMS_ON) { | 1263 | if (mode != DRM_MODE_DPMS_ON) { |
1264 | ironlake_edp_backlight_off(intel_dp); | ||
1265 | ironlake_edp_panel_off(intel_dp); | ||
1266 | |||
1233 | ironlake_edp_panel_vdd_on(intel_dp); | 1267 | ironlake_edp_panel_vdd_on(intel_dp); |
1234 | if (is_edp(intel_dp)) | ||
1235 | ironlake_edp_backlight_off(intel_dp); | ||
1236 | intel_dp_sink_dpms(intel_dp, mode); | 1268 | intel_dp_sink_dpms(intel_dp, mode); |
1237 | intel_dp_link_down(intel_dp); | 1269 | intel_dp_link_down(intel_dp); |
1238 | ironlake_edp_panel_off(encoder); | ||
1239 | if (is_edp(intel_dp) && !is_pch_edp(intel_dp)) | ||
1240 | ironlake_edp_pll_off(encoder); | ||
1241 | ironlake_edp_panel_vdd_off(intel_dp, false); | 1270 | ironlake_edp_panel_vdd_off(intel_dp, false); |
1271 | |||
1272 | if (is_cpu_edp(intel_dp)) | ||
1273 | ironlake_edp_pll_off(encoder); | ||
1242 | } else { | 1274 | } else { |
1275 | if (is_cpu_edp(intel_dp)) | ||
1276 | ironlake_edp_pll_on(encoder); | ||
1277 | |||
1243 | ironlake_edp_panel_vdd_on(intel_dp); | 1278 | ironlake_edp_panel_vdd_on(intel_dp); |
1244 | intel_dp_sink_dpms(intel_dp, mode); | 1279 | intel_dp_sink_dpms(intel_dp, mode); |
1245 | if (!(dp_reg & DP_PORT_EN)) { | 1280 | if (!(dp_reg & DP_PORT_EN)) { |
@@ -1247,7 +1282,6 @@ intel_dp_dpms(struct drm_encoder *encoder, int mode) | |||
1247 | ironlake_edp_panel_on(intel_dp); | 1282 | ironlake_edp_panel_on(intel_dp); |
1248 | ironlake_edp_panel_vdd_off(intel_dp, true); | 1283 | ironlake_edp_panel_vdd_off(intel_dp, true); |
1249 | intel_dp_complete_link_train(intel_dp); | 1284 | intel_dp_complete_link_train(intel_dp); |
1250 | ironlake_edp_backlight_on(intel_dp); | ||
1251 | } else | 1285 | } else |
1252 | ironlake_edp_panel_vdd_off(intel_dp, false); | 1286 | ironlake_edp_panel_vdd_off(intel_dp, false); |
1253 | ironlake_edp_backlight_on(intel_dp); | 1287 | ironlake_edp_backlight_on(intel_dp); |
@@ -1285,11 +1319,11 @@ intel_dp_aux_native_read_retry(struct intel_dp *intel_dp, uint16_t address, | |||
1285 | * link status information | 1319 | * link status information |
1286 | */ | 1320 | */ |
1287 | static bool | 1321 | static bool |
1288 | intel_dp_get_link_status(struct intel_dp *intel_dp) | 1322 | intel_dp_get_link_status(struct intel_dp *intel_dp, uint8_t link_status[DP_LINK_STATUS_SIZE]) |
1289 | { | 1323 | { |
1290 | return intel_dp_aux_native_read_retry(intel_dp, | 1324 | return intel_dp_aux_native_read_retry(intel_dp, |
1291 | DP_LANE0_1_STATUS, | 1325 | DP_LANE0_1_STATUS, |
1292 | intel_dp->link_status, | 1326 | link_status, |
1293 | DP_LINK_STATUS_SIZE); | 1327 | DP_LINK_STATUS_SIZE); |
1294 | } | 1328 | } |
1295 | 1329 | ||
@@ -1301,27 +1335,25 @@ intel_dp_link_status(uint8_t link_status[DP_LINK_STATUS_SIZE], | |||
1301 | } | 1335 | } |
1302 | 1336 | ||
1303 | static uint8_t | 1337 | static uint8_t |
1304 | intel_get_adjust_request_voltage(uint8_t link_status[DP_LINK_STATUS_SIZE], | 1338 | intel_get_adjust_request_voltage(uint8_t adjust_request[2], |
1305 | int lane) | 1339 | int lane) |
1306 | { | 1340 | { |
1307 | int i = DP_ADJUST_REQUEST_LANE0_1 + (lane >> 1); | ||
1308 | int s = ((lane & 1) ? | 1341 | int s = ((lane & 1) ? |
1309 | DP_ADJUST_VOLTAGE_SWING_LANE1_SHIFT : | 1342 | DP_ADJUST_VOLTAGE_SWING_LANE1_SHIFT : |
1310 | DP_ADJUST_VOLTAGE_SWING_LANE0_SHIFT); | 1343 | DP_ADJUST_VOLTAGE_SWING_LANE0_SHIFT); |
1311 | uint8_t l = intel_dp_link_status(link_status, i); | 1344 | uint8_t l = adjust_request[lane>>1]; |
1312 | 1345 | ||
1313 | return ((l >> s) & 3) << DP_TRAIN_VOLTAGE_SWING_SHIFT; | 1346 | return ((l >> s) & 3) << DP_TRAIN_VOLTAGE_SWING_SHIFT; |
1314 | } | 1347 | } |
1315 | 1348 | ||
1316 | static uint8_t | 1349 | static uint8_t |
1317 | intel_get_adjust_request_pre_emphasis(uint8_t link_status[DP_LINK_STATUS_SIZE], | 1350 | intel_get_adjust_request_pre_emphasis(uint8_t adjust_request[2], |
1318 | int lane) | 1351 | int lane) |
1319 | { | 1352 | { |
1320 | int i = DP_ADJUST_REQUEST_LANE0_1 + (lane >> 1); | ||
1321 | int s = ((lane & 1) ? | 1353 | int s = ((lane & 1) ? |
1322 | DP_ADJUST_PRE_EMPHASIS_LANE1_SHIFT : | 1354 | DP_ADJUST_PRE_EMPHASIS_LANE1_SHIFT : |
1323 | DP_ADJUST_PRE_EMPHASIS_LANE0_SHIFT); | 1355 | DP_ADJUST_PRE_EMPHASIS_LANE0_SHIFT); |
1324 | uint8_t l = intel_dp_link_status(link_status, i); | 1356 | uint8_t l = adjust_request[lane>>1]; |
1325 | 1357 | ||
1326 | return ((l >> s) & 3) << DP_TRAIN_PRE_EMPHASIS_SHIFT; | 1358 | return ((l >> s) & 3) << DP_TRAIN_PRE_EMPHASIS_SHIFT; |
1327 | } | 1359 | } |
@@ -1344,6 +1376,7 @@ static char *link_train_names[] = { | |||
1344 | * a maximum voltage of 800mV and a maximum pre-emphasis of 6dB | 1376 | * a maximum voltage of 800mV and a maximum pre-emphasis of 6dB |
1345 | */ | 1377 | */ |
1346 | #define I830_DP_VOLTAGE_MAX DP_TRAIN_VOLTAGE_SWING_800 | 1378 | #define I830_DP_VOLTAGE_MAX DP_TRAIN_VOLTAGE_SWING_800 |
1379 | #define I830_DP_VOLTAGE_MAX_CPT DP_TRAIN_VOLTAGE_SWING_1200 | ||
1347 | 1380 | ||
1348 | static uint8_t | 1381 | static uint8_t |
1349 | intel_dp_pre_emphasis_max(uint8_t voltage_swing) | 1382 | intel_dp_pre_emphasis_max(uint8_t voltage_swing) |
@@ -1362,15 +1395,18 @@ intel_dp_pre_emphasis_max(uint8_t voltage_swing) | |||
1362 | } | 1395 | } |
1363 | 1396 | ||
1364 | static void | 1397 | static void |
1365 | intel_get_adjust_train(struct intel_dp *intel_dp) | 1398 | intel_get_adjust_train(struct intel_dp *intel_dp, uint8_t link_status[DP_LINK_STATUS_SIZE]) |
1366 | { | 1399 | { |
1400 | struct drm_device *dev = intel_dp->base.base.dev; | ||
1367 | uint8_t v = 0; | 1401 | uint8_t v = 0; |
1368 | uint8_t p = 0; | 1402 | uint8_t p = 0; |
1369 | int lane; | 1403 | int lane; |
1404 | uint8_t *adjust_request = link_status + (DP_ADJUST_REQUEST_LANE0_1 - DP_LANE0_1_STATUS); | ||
1405 | int voltage_max; | ||
1370 | 1406 | ||
1371 | for (lane = 0; lane < intel_dp->lane_count; lane++) { | 1407 | for (lane = 0; lane < intel_dp->lane_count; lane++) { |
1372 | uint8_t this_v = intel_get_adjust_request_voltage(intel_dp->link_status, lane); | 1408 | uint8_t this_v = intel_get_adjust_request_voltage(adjust_request, lane); |
1373 | uint8_t this_p = intel_get_adjust_request_pre_emphasis(intel_dp->link_status, lane); | 1409 | uint8_t this_p = intel_get_adjust_request_pre_emphasis(adjust_request, lane); |
1374 | 1410 | ||
1375 | if (this_v > v) | 1411 | if (this_v > v) |
1376 | v = this_v; | 1412 | v = this_v; |
@@ -1378,8 +1414,12 @@ intel_get_adjust_train(struct intel_dp *intel_dp) | |||
1378 | p = this_p; | 1414 | p = this_p; |
1379 | } | 1415 | } |
1380 | 1416 | ||
1381 | if (v >= I830_DP_VOLTAGE_MAX) | 1417 | if (HAS_PCH_CPT(dev) && !is_cpu_edp(intel_dp)) |
1382 | v = I830_DP_VOLTAGE_MAX | DP_TRAIN_MAX_SWING_REACHED; | 1418 | voltage_max = I830_DP_VOLTAGE_MAX_CPT; |
1419 | else | ||
1420 | voltage_max = I830_DP_VOLTAGE_MAX; | ||
1421 | if (v >= voltage_max) | ||
1422 | v = voltage_max | DP_TRAIN_MAX_SWING_REACHED; | ||
1383 | 1423 | ||
1384 | if (p >= intel_dp_pre_emphasis_max(v)) | 1424 | if (p >= intel_dp_pre_emphasis_max(v)) |
1385 | p = intel_dp_pre_emphasis_max(v) | DP_TRAIN_MAX_PRE_EMPHASIS_REACHED; | 1425 | p = intel_dp_pre_emphasis_max(v) | DP_TRAIN_MAX_PRE_EMPHASIS_REACHED; |
@@ -1389,7 +1429,7 @@ intel_get_adjust_train(struct intel_dp *intel_dp) | |||
1389 | } | 1429 | } |
1390 | 1430 | ||
1391 | static uint32_t | 1431 | static uint32_t |
1392 | intel_dp_signal_levels(uint8_t train_set, int lane_count) | 1432 | intel_dp_signal_levels(uint8_t train_set) |
1393 | { | 1433 | { |
1394 | uint32_t signal_levels = 0; | 1434 | uint32_t signal_levels = 0; |
1395 | 1435 | ||
@@ -1458,9 +1498,8 @@ static uint8_t | |||
1458 | intel_get_lane_status(uint8_t link_status[DP_LINK_STATUS_SIZE], | 1498 | intel_get_lane_status(uint8_t link_status[DP_LINK_STATUS_SIZE], |
1459 | int lane) | 1499 | int lane) |
1460 | { | 1500 | { |
1461 | int i = DP_LANE0_1_STATUS + (lane >> 1); | ||
1462 | int s = (lane & 1) * 4; | 1501 | int s = (lane & 1) * 4; |
1463 | uint8_t l = intel_dp_link_status(link_status, i); | 1502 | uint8_t l = link_status[lane>>1]; |
1464 | 1503 | ||
1465 | return (l >> s) & 0xf; | 1504 | return (l >> s) & 0xf; |
1466 | } | 1505 | } |
@@ -1485,18 +1524,18 @@ intel_clock_recovery_ok(uint8_t link_status[DP_LINK_STATUS_SIZE], int lane_count | |||
1485 | DP_LANE_CHANNEL_EQ_DONE|\ | 1524 | DP_LANE_CHANNEL_EQ_DONE|\ |
1486 | DP_LANE_SYMBOL_LOCKED) | 1525 | DP_LANE_SYMBOL_LOCKED) |
1487 | static bool | 1526 | static bool |
1488 | intel_channel_eq_ok(struct intel_dp *intel_dp) | 1527 | intel_channel_eq_ok(struct intel_dp *intel_dp, uint8_t link_status[DP_LINK_STATUS_SIZE]) |
1489 | { | 1528 | { |
1490 | uint8_t lane_align; | 1529 | uint8_t lane_align; |
1491 | uint8_t lane_status; | 1530 | uint8_t lane_status; |
1492 | int lane; | 1531 | int lane; |
1493 | 1532 | ||
1494 | lane_align = intel_dp_link_status(intel_dp->link_status, | 1533 | lane_align = intel_dp_link_status(link_status, |
1495 | DP_LANE_ALIGN_STATUS_UPDATED); | 1534 | DP_LANE_ALIGN_STATUS_UPDATED); |
1496 | if ((lane_align & DP_INTERLANE_ALIGN_DONE) == 0) | 1535 | if ((lane_align & DP_INTERLANE_ALIGN_DONE) == 0) |
1497 | return false; | 1536 | return false; |
1498 | for (lane = 0; lane < intel_dp->lane_count; lane++) { | 1537 | for (lane = 0; lane < intel_dp->lane_count; lane++) { |
1499 | lane_status = intel_get_lane_status(intel_dp->link_status, lane); | 1538 | lane_status = intel_get_lane_status(link_status, lane); |
1500 | if ((lane_status & CHANNEL_EQ_BITS) != CHANNEL_EQ_BITS) | 1539 | if ((lane_status & CHANNEL_EQ_BITS) != CHANNEL_EQ_BITS) |
1501 | return false; | 1540 | return false; |
1502 | } | 1541 | } |
@@ -1521,8 +1560,9 @@ intel_dp_set_link_train(struct intel_dp *intel_dp, | |||
1521 | 1560 | ||
1522 | ret = intel_dp_aux_native_write(intel_dp, | 1561 | ret = intel_dp_aux_native_write(intel_dp, |
1523 | DP_TRAINING_LANE0_SET, | 1562 | DP_TRAINING_LANE0_SET, |
1524 | intel_dp->train_set, 4); | 1563 | intel_dp->train_set, |
1525 | if (ret != 4) | 1564 | intel_dp->lane_count); |
1565 | if (ret != intel_dp->lane_count) | ||
1526 | return false; | 1566 | return false; |
1527 | 1567 | ||
1528 | return true; | 1568 | return true; |
@@ -1538,7 +1578,7 @@ intel_dp_start_link_train(struct intel_dp *intel_dp) | |||
1538 | int i; | 1578 | int i; |
1539 | uint8_t voltage; | 1579 | uint8_t voltage; |
1540 | bool clock_recovery = false; | 1580 | bool clock_recovery = false; |
1541 | int tries; | 1581 | int voltage_tries, loop_tries; |
1542 | u32 reg; | 1582 | u32 reg; |
1543 | uint32_t DP = intel_dp->DP; | 1583 | uint32_t DP = intel_dp->DP; |
1544 | 1584 | ||
@@ -1565,16 +1605,20 @@ intel_dp_start_link_train(struct intel_dp *intel_dp) | |||
1565 | DP &= ~DP_LINK_TRAIN_MASK; | 1605 | DP &= ~DP_LINK_TRAIN_MASK; |
1566 | memset(intel_dp->train_set, 0, 4); | 1606 | memset(intel_dp->train_set, 0, 4); |
1567 | voltage = 0xff; | 1607 | voltage = 0xff; |
1568 | tries = 0; | 1608 | voltage_tries = 0; |
1609 | loop_tries = 0; | ||
1569 | clock_recovery = false; | 1610 | clock_recovery = false; |
1570 | for (;;) { | 1611 | for (;;) { |
1571 | /* Use intel_dp->train_set[0] to set the voltage and pre emphasis values */ | 1612 | /* Use intel_dp->train_set[0] to set the voltage and pre emphasis values */ |
1613 | uint8_t link_status[DP_LINK_STATUS_SIZE]; | ||
1572 | uint32_t signal_levels; | 1614 | uint32_t signal_levels; |
1573 | if (IS_GEN6(dev) && is_edp(intel_dp)) { | 1615 | |
1616 | if (IS_GEN6(dev) && is_cpu_edp(intel_dp)) { | ||
1574 | signal_levels = intel_gen6_edp_signal_levels(intel_dp->train_set[0]); | 1617 | signal_levels = intel_gen6_edp_signal_levels(intel_dp->train_set[0]); |
1575 | DP = (DP & ~EDP_LINK_TRAIN_VOL_EMP_MASK_SNB) | signal_levels; | 1618 | DP = (DP & ~EDP_LINK_TRAIN_VOL_EMP_MASK_SNB) | signal_levels; |
1576 | } else { | 1619 | } else { |
1577 | signal_levels = intel_dp_signal_levels(intel_dp->train_set[0], intel_dp->lane_count); | 1620 | signal_levels = intel_dp_signal_levels(intel_dp->train_set[0]); |
1621 | DRM_DEBUG_KMS("training pattern 1 signal levels %08x\n", signal_levels); | ||
1578 | DP = (DP & ~(DP_VOLTAGE_MASK|DP_PRE_EMPHASIS_MASK)) | signal_levels; | 1622 | DP = (DP & ~(DP_VOLTAGE_MASK|DP_PRE_EMPHASIS_MASK)) | signal_levels; |
1579 | } | 1623 | } |
1580 | 1624 | ||
@@ -1590,10 +1634,13 @@ intel_dp_start_link_train(struct intel_dp *intel_dp) | |||
1590 | /* Set training pattern 1 */ | 1634 | /* Set training pattern 1 */ |
1591 | 1635 | ||
1592 | udelay(100); | 1636 | udelay(100); |
1593 | if (!intel_dp_get_link_status(intel_dp)) | 1637 | if (!intel_dp_get_link_status(intel_dp, link_status)) { |
1638 | DRM_ERROR("failed to get link status\n"); | ||
1594 | break; | 1639 | break; |
1640 | } | ||
1595 | 1641 | ||
1596 | if (intel_clock_recovery_ok(intel_dp->link_status, intel_dp->lane_count)) { | 1642 | if (intel_clock_recovery_ok(link_status, intel_dp->lane_count)) { |
1643 | DRM_DEBUG_KMS("clock recovery OK\n"); | ||
1597 | clock_recovery = true; | 1644 | clock_recovery = true; |
1598 | break; | 1645 | break; |
1599 | } | 1646 | } |
@@ -1602,20 +1649,30 @@ intel_dp_start_link_train(struct intel_dp *intel_dp) | |||
1602 | for (i = 0; i < intel_dp->lane_count; i++) | 1649 | for (i = 0; i < intel_dp->lane_count; i++) |
1603 | if ((intel_dp->train_set[i] & DP_TRAIN_MAX_SWING_REACHED) == 0) | 1650 | if ((intel_dp->train_set[i] & DP_TRAIN_MAX_SWING_REACHED) == 0) |
1604 | break; | 1651 | break; |
1605 | if (i == intel_dp->lane_count) | 1652 | if (i == intel_dp->lane_count) { |
1606 | break; | 1653 | ++loop_tries; |
1654 | if (loop_tries == 5) { | ||
1655 | DRM_DEBUG_KMS("too many full retries, give up\n"); | ||
1656 | break; | ||
1657 | } | ||
1658 | memset(intel_dp->train_set, 0, 4); | ||
1659 | voltage_tries = 0; | ||
1660 | continue; | ||
1661 | } | ||
1607 | 1662 | ||
1608 | /* Check to see if we've tried the same voltage 5 times */ | 1663 | /* Check to see if we've tried the same voltage 5 times */ |
1609 | if ((intel_dp->train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK) == voltage) { | 1664 | if ((intel_dp->train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK) == voltage) { |
1610 | ++tries; | 1665 | ++voltage_tries; |
1611 | if (tries == 5) | 1666 | if (voltage_tries == 5) { |
1667 | DRM_DEBUG_KMS("too many voltage retries, give up\n"); | ||
1612 | break; | 1668 | break; |
1669 | } | ||
1613 | } else | 1670 | } else |
1614 | tries = 0; | 1671 | voltage_tries = 0; |
1615 | voltage = intel_dp->train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK; | 1672 | voltage = intel_dp->train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK; |
1616 | 1673 | ||
1617 | /* Compute new intel_dp->train_set as requested by target */ | 1674 | /* Compute new intel_dp->train_set as requested by target */ |
1618 | intel_get_adjust_train(intel_dp); | 1675 | intel_get_adjust_train(intel_dp, link_status); |
1619 | } | 1676 | } |
1620 | 1677 | ||
1621 | intel_dp->DP = DP; | 1678 | intel_dp->DP = DP; |
@@ -1638,6 +1695,7 @@ intel_dp_complete_link_train(struct intel_dp *intel_dp) | |||
1638 | for (;;) { | 1695 | for (;;) { |
1639 | /* Use intel_dp->train_set[0] to set the voltage and pre emphasis values */ | 1696 | /* Use intel_dp->train_set[0] to set the voltage and pre emphasis values */ |
1640 | uint32_t signal_levels; | 1697 | uint32_t signal_levels; |
1698 | uint8_t link_status[DP_LINK_STATUS_SIZE]; | ||
1641 | 1699 | ||
1642 | if (cr_tries > 5) { | 1700 | if (cr_tries > 5) { |
1643 | DRM_ERROR("failed to train DP, aborting\n"); | 1701 | DRM_ERROR("failed to train DP, aborting\n"); |
@@ -1645,11 +1703,11 @@ intel_dp_complete_link_train(struct intel_dp *intel_dp) | |||
1645 | break; | 1703 | break; |
1646 | } | 1704 | } |
1647 | 1705 | ||
1648 | if (IS_GEN6(dev) && is_edp(intel_dp)) { | 1706 | if (IS_GEN6(dev) && is_cpu_edp(intel_dp)) { |
1649 | signal_levels = intel_gen6_edp_signal_levels(intel_dp->train_set[0]); | 1707 | signal_levels = intel_gen6_edp_signal_levels(intel_dp->train_set[0]); |
1650 | DP = (DP & ~EDP_LINK_TRAIN_VOL_EMP_MASK_SNB) | signal_levels; | 1708 | DP = (DP & ~EDP_LINK_TRAIN_VOL_EMP_MASK_SNB) | signal_levels; |
1651 | } else { | 1709 | } else { |
1652 | signal_levels = intel_dp_signal_levels(intel_dp->train_set[0], intel_dp->lane_count); | 1710 | signal_levels = intel_dp_signal_levels(intel_dp->train_set[0]); |
1653 | DP = (DP & ~(DP_VOLTAGE_MASK|DP_PRE_EMPHASIS_MASK)) | signal_levels; | 1711 | DP = (DP & ~(DP_VOLTAGE_MASK|DP_PRE_EMPHASIS_MASK)) | signal_levels; |
1654 | } | 1712 | } |
1655 | 1713 | ||
@@ -1665,17 +1723,17 @@ intel_dp_complete_link_train(struct intel_dp *intel_dp) | |||
1665 | break; | 1723 | break; |
1666 | 1724 | ||
1667 | udelay(400); | 1725 | udelay(400); |
1668 | if (!intel_dp_get_link_status(intel_dp)) | 1726 | if (!intel_dp_get_link_status(intel_dp, link_status)) |
1669 | break; | 1727 | break; |
1670 | 1728 | ||
1671 | /* Make sure clock is still ok */ | 1729 | /* Make sure clock is still ok */ |
1672 | if (!intel_clock_recovery_ok(intel_dp->link_status, intel_dp->lane_count)) { | 1730 | if (!intel_clock_recovery_ok(link_status, intel_dp->lane_count)) { |
1673 | intel_dp_start_link_train(intel_dp); | 1731 | intel_dp_start_link_train(intel_dp); |
1674 | cr_tries++; | 1732 | cr_tries++; |
1675 | continue; | 1733 | continue; |
1676 | } | 1734 | } |
1677 | 1735 | ||
1678 | if (intel_channel_eq_ok(intel_dp)) { | 1736 | if (intel_channel_eq_ok(intel_dp, link_status)) { |
1679 | channel_eq = true; | 1737 | channel_eq = true; |
1680 | break; | 1738 | break; |
1681 | } | 1739 | } |
@@ -1690,7 +1748,7 @@ intel_dp_complete_link_train(struct intel_dp *intel_dp) | |||
1690 | } | 1748 | } |
1691 | 1749 | ||
1692 | /* Compute new intel_dp->train_set as requested by target */ | 1750 | /* Compute new intel_dp->train_set as requested by target */ |
1693 | intel_get_adjust_train(intel_dp); | 1751 | intel_get_adjust_train(intel_dp, link_status); |
1694 | ++tries; | 1752 | ++tries; |
1695 | } | 1753 | } |
1696 | 1754 | ||
@@ -1735,8 +1793,12 @@ intel_dp_link_down(struct intel_dp *intel_dp) | |||
1735 | 1793 | ||
1736 | msleep(17); | 1794 | msleep(17); |
1737 | 1795 | ||
1738 | if (is_edp(intel_dp)) | 1796 | if (is_edp(intel_dp)) { |
1739 | DP |= DP_LINK_TRAIN_OFF; | 1797 | if (HAS_PCH_CPT(dev) && !is_cpu_edp(intel_dp)) |
1798 | DP |= DP_LINK_TRAIN_OFF_CPT; | ||
1799 | else | ||
1800 | DP |= DP_LINK_TRAIN_OFF; | ||
1801 | } | ||
1740 | 1802 | ||
1741 | if (!HAS_PCH_CPT(dev) && | 1803 | if (!HAS_PCH_CPT(dev) && |
1742 | I915_READ(intel_dp->output_reg) & DP_PIPEB_SELECT) { | 1804 | I915_READ(intel_dp->output_reg) & DP_PIPEB_SELECT) { |
@@ -1822,6 +1884,7 @@ static void | |||
1822 | intel_dp_check_link_status(struct intel_dp *intel_dp) | 1884 | intel_dp_check_link_status(struct intel_dp *intel_dp) |
1823 | { | 1885 | { |
1824 | u8 sink_irq_vector; | 1886 | u8 sink_irq_vector; |
1887 | u8 link_status[DP_LINK_STATUS_SIZE]; | ||
1825 | 1888 | ||
1826 | if (intel_dp->dpms_mode != DRM_MODE_DPMS_ON) | 1889 | if (intel_dp->dpms_mode != DRM_MODE_DPMS_ON) |
1827 | return; | 1890 | return; |
@@ -1830,7 +1893,7 @@ intel_dp_check_link_status(struct intel_dp *intel_dp) | |||
1830 | return; | 1893 | return; |
1831 | 1894 | ||
1832 | /* Try to read receiver status if the link appears to be up */ | 1895 | /* Try to read receiver status if the link appears to be up */ |
1833 | if (!intel_dp_get_link_status(intel_dp)) { | 1896 | if (!intel_dp_get_link_status(intel_dp, link_status)) { |
1834 | intel_dp_link_down(intel_dp); | 1897 | intel_dp_link_down(intel_dp); |
1835 | return; | 1898 | return; |
1836 | } | 1899 | } |
@@ -1855,7 +1918,7 @@ intel_dp_check_link_status(struct intel_dp *intel_dp) | |||
1855 | DRM_DEBUG_DRIVER("CP or sink specific irq unhandled\n"); | 1918 | DRM_DEBUG_DRIVER("CP or sink specific irq unhandled\n"); |
1856 | } | 1919 | } |
1857 | 1920 | ||
1858 | if (!intel_channel_eq_ok(intel_dp)) { | 1921 | if (!intel_channel_eq_ok(intel_dp, link_status)) { |
1859 | DRM_DEBUG_KMS("%s: channel EQ not ok, retraining\n", | 1922 | DRM_DEBUG_KMS("%s: channel EQ not ok, retraining\n", |
1860 | drm_get_encoder_name(&intel_dp->base.base)); | 1923 | drm_get_encoder_name(&intel_dp->base.base)); |
1861 | intel_dp_start_link_train(intel_dp); | 1924 | intel_dp_start_link_train(intel_dp); |
@@ -2179,7 +2242,8 @@ intel_trans_dp_port_sel(struct drm_crtc *crtc) | |||
2179 | continue; | 2242 | continue; |
2180 | 2243 | ||
2181 | intel_dp = enc_to_intel_dp(encoder); | 2244 | intel_dp = enc_to_intel_dp(encoder); |
2182 | if (intel_dp->base.type == INTEL_OUTPUT_DISPLAYPORT) | 2245 | if (intel_dp->base.type == INTEL_OUTPUT_DISPLAYPORT || |
2246 | intel_dp->base.type == INTEL_OUTPUT_EDP) | ||
2183 | return intel_dp->output_reg; | 2247 | return intel_dp->output_reg; |
2184 | } | 2248 | } |
2185 | 2249 | ||
@@ -2321,7 +2385,7 @@ intel_dp_init(struct drm_device *dev, int output_reg) | |||
2321 | 2385 | ||
2322 | cur.t8 = (pp_on & PANEL_LIGHT_ON_DELAY_MASK) >> | 2386 | cur.t8 = (pp_on & PANEL_LIGHT_ON_DELAY_MASK) >> |
2323 | PANEL_LIGHT_ON_DELAY_SHIFT; | 2387 | PANEL_LIGHT_ON_DELAY_SHIFT; |
2324 | 2388 | ||
2325 | cur.t9 = (pp_off & PANEL_LIGHT_OFF_DELAY_MASK) >> | 2389 | cur.t9 = (pp_off & PANEL_LIGHT_OFF_DELAY_MASK) >> |
2326 | PANEL_LIGHT_OFF_DELAY_SHIFT; | 2390 | PANEL_LIGHT_OFF_DELAY_SHIFT; |
2327 | 2391 | ||
@@ -2354,11 +2418,10 @@ intel_dp_init(struct drm_device *dev, int output_reg) | |||
2354 | DRM_DEBUG_KMS("backlight on delay %d, off delay %d\n", | 2418 | DRM_DEBUG_KMS("backlight on delay %d, off delay %d\n", |
2355 | intel_dp->backlight_on_delay, intel_dp->backlight_off_delay); | 2419 | intel_dp->backlight_on_delay, intel_dp->backlight_off_delay); |
2356 | 2420 | ||
2357 | intel_dp->panel_off_jiffies = jiffies - intel_dp->panel_power_down_delay; | ||
2358 | |||
2359 | ironlake_edp_panel_vdd_on(intel_dp); | 2421 | ironlake_edp_panel_vdd_on(intel_dp); |
2360 | ret = intel_dp_get_dpcd(intel_dp); | 2422 | ret = intel_dp_get_dpcd(intel_dp); |
2361 | ironlake_edp_panel_vdd_off(intel_dp, false); | 2423 | ironlake_edp_panel_vdd_off(intel_dp, false); |
2424 | |||
2362 | if (ret) { | 2425 | if (ret) { |
2363 | if (intel_dp->dpcd[DP_DPCD_REV] >= 0x11) | 2426 | if (intel_dp->dpcd[DP_DPCD_REV] >= 0x11) |
2364 | dev_priv->no_aux_handshake = | 2427 | dev_priv->no_aux_handshake = |
diff --git a/drivers/gpu/drm/i915/intel_panel.c b/drivers/gpu/drm/i915/intel_panel.c index 499d4c0dbeeb..21f60b7d69a3 100644 --- a/drivers/gpu/drm/i915/intel_panel.c +++ b/drivers/gpu/drm/i915/intel_panel.c | |||
@@ -326,7 +326,8 @@ static int intel_panel_update_status(struct backlight_device *bd) | |||
326 | static int intel_panel_get_brightness(struct backlight_device *bd) | 326 | static int intel_panel_get_brightness(struct backlight_device *bd) |
327 | { | 327 | { |
328 | struct drm_device *dev = bl_get_data(bd); | 328 | struct drm_device *dev = bl_get_data(bd); |
329 | return intel_panel_get_backlight(dev); | 329 | struct drm_i915_private *dev_priv = dev->dev_private; |
330 | return dev_priv->backlight_level; | ||
330 | } | 331 | } |
331 | 332 | ||
332 | static const struct backlight_ops intel_panel_bl_ops = { | 333 | static const struct backlight_ops intel_panel_bl_ops = { |
diff --git a/drivers/gpu/drm/radeon/evergreen_cs.c b/drivers/gpu/drm/radeon/evergreen_cs.c index 7fdfa8ea7570..38e1bda73d33 100644 --- a/drivers/gpu/drm/radeon/evergreen_cs.c +++ b/drivers/gpu/drm/radeon/evergreen_cs.c | |||
@@ -480,21 +480,23 @@ static int evergreen_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx) | |||
480 | } | 480 | } |
481 | break; | 481 | break; |
482 | case DB_Z_INFO: | 482 | case DB_Z_INFO: |
483 | r = evergreen_cs_packet_next_reloc(p, &reloc); | ||
484 | if (r) { | ||
485 | dev_warn(p->dev, "bad SET_CONTEXT_REG " | ||
486 | "0x%04X\n", reg); | ||
487 | return -EINVAL; | ||
488 | } | ||
489 | track->db_z_info = radeon_get_ib_value(p, idx); | 483 | track->db_z_info = radeon_get_ib_value(p, idx); |
490 | ib[idx] &= ~Z_ARRAY_MODE(0xf); | 484 | if (!p->keep_tiling_flags) { |
491 | track->db_z_info &= ~Z_ARRAY_MODE(0xf); | 485 | r = evergreen_cs_packet_next_reloc(p, &reloc); |
492 | if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO) { | 486 | if (r) { |
493 | ib[idx] |= Z_ARRAY_MODE(ARRAY_2D_TILED_THIN1); | 487 | dev_warn(p->dev, "bad SET_CONTEXT_REG " |
494 | track->db_z_info |= Z_ARRAY_MODE(ARRAY_2D_TILED_THIN1); | 488 | "0x%04X\n", reg); |
495 | } else { | 489 | return -EINVAL; |
496 | ib[idx] |= Z_ARRAY_MODE(ARRAY_1D_TILED_THIN1); | 490 | } |
497 | track->db_z_info |= Z_ARRAY_MODE(ARRAY_1D_TILED_THIN1); | 491 | ib[idx] &= ~Z_ARRAY_MODE(0xf); |
492 | track->db_z_info &= ~Z_ARRAY_MODE(0xf); | ||
493 | if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO) { | ||
494 | ib[idx] |= Z_ARRAY_MODE(ARRAY_2D_TILED_THIN1); | ||
495 | track->db_z_info |= Z_ARRAY_MODE(ARRAY_2D_TILED_THIN1); | ||
496 | } else { | ||
497 | ib[idx] |= Z_ARRAY_MODE(ARRAY_1D_TILED_THIN1); | ||
498 | track->db_z_info |= Z_ARRAY_MODE(ARRAY_1D_TILED_THIN1); | ||
499 | } | ||
498 | } | 500 | } |
499 | break; | 501 | break; |
500 | case DB_STENCIL_INFO: | 502 | case DB_STENCIL_INFO: |
@@ -607,40 +609,44 @@ static int evergreen_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx) | |||
607 | case CB_COLOR5_INFO: | 609 | case CB_COLOR5_INFO: |
608 | case CB_COLOR6_INFO: | 610 | case CB_COLOR6_INFO: |
609 | case CB_COLOR7_INFO: | 611 | case CB_COLOR7_INFO: |
610 | r = evergreen_cs_packet_next_reloc(p, &reloc); | ||
611 | if (r) { | ||
612 | dev_warn(p->dev, "bad SET_CONTEXT_REG " | ||
613 | "0x%04X\n", reg); | ||
614 | return -EINVAL; | ||
615 | } | ||
616 | tmp = (reg - CB_COLOR0_INFO) / 0x3c; | 612 | tmp = (reg - CB_COLOR0_INFO) / 0x3c; |
617 | track->cb_color_info[tmp] = radeon_get_ib_value(p, idx); | 613 | track->cb_color_info[tmp] = radeon_get_ib_value(p, idx); |
618 | if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO) { | 614 | if (!p->keep_tiling_flags) { |
619 | ib[idx] |= CB_ARRAY_MODE(ARRAY_2D_TILED_THIN1); | 615 | r = evergreen_cs_packet_next_reloc(p, &reloc); |
620 | track->cb_color_info[tmp] |= CB_ARRAY_MODE(ARRAY_2D_TILED_THIN1); | 616 | if (r) { |
621 | } else if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO) { | 617 | dev_warn(p->dev, "bad SET_CONTEXT_REG " |
622 | ib[idx] |= CB_ARRAY_MODE(ARRAY_1D_TILED_THIN1); | 618 | "0x%04X\n", reg); |
623 | track->cb_color_info[tmp] |= CB_ARRAY_MODE(ARRAY_1D_TILED_THIN1); | 619 | return -EINVAL; |
620 | } | ||
621 | if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO) { | ||
622 | ib[idx] |= CB_ARRAY_MODE(ARRAY_2D_TILED_THIN1); | ||
623 | track->cb_color_info[tmp] |= CB_ARRAY_MODE(ARRAY_2D_TILED_THIN1); | ||
624 | } else if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO) { | ||
625 | ib[idx] |= CB_ARRAY_MODE(ARRAY_1D_TILED_THIN1); | ||
626 | track->cb_color_info[tmp] |= CB_ARRAY_MODE(ARRAY_1D_TILED_THIN1); | ||
627 | } | ||
624 | } | 628 | } |
625 | break; | 629 | break; |
626 | case CB_COLOR8_INFO: | 630 | case CB_COLOR8_INFO: |
627 | case CB_COLOR9_INFO: | 631 | case CB_COLOR9_INFO: |
628 | case CB_COLOR10_INFO: | 632 | case CB_COLOR10_INFO: |
629 | case CB_COLOR11_INFO: | 633 | case CB_COLOR11_INFO: |
630 | r = evergreen_cs_packet_next_reloc(p, &reloc); | ||
631 | if (r) { | ||
632 | dev_warn(p->dev, "bad SET_CONTEXT_REG " | ||
633 | "0x%04X\n", reg); | ||
634 | return -EINVAL; | ||
635 | } | ||
636 | tmp = ((reg - CB_COLOR8_INFO) / 0x1c) + 8; | 634 | tmp = ((reg - CB_COLOR8_INFO) / 0x1c) + 8; |
637 | track->cb_color_info[tmp] = radeon_get_ib_value(p, idx); | 635 | track->cb_color_info[tmp] = radeon_get_ib_value(p, idx); |
638 | if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO) { | 636 | if (!p->keep_tiling_flags) { |
639 | ib[idx] |= CB_ARRAY_MODE(ARRAY_2D_TILED_THIN1); | 637 | r = evergreen_cs_packet_next_reloc(p, &reloc); |
640 | track->cb_color_info[tmp] |= CB_ARRAY_MODE(ARRAY_2D_TILED_THIN1); | 638 | if (r) { |
641 | } else if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO) { | 639 | dev_warn(p->dev, "bad SET_CONTEXT_REG " |
642 | ib[idx] |= CB_ARRAY_MODE(ARRAY_1D_TILED_THIN1); | 640 | "0x%04X\n", reg); |
643 | track->cb_color_info[tmp] |= CB_ARRAY_MODE(ARRAY_1D_TILED_THIN1); | 641 | return -EINVAL; |
642 | } | ||
643 | if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO) { | ||
644 | ib[idx] |= CB_ARRAY_MODE(ARRAY_2D_TILED_THIN1); | ||
645 | track->cb_color_info[tmp] |= CB_ARRAY_MODE(ARRAY_2D_TILED_THIN1); | ||
646 | } else if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO) { | ||
647 | ib[idx] |= CB_ARRAY_MODE(ARRAY_1D_TILED_THIN1); | ||
648 | track->cb_color_info[tmp] |= CB_ARRAY_MODE(ARRAY_1D_TILED_THIN1); | ||
649 | } | ||
644 | } | 650 | } |
645 | break; | 651 | break; |
646 | case CB_COLOR0_PITCH: | 652 | case CB_COLOR0_PITCH: |
@@ -1311,10 +1317,12 @@ static int evergreen_packet3_check(struct radeon_cs_parser *p, | |||
1311 | return -EINVAL; | 1317 | return -EINVAL; |
1312 | } | 1318 | } |
1313 | ib[idx+1+(i*8)+2] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff); | 1319 | ib[idx+1+(i*8)+2] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff); |
1314 | if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO) | 1320 | if (!p->keep_tiling_flags) { |
1315 | ib[idx+1+(i*8)+1] |= TEX_ARRAY_MODE(ARRAY_2D_TILED_THIN1); | 1321 | if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO) |
1316 | else if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO) | 1322 | ib[idx+1+(i*8)+1] |= TEX_ARRAY_MODE(ARRAY_2D_TILED_THIN1); |
1317 | ib[idx+1+(i*8)+1] |= TEX_ARRAY_MODE(ARRAY_1D_TILED_THIN1); | 1323 | else if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO) |
1324 | ib[idx+1+(i*8)+1] |= TEX_ARRAY_MODE(ARRAY_1D_TILED_THIN1); | ||
1325 | } | ||
1318 | texture = reloc->robj; | 1326 | texture = reloc->robj; |
1319 | /* tex mip base */ | 1327 | /* tex mip base */ |
1320 | r = evergreen_cs_packet_next_reloc(p, &reloc); | 1328 | r = evergreen_cs_packet_next_reloc(p, &reloc); |
diff --git a/drivers/gpu/drm/radeon/r300.c b/drivers/gpu/drm/radeon/r300.c index 400b26df652a..c93bc64707e1 100644 --- a/drivers/gpu/drm/radeon/r300.c +++ b/drivers/gpu/drm/radeon/r300.c | |||
@@ -701,16 +701,21 @@ static int r300_packet0_check(struct radeon_cs_parser *p, | |||
701 | return r; | 701 | return r; |
702 | } | 702 | } |
703 | 703 | ||
704 | if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO) | 704 | if (p->keep_tiling_flags) { |
705 | tile_flags |= R300_TXO_MACRO_TILE; | 705 | ib[idx] = (idx_value & 31) | /* keep the 1st 5 bits */ |
706 | if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO) | 706 | ((idx_value & ~31) + (u32)reloc->lobj.gpu_offset); |
707 | tile_flags |= R300_TXO_MICRO_TILE; | 707 | } else { |
708 | else if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO_SQUARE) | 708 | if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO) |
709 | tile_flags |= R300_TXO_MICRO_TILE_SQUARE; | 709 | tile_flags |= R300_TXO_MACRO_TILE; |
710 | 710 | if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO) | |
711 | tmp = idx_value + ((u32)reloc->lobj.gpu_offset); | 711 | tile_flags |= R300_TXO_MICRO_TILE; |
712 | tmp |= tile_flags; | 712 | else if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO_SQUARE) |
713 | ib[idx] = tmp; | 713 | tile_flags |= R300_TXO_MICRO_TILE_SQUARE; |
714 | |||
715 | tmp = idx_value + ((u32)reloc->lobj.gpu_offset); | ||
716 | tmp |= tile_flags; | ||
717 | ib[idx] = tmp; | ||
718 | } | ||
714 | track->textures[i].robj = reloc->robj; | 719 | track->textures[i].robj = reloc->robj; |
715 | track->tex_dirty = true; | 720 | track->tex_dirty = true; |
716 | break; | 721 | break; |
@@ -760,24 +765,26 @@ static int r300_packet0_check(struct radeon_cs_parser *p, | |||
760 | /* RB3D_COLORPITCH1 */ | 765 | /* RB3D_COLORPITCH1 */ |
761 | /* RB3D_COLORPITCH2 */ | 766 | /* RB3D_COLORPITCH2 */ |
762 | /* RB3D_COLORPITCH3 */ | 767 | /* RB3D_COLORPITCH3 */ |
763 | r = r100_cs_packet_next_reloc(p, &reloc); | 768 | if (!p->keep_tiling_flags) { |
764 | if (r) { | 769 | r = r100_cs_packet_next_reloc(p, &reloc); |
765 | DRM_ERROR("No reloc for ib[%d]=0x%04X\n", | 770 | if (r) { |
766 | idx, reg); | 771 | DRM_ERROR("No reloc for ib[%d]=0x%04X\n", |
767 | r100_cs_dump_packet(p, pkt); | 772 | idx, reg); |
768 | return r; | 773 | r100_cs_dump_packet(p, pkt); |
769 | } | 774 | return r; |
775 | } | ||
770 | 776 | ||
771 | if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO) | 777 | if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO) |
772 | tile_flags |= R300_COLOR_TILE_ENABLE; | 778 | tile_flags |= R300_COLOR_TILE_ENABLE; |
773 | if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO) | 779 | if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO) |
774 | tile_flags |= R300_COLOR_MICROTILE_ENABLE; | 780 | tile_flags |= R300_COLOR_MICROTILE_ENABLE; |
775 | else if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO_SQUARE) | 781 | else if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO_SQUARE) |
776 | tile_flags |= R300_COLOR_MICROTILE_SQUARE_ENABLE; | 782 | tile_flags |= R300_COLOR_MICROTILE_SQUARE_ENABLE; |
777 | 783 | ||
778 | tmp = idx_value & ~(0x7 << 16); | 784 | tmp = idx_value & ~(0x7 << 16); |
779 | tmp |= tile_flags; | 785 | tmp |= tile_flags; |
780 | ib[idx] = tmp; | 786 | ib[idx] = tmp; |
787 | } | ||
781 | i = (reg - 0x4E38) >> 2; | 788 | i = (reg - 0x4E38) >> 2; |
782 | track->cb[i].pitch = idx_value & 0x3FFE; | 789 | track->cb[i].pitch = idx_value & 0x3FFE; |
783 | switch (((idx_value >> 21) & 0xF)) { | 790 | switch (((idx_value >> 21) & 0xF)) { |
@@ -843,25 +850,26 @@ static int r300_packet0_check(struct radeon_cs_parser *p, | |||
843 | break; | 850 | break; |
844 | case 0x4F24: | 851 | case 0x4F24: |
845 | /* ZB_DEPTHPITCH */ | 852 | /* ZB_DEPTHPITCH */ |
846 | r = r100_cs_packet_next_reloc(p, &reloc); | 853 | if (!p->keep_tiling_flags) { |
847 | if (r) { | 854 | r = r100_cs_packet_next_reloc(p, &reloc); |
848 | DRM_ERROR("No reloc for ib[%d]=0x%04X\n", | 855 | if (r) { |
849 | idx, reg); | 856 | DRM_ERROR("No reloc for ib[%d]=0x%04X\n", |
850 | r100_cs_dump_packet(p, pkt); | 857 | idx, reg); |
851 | return r; | 858 | r100_cs_dump_packet(p, pkt); |
852 | } | 859 | return r; |
853 | 860 | } | |
854 | if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO) | ||
855 | tile_flags |= R300_DEPTHMACROTILE_ENABLE; | ||
856 | if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO) | ||
857 | tile_flags |= R300_DEPTHMICROTILE_TILED; | ||
858 | else if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO_SQUARE) | ||
859 | tile_flags |= R300_DEPTHMICROTILE_TILED_SQUARE; | ||
860 | 861 | ||
861 | tmp = idx_value & ~(0x7 << 16); | 862 | if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO) |
862 | tmp |= tile_flags; | 863 | tile_flags |= R300_DEPTHMACROTILE_ENABLE; |
863 | ib[idx] = tmp; | 864 | if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO) |
865 | tile_flags |= R300_DEPTHMICROTILE_TILED; | ||
866 | else if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO_SQUARE) | ||
867 | tile_flags |= R300_DEPTHMICROTILE_TILED_SQUARE; | ||
864 | 868 | ||
869 | tmp = idx_value & ~(0x7 << 16); | ||
870 | tmp |= tile_flags; | ||
871 | ib[idx] = tmp; | ||
872 | } | ||
865 | track->zb.pitch = idx_value & 0x3FFC; | 873 | track->zb.pitch = idx_value & 0x3FFC; |
866 | track->zb_dirty = true; | 874 | track->zb_dirty = true; |
867 | break; | 875 | break; |
diff --git a/drivers/gpu/drm/radeon/r600_cs.c b/drivers/gpu/drm/radeon/r600_cs.c index 0a2e023c1557..cb1acffd2430 100644 --- a/drivers/gpu/drm/radeon/r600_cs.c +++ b/drivers/gpu/drm/radeon/r600_cs.c | |||
@@ -941,7 +941,8 @@ static int r600_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx) | |||
941 | track->db_depth_control = radeon_get_ib_value(p, idx); | 941 | track->db_depth_control = radeon_get_ib_value(p, idx); |
942 | break; | 942 | break; |
943 | case R_028010_DB_DEPTH_INFO: | 943 | case R_028010_DB_DEPTH_INFO: |
944 | if (r600_cs_packet_next_is_pkt3_nop(p)) { | 944 | if (!p->keep_tiling_flags && |
945 | r600_cs_packet_next_is_pkt3_nop(p)) { | ||
945 | r = r600_cs_packet_next_reloc(p, &reloc); | 946 | r = r600_cs_packet_next_reloc(p, &reloc); |
946 | if (r) { | 947 | if (r) { |
947 | dev_warn(p->dev, "bad SET_CONTEXT_REG " | 948 | dev_warn(p->dev, "bad SET_CONTEXT_REG " |
@@ -992,7 +993,8 @@ static int r600_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx) | |||
992 | case R_0280B4_CB_COLOR5_INFO: | 993 | case R_0280B4_CB_COLOR5_INFO: |
993 | case R_0280B8_CB_COLOR6_INFO: | 994 | case R_0280B8_CB_COLOR6_INFO: |
994 | case R_0280BC_CB_COLOR7_INFO: | 995 | case R_0280BC_CB_COLOR7_INFO: |
995 | if (r600_cs_packet_next_is_pkt3_nop(p)) { | 996 | if (!p->keep_tiling_flags && |
997 | r600_cs_packet_next_is_pkt3_nop(p)) { | ||
996 | r = r600_cs_packet_next_reloc(p, &reloc); | 998 | r = r600_cs_packet_next_reloc(p, &reloc); |
997 | if (r) { | 999 | if (r) { |
998 | dev_err(p->dev, "bad SET_CONTEXT_REG 0x%04X\n", reg); | 1000 | dev_err(p->dev, "bad SET_CONTEXT_REG 0x%04X\n", reg); |
@@ -1291,10 +1293,12 @@ static int r600_check_texture_resource(struct radeon_cs_parser *p, u32 idx, | |||
1291 | mip_offset <<= 8; | 1293 | mip_offset <<= 8; |
1292 | 1294 | ||
1293 | word0 = radeon_get_ib_value(p, idx + 0); | 1295 | word0 = radeon_get_ib_value(p, idx + 0); |
1294 | if (tiling_flags & RADEON_TILING_MACRO) | 1296 | if (!p->keep_tiling_flags) { |
1295 | word0 |= S_038000_TILE_MODE(V_038000_ARRAY_2D_TILED_THIN1); | 1297 | if (tiling_flags & RADEON_TILING_MACRO) |
1296 | else if (tiling_flags & RADEON_TILING_MICRO) | 1298 | word0 |= S_038000_TILE_MODE(V_038000_ARRAY_2D_TILED_THIN1); |
1297 | word0 |= S_038000_TILE_MODE(V_038000_ARRAY_1D_TILED_THIN1); | 1299 | else if (tiling_flags & RADEON_TILING_MICRO) |
1300 | word0 |= S_038000_TILE_MODE(V_038000_ARRAY_1D_TILED_THIN1); | ||
1301 | } | ||
1298 | word1 = radeon_get_ib_value(p, idx + 1); | 1302 | word1 = radeon_get_ib_value(p, idx + 1); |
1299 | w0 = G_038000_TEX_WIDTH(word0) + 1; | 1303 | w0 = G_038000_TEX_WIDTH(word0) + 1; |
1300 | h0 = G_038004_TEX_HEIGHT(word1) + 1; | 1304 | h0 = G_038004_TEX_HEIGHT(word1) + 1; |
@@ -1621,10 +1625,12 @@ static int r600_packet3_check(struct radeon_cs_parser *p, | |||
1621 | return -EINVAL; | 1625 | return -EINVAL; |
1622 | } | 1626 | } |
1623 | base_offset = (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff); | 1627 | base_offset = (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff); |
1624 | if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO) | 1628 | if (!p->keep_tiling_flags) { |
1625 | ib[idx+1+(i*7)+0] |= S_038000_TILE_MODE(V_038000_ARRAY_2D_TILED_THIN1); | 1629 | if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO) |
1626 | else if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO) | 1630 | ib[idx+1+(i*7)+0] |= S_038000_TILE_MODE(V_038000_ARRAY_2D_TILED_THIN1); |
1627 | ib[idx+1+(i*7)+0] |= S_038000_TILE_MODE(V_038000_ARRAY_1D_TILED_THIN1); | 1631 | else if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO) |
1632 | ib[idx+1+(i*7)+0] |= S_038000_TILE_MODE(V_038000_ARRAY_1D_TILED_THIN1); | ||
1633 | } | ||
1628 | texture = reloc->robj; | 1634 | texture = reloc->robj; |
1629 | /* tex mip base */ | 1635 | /* tex mip base */ |
1630 | r = r600_cs_packet_next_reloc(p, &reloc); | 1636 | r = r600_cs_packet_next_reloc(p, &reloc); |
diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h index fc5a1d642cb5..8227e76b5c70 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h | |||
@@ -611,7 +611,8 @@ struct radeon_cs_parser { | |||
611 | struct radeon_ib *ib; | 611 | struct radeon_ib *ib; |
612 | void *track; | 612 | void *track; |
613 | unsigned family; | 613 | unsigned family; |
614 | int parser_error; | 614 | int parser_error; |
615 | bool keep_tiling_flags; | ||
615 | }; | 616 | }; |
616 | 617 | ||
617 | extern int radeon_cs_update_pages(struct radeon_cs_parser *p, int pg_idx); | 618 | extern int radeon_cs_update_pages(struct radeon_cs_parser *p, int pg_idx); |
diff --git a/drivers/gpu/drm/radeon/radeon_atombios.c b/drivers/gpu/drm/radeon/radeon_atombios.c index fecd705a1a5f..d24baf30efcb 100644 --- a/drivers/gpu/drm/radeon/radeon_atombios.c +++ b/drivers/gpu/drm/radeon/radeon_atombios.c | |||
@@ -62,6 +62,87 @@ union atom_supported_devices { | |||
62 | struct _ATOM_SUPPORTED_DEVICES_INFO_2d1 info_2d1; | 62 | struct _ATOM_SUPPORTED_DEVICES_INFO_2d1 info_2d1; |
63 | }; | 63 | }; |
64 | 64 | ||
65 | static void radeon_lookup_i2c_gpio_quirks(struct radeon_device *rdev, | ||
66 | ATOM_GPIO_I2C_ASSIGMENT *gpio, | ||
67 | u8 index) | ||
68 | { | ||
69 | /* r4xx mask is technically not used by the hw, so patch in the legacy mask bits */ | ||
70 | if ((rdev->family == CHIP_R420) || | ||
71 | (rdev->family == CHIP_R423) || | ||
72 | (rdev->family == CHIP_RV410)) { | ||
73 | if ((le16_to_cpu(gpio->usClkMaskRegisterIndex) == 0x0018) || | ||
74 | (le16_to_cpu(gpio->usClkMaskRegisterIndex) == 0x0019) || | ||
75 | (le16_to_cpu(gpio->usClkMaskRegisterIndex) == 0x001a)) { | ||
76 | gpio->ucClkMaskShift = 0x19; | ||
77 | gpio->ucDataMaskShift = 0x18; | ||
78 | } | ||
79 | } | ||
80 | |||
81 | /* some evergreen boards have bad data for this entry */ | ||
82 | if (ASIC_IS_DCE4(rdev)) { | ||
83 | if ((index == 7) && | ||
84 | (le16_to_cpu(gpio->usClkMaskRegisterIndex) == 0x1936) && | ||
85 | (gpio->sucI2cId.ucAccess == 0)) { | ||
86 | gpio->sucI2cId.ucAccess = 0x97; | ||
87 | gpio->ucDataMaskShift = 8; | ||
88 | gpio->ucDataEnShift = 8; | ||
89 | gpio->ucDataY_Shift = 8; | ||
90 | gpio->ucDataA_Shift = 8; | ||
91 | } | ||
92 | } | ||
93 | |||
94 | /* some DCE3 boards have bad data for this entry */ | ||
95 | if (ASIC_IS_DCE3(rdev)) { | ||
96 | if ((index == 4) && | ||
97 | (le16_to_cpu(gpio->usClkMaskRegisterIndex) == 0x1fda) && | ||
98 | (gpio->sucI2cId.ucAccess == 0x94)) | ||
99 | gpio->sucI2cId.ucAccess = 0x14; | ||
100 | } | ||
101 | } | ||
102 | |||
103 | static struct radeon_i2c_bus_rec radeon_get_bus_rec_for_i2c_gpio(ATOM_GPIO_I2C_ASSIGMENT *gpio) | ||
104 | { | ||
105 | struct radeon_i2c_bus_rec i2c; | ||
106 | |||
107 | memset(&i2c, 0, sizeof(struct radeon_i2c_bus_rec)); | ||
108 | |||
109 | i2c.mask_clk_reg = le16_to_cpu(gpio->usClkMaskRegisterIndex) * 4; | ||
110 | i2c.mask_data_reg = le16_to_cpu(gpio->usDataMaskRegisterIndex) * 4; | ||
111 | i2c.en_clk_reg = le16_to_cpu(gpio->usClkEnRegisterIndex) * 4; | ||
112 | i2c.en_data_reg = le16_to_cpu(gpio->usDataEnRegisterIndex) * 4; | ||
113 | i2c.y_clk_reg = le16_to_cpu(gpio->usClkY_RegisterIndex) * 4; | ||
114 | i2c.y_data_reg = le16_to_cpu(gpio->usDataY_RegisterIndex) * 4; | ||
115 | i2c.a_clk_reg = le16_to_cpu(gpio->usClkA_RegisterIndex) * 4; | ||
116 | i2c.a_data_reg = le16_to_cpu(gpio->usDataA_RegisterIndex) * 4; | ||
117 | i2c.mask_clk_mask = (1 << gpio->ucClkMaskShift); | ||
118 | i2c.mask_data_mask = (1 << gpio->ucDataMaskShift); | ||
119 | i2c.en_clk_mask = (1 << gpio->ucClkEnShift); | ||
120 | i2c.en_data_mask = (1 << gpio->ucDataEnShift); | ||
121 | i2c.y_clk_mask = (1 << gpio->ucClkY_Shift); | ||
122 | i2c.y_data_mask = (1 << gpio->ucDataY_Shift); | ||
123 | i2c.a_clk_mask = (1 << gpio->ucClkA_Shift); | ||
124 | i2c.a_data_mask = (1 << gpio->ucDataA_Shift); | ||
125 | |||
126 | if (gpio->sucI2cId.sbfAccess.bfHW_Capable) | ||
127 | i2c.hw_capable = true; | ||
128 | else | ||
129 | i2c.hw_capable = false; | ||
130 | |||
131 | if (gpio->sucI2cId.ucAccess == 0xa0) | ||
132 | i2c.mm_i2c = true; | ||
133 | else | ||
134 | i2c.mm_i2c = false; | ||
135 | |||
136 | i2c.i2c_id = gpio->sucI2cId.ucAccess; | ||
137 | |||
138 | if (i2c.mask_clk_reg) | ||
139 | i2c.valid = true; | ||
140 | else | ||
141 | i2c.valid = false; | ||
142 | |||
143 | return i2c; | ||
144 | } | ||
145 | |||
65 | static struct radeon_i2c_bus_rec radeon_lookup_i2c_gpio(struct radeon_device *rdev, | 146 | static struct radeon_i2c_bus_rec radeon_lookup_i2c_gpio(struct radeon_device *rdev, |
66 | uint8_t id) | 147 | uint8_t id) |
67 | { | 148 | { |
@@ -85,71 +166,10 @@ static struct radeon_i2c_bus_rec radeon_lookup_i2c_gpio(struct radeon_device *rd | |||
85 | for (i = 0; i < num_indices; i++) { | 166 | for (i = 0; i < num_indices; i++) { |
86 | gpio = &i2c_info->asGPIO_Info[i]; | 167 | gpio = &i2c_info->asGPIO_Info[i]; |
87 | 168 | ||
88 | /* r4xx mask is technically not used by the hw, so patch in the legacy mask bits */ | 169 | radeon_lookup_i2c_gpio_quirks(rdev, gpio, i); |
89 | if ((rdev->family == CHIP_R420) || | ||
90 | (rdev->family == CHIP_R423) || | ||
91 | (rdev->family == CHIP_RV410)) { | ||
92 | if ((le16_to_cpu(gpio->usClkMaskRegisterIndex) == 0x0018) || | ||
93 | (le16_to_cpu(gpio->usClkMaskRegisterIndex) == 0x0019) || | ||
94 | (le16_to_cpu(gpio->usClkMaskRegisterIndex) == 0x001a)) { | ||
95 | gpio->ucClkMaskShift = 0x19; | ||
96 | gpio->ucDataMaskShift = 0x18; | ||
97 | } | ||
98 | } | ||
99 | |||
100 | /* some evergreen boards have bad data for this entry */ | ||
101 | if (ASIC_IS_DCE4(rdev)) { | ||
102 | if ((i == 7) && | ||
103 | (le16_to_cpu(gpio->usClkMaskRegisterIndex) == 0x1936) && | ||
104 | (gpio->sucI2cId.ucAccess == 0)) { | ||
105 | gpio->sucI2cId.ucAccess = 0x97; | ||
106 | gpio->ucDataMaskShift = 8; | ||
107 | gpio->ucDataEnShift = 8; | ||
108 | gpio->ucDataY_Shift = 8; | ||
109 | gpio->ucDataA_Shift = 8; | ||
110 | } | ||
111 | } | ||
112 | |||
113 | /* some DCE3 boards have bad data for this entry */ | ||
114 | if (ASIC_IS_DCE3(rdev)) { | ||
115 | if ((i == 4) && | ||
116 | (le16_to_cpu(gpio->usClkMaskRegisterIndex) == 0x1fda) && | ||
117 | (gpio->sucI2cId.ucAccess == 0x94)) | ||
118 | gpio->sucI2cId.ucAccess = 0x14; | ||
119 | } | ||
120 | 170 | ||
121 | if (gpio->sucI2cId.ucAccess == id) { | 171 | if (gpio->sucI2cId.ucAccess == id) { |
122 | i2c.mask_clk_reg = le16_to_cpu(gpio->usClkMaskRegisterIndex) * 4; | 172 | i2c = radeon_get_bus_rec_for_i2c_gpio(gpio); |
123 | i2c.mask_data_reg = le16_to_cpu(gpio->usDataMaskRegisterIndex) * 4; | ||
124 | i2c.en_clk_reg = le16_to_cpu(gpio->usClkEnRegisterIndex) * 4; | ||
125 | i2c.en_data_reg = le16_to_cpu(gpio->usDataEnRegisterIndex) * 4; | ||
126 | i2c.y_clk_reg = le16_to_cpu(gpio->usClkY_RegisterIndex) * 4; | ||
127 | i2c.y_data_reg = le16_to_cpu(gpio->usDataY_RegisterIndex) * 4; | ||
128 | i2c.a_clk_reg = le16_to_cpu(gpio->usClkA_RegisterIndex) * 4; | ||
129 | i2c.a_data_reg = le16_to_cpu(gpio->usDataA_RegisterIndex) * 4; | ||
130 | i2c.mask_clk_mask = (1 << gpio->ucClkMaskShift); | ||
131 | i2c.mask_data_mask = (1 << gpio->ucDataMaskShift); | ||
132 | i2c.en_clk_mask = (1 << gpio->ucClkEnShift); | ||
133 | i2c.en_data_mask = (1 << gpio->ucDataEnShift); | ||
134 | i2c.y_clk_mask = (1 << gpio->ucClkY_Shift); | ||
135 | i2c.y_data_mask = (1 << gpio->ucDataY_Shift); | ||
136 | i2c.a_clk_mask = (1 << gpio->ucClkA_Shift); | ||
137 | i2c.a_data_mask = (1 << gpio->ucDataA_Shift); | ||
138 | |||
139 | if (gpio->sucI2cId.sbfAccess.bfHW_Capable) | ||
140 | i2c.hw_capable = true; | ||
141 | else | ||
142 | i2c.hw_capable = false; | ||
143 | |||
144 | if (gpio->sucI2cId.ucAccess == 0xa0) | ||
145 | i2c.mm_i2c = true; | ||
146 | else | ||
147 | i2c.mm_i2c = false; | ||
148 | |||
149 | i2c.i2c_id = gpio->sucI2cId.ucAccess; | ||
150 | |||
151 | if (i2c.mask_clk_reg) | ||
152 | i2c.valid = true; | ||
153 | break; | 173 | break; |
154 | } | 174 | } |
155 | } | 175 | } |
@@ -169,8 +189,6 @@ void radeon_atombios_i2c_init(struct radeon_device *rdev) | |||
169 | int i, num_indices; | 189 | int i, num_indices; |
170 | char stmp[32]; | 190 | char stmp[32]; |
171 | 191 | ||
172 | memset(&i2c, 0, sizeof(struct radeon_i2c_bus_rec)); | ||
173 | |||
174 | if (atom_parse_data_header(ctx, index, &size, NULL, NULL, &data_offset)) { | 192 | if (atom_parse_data_header(ctx, index, &size, NULL, NULL, &data_offset)) { |
175 | i2c_info = (struct _ATOM_GPIO_I2C_INFO *)(ctx->bios + data_offset); | 193 | i2c_info = (struct _ATOM_GPIO_I2C_INFO *)(ctx->bios + data_offset); |
176 | 194 | ||
@@ -179,60 +197,12 @@ void radeon_atombios_i2c_init(struct radeon_device *rdev) | |||
179 | 197 | ||
180 | for (i = 0; i < num_indices; i++) { | 198 | for (i = 0; i < num_indices; i++) { |
181 | gpio = &i2c_info->asGPIO_Info[i]; | 199 | gpio = &i2c_info->asGPIO_Info[i]; |
182 | i2c.valid = false; | ||
183 | |||
184 | /* some evergreen boards have bad data for this entry */ | ||
185 | if (ASIC_IS_DCE4(rdev)) { | ||
186 | if ((i == 7) && | ||
187 | (le16_to_cpu(gpio->usClkMaskRegisterIndex) == 0x1936) && | ||
188 | (gpio->sucI2cId.ucAccess == 0)) { | ||
189 | gpio->sucI2cId.ucAccess = 0x97; | ||
190 | gpio->ucDataMaskShift = 8; | ||
191 | gpio->ucDataEnShift = 8; | ||
192 | gpio->ucDataY_Shift = 8; | ||
193 | gpio->ucDataA_Shift = 8; | ||
194 | } | ||
195 | } | ||
196 | 200 | ||
197 | /* some DCE3 boards have bad data for this entry */ | 201 | radeon_lookup_i2c_gpio_quirks(rdev, gpio, i); |
198 | if (ASIC_IS_DCE3(rdev)) { | ||
199 | if ((i == 4) && | ||
200 | (le16_to_cpu(gpio->usClkMaskRegisterIndex) == 0x1fda) && | ||
201 | (gpio->sucI2cId.ucAccess == 0x94)) | ||
202 | gpio->sucI2cId.ucAccess = 0x14; | ||
203 | } | ||
204 | |||
205 | i2c.mask_clk_reg = le16_to_cpu(gpio->usClkMaskRegisterIndex) * 4; | ||
206 | i2c.mask_data_reg = le16_to_cpu(gpio->usDataMaskRegisterIndex) * 4; | ||
207 | i2c.en_clk_reg = le16_to_cpu(gpio->usClkEnRegisterIndex) * 4; | ||
208 | i2c.en_data_reg = le16_to_cpu(gpio->usDataEnRegisterIndex) * 4; | ||
209 | i2c.y_clk_reg = le16_to_cpu(gpio->usClkY_RegisterIndex) * 4; | ||
210 | i2c.y_data_reg = le16_to_cpu(gpio->usDataY_RegisterIndex) * 4; | ||
211 | i2c.a_clk_reg = le16_to_cpu(gpio->usClkA_RegisterIndex) * 4; | ||
212 | i2c.a_data_reg = le16_to_cpu(gpio->usDataA_RegisterIndex) * 4; | ||
213 | i2c.mask_clk_mask = (1 << gpio->ucClkMaskShift); | ||
214 | i2c.mask_data_mask = (1 << gpio->ucDataMaskShift); | ||
215 | i2c.en_clk_mask = (1 << gpio->ucClkEnShift); | ||
216 | i2c.en_data_mask = (1 << gpio->ucDataEnShift); | ||
217 | i2c.y_clk_mask = (1 << gpio->ucClkY_Shift); | ||
218 | i2c.y_data_mask = (1 << gpio->ucDataY_Shift); | ||
219 | i2c.a_clk_mask = (1 << gpio->ucClkA_Shift); | ||
220 | i2c.a_data_mask = (1 << gpio->ucDataA_Shift); | ||
221 | |||
222 | if (gpio->sucI2cId.sbfAccess.bfHW_Capable) | ||
223 | i2c.hw_capable = true; | ||
224 | else | ||
225 | i2c.hw_capable = false; | ||
226 | |||
227 | if (gpio->sucI2cId.ucAccess == 0xa0) | ||
228 | i2c.mm_i2c = true; | ||
229 | else | ||
230 | i2c.mm_i2c = false; | ||
231 | 202 | ||
232 | i2c.i2c_id = gpio->sucI2cId.ucAccess; | 203 | i2c = radeon_get_bus_rec_for_i2c_gpio(gpio); |
233 | 204 | ||
234 | if (i2c.mask_clk_reg) { | 205 | if (i2c.valid) { |
235 | i2c.valid = true; | ||
236 | sprintf(stmp, "0x%x", i2c.i2c_id); | 206 | sprintf(stmp, "0x%x", i2c.i2c_id); |
237 | rdev->i2c_bus[i] = radeon_i2c_create(rdev->ddev, &i2c, stmp); | 207 | rdev->i2c_bus[i] = radeon_i2c_create(rdev->ddev, &i2c, stmp); |
238 | } | 208 | } |
diff --git a/drivers/gpu/drm/radeon/radeon_cs.c b/drivers/gpu/drm/radeon/radeon_cs.c index ccaa243c1442..29afd71e0840 100644 --- a/drivers/gpu/drm/radeon/radeon_cs.c +++ b/drivers/gpu/drm/radeon/radeon_cs.c | |||
@@ -93,7 +93,7 @@ int radeon_cs_parser_init(struct radeon_cs_parser *p, void *data) | |||
93 | { | 93 | { |
94 | struct drm_radeon_cs *cs = data; | 94 | struct drm_radeon_cs *cs = data; |
95 | uint64_t *chunk_array_ptr; | 95 | uint64_t *chunk_array_ptr; |
96 | unsigned size, i; | 96 | unsigned size, i, flags = 0; |
97 | 97 | ||
98 | if (!cs->num_chunks) { | 98 | if (!cs->num_chunks) { |
99 | return 0; | 99 | return 0; |
@@ -140,6 +140,10 @@ int radeon_cs_parser_init(struct radeon_cs_parser *p, void *data) | |||
140 | if (p->chunks[i].length_dw == 0) | 140 | if (p->chunks[i].length_dw == 0) |
141 | return -EINVAL; | 141 | return -EINVAL; |
142 | } | 142 | } |
143 | if (p->chunks[i].chunk_id == RADEON_CHUNK_ID_FLAGS && | ||
144 | !p->chunks[i].length_dw) { | ||
145 | return -EINVAL; | ||
146 | } | ||
143 | 147 | ||
144 | p->chunks[i].length_dw = user_chunk.length_dw; | 148 | p->chunks[i].length_dw = user_chunk.length_dw; |
145 | p->chunks[i].user_ptr = (void __user *)(unsigned long)user_chunk.chunk_data; | 149 | p->chunks[i].user_ptr = (void __user *)(unsigned long)user_chunk.chunk_data; |
@@ -155,6 +159,9 @@ int radeon_cs_parser_init(struct radeon_cs_parser *p, void *data) | |||
155 | p->chunks[i].user_ptr, size)) { | 159 | p->chunks[i].user_ptr, size)) { |
156 | return -EFAULT; | 160 | return -EFAULT; |
157 | } | 161 | } |
162 | if (p->chunks[i].chunk_id == RADEON_CHUNK_ID_FLAGS) { | ||
163 | flags = p->chunks[i].kdata[0]; | ||
164 | } | ||
158 | } else { | 165 | } else { |
159 | p->chunks[i].kpage[0] = kmalloc(PAGE_SIZE, GFP_KERNEL); | 166 | p->chunks[i].kpage[0] = kmalloc(PAGE_SIZE, GFP_KERNEL); |
160 | p->chunks[i].kpage[1] = kmalloc(PAGE_SIZE, GFP_KERNEL); | 167 | p->chunks[i].kpage[1] = kmalloc(PAGE_SIZE, GFP_KERNEL); |
@@ -174,6 +181,8 @@ int radeon_cs_parser_init(struct radeon_cs_parser *p, void *data) | |||
174 | p->chunks[p->chunk_ib_idx].length_dw); | 181 | p->chunks[p->chunk_ib_idx].length_dw); |
175 | return -EINVAL; | 182 | return -EINVAL; |
176 | } | 183 | } |
184 | |||
185 | p->keep_tiling_flags = (flags & RADEON_CS_KEEP_TILING_FLAGS) != 0; | ||
177 | return 0; | 186 | return 0; |
178 | } | 187 | } |
179 | 188 | ||
diff --git a/drivers/gpu/drm/radeon/radeon_drv.c b/drivers/gpu/drm/radeon/radeon_drv.c index a0b35e909489..71499fc3daf5 100644 --- a/drivers/gpu/drm/radeon/radeon_drv.c +++ b/drivers/gpu/drm/radeon/radeon_drv.c | |||
@@ -53,9 +53,10 @@ | |||
53 | * 2.9.0 - r600 tiling (s3tc,rgtc) working, SET_PREDICATION packet 3 on r600 + eg, backend query | 53 | * 2.9.0 - r600 tiling (s3tc,rgtc) working, SET_PREDICATION packet 3 on r600 + eg, backend query |
54 | * 2.10.0 - fusion 2D tiling | 54 | * 2.10.0 - fusion 2D tiling |
55 | * 2.11.0 - backend map, initial compute support for the CS checker | 55 | * 2.11.0 - backend map, initial compute support for the CS checker |
56 | * 2.12.0 - RADEON_CS_KEEP_TILING_FLAGS | ||
56 | */ | 57 | */ |
57 | #define KMS_DRIVER_MAJOR 2 | 58 | #define KMS_DRIVER_MAJOR 2 |
58 | #define KMS_DRIVER_MINOR 11 | 59 | #define KMS_DRIVER_MINOR 12 |
59 | #define KMS_DRIVER_PATCHLEVEL 0 | 60 | #define KMS_DRIVER_PATCHLEVEL 0 |
60 | int radeon_driver_load_kms(struct drm_device *dev, unsigned long flags); | 61 | int radeon_driver_load_kms(struct drm_device *dev, unsigned long flags); |
61 | int radeon_driver_unload_kms(struct drm_device *dev); | 62 | int radeon_driver_unload_kms(struct drm_device *dev); |
diff --git a/drivers/gpu/drm/ttm/ttm_bo.c b/drivers/gpu/drm/ttm/ttm_bo.c index 617b64678fc6..0bb0f5f713e6 100644 --- a/drivers/gpu/drm/ttm/ttm_bo.c +++ b/drivers/gpu/drm/ttm/ttm_bo.c | |||
@@ -574,10 +574,16 @@ retry: | |||
574 | return ret; | 574 | return ret; |
575 | 575 | ||
576 | spin_lock(&glob->lru_lock); | 576 | spin_lock(&glob->lru_lock); |
577 | |||
578 | if (unlikely(list_empty(&bo->ddestroy))) { | ||
579 | spin_unlock(&glob->lru_lock); | ||
580 | return 0; | ||
581 | } | ||
582 | |||
577 | ret = ttm_bo_reserve_locked(bo, interruptible, | 583 | ret = ttm_bo_reserve_locked(bo, interruptible, |
578 | no_wait_reserve, false, 0); | 584 | no_wait_reserve, false, 0); |
579 | 585 | ||
580 | if (unlikely(ret != 0) || list_empty(&bo->ddestroy)) { | 586 | if (unlikely(ret != 0)) { |
581 | spin_unlock(&glob->lru_lock); | 587 | spin_unlock(&glob->lru_lock); |
582 | return ret; | 588 | return ret; |
583 | } | 589 | } |
diff --git a/drivers/gpu/vga/vgaarb.c b/drivers/gpu/vga/vgaarb.c index bdde899af72e..111d956d8e7d 100644 --- a/drivers/gpu/vga/vgaarb.c +++ b/drivers/gpu/vga/vgaarb.c | |||
@@ -991,14 +991,20 @@ static ssize_t vga_arb_write(struct file *file, const char __user * buf, | |||
991 | uc = &priv->cards[i]; | 991 | uc = &priv->cards[i]; |
992 | } | 992 | } |
993 | 993 | ||
994 | if (!uc) | 994 | if (!uc) { |
995 | return -EINVAL; | 995 | ret_val = -EINVAL; |
996 | goto done; | ||
997 | } | ||
996 | 998 | ||
997 | if (io_state & VGA_RSRC_LEGACY_IO && uc->io_cnt == 0) | 999 | if (io_state & VGA_RSRC_LEGACY_IO && uc->io_cnt == 0) { |
998 | return -EINVAL; | 1000 | ret_val = -EINVAL; |
1001 | goto done; | ||
1002 | } | ||
999 | 1003 | ||
1000 | if (io_state & VGA_RSRC_LEGACY_MEM && uc->mem_cnt == 0) | 1004 | if (io_state & VGA_RSRC_LEGACY_MEM && uc->mem_cnt == 0) { |
1001 | return -EINVAL; | 1005 | ret_val = -EINVAL; |
1006 | goto done; | ||
1007 | } | ||
1002 | 1008 | ||
1003 | vga_put(pdev, io_state); | 1009 | vga_put(pdev, io_state); |
1004 | 1010 | ||
diff --git a/drivers/hwmon/ad7314.c b/drivers/hwmon/ad7314.c index 318e38e85376..5d760f3d21c2 100644 --- a/drivers/hwmon/ad7314.c +++ b/drivers/hwmon/ad7314.c | |||
@@ -160,7 +160,6 @@ MODULE_DEVICE_TABLE(spi, ad7314_id); | |||
160 | static struct spi_driver ad7314_driver = { | 160 | static struct spi_driver ad7314_driver = { |
161 | .driver = { | 161 | .driver = { |
162 | .name = "ad7314", | 162 | .name = "ad7314", |
163 | .bus = &spi_bus_type, | ||
164 | .owner = THIS_MODULE, | 163 | .owner = THIS_MODULE, |
165 | }, | 164 | }, |
166 | .probe = ad7314_probe, | 165 | .probe = ad7314_probe, |
diff --git a/drivers/hwmon/ads7871.c b/drivers/hwmon/ads7871.c index 52319340e182..04450f8bf5da 100644 --- a/drivers/hwmon/ads7871.c +++ b/drivers/hwmon/ads7871.c | |||
@@ -227,7 +227,6 @@ static int __devexit ads7871_remove(struct spi_device *spi) | |||
227 | static struct spi_driver ads7871_driver = { | 227 | static struct spi_driver ads7871_driver = { |
228 | .driver = { | 228 | .driver = { |
229 | .name = DEVICE_NAME, | 229 | .name = DEVICE_NAME, |
230 | .bus = &spi_bus_type, | ||
231 | .owner = THIS_MODULE, | 230 | .owner = THIS_MODULE, |
232 | }, | 231 | }, |
233 | 232 | ||
diff --git a/drivers/hwmon/exynos4_tmu.c b/drivers/hwmon/exynos4_tmu.c index faa0884f61f6..f2359a0093bd 100644 --- a/drivers/hwmon/exynos4_tmu.c +++ b/drivers/hwmon/exynos4_tmu.c | |||
@@ -506,17 +506,7 @@ static struct platform_driver exynos4_tmu_driver = { | |||
506 | .resume = exynos4_tmu_resume, | 506 | .resume = exynos4_tmu_resume, |
507 | }; | 507 | }; |
508 | 508 | ||
509 | static int __init exynos4_tmu_driver_init(void) | 509 | module_platform_driver(exynos4_tmu_driver); |
510 | { | ||
511 | return platform_driver_register(&exynos4_tmu_driver); | ||
512 | } | ||
513 | module_init(exynos4_tmu_driver_init); | ||
514 | |||
515 | static void __exit exynos4_tmu_driver_exit(void) | ||
516 | { | ||
517 | platform_driver_unregister(&exynos4_tmu_driver); | ||
518 | } | ||
519 | module_exit(exynos4_tmu_driver_exit); | ||
520 | 510 | ||
521 | MODULE_DESCRIPTION("EXYNOS4 TMU Driver"); | 511 | MODULE_DESCRIPTION("EXYNOS4 TMU Driver"); |
522 | MODULE_AUTHOR("Donggeun Kim <dg77.kim@samsung.com>"); | 512 | MODULE_AUTHOR("Donggeun Kim <dg77.kim@samsung.com>"); |
diff --git a/drivers/hwmon/gpio-fan.c b/drivers/hwmon/gpio-fan.c index 89aa9fb743af..9ba38f318ffb 100644 --- a/drivers/hwmon/gpio-fan.c +++ b/drivers/hwmon/gpio-fan.c | |||
@@ -539,18 +539,7 @@ static struct platform_driver gpio_fan_driver = { | |||
539 | }, | 539 | }, |
540 | }; | 540 | }; |
541 | 541 | ||
542 | static int __init gpio_fan_init(void) | 542 | module_platform_driver(gpio_fan_driver); |
543 | { | ||
544 | return platform_driver_register(&gpio_fan_driver); | ||
545 | } | ||
546 | |||
547 | static void __exit gpio_fan_exit(void) | ||
548 | { | ||
549 | platform_driver_unregister(&gpio_fan_driver); | ||
550 | } | ||
551 | |||
552 | module_init(gpio_fan_init); | ||
553 | module_exit(gpio_fan_exit); | ||
554 | 543 | ||
555 | MODULE_AUTHOR("Simon Guinot <sguinot@lacie.com>"); | 544 | MODULE_AUTHOR("Simon Guinot <sguinot@lacie.com>"); |
556 | MODULE_DESCRIPTION("GPIO FAN driver"); | 545 | MODULE_DESCRIPTION("GPIO FAN driver"); |
diff --git a/drivers/hwmon/jz4740-hwmon.c b/drivers/hwmon/jz4740-hwmon.c index fea292d43407..7a48b1eb4233 100644 --- a/drivers/hwmon/jz4740-hwmon.c +++ b/drivers/hwmon/jz4740-hwmon.c | |||
@@ -212,17 +212,7 @@ struct platform_driver jz4740_hwmon_driver = { | |||
212 | }, | 212 | }, |
213 | }; | 213 | }; |
214 | 214 | ||
215 | static int __init jz4740_hwmon_init(void) | 215 | module_platform_driver(jz4740_hwmon_driver); |
216 | { | ||
217 | return platform_driver_register(&jz4740_hwmon_driver); | ||
218 | } | ||
219 | module_init(jz4740_hwmon_init); | ||
220 | |||
221 | static void __exit jz4740_hwmon_exit(void) | ||
222 | { | ||
223 | platform_driver_unregister(&jz4740_hwmon_driver); | ||
224 | } | ||
225 | module_exit(jz4740_hwmon_exit); | ||
226 | 216 | ||
227 | MODULE_DESCRIPTION("JZ4740 SoC HWMON driver"); | 217 | MODULE_DESCRIPTION("JZ4740 SoC HWMON driver"); |
228 | MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>"); | 218 | MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>"); |
diff --git a/drivers/hwmon/ntc_thermistor.c b/drivers/hwmon/ntc_thermistor.c index eab11615dced..9b382ec2c3bd 100644 --- a/drivers/hwmon/ntc_thermistor.c +++ b/drivers/hwmon/ntc_thermistor.c | |||
@@ -432,19 +432,7 @@ static struct platform_driver ntc_thermistor_driver = { | |||
432 | .id_table = ntc_thermistor_id, | 432 | .id_table = ntc_thermistor_id, |
433 | }; | 433 | }; |
434 | 434 | ||
435 | static int __init ntc_thermistor_init(void) | 435 | module_platform_driver(ntc_thermistor_driver); |
436 | { | ||
437 | return platform_driver_register(&ntc_thermistor_driver); | ||
438 | } | ||
439 | |||
440 | module_init(ntc_thermistor_init); | ||
441 | |||
442 | static void __exit ntc_thermistor_cleanup(void) | ||
443 | { | ||
444 | platform_driver_unregister(&ntc_thermistor_driver); | ||
445 | } | ||
446 | |||
447 | module_exit(ntc_thermistor_cleanup); | ||
448 | 436 | ||
449 | MODULE_DESCRIPTION("NTC Thermistor Driver"); | 437 | MODULE_DESCRIPTION("NTC Thermistor Driver"); |
450 | MODULE_AUTHOR("MyungJoo Ham <myungjoo.ham@samsung.com>"); | 438 | MODULE_AUTHOR("MyungJoo Ham <myungjoo.ham@samsung.com>"); |
diff --git a/drivers/hwmon/s3c-hwmon.c b/drivers/hwmon/s3c-hwmon.c index b39f52e2752a..f6c26d19f521 100644 --- a/drivers/hwmon/s3c-hwmon.c +++ b/drivers/hwmon/s3c-hwmon.c | |||
@@ -393,18 +393,7 @@ static struct platform_driver s3c_hwmon_driver = { | |||
393 | .remove = __devexit_p(s3c_hwmon_remove), | 393 | .remove = __devexit_p(s3c_hwmon_remove), |
394 | }; | 394 | }; |
395 | 395 | ||
396 | static int __init s3c_hwmon_init(void) | 396 | module_platform_driver(s3c_hwmon_driver); |
397 | { | ||
398 | return platform_driver_register(&s3c_hwmon_driver); | ||
399 | } | ||
400 | |||
401 | static void __exit s3c_hwmon_exit(void) | ||
402 | { | ||
403 | platform_driver_unregister(&s3c_hwmon_driver); | ||
404 | } | ||
405 | |||
406 | module_init(s3c_hwmon_init); | ||
407 | module_exit(s3c_hwmon_exit); | ||
408 | 397 | ||
409 | MODULE_AUTHOR("Ben Dooks <ben@simtec.co.uk>"); | 398 | MODULE_AUTHOR("Ben Dooks <ben@simtec.co.uk>"); |
410 | MODULE_DESCRIPTION("S3C ADC HWMon driver"); | 399 | MODULE_DESCRIPTION("S3C ADC HWMon driver"); |
diff --git a/drivers/hwmon/sch5627.c b/drivers/hwmon/sch5627.c index e3b5c6039c25..79b6dabe3161 100644 --- a/drivers/hwmon/sch5627.c +++ b/drivers/hwmon/sch5627.c | |||
@@ -590,19 +590,8 @@ static struct platform_driver sch5627_driver = { | |||
590 | .remove = sch5627_remove, | 590 | .remove = sch5627_remove, |
591 | }; | 591 | }; |
592 | 592 | ||
593 | static int __init sch5627_init(void) | 593 | module_platform_driver(sch5627_driver); |
594 | { | ||
595 | return platform_driver_register(&sch5627_driver); | ||
596 | } | ||
597 | |||
598 | static void __exit sch5627_exit(void) | ||
599 | { | ||
600 | platform_driver_unregister(&sch5627_driver); | ||
601 | } | ||
602 | 594 | ||
603 | MODULE_DESCRIPTION("SMSC SCH5627 Hardware Monitoring Driver"); | 595 | MODULE_DESCRIPTION("SMSC SCH5627 Hardware Monitoring Driver"); |
604 | MODULE_AUTHOR("Hans de Goede <hdegoede@redhat.com>"); | 596 | MODULE_AUTHOR("Hans de Goede <hdegoede@redhat.com>"); |
605 | MODULE_LICENSE("GPL"); | 597 | MODULE_LICENSE("GPL"); |
606 | |||
607 | module_init(sch5627_init); | ||
608 | module_exit(sch5627_exit); | ||
diff --git a/drivers/hwmon/sch5636.c b/drivers/hwmon/sch5636.c index 244407aa79fc..9d5236fb09b4 100644 --- a/drivers/hwmon/sch5636.c +++ b/drivers/hwmon/sch5636.c | |||
@@ -521,19 +521,8 @@ static struct platform_driver sch5636_driver = { | |||
521 | .remove = sch5636_remove, | 521 | .remove = sch5636_remove, |
522 | }; | 522 | }; |
523 | 523 | ||
524 | static int __init sch5636_init(void) | 524 | module_platform_driver(sch5636_driver); |
525 | { | ||
526 | return platform_driver_register(&sch5636_driver); | ||
527 | } | ||
528 | |||
529 | static void __exit sch5636_exit(void) | ||
530 | { | ||
531 | platform_driver_unregister(&sch5636_driver); | ||
532 | } | ||
533 | 525 | ||
534 | MODULE_DESCRIPTION("SMSC SCH5636 Hardware Monitoring Driver"); | 526 | MODULE_DESCRIPTION("SMSC SCH5636 Hardware Monitoring Driver"); |
535 | MODULE_AUTHOR("Hans de Goede <hdegoede@redhat.com>"); | 527 | MODULE_AUTHOR("Hans de Goede <hdegoede@redhat.com>"); |
536 | MODULE_LICENSE("GPL"); | 528 | MODULE_LICENSE("GPL"); |
537 | |||
538 | module_init(sch5636_init); | ||
539 | module_exit(sch5636_exit); | ||
diff --git a/drivers/hwmon/twl4030-madc-hwmon.c b/drivers/hwmon/twl4030-madc-hwmon.c index 57240740b161..0018c7dd0097 100644 --- a/drivers/hwmon/twl4030-madc-hwmon.c +++ b/drivers/hwmon/twl4030-madc-hwmon.c | |||
@@ -136,19 +136,7 @@ static struct platform_driver twl4030_madc_hwmon_driver = { | |||
136 | }, | 136 | }, |
137 | }; | 137 | }; |
138 | 138 | ||
139 | static int __init twl4030_madc_hwmon_init(void) | 139 | module_platform_driver(twl4030_madc_hwmon_driver); |
140 | { | ||
141 | return platform_driver_register(&twl4030_madc_hwmon_driver); | ||
142 | } | ||
143 | |||
144 | module_init(twl4030_madc_hwmon_init); | ||
145 | |||
146 | static void __exit twl4030_madc_hwmon_exit(void) | ||
147 | { | ||
148 | platform_driver_unregister(&twl4030_madc_hwmon_driver); | ||
149 | } | ||
150 | |||
151 | module_exit(twl4030_madc_hwmon_exit); | ||
152 | 140 | ||
153 | MODULE_DESCRIPTION("TWL4030 ADC Hwmon driver"); | 141 | MODULE_DESCRIPTION("TWL4030 ADC Hwmon driver"); |
154 | MODULE_LICENSE("GPL"); | 142 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/hwmon/ultra45_env.c b/drivers/hwmon/ultra45_env.c index 3cd07bf42dca..b9a87e89bab4 100644 --- a/drivers/hwmon/ultra45_env.c +++ b/drivers/hwmon/ultra45_env.c | |||
@@ -309,15 +309,4 @@ static struct platform_driver env_driver = { | |||
309 | .remove = __devexit_p(env_remove), | 309 | .remove = __devexit_p(env_remove), |
310 | }; | 310 | }; |
311 | 311 | ||
312 | static int __init env_init(void) | 312 | module_platform_driver(env_driver); |
313 | { | ||
314 | return platform_driver_register(&env_driver); | ||
315 | } | ||
316 | |||
317 | static void __exit env_exit(void) | ||
318 | { | ||
319 | platform_driver_unregister(&env_driver); | ||
320 | } | ||
321 | |||
322 | module_init(env_init); | ||
323 | module_exit(env_exit); | ||
diff --git a/drivers/hwmon/wm831x-hwmon.c b/drivers/hwmon/wm831x-hwmon.c index 97b1f834a471..9b598ed26020 100644 --- a/drivers/hwmon/wm831x-hwmon.c +++ b/drivers/hwmon/wm831x-hwmon.c | |||
@@ -209,17 +209,7 @@ static struct platform_driver wm831x_hwmon_driver = { | |||
209 | }, | 209 | }, |
210 | }; | 210 | }; |
211 | 211 | ||
212 | static int __init wm831x_hwmon_init(void) | 212 | module_platform_driver(wm831x_hwmon_driver); |
213 | { | ||
214 | return platform_driver_register(&wm831x_hwmon_driver); | ||
215 | } | ||
216 | module_init(wm831x_hwmon_init); | ||
217 | |||
218 | static void __exit wm831x_hwmon_exit(void) | ||
219 | { | ||
220 | platform_driver_unregister(&wm831x_hwmon_driver); | ||
221 | } | ||
222 | module_exit(wm831x_hwmon_exit); | ||
223 | 213 | ||
224 | MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>"); | 214 | MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>"); |
225 | MODULE_DESCRIPTION("WM831x Hardware Monitoring"); | 215 | MODULE_DESCRIPTION("WM831x Hardware Monitoring"); |
diff --git a/drivers/hwmon/wm8350-hwmon.c b/drivers/hwmon/wm8350-hwmon.c index 13290595ca86..3ff67edbdc44 100644 --- a/drivers/hwmon/wm8350-hwmon.c +++ b/drivers/hwmon/wm8350-hwmon.c | |||
@@ -133,17 +133,7 @@ static struct platform_driver wm8350_hwmon_driver = { | |||
133 | }, | 133 | }, |
134 | }; | 134 | }; |
135 | 135 | ||
136 | static int __init wm8350_hwmon_init(void) | 136 | module_platform_driver(wm8350_hwmon_driver); |
137 | { | ||
138 | return platform_driver_register(&wm8350_hwmon_driver); | ||
139 | } | ||
140 | module_init(wm8350_hwmon_init); | ||
141 | |||
142 | static void __exit wm8350_hwmon_exit(void) | ||
143 | { | ||
144 | platform_driver_unregister(&wm8350_hwmon_driver); | ||
145 | } | ||
146 | module_exit(wm8350_hwmon_exit); | ||
147 | 137 | ||
148 | MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>"); | 138 | MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>"); |
149 | MODULE_DESCRIPTION("WM8350 Hardware Monitoring"); | 139 | MODULE_DESCRIPTION("WM8350 Hardware Monitoring"); |
diff --git a/drivers/i2c/algos/i2c-algo-bit.c b/drivers/i2c/algos/i2c-algo-bit.c index 85584a547c25..525c7345fa0b 100644 --- a/drivers/i2c/algos/i2c-algo-bit.c +++ b/drivers/i2c/algos/i2c-algo-bit.c | |||
@@ -488,7 +488,7 @@ static int bit_doAddress(struct i2c_adapter *i2c_adap, struct i2c_msg *msg) | |||
488 | 488 | ||
489 | if (flags & I2C_M_TEN) { | 489 | if (flags & I2C_M_TEN) { |
490 | /* a ten bit address */ | 490 | /* a ten bit address */ |
491 | addr = 0xf0 | ((msg->addr >> 7) & 0x03); | 491 | addr = 0xf0 | ((msg->addr >> 7) & 0x06); |
492 | bit_dbg(2, &i2c_adap->dev, "addr0: %d\n", addr); | 492 | bit_dbg(2, &i2c_adap->dev, "addr0: %d\n", addr); |
493 | /* try extended address code...*/ | 493 | /* try extended address code...*/ |
494 | ret = try_address(i2c_adap, addr, retries); | 494 | ret = try_address(i2c_adap, addr, retries); |
@@ -498,7 +498,7 @@ static int bit_doAddress(struct i2c_adapter *i2c_adap, struct i2c_msg *msg) | |||
498 | return -ENXIO; | 498 | return -ENXIO; |
499 | } | 499 | } |
500 | /* the remaining 8 bit address */ | 500 | /* the remaining 8 bit address */ |
501 | ret = i2c_outb(i2c_adap, msg->addr & 0x7f); | 501 | ret = i2c_outb(i2c_adap, msg->addr & 0xff); |
502 | if ((ret != 1) && !nak_ok) { | 502 | if ((ret != 1) && !nak_ok) { |
503 | /* the chip did not ack / xmission error occurred */ | 503 | /* the chip did not ack / xmission error occurred */ |
504 | dev_err(&i2c_adap->dev, "died at 2nd address code\n"); | 504 | dev_err(&i2c_adap->dev, "died at 2nd address code\n"); |
diff --git a/drivers/i2c/busses/i2c-nuc900.c b/drivers/i2c/busses/i2c-nuc900.c index 835e47b39bc2..03b615778887 100644 --- a/drivers/i2c/busses/i2c-nuc900.c +++ b/drivers/i2c/busses/i2c-nuc900.c | |||
@@ -593,7 +593,7 @@ static int __devinit nuc900_i2c_probe(struct platform_device *pdev) | |||
593 | i2c->adap.algo_data = i2c; | 593 | i2c->adap.algo_data = i2c; |
594 | i2c->adap.dev.parent = &pdev->dev; | 594 | i2c->adap.dev.parent = &pdev->dev; |
595 | 595 | ||
596 | mfp_set_groupg(&pdev->dev); | 596 | mfp_set_groupg(&pdev->dev, NULL); |
597 | 597 | ||
598 | clk_get_rate(i2c->clk); | 598 | clk_get_rate(i2c->clk); |
599 | 599 | ||
diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c index 131079a3e292..1e5606185b4f 100644 --- a/drivers/i2c/i2c-core.c +++ b/drivers/i2c/i2c-core.c | |||
@@ -539,8 +539,10 @@ i2c_new_device(struct i2c_adapter *adap, struct i2c_board_info const *info) | |||
539 | client->dev.type = &i2c_client_type; | 539 | client->dev.type = &i2c_client_type; |
540 | client->dev.of_node = info->of_node; | 540 | client->dev.of_node = info->of_node; |
541 | 541 | ||
542 | /* For 10-bit clients, add an arbitrary offset to avoid collisions */ | ||
542 | dev_set_name(&client->dev, "%d-%04x", i2c_adapter_id(adap), | 543 | dev_set_name(&client->dev, "%d-%04x", i2c_adapter_id(adap), |
543 | client->addr); | 544 | client->addr | ((client->flags & I2C_CLIENT_TEN) |
545 | ? 0xa000 : 0)); | ||
544 | status = device_register(&client->dev); | 546 | status = device_register(&client->dev); |
545 | if (status) | 547 | if (status) |
546 | goto out_err; | 548 | goto out_err; |
diff --git a/drivers/i2c/i2c-dev.c b/drivers/i2c/i2c-dev.c index c90ce50b619f..57a45ce84b2d 100644 --- a/drivers/i2c/i2c-dev.c +++ b/drivers/i2c/i2c-dev.c | |||
@@ -579,7 +579,7 @@ static int i2cdev_detach_adapter(struct device *dev, void *dummy) | |||
579 | return 0; | 579 | return 0; |
580 | } | 580 | } |
581 | 581 | ||
582 | int i2cdev_notifier_call(struct notifier_block *nb, unsigned long action, | 582 | static int i2cdev_notifier_call(struct notifier_block *nb, unsigned long action, |
583 | void *data) | 583 | void *data) |
584 | { | 584 | { |
585 | struct device *dev = data; | 585 | struct device *dev = data; |
diff --git a/drivers/infiniband/core/addr.c b/drivers/infiniband/core/addr.c index adf0757280ed..a20c3c8224ea 100644 --- a/drivers/infiniband/core/addr.c +++ b/drivers/infiniband/core/addr.c | |||
@@ -216,7 +216,9 @@ static int addr4_resolve(struct sockaddr_in *src_in, | |||
216 | 216 | ||
217 | neigh = neigh_lookup(&arp_tbl, &rt->rt_gateway, rt->dst.dev); | 217 | neigh = neigh_lookup(&arp_tbl, &rt->rt_gateway, rt->dst.dev); |
218 | if (!neigh || !(neigh->nud_state & NUD_VALID)) { | 218 | if (!neigh || !(neigh->nud_state & NUD_VALID)) { |
219 | rcu_read_lock(); | ||
219 | neigh_event_send(dst_get_neighbour(&rt->dst), NULL); | 220 | neigh_event_send(dst_get_neighbour(&rt->dst), NULL); |
221 | rcu_read_unlock(); | ||
220 | ret = -ENODATA; | 222 | ret = -ENODATA; |
221 | if (neigh) | 223 | if (neigh) |
222 | goto release; | 224 | goto release; |
@@ -274,15 +276,16 @@ static int addr6_resolve(struct sockaddr_in6 *src_in, | |||
274 | goto put; | 276 | goto put; |
275 | } | 277 | } |
276 | 278 | ||
279 | rcu_read_lock(); | ||
277 | neigh = dst_get_neighbour(dst); | 280 | neigh = dst_get_neighbour(dst); |
278 | if (!neigh || !(neigh->nud_state & NUD_VALID)) { | 281 | if (!neigh || !(neigh->nud_state & NUD_VALID)) { |
279 | if (neigh) | 282 | if (neigh) |
280 | neigh_event_send(neigh, NULL); | 283 | neigh_event_send(neigh, NULL); |
281 | ret = -ENODATA; | 284 | ret = -ENODATA; |
282 | goto put; | 285 | } else { |
286 | ret = rdma_copy_addr(addr, dst->dev, neigh->ha); | ||
283 | } | 287 | } |
284 | 288 | rcu_read_unlock(); | |
285 | ret = rdma_copy_addr(addr, dst->dev, neigh->ha); | ||
286 | put: | 289 | put: |
287 | dst_release(dst); | 290 | dst_release(dst); |
288 | return ret; | 291 | return ret; |
diff --git a/drivers/infiniband/hw/cxgb3/iwch_cm.c b/drivers/infiniband/hw/cxgb3/iwch_cm.c index de6d0774e609..c88b12beef25 100644 --- a/drivers/infiniband/hw/cxgb3/iwch_cm.c +++ b/drivers/infiniband/hw/cxgb3/iwch_cm.c | |||
@@ -1375,8 +1375,10 @@ static int pass_accept_req(struct t3cdev *tdev, struct sk_buff *skb, void *ctx) | |||
1375 | goto reject; | 1375 | goto reject; |
1376 | } | 1376 | } |
1377 | dst = &rt->dst; | 1377 | dst = &rt->dst; |
1378 | rcu_read_lock(); | ||
1378 | neigh = dst_get_neighbour(dst); | 1379 | neigh = dst_get_neighbour(dst); |
1379 | l2t = t3_l2t_get(tdev, neigh, neigh->dev); | 1380 | l2t = t3_l2t_get(tdev, neigh, neigh->dev); |
1381 | rcu_read_unlock(); | ||
1380 | if (!l2t) { | 1382 | if (!l2t) { |
1381 | printk(KERN_ERR MOD "%s - failed to allocate l2t entry!\n", | 1383 | printk(KERN_ERR MOD "%s - failed to allocate l2t entry!\n", |
1382 | __func__); | 1384 | __func__); |
@@ -1946,10 +1948,12 @@ int iwch_connect(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param) | |||
1946 | } | 1948 | } |
1947 | ep->dst = &rt->dst; | 1949 | ep->dst = &rt->dst; |
1948 | 1950 | ||
1951 | rcu_read_lock(); | ||
1949 | neigh = dst_get_neighbour(ep->dst); | 1952 | neigh = dst_get_neighbour(ep->dst); |
1950 | 1953 | ||
1951 | /* get a l2t entry */ | 1954 | /* get a l2t entry */ |
1952 | ep->l2t = t3_l2t_get(ep->com.tdev, neigh, neigh->dev); | 1955 | ep->l2t = t3_l2t_get(ep->com.tdev, neigh, neigh->dev); |
1956 | rcu_read_unlock(); | ||
1953 | if (!ep->l2t) { | 1957 | if (!ep->l2t) { |
1954 | printk(KERN_ERR MOD "%s - cannot alloc l2e.\n", __func__); | 1958 | printk(KERN_ERR MOD "%s - cannot alloc l2e.\n", __func__); |
1955 | err = -ENOMEM; | 1959 | err = -ENOMEM; |
diff --git a/drivers/infiniband/hw/cxgb4/cm.c b/drivers/infiniband/hw/cxgb4/cm.c index b36cdac9c558..0747004313ad 100644 --- a/drivers/infiniband/hw/cxgb4/cm.c +++ b/drivers/infiniband/hw/cxgb4/cm.c | |||
@@ -542,8 +542,10 @@ static void send_mpa_req(struct c4iw_ep *ep, struct sk_buff *skb, | |||
542 | (mpa_rev_to_use == 2 ? MPA_ENHANCED_RDMA_CONN : 0); | 542 | (mpa_rev_to_use == 2 ? MPA_ENHANCED_RDMA_CONN : 0); |
543 | mpa->private_data_size = htons(ep->plen); | 543 | mpa->private_data_size = htons(ep->plen); |
544 | mpa->revision = mpa_rev_to_use; | 544 | mpa->revision = mpa_rev_to_use; |
545 | if (mpa_rev_to_use == 1) | 545 | if (mpa_rev_to_use == 1) { |
546 | ep->tried_with_mpa_v1 = 1; | 546 | ep->tried_with_mpa_v1 = 1; |
547 | ep->retry_with_mpa_v1 = 0; | ||
548 | } | ||
547 | 549 | ||
548 | if (mpa_rev_to_use == 2) { | 550 | if (mpa_rev_to_use == 2) { |
549 | mpa->private_data_size += | 551 | mpa->private_data_size += |
@@ -1594,6 +1596,7 @@ static int pass_accept_req(struct c4iw_dev *dev, struct sk_buff *skb) | |||
1594 | goto reject; | 1596 | goto reject; |
1595 | } | 1597 | } |
1596 | dst = &rt->dst; | 1598 | dst = &rt->dst; |
1599 | rcu_read_lock(); | ||
1597 | neigh = dst_get_neighbour(dst); | 1600 | neigh = dst_get_neighbour(dst); |
1598 | if (neigh->dev->flags & IFF_LOOPBACK) { | 1601 | if (neigh->dev->flags & IFF_LOOPBACK) { |
1599 | pdev = ip_dev_find(&init_net, peer_ip); | 1602 | pdev = ip_dev_find(&init_net, peer_ip); |
@@ -1620,6 +1623,7 @@ static int pass_accept_req(struct c4iw_dev *dev, struct sk_buff *skb) | |||
1620 | rss_qid = dev->rdev.lldi.rxq_ids[ | 1623 | rss_qid = dev->rdev.lldi.rxq_ids[ |
1621 | cxgb4_port_idx(neigh->dev) * step]; | 1624 | cxgb4_port_idx(neigh->dev) * step]; |
1622 | } | 1625 | } |
1626 | rcu_read_unlock(); | ||
1623 | if (!l2t) { | 1627 | if (!l2t) { |
1624 | printk(KERN_ERR MOD "%s - failed to allocate l2t entry!\n", | 1628 | printk(KERN_ERR MOD "%s - failed to allocate l2t entry!\n", |
1625 | __func__); | 1629 | __func__); |
@@ -1820,6 +1824,7 @@ static int c4iw_reconnect(struct c4iw_ep *ep) | |||
1820 | } | 1824 | } |
1821 | ep->dst = &rt->dst; | 1825 | ep->dst = &rt->dst; |
1822 | 1826 | ||
1827 | rcu_read_lock(); | ||
1823 | neigh = dst_get_neighbour(ep->dst); | 1828 | neigh = dst_get_neighbour(ep->dst); |
1824 | 1829 | ||
1825 | /* get a l2t entry */ | 1830 | /* get a l2t entry */ |
@@ -1856,6 +1861,7 @@ static int c4iw_reconnect(struct c4iw_ep *ep) | |||
1856 | ep->rss_qid = ep->com.dev->rdev.lldi.rxq_ids[ | 1861 | ep->rss_qid = ep->com.dev->rdev.lldi.rxq_ids[ |
1857 | cxgb4_port_idx(neigh->dev) * step]; | 1862 | cxgb4_port_idx(neigh->dev) * step]; |
1858 | } | 1863 | } |
1864 | rcu_read_unlock(); | ||
1859 | if (!ep->l2t) { | 1865 | if (!ep->l2t) { |
1860 | printk(KERN_ERR MOD "%s - cannot alloc l2e.\n", __func__); | 1866 | printk(KERN_ERR MOD "%s - cannot alloc l2e.\n", __func__); |
1861 | err = -ENOMEM; | 1867 | err = -ENOMEM; |
@@ -2301,6 +2307,7 @@ int c4iw_connect(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param) | |||
2301 | } | 2307 | } |
2302 | ep->dst = &rt->dst; | 2308 | ep->dst = &rt->dst; |
2303 | 2309 | ||
2310 | rcu_read_lock(); | ||
2304 | neigh = dst_get_neighbour(ep->dst); | 2311 | neigh = dst_get_neighbour(ep->dst); |
2305 | 2312 | ||
2306 | /* get a l2t entry */ | 2313 | /* get a l2t entry */ |
@@ -2339,6 +2346,7 @@ int c4iw_connect(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param) | |||
2339 | ep->retry_with_mpa_v1 = 0; | 2346 | ep->retry_with_mpa_v1 = 0; |
2340 | ep->tried_with_mpa_v1 = 0; | 2347 | ep->tried_with_mpa_v1 = 0; |
2341 | } | 2348 | } |
2349 | rcu_read_unlock(); | ||
2342 | if (!ep->l2t) { | 2350 | if (!ep->l2t) { |
2343 | printk(KERN_ERR MOD "%s - cannot alloc l2e.\n", __func__); | 2351 | printk(KERN_ERR MOD "%s - cannot alloc l2e.\n", __func__); |
2344 | err = -ENOMEM; | 2352 | err = -ENOMEM; |
diff --git a/drivers/infiniband/hw/cxgb4/cq.c b/drivers/infiniband/hw/cxgb4/cq.c index f35a935267e7..0f1607c8325a 100644 --- a/drivers/infiniband/hw/cxgb4/cq.c +++ b/drivers/infiniband/hw/cxgb4/cq.c | |||
@@ -311,7 +311,7 @@ void c4iw_count_rcqes(struct t4_cq *cq, struct t4_wq *wq, int *count) | |||
311 | while (ptr != cq->sw_pidx) { | 311 | while (ptr != cq->sw_pidx) { |
312 | cqe = &cq->sw_queue[ptr]; | 312 | cqe = &cq->sw_queue[ptr]; |
313 | if (RQ_TYPE(cqe) && (CQE_OPCODE(cqe) != FW_RI_READ_RESP) && | 313 | if (RQ_TYPE(cqe) && (CQE_OPCODE(cqe) != FW_RI_READ_RESP) && |
314 | (CQE_QPID(cqe) == wq->rq.qid) && cqe_completes_wr(cqe, wq)) | 314 | (CQE_QPID(cqe) == wq->sq.qid) && cqe_completes_wr(cqe, wq)) |
315 | (*count)++; | 315 | (*count)++; |
316 | if (++ptr == cq->size) | 316 | if (++ptr == cq->size) |
317 | ptr = 0; | 317 | ptr = 0; |
diff --git a/drivers/infiniband/hw/nes/nes_cm.c b/drivers/infiniband/hw/nes/nes_cm.c index dfce9ea98a39..0a52d72371ee 100644 --- a/drivers/infiniband/hw/nes/nes_cm.c +++ b/drivers/infiniband/hw/nes/nes_cm.c | |||
@@ -1377,9 +1377,11 @@ static int nes_addr_resolve_neigh(struct nes_vnic *nesvnic, u32 dst_ip, int arpi | |||
1377 | neigh_release(neigh); | 1377 | neigh_release(neigh); |
1378 | } | 1378 | } |
1379 | 1379 | ||
1380 | if ((neigh == NULL) || (!(neigh->nud_state & NUD_VALID))) | 1380 | if ((neigh == NULL) || (!(neigh->nud_state & NUD_VALID))) { |
1381 | rcu_read_lock(); | ||
1381 | neigh_event_send(dst_get_neighbour(&rt->dst), NULL); | 1382 | neigh_event_send(dst_get_neighbour(&rt->dst), NULL); |
1382 | 1383 | rcu_read_unlock(); | |
1384 | } | ||
1383 | ip_rt_put(rt); | 1385 | ip_rt_put(rt); |
1384 | return rc; | 1386 | return rc; |
1385 | } | 1387 | } |
diff --git a/drivers/infiniband/hw/qib/qib_iba7322.c b/drivers/infiniband/hw/qib/qib_iba7322.c index 5bd2162b95dc..1d5895941e19 100644 --- a/drivers/infiniband/hw/qib/qib_iba7322.c +++ b/drivers/infiniband/hw/qib/qib_iba7322.c | |||
@@ -2307,19 +2307,11 @@ static int qib_7322_bringup_serdes(struct qib_pportdata *ppd) | |||
2307 | SYM_LSB(IBCCtrlA_0, MaxPktLen); | 2307 | SYM_LSB(IBCCtrlA_0, MaxPktLen); |
2308 | ppd->cpspec->ibcctrl_a = ibc; /* without linkcmd or linkinitcmd! */ | 2308 | ppd->cpspec->ibcctrl_a = ibc; /* without linkcmd or linkinitcmd! */ |
2309 | 2309 | ||
2310 | /* initially come up waiting for TS1, without sending anything. */ | ||
2311 | val = ppd->cpspec->ibcctrl_a | (QLOGIC_IB_IBCC_LINKINITCMD_DISABLE << | ||
2312 | QLOGIC_IB_IBCC_LINKINITCMD_SHIFT); | ||
2313 | |||
2314 | ppd->cpspec->ibcctrl_a = val; | ||
2315 | /* | 2310 | /* |
2316 | * Reset the PCS interface to the serdes (and also ibc, which is still | 2311 | * Reset the PCS interface to the serdes (and also ibc, which is still |
2317 | * in reset from above). Writes new value of ibcctrl_a as last step. | 2312 | * in reset from above). Writes new value of ibcctrl_a as last step. |
2318 | */ | 2313 | */ |
2319 | qib_7322_mini_pcs_reset(ppd); | 2314 | qib_7322_mini_pcs_reset(ppd); |
2320 | qib_write_kreg(dd, kr_scratch, 0ULL); | ||
2321 | /* clear the linkinit cmds */ | ||
2322 | ppd->cpspec->ibcctrl_a &= ~SYM_MASK(IBCCtrlA_0, LinkInitCmd); | ||
2323 | 2315 | ||
2324 | if (!ppd->cpspec->ibcctrl_b) { | 2316 | if (!ppd->cpspec->ibcctrl_b) { |
2325 | unsigned lse = ppd->link_speed_enabled; | 2317 | unsigned lse = ppd->link_speed_enabled; |
@@ -2385,6 +2377,14 @@ static int qib_7322_bringup_serdes(struct qib_pportdata *ppd) | |||
2385 | ppd->cpspec->ibcctrl_a |= SYM_MASK(IBCCtrlA_0, IBLinkEn); | 2377 | ppd->cpspec->ibcctrl_a |= SYM_MASK(IBCCtrlA_0, IBLinkEn); |
2386 | set_vls(ppd); | 2378 | set_vls(ppd); |
2387 | 2379 | ||
2380 | /* initially come up DISABLED, without sending anything. */ | ||
2381 | val = ppd->cpspec->ibcctrl_a | (QLOGIC_IB_IBCC_LINKINITCMD_DISABLE << | ||
2382 | QLOGIC_IB_IBCC_LINKINITCMD_SHIFT); | ||
2383 | qib_write_kreg_port(ppd, krp_ibcctrl_a, val); | ||
2384 | qib_write_kreg(dd, kr_scratch, 0ULL); | ||
2385 | /* clear the linkinit cmds */ | ||
2386 | ppd->cpspec->ibcctrl_a = val & ~SYM_MASK(IBCCtrlA_0, LinkInitCmd); | ||
2387 | |||
2388 | /* be paranoid against later code motion, etc. */ | 2388 | /* be paranoid against later code motion, etc. */ |
2389 | spin_lock_irqsave(&dd->cspec->rcvmod_lock, flags); | 2389 | spin_lock_irqsave(&dd->cspec->rcvmod_lock, flags); |
2390 | ppd->p_rcvctrl |= SYM_MASK(RcvCtrl_0, RcvIBPortEnable); | 2390 | ppd->p_rcvctrl |= SYM_MASK(RcvCtrl_0, RcvIBPortEnable); |
@@ -5241,7 +5241,7 @@ static int qib_7322_ib_updown(struct qib_pportdata *ppd, int ibup, u64 ibcs) | |||
5241 | off */ | 5241 | off */ |
5242 | if (ppd->dd->flags & QIB_HAS_QSFP) { | 5242 | if (ppd->dd->flags & QIB_HAS_QSFP) { |
5243 | qd->t_insert = get_jiffies_64(); | 5243 | qd->t_insert = get_jiffies_64(); |
5244 | schedule_work(&qd->work); | 5244 | queue_work(ib_wq, &qd->work); |
5245 | } | 5245 | } |
5246 | spin_lock_irqsave(&ppd->sdma_lock, flags); | 5246 | spin_lock_irqsave(&ppd->sdma_lock, flags); |
5247 | if (__qib_sdma_running(ppd)) | 5247 | if (__qib_sdma_running(ppd)) |
diff --git a/drivers/infiniband/hw/qib/qib_qsfp.c b/drivers/infiniband/hw/qib/qib_qsfp.c index e06c4ed383f1..fa71b1e666c5 100644 --- a/drivers/infiniband/hw/qib/qib_qsfp.c +++ b/drivers/infiniband/hw/qib/qib_qsfp.c | |||
@@ -480,18 +480,6 @@ void qib_qsfp_init(struct qib_qsfp_data *qd, | |||
480 | udelay(20); /* Generous RST dwell */ | 480 | udelay(20); /* Generous RST dwell */ |
481 | 481 | ||
482 | dd->f_gpio_mod(dd, mask, mask, mask); | 482 | dd->f_gpio_mod(dd, mask, mask, mask); |
483 | /* Spec says module can take up to two seconds! */ | ||
484 | mask = QSFP_GPIO_MOD_PRS_N; | ||
485 | if (qd->ppd->hw_pidx) | ||
486 | mask <<= QSFP_GPIO_PORT2_SHIFT; | ||
487 | |||
488 | /* Do not try to wait here. Better to let event handle it */ | ||
489 | if (!qib_qsfp_mod_present(qd->ppd)) | ||
490 | goto bail; | ||
491 | /* We see a module, but it may be unwise to look yet. Just schedule */ | ||
492 | qd->t_insert = get_jiffies_64(); | ||
493 | queue_work(ib_wq, &qd->work); | ||
494 | bail: | ||
495 | return; | 483 | return; |
496 | } | 484 | } |
497 | 485 | ||
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_ib.c b/drivers/infiniband/ulp/ipoib/ipoib_ib.c index 0ef9af94997d..4115be54ba3b 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_ib.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_ib.c | |||
@@ -57,21 +57,24 @@ struct ipoib_ah *ipoib_create_ah(struct net_device *dev, | |||
57 | struct ib_pd *pd, struct ib_ah_attr *attr) | 57 | struct ib_pd *pd, struct ib_ah_attr *attr) |
58 | { | 58 | { |
59 | struct ipoib_ah *ah; | 59 | struct ipoib_ah *ah; |
60 | struct ib_ah *vah; | ||
60 | 61 | ||
61 | ah = kmalloc(sizeof *ah, GFP_KERNEL); | 62 | ah = kmalloc(sizeof *ah, GFP_KERNEL); |
62 | if (!ah) | 63 | if (!ah) |
63 | return NULL; | 64 | return ERR_PTR(-ENOMEM); |
64 | 65 | ||
65 | ah->dev = dev; | 66 | ah->dev = dev; |
66 | ah->last_send = 0; | 67 | ah->last_send = 0; |
67 | kref_init(&ah->ref); | 68 | kref_init(&ah->ref); |
68 | 69 | ||
69 | ah->ah = ib_create_ah(pd, attr); | 70 | vah = ib_create_ah(pd, attr); |
70 | if (IS_ERR(ah->ah)) { | 71 | if (IS_ERR(vah)) { |
71 | kfree(ah); | 72 | kfree(ah); |
72 | ah = NULL; | 73 | ah = (struct ipoib_ah *)vah; |
73 | } else | 74 | } else { |
75 | ah->ah = vah; | ||
74 | ipoib_dbg(netdev_priv(dev), "Created ah %p\n", ah->ah); | 76 | ipoib_dbg(netdev_priv(dev), "Created ah %p\n", ah->ah); |
77 | } | ||
75 | 78 | ||
76 | return ah; | 79 | return ah; |
77 | } | 80 | } |
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_main.c b/drivers/infiniband/ulp/ipoib/ipoib_main.c index 57ae9b9265e3..d3ed89ca4852 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_main.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_main.c | |||
@@ -432,7 +432,7 @@ static void path_rec_completion(int status, | |||
432 | 432 | ||
433 | spin_lock_irqsave(&priv->lock, flags); | 433 | spin_lock_irqsave(&priv->lock, flags); |
434 | 434 | ||
435 | if (ah) { | 435 | if (!IS_ERR_OR_NULL(ah)) { |
436 | path->pathrec = *pathrec; | 436 | path->pathrec = *pathrec; |
437 | 437 | ||
438 | old_ah = path->ah; | 438 | old_ah = path->ah; |
@@ -555,6 +555,7 @@ static int path_rec_start(struct net_device *dev, | |||
555 | return 0; | 555 | return 0; |
556 | } | 556 | } |
557 | 557 | ||
558 | /* called with rcu_read_lock */ | ||
558 | static void neigh_add_path(struct sk_buff *skb, struct net_device *dev) | 559 | static void neigh_add_path(struct sk_buff *skb, struct net_device *dev) |
559 | { | 560 | { |
560 | struct ipoib_dev_priv *priv = netdev_priv(dev); | 561 | struct ipoib_dev_priv *priv = netdev_priv(dev); |
@@ -636,6 +637,7 @@ err_drop: | |||
636 | spin_unlock_irqrestore(&priv->lock, flags); | 637 | spin_unlock_irqrestore(&priv->lock, flags); |
637 | } | 638 | } |
638 | 639 | ||
640 | /* called with rcu_read_lock */ | ||
639 | static void ipoib_path_lookup(struct sk_buff *skb, struct net_device *dev) | 641 | static void ipoib_path_lookup(struct sk_buff *skb, struct net_device *dev) |
640 | { | 642 | { |
641 | struct ipoib_dev_priv *priv = netdev_priv(skb->dev); | 643 | struct ipoib_dev_priv *priv = netdev_priv(skb->dev); |
@@ -720,13 +722,14 @@ static int ipoib_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
720 | struct neighbour *n = NULL; | 722 | struct neighbour *n = NULL; |
721 | unsigned long flags; | 723 | unsigned long flags; |
722 | 724 | ||
725 | rcu_read_lock(); | ||
723 | if (likely(skb_dst(skb))) | 726 | if (likely(skb_dst(skb))) |
724 | n = dst_get_neighbour(skb_dst(skb)); | 727 | n = dst_get_neighbour(skb_dst(skb)); |
725 | 728 | ||
726 | if (likely(n)) { | 729 | if (likely(n)) { |
727 | if (unlikely(!*to_ipoib_neigh(n))) { | 730 | if (unlikely(!*to_ipoib_neigh(n))) { |
728 | ipoib_path_lookup(skb, dev); | 731 | ipoib_path_lookup(skb, dev); |
729 | return NETDEV_TX_OK; | 732 | goto unlock; |
730 | } | 733 | } |
731 | 734 | ||
732 | neigh = *to_ipoib_neigh(n); | 735 | neigh = *to_ipoib_neigh(n); |
@@ -749,17 +752,17 @@ static int ipoib_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
749 | ipoib_neigh_free(dev, neigh); | 752 | ipoib_neigh_free(dev, neigh); |
750 | spin_unlock_irqrestore(&priv->lock, flags); | 753 | spin_unlock_irqrestore(&priv->lock, flags); |
751 | ipoib_path_lookup(skb, dev); | 754 | ipoib_path_lookup(skb, dev); |
752 | return NETDEV_TX_OK; | 755 | goto unlock; |
753 | } | 756 | } |
754 | 757 | ||
755 | if (ipoib_cm_get(neigh)) { | 758 | if (ipoib_cm_get(neigh)) { |
756 | if (ipoib_cm_up(neigh)) { | 759 | if (ipoib_cm_up(neigh)) { |
757 | ipoib_cm_send(dev, skb, ipoib_cm_get(neigh)); | 760 | ipoib_cm_send(dev, skb, ipoib_cm_get(neigh)); |
758 | return NETDEV_TX_OK; | 761 | goto unlock; |
759 | } | 762 | } |
760 | } else if (neigh->ah) { | 763 | } else if (neigh->ah) { |
761 | ipoib_send(dev, skb, neigh->ah, IPOIB_QPN(n->ha)); | 764 | ipoib_send(dev, skb, neigh->ah, IPOIB_QPN(n->ha)); |
762 | return NETDEV_TX_OK; | 765 | goto unlock; |
763 | } | 766 | } |
764 | 767 | ||
765 | if (skb_queue_len(&neigh->queue) < IPOIB_MAX_PATH_REC_QUEUE) { | 768 | if (skb_queue_len(&neigh->queue) < IPOIB_MAX_PATH_REC_QUEUE) { |
@@ -793,13 +796,14 @@ static int ipoib_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
793 | phdr->hwaddr + 4); | 796 | phdr->hwaddr + 4); |
794 | dev_kfree_skb_any(skb); | 797 | dev_kfree_skb_any(skb); |
795 | ++dev->stats.tx_dropped; | 798 | ++dev->stats.tx_dropped; |
796 | return NETDEV_TX_OK; | 799 | goto unlock; |
797 | } | 800 | } |
798 | 801 | ||
799 | unicast_arp_send(skb, dev, phdr); | 802 | unicast_arp_send(skb, dev, phdr); |
800 | } | 803 | } |
801 | } | 804 | } |
802 | 805 | unlock: | |
806 | rcu_read_unlock(); | ||
803 | return NETDEV_TX_OK; | 807 | return NETDEV_TX_OK; |
804 | } | 808 | } |
805 | 809 | ||
@@ -837,7 +841,7 @@ static int ipoib_hard_header(struct sk_buff *skb, | |||
837 | dst = skb_dst(skb); | 841 | dst = skb_dst(skb); |
838 | n = NULL; | 842 | n = NULL; |
839 | if (dst) | 843 | if (dst) |
840 | n = dst_get_neighbour(dst); | 844 | n = dst_get_neighbour_raw(dst); |
841 | if ((!dst || !n) && daddr) { | 845 | if ((!dst || !n) && daddr) { |
842 | struct ipoib_pseudoheader *phdr = | 846 | struct ipoib_pseudoheader *phdr = |
843 | (struct ipoib_pseudoheader *) skb_push(skb, sizeof *phdr); | 847 | (struct ipoib_pseudoheader *) skb_push(skb, sizeof *phdr); |
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c index 1b7a97686356..873bff97e69e 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c | |||
@@ -240,8 +240,11 @@ static int ipoib_mcast_join_finish(struct ipoib_mcast *mcast, | |||
240 | av.grh.dgid = mcast->mcmember.mgid; | 240 | av.grh.dgid = mcast->mcmember.mgid; |
241 | 241 | ||
242 | ah = ipoib_create_ah(dev, priv->pd, &av); | 242 | ah = ipoib_create_ah(dev, priv->pd, &av); |
243 | if (!ah) { | 243 | if (IS_ERR(ah)) { |
244 | ipoib_warn(priv, "ib_address_create failed\n"); | 244 | ipoib_warn(priv, "ib_address_create failed %ld\n", |
245 | -PTR_ERR(ah)); | ||
246 | /* use original error */ | ||
247 | return PTR_ERR(ah); | ||
245 | } else { | 248 | } else { |
246 | spin_lock_irq(&priv->lock); | 249 | spin_lock_irq(&priv->lock); |
247 | mcast->ah = ah; | 250 | mcast->ah = ah; |
@@ -266,7 +269,7 @@ static int ipoib_mcast_join_finish(struct ipoib_mcast *mcast, | |||
266 | 269 | ||
267 | skb->dev = dev; | 270 | skb->dev = dev; |
268 | if (dst) | 271 | if (dst) |
269 | n = dst_get_neighbour(dst); | 272 | n = dst_get_neighbour_raw(dst); |
270 | if (!dst || !n) { | 273 | if (!dst || !n) { |
271 | /* put pseudoheader back on for next time */ | 274 | /* put pseudoheader back on for next time */ |
272 | skb_push(skb, sizeof (struct ipoib_pseudoheader)); | 275 | skb_push(skb, sizeof (struct ipoib_pseudoheader)); |
@@ -722,6 +725,8 @@ out: | |||
722 | if (mcast && mcast->ah) { | 725 | if (mcast && mcast->ah) { |
723 | struct dst_entry *dst = skb_dst(skb); | 726 | struct dst_entry *dst = skb_dst(skb); |
724 | struct neighbour *n = NULL; | 727 | struct neighbour *n = NULL; |
728 | |||
729 | rcu_read_lock(); | ||
725 | if (dst) | 730 | if (dst) |
726 | n = dst_get_neighbour(dst); | 731 | n = dst_get_neighbour(dst); |
727 | if (n && !*to_ipoib_neigh(n)) { | 732 | if (n && !*to_ipoib_neigh(n)) { |
@@ -734,7 +739,7 @@ out: | |||
734 | list_add_tail(&neigh->list, &mcast->neigh_list); | 739 | list_add_tail(&neigh->list, &mcast->neigh_list); |
735 | } | 740 | } |
736 | } | 741 | } |
737 | 742 | rcu_read_unlock(); | |
738 | spin_unlock_irqrestore(&priv->lock, flags); | 743 | spin_unlock_irqrestore(&priv->lock, flags); |
739 | ipoib_send(dev, skb, mcast->ah, IB_MULTICAST_QPN); | 744 | ipoib_send(dev, skb, mcast->ah, IB_MULTICAST_QPN); |
740 | return; | 745 | return; |
diff --git a/drivers/input/mouse/elantech.c b/drivers/input/mouse/elantech.c index 09b93b11a274..e2a9867c19d5 100644 --- a/drivers/input/mouse/elantech.c +++ b/drivers/input/mouse/elantech.c | |||
@@ -1210,18 +1210,28 @@ static int elantech_reconnect(struct psmouse *psmouse) | |||
1210 | */ | 1210 | */ |
1211 | static int elantech_set_properties(struct elantech_data *etd) | 1211 | static int elantech_set_properties(struct elantech_data *etd) |
1212 | { | 1212 | { |
1213 | /* This represents the version of IC body. */ | ||
1213 | int ver = (etd->fw_version & 0x0f0000) >> 16; | 1214 | int ver = (etd->fw_version & 0x0f0000) >> 16; |
1214 | 1215 | ||
1216 | /* Early version of Elan touchpads doesn't obey the rule. */ | ||
1215 | if (etd->fw_version < 0x020030 || etd->fw_version == 0x020600) | 1217 | if (etd->fw_version < 0x020030 || etd->fw_version == 0x020600) |
1216 | etd->hw_version = 1; | 1218 | etd->hw_version = 1; |
1217 | else if (etd->fw_version < 0x150600) | 1219 | else { |
1218 | etd->hw_version = 2; | 1220 | switch (ver) { |
1219 | else if (ver == 5) | 1221 | case 2: |
1220 | etd->hw_version = 3; | 1222 | case 4: |
1221 | else if (ver == 6) | 1223 | etd->hw_version = 2; |
1222 | etd->hw_version = 4; | 1224 | break; |
1223 | else | 1225 | case 5: |
1224 | return -1; | 1226 | etd->hw_version = 3; |
1227 | break; | ||
1228 | case 6: | ||
1229 | etd->hw_version = 4; | ||
1230 | break; | ||
1231 | default: | ||
1232 | return -1; | ||
1233 | } | ||
1234 | } | ||
1225 | 1235 | ||
1226 | /* | 1236 | /* |
1227 | * Turn on packet checking by default. | 1237 | * Turn on packet checking by default. |
diff --git a/drivers/input/serio/ams_delta_serio.c b/drivers/input/serio/ams_delta_serio.c index 4b2a42f9f0bb..d4d08bd9205b 100644 --- a/drivers/input/serio/ams_delta_serio.c +++ b/drivers/input/serio/ams_delta_serio.c | |||
@@ -24,6 +24,7 @@ | |||
24 | #include <linux/irq.h> | 24 | #include <linux/irq.h> |
25 | #include <linux/serio.h> | 25 | #include <linux/serio.h> |
26 | #include <linux/slab.h> | 26 | #include <linux/slab.h> |
27 | #include <linux/module.h> | ||
27 | 28 | ||
28 | #include <asm/mach-types.h> | 29 | #include <asm/mach-types.h> |
29 | #include <plat/board-ams-delta.h> | 30 | #include <plat/board-ams-delta.h> |
diff --git a/drivers/input/serio/i8042-x86ia64io.h b/drivers/input/serio/i8042-x86ia64io.h index bb9f5d31f0d0..b4cfc6c8be89 100644 --- a/drivers/input/serio/i8042-x86ia64io.h +++ b/drivers/input/serio/i8042-x86ia64io.h | |||
@@ -431,6 +431,13 @@ static const struct dmi_system_id __initconst i8042_dmi_nomux_table[] = { | |||
431 | DMI_MATCH(DMI_PRODUCT_NAME, "Vostro V13"), | 431 | DMI_MATCH(DMI_PRODUCT_NAME, "Vostro V13"), |
432 | }, | 432 | }, |
433 | }, | 433 | }, |
434 | { | ||
435 | /* Newer HP Pavilion dv4 models */ | ||
436 | .matches = { | ||
437 | DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), | ||
438 | DMI_MATCH(DMI_PRODUCT_NAME, "HP Pavilion dv4 Notebook PC"), | ||
439 | }, | ||
440 | }, | ||
434 | { } | 441 | { } |
435 | }; | 442 | }; |
436 | 443 | ||
@@ -560,6 +567,13 @@ static const struct dmi_system_id __initconst i8042_dmi_notimeout_table[] = { | |||
560 | DMI_MATCH(DMI_PRODUCT_NAME, "Vostro V13"), | 567 | DMI_MATCH(DMI_PRODUCT_NAME, "Vostro V13"), |
561 | }, | 568 | }, |
562 | }, | 569 | }, |
570 | { | ||
571 | /* Newer HP Pavilion dv4 models */ | ||
572 | .matches = { | ||
573 | DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), | ||
574 | DMI_MATCH(DMI_PRODUCT_NAME, "HP Pavilion dv4 Notebook PC"), | ||
575 | }, | ||
576 | }, | ||
563 | { } | 577 | { } |
564 | }; | 578 | }; |
565 | 579 | ||
diff --git a/drivers/isdn/divert/divert_procfs.c b/drivers/isdn/divert/divert_procfs.c index 33ec9e467772..9021182c4b76 100644 --- a/drivers/isdn/divert/divert_procfs.c +++ b/drivers/isdn/divert/divert_procfs.c | |||
@@ -242,6 +242,12 @@ static int isdn_divert_ioctl_unlocked(struct file *file, uint cmd, ulong arg) | |||
242 | case IIOCDOCFINT: | 242 | case IIOCDOCFINT: |
243 | if (!divert_if.drv_to_name(dioctl.cf_ctrl.drvid)) | 243 | if (!divert_if.drv_to_name(dioctl.cf_ctrl.drvid)) |
244 | return (-EINVAL); /* invalid driver */ | 244 | return (-EINVAL); /* invalid driver */ |
245 | if (strnlen(dioctl.cf_ctrl.msn, sizeof(dioctl.cf_ctrl.msn)) == | ||
246 | sizeof(dioctl.cf_ctrl.msn)) | ||
247 | return -EINVAL; | ||
248 | if (strnlen(dioctl.cf_ctrl.fwd_nr, sizeof(dioctl.cf_ctrl.fwd_nr)) == | ||
249 | sizeof(dioctl.cf_ctrl.fwd_nr)) | ||
250 | return -EINVAL; | ||
245 | if ((i = cf_command(dioctl.cf_ctrl.drvid, | 251 | if ((i = cf_command(dioctl.cf_ctrl.drvid, |
246 | (cmd == IIOCDOCFACT) ? 1 : (cmd == IIOCDOCFDIS) ? 0 : 2, | 252 | (cmd == IIOCDOCFACT) ? 1 : (cmd == IIOCDOCFDIS) ? 0 : 2, |
247 | dioctl.cf_ctrl.cfproc, | 253 | dioctl.cf_ctrl.cfproc, |
diff --git a/drivers/isdn/i4l/isdn_net.c b/drivers/isdn/i4l/isdn_net.c index 1f73d7f7e024..2339d7396b9e 100644 --- a/drivers/isdn/i4l/isdn_net.c +++ b/drivers/isdn/i4l/isdn_net.c | |||
@@ -2756,6 +2756,9 @@ isdn_net_setcfg(isdn_net_ioctl_cfg * cfg) | |||
2756 | char *c, | 2756 | char *c, |
2757 | *e; | 2757 | *e; |
2758 | 2758 | ||
2759 | if (strnlen(cfg->drvid, sizeof(cfg->drvid)) == | ||
2760 | sizeof(cfg->drvid)) | ||
2761 | return -EINVAL; | ||
2759 | drvidx = -1; | 2762 | drvidx = -1; |
2760 | chidx = -1; | 2763 | chidx = -1; |
2761 | strcpy(drvid, cfg->drvid); | 2764 | strcpy(drvid, cfg->drvid); |
diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig index d593878d66d0..5664696f2d3a 100644 --- a/drivers/misc/Kconfig +++ b/drivers/misc/Kconfig | |||
@@ -472,7 +472,7 @@ config BMP085 | |||
472 | module will be called bmp085. | 472 | module will be called bmp085. |
473 | 473 | ||
474 | config PCH_PHUB | 474 | config PCH_PHUB |
475 | tristate "Intel EG20T PCH / OKI SEMICONDUCTOR IOH(ML7213/ML7223) PHUB" | 475 | tristate "Intel EG20T PCH/LAPIS Semicon IOH(ML7213/ML7223/ML7831) PHUB" |
476 | depends on PCI | 476 | depends on PCI |
477 | help | 477 | help |
478 | This driver is for PCH(Platform controller Hub) PHUB(Packet Hub) of | 478 | This driver is for PCH(Platform controller Hub) PHUB(Packet Hub) of |
@@ -480,12 +480,13 @@ config PCH_PHUB | |||
480 | processor. The Topcliff has MAC address and Option ROM data in SROM. | 480 | processor. The Topcliff has MAC address and Option ROM data in SROM. |
481 | This driver can access MAC address and Option ROM data in SROM. | 481 | This driver can access MAC address and Option ROM data in SROM. |
482 | 482 | ||
483 | This driver also can be used for OKI SEMICONDUCTOR IOH(Input/ | 483 | This driver also can be used for LAPIS Semiconductor's IOH, |
484 | Output Hub), ML7213 and ML7223. | 484 | ML7213/ML7223/ML7831. |
485 | ML7213 IOH is for IVI(In-Vehicle Infotainment) use and ML7223 IOH is | 485 | ML7213 which is for IVI(In-Vehicle Infotainment) use. |
486 | for MP(Media Phone) use. | 486 | ML7223 IOH is for MP(Media Phone) use. |
487 | ML7213/ML7223 is companion chip for Intel Atom E6xx series. | 487 | ML7831 IOH is for general purpose use. |
488 | ML7213/ML7223 is completely compatible for Intel EG20T PCH. | 488 | ML7213/ML7223/ML7831 is companion chip for Intel Atom E6xx series. |
489 | ML7213/ML7223/ML7831 is completely compatible for Intel EG20T PCH. | ||
489 | 490 | ||
490 | To compile this driver as a module, choose M here: the module will | 491 | To compile this driver as a module, choose M here: the module will |
491 | be called pch_phub. | 492 | be called pch_phub. |
diff --git a/drivers/misc/ad525x_dpot.h b/drivers/misc/ad525x_dpot.h index a662f5987b68..82b2cb77ae19 100644 --- a/drivers/misc/ad525x_dpot.h +++ b/drivers/misc/ad525x_dpot.h | |||
@@ -100,7 +100,7 @@ enum dpot_devid { | |||
100 | AD5293_ID = DPOT_CONF(F_RDACS_RW | F_SPI_16BIT, BRDAC0, 10, 27), | 100 | AD5293_ID = DPOT_CONF(F_RDACS_RW | F_SPI_16BIT, BRDAC0, 10, 27), |
101 | AD7376_ID = DPOT_CONF(F_RDACS_WONLY | F_AD_APPDATA | F_SPI_8BIT, | 101 | AD7376_ID = DPOT_CONF(F_RDACS_WONLY | F_AD_APPDATA | F_SPI_8BIT, |
102 | BRDAC0, 7, 28), | 102 | BRDAC0, 7, 28), |
103 | AD8400_ID = DPOT_CONF(F_RDACS_WONLY | F_AD_APPDATA | F_SPI_8BIT, | 103 | AD8400_ID = DPOT_CONF(F_RDACS_WONLY | F_AD_APPDATA | F_SPI_16BIT, |
104 | BRDAC0, 8, 29), | 104 | BRDAC0, 8, 29), |
105 | AD8402_ID = DPOT_CONF(F_RDACS_WONLY | F_AD_APPDATA | F_SPI_16BIT, | 105 | AD8402_ID = DPOT_CONF(F_RDACS_WONLY | F_AD_APPDATA | F_SPI_16BIT, |
106 | BRDAC0 | BRDAC1, 8, 30), | 106 | BRDAC0 | BRDAC1, 8, 30), |
diff --git a/drivers/misc/pch_phub.c b/drivers/misc/pch_phub.c index dee33addcaeb..10fc4785dba7 100644 --- a/drivers/misc/pch_phub.c +++ b/drivers/misc/pch_phub.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (C) 2010 OKI SEMICONDUCTOR CO., LTD. | 2 | * Copyright (C) 2011 LAPIS Semiconductor Co., Ltd. |
3 | * | 3 | * |
4 | * This program is free software; you can redistribute it and/or modify | 4 | * This program is free software; you can redistribute it and/or modify |
5 | * it under the terms of the GNU General Public License as published by | 5 | * it under the terms of the GNU General Public License as published by |
@@ -41,10 +41,10 @@ | |||
41 | #define PCH_PHUB_ROM_START_ADDR_EG20T 0x80 /* ROM data area start address offset | 41 | #define PCH_PHUB_ROM_START_ADDR_EG20T 0x80 /* ROM data area start address offset |
42 | (Intel EG20T PCH)*/ | 42 | (Intel EG20T PCH)*/ |
43 | #define PCH_PHUB_ROM_START_ADDR_ML7213 0x400 /* ROM data area start address | 43 | #define PCH_PHUB_ROM_START_ADDR_ML7213 0x400 /* ROM data area start address |
44 | offset(OKI SEMICONDUCTOR ML7213) | 44 | offset(LAPIS Semicon ML7213) |
45 | */ | 45 | */ |
46 | #define PCH_PHUB_ROM_START_ADDR_ML7223 0x400 /* ROM data area start address | 46 | #define PCH_PHUB_ROM_START_ADDR_ML7223 0x400 /* ROM data area start address |
47 | offset(OKI SEMICONDUCTOR ML7223) | 47 | offset(LAPIS Semicon ML7223) |
48 | */ | 48 | */ |
49 | 49 | ||
50 | /* MAX number of INT_REDUCE_CONTROL registers */ | 50 | /* MAX number of INT_REDUCE_CONTROL registers */ |
@@ -73,6 +73,9 @@ | |||
73 | #define PCI_DEVICE_ID_ROHM_ML7223_mPHUB 0x8012 /* for Bus-m */ | 73 | #define PCI_DEVICE_ID_ROHM_ML7223_mPHUB 0x8012 /* for Bus-m */ |
74 | #define PCI_DEVICE_ID_ROHM_ML7223_nPHUB 0x8002 /* for Bus-n */ | 74 | #define PCI_DEVICE_ID_ROHM_ML7223_nPHUB 0x8002 /* for Bus-n */ |
75 | 75 | ||
76 | /* Macros for ML7831 */ | ||
77 | #define PCI_DEVICE_ID_ROHM_ML7831_PHUB 0x8801 | ||
78 | |||
76 | /* SROM ACCESS Macro */ | 79 | /* SROM ACCESS Macro */ |
77 | #define PCH_WORD_ADDR_MASK (~((1 << 2) - 1)) | 80 | #define PCH_WORD_ADDR_MASK (~((1 << 2) - 1)) |
78 | 81 | ||
@@ -115,6 +118,7 @@ | |||
115 | * @pch_mac_start_address: MAC address area start address | 118 | * @pch_mac_start_address: MAC address area start address |
116 | * @pch_opt_rom_start_address: Option ROM start address | 119 | * @pch_opt_rom_start_address: Option ROM start address |
117 | * @ioh_type: Save IOH type | 120 | * @ioh_type: Save IOH type |
121 | * @pdev: pointer to pci device struct | ||
118 | */ | 122 | */ |
119 | struct pch_phub_reg { | 123 | struct pch_phub_reg { |
120 | u32 phub_id_reg; | 124 | u32 phub_id_reg; |
@@ -136,6 +140,7 @@ struct pch_phub_reg { | |||
136 | u32 pch_mac_start_address; | 140 | u32 pch_mac_start_address; |
137 | u32 pch_opt_rom_start_address; | 141 | u32 pch_opt_rom_start_address; |
138 | int ioh_type; | 142 | int ioh_type; |
143 | struct pci_dev *pdev; | ||
139 | }; | 144 | }; |
140 | 145 | ||
141 | /* SROM SPEC for MAC address assignment offset */ | 146 | /* SROM SPEC for MAC address assignment offset */ |
@@ -471,7 +476,7 @@ static int pch_phub_write_gbe_mac_addr(struct pch_phub_reg *chip, u8 *data) | |||
471 | int retval; | 476 | int retval; |
472 | int i; | 477 | int i; |
473 | 478 | ||
474 | if (chip->ioh_type == 1) /* EG20T */ | 479 | if ((chip->ioh_type == 1) || (chip->ioh_type == 5)) /* EG20T or ML7831*/ |
475 | retval = pch_phub_gbe_serial_rom_conf(chip); | 480 | retval = pch_phub_gbe_serial_rom_conf(chip); |
476 | else /* ML7223 */ | 481 | else /* ML7223 */ |
477 | retval = pch_phub_gbe_serial_rom_conf_mp(chip); | 482 | retval = pch_phub_gbe_serial_rom_conf_mp(chip); |
@@ -498,6 +503,7 @@ static ssize_t pch_phub_bin_read(struct file *filp, struct kobject *kobj, | |||
498 | unsigned int orom_size; | 503 | unsigned int orom_size; |
499 | int ret; | 504 | int ret; |
500 | int err; | 505 | int err; |
506 | ssize_t rom_size; | ||
501 | 507 | ||
502 | struct pch_phub_reg *chip = | 508 | struct pch_phub_reg *chip = |
503 | dev_get_drvdata(container_of(kobj, struct device, kobj)); | 509 | dev_get_drvdata(container_of(kobj, struct device, kobj)); |
@@ -509,6 +515,10 @@ static ssize_t pch_phub_bin_read(struct file *filp, struct kobject *kobj, | |||
509 | } | 515 | } |
510 | 516 | ||
511 | /* Get Rom signature */ | 517 | /* Get Rom signature */ |
518 | chip->pch_phub_extrom_base_address = pci_map_rom(chip->pdev, &rom_size); | ||
519 | if (!chip->pch_phub_extrom_base_address) | ||
520 | goto exrom_map_err; | ||
521 | |||
512 | pch_phub_read_serial_rom(chip, chip->pch_opt_rom_start_address, | 522 | pch_phub_read_serial_rom(chip, chip->pch_opt_rom_start_address, |
513 | (unsigned char *)&rom_signature); | 523 | (unsigned char *)&rom_signature); |
514 | rom_signature &= 0xff; | 524 | rom_signature &= 0xff; |
@@ -539,10 +549,13 @@ static ssize_t pch_phub_bin_read(struct file *filp, struct kobject *kobj, | |||
539 | goto return_err; | 549 | goto return_err; |
540 | } | 550 | } |
541 | return_ok: | 551 | return_ok: |
552 | pci_unmap_rom(chip->pdev, chip->pch_phub_extrom_base_address); | ||
542 | mutex_unlock(&pch_phub_mutex); | 553 | mutex_unlock(&pch_phub_mutex); |
543 | return addr_offset; | 554 | return addr_offset; |
544 | 555 | ||
545 | return_err: | 556 | return_err: |
557 | pci_unmap_rom(chip->pdev, chip->pch_phub_extrom_base_address); | ||
558 | exrom_map_err: | ||
546 | mutex_unlock(&pch_phub_mutex); | 559 | mutex_unlock(&pch_phub_mutex); |
547 | return_err_nomutex: | 560 | return_err_nomutex: |
548 | return err; | 561 | return err; |
@@ -555,6 +568,7 @@ static ssize_t pch_phub_bin_write(struct file *filp, struct kobject *kobj, | |||
555 | int err; | 568 | int err; |
556 | unsigned int addr_offset; | 569 | unsigned int addr_offset; |
557 | int ret; | 570 | int ret; |
571 | ssize_t rom_size; | ||
558 | struct pch_phub_reg *chip = | 572 | struct pch_phub_reg *chip = |
559 | dev_get_drvdata(container_of(kobj, struct device, kobj)); | 573 | dev_get_drvdata(container_of(kobj, struct device, kobj)); |
560 | 574 | ||
@@ -571,6 +585,12 @@ static ssize_t pch_phub_bin_write(struct file *filp, struct kobject *kobj, | |||
571 | goto return_ok; | 585 | goto return_ok; |
572 | } | 586 | } |
573 | 587 | ||
588 | chip->pch_phub_extrom_base_address = pci_map_rom(chip->pdev, &rom_size); | ||
589 | if (!chip->pch_phub_extrom_base_address) { | ||
590 | err = -ENOMEM; | ||
591 | goto exrom_map_err; | ||
592 | } | ||
593 | |||
574 | for (addr_offset = 0; addr_offset < count; addr_offset++) { | 594 | for (addr_offset = 0; addr_offset < count; addr_offset++) { |
575 | if (PCH_PHUB_OROM_SIZE < off + addr_offset) | 595 | if (PCH_PHUB_OROM_SIZE < off + addr_offset) |
576 | goto return_ok; | 596 | goto return_ok; |
@@ -585,10 +605,14 @@ static ssize_t pch_phub_bin_write(struct file *filp, struct kobject *kobj, | |||
585 | } | 605 | } |
586 | 606 | ||
587 | return_ok: | 607 | return_ok: |
608 | pci_unmap_rom(chip->pdev, chip->pch_phub_extrom_base_address); | ||
588 | mutex_unlock(&pch_phub_mutex); | 609 | mutex_unlock(&pch_phub_mutex); |
589 | return addr_offset; | 610 | return addr_offset; |
590 | 611 | ||
591 | return_err: | 612 | return_err: |
613 | pci_unmap_rom(chip->pdev, chip->pch_phub_extrom_base_address); | ||
614 | |||
615 | exrom_map_err: | ||
592 | mutex_unlock(&pch_phub_mutex); | 616 | mutex_unlock(&pch_phub_mutex); |
593 | return err; | 617 | return err; |
594 | } | 618 | } |
@@ -598,8 +622,14 @@ static ssize_t show_pch_mac(struct device *dev, struct device_attribute *attr, | |||
598 | { | 622 | { |
599 | u8 mac[8]; | 623 | u8 mac[8]; |
600 | struct pch_phub_reg *chip = dev_get_drvdata(dev); | 624 | struct pch_phub_reg *chip = dev_get_drvdata(dev); |
625 | ssize_t rom_size; | ||
626 | |||
627 | chip->pch_phub_extrom_base_address = pci_map_rom(chip->pdev, &rom_size); | ||
628 | if (!chip->pch_phub_extrom_base_address) | ||
629 | return -ENOMEM; | ||
601 | 630 | ||
602 | pch_phub_read_gbe_mac_addr(chip, mac); | 631 | pch_phub_read_gbe_mac_addr(chip, mac); |
632 | pci_unmap_rom(chip->pdev, chip->pch_phub_extrom_base_address); | ||
603 | 633 | ||
604 | return sprintf(buf, "%pM\n", mac); | 634 | return sprintf(buf, "%pM\n", mac); |
605 | } | 635 | } |
@@ -608,6 +638,7 @@ static ssize_t store_pch_mac(struct device *dev, struct device_attribute *attr, | |||
608 | const char *buf, size_t count) | 638 | const char *buf, size_t count) |
609 | { | 639 | { |
610 | u8 mac[6]; | 640 | u8 mac[6]; |
641 | ssize_t rom_size; | ||
611 | struct pch_phub_reg *chip = dev_get_drvdata(dev); | 642 | struct pch_phub_reg *chip = dev_get_drvdata(dev); |
612 | 643 | ||
613 | if (count != 18) | 644 | if (count != 18) |
@@ -617,7 +648,12 @@ static ssize_t store_pch_mac(struct device *dev, struct device_attribute *attr, | |||
617 | (u32 *)&mac[0], (u32 *)&mac[1], (u32 *)&mac[2], (u32 *)&mac[3], | 648 | (u32 *)&mac[0], (u32 *)&mac[1], (u32 *)&mac[2], (u32 *)&mac[3], |
618 | (u32 *)&mac[4], (u32 *)&mac[5]); | 649 | (u32 *)&mac[4], (u32 *)&mac[5]); |
619 | 650 | ||
651 | chip->pch_phub_extrom_base_address = pci_map_rom(chip->pdev, &rom_size); | ||
652 | if (!chip->pch_phub_extrom_base_address) | ||
653 | return -ENOMEM; | ||
654 | |||
620 | pch_phub_write_gbe_mac_addr(chip, mac); | 655 | pch_phub_write_gbe_mac_addr(chip, mac); |
656 | pci_unmap_rom(chip->pdev, chip->pch_phub_extrom_base_address); | ||
621 | 657 | ||
622 | return count; | 658 | return count; |
623 | } | 659 | } |
@@ -640,7 +676,6 @@ static int __devinit pch_phub_probe(struct pci_dev *pdev, | |||
640 | int retval; | 676 | int retval; |
641 | 677 | ||
642 | int ret; | 678 | int ret; |
643 | ssize_t rom_size; | ||
644 | struct pch_phub_reg *chip; | 679 | struct pch_phub_reg *chip; |
645 | 680 | ||
646 | chip = kzalloc(sizeof(struct pch_phub_reg), GFP_KERNEL); | 681 | chip = kzalloc(sizeof(struct pch_phub_reg), GFP_KERNEL); |
@@ -677,19 +712,7 @@ static int __devinit pch_phub_probe(struct pci_dev *pdev, | |||
677 | "in pch_phub_base_address variable is %p\n", __func__, | 712 | "in pch_phub_base_address variable is %p\n", __func__, |
678 | chip->pch_phub_base_address); | 713 | chip->pch_phub_base_address); |
679 | 714 | ||
680 | if (id->driver_data != 3) { | 715 | chip->pdev = pdev; /* Save pci device struct */ |
681 | chip->pch_phub_extrom_base_address =\ | ||
682 | pci_map_rom(pdev, &rom_size); | ||
683 | if (chip->pch_phub_extrom_base_address == 0) { | ||
684 | dev_err(&pdev->dev, "%s: pci_map_rom FAILED", __func__); | ||
685 | ret = -ENOMEM; | ||
686 | goto err_pci_map; | ||
687 | } | ||
688 | dev_dbg(&pdev->dev, "%s : " | ||
689 | "pci_map_rom SUCCESS and value in " | ||
690 | "pch_phub_extrom_base_address variable is %p\n", | ||
691 | __func__, chip->pch_phub_extrom_base_address); | ||
692 | } | ||
693 | 716 | ||
694 | if (id->driver_data == 1) { /* EG20T PCH */ | 717 | if (id->driver_data == 1) { /* EG20T PCH */ |
695 | const char *board_name; | 718 | const char *board_name; |
@@ -763,6 +786,22 @@ static int __devinit pch_phub_probe(struct pci_dev *pdev, | |||
763 | chip->pch_opt_rom_start_address =\ | 786 | chip->pch_opt_rom_start_address =\ |
764 | PCH_PHUB_ROM_START_ADDR_ML7223; | 787 | PCH_PHUB_ROM_START_ADDR_ML7223; |
765 | chip->pch_mac_start_address = PCH_PHUB_MAC_START_ADDR_ML7223; | 788 | chip->pch_mac_start_address = PCH_PHUB_MAC_START_ADDR_ML7223; |
789 | } else if (id->driver_data == 5) { /* ML7831 */ | ||
790 | retval = sysfs_create_file(&pdev->dev.kobj, | ||
791 | &dev_attr_pch_mac.attr); | ||
792 | if (retval) | ||
793 | goto err_sysfs_create; | ||
794 | |||
795 | retval = sysfs_create_bin_file(&pdev->dev.kobj, &pch_bin_attr); | ||
796 | if (retval) | ||
797 | goto exit_bin_attr; | ||
798 | |||
799 | /* set the prefech value */ | ||
800 | iowrite32(0x000affaa, chip->pch_phub_base_address + 0x14); | ||
801 | /* set the interrupt delay value */ | ||
802 | iowrite32(0x25, chip->pch_phub_base_address + 0x44); | ||
803 | chip->pch_opt_rom_start_address = PCH_PHUB_ROM_START_ADDR_EG20T; | ||
804 | chip->pch_mac_start_address = PCH_PHUB_MAC_START_ADDR_EG20T; | ||
766 | } | 805 | } |
767 | 806 | ||
768 | chip->ioh_type = id->driver_data; | 807 | chip->ioh_type = id->driver_data; |
@@ -773,8 +812,6 @@ exit_bin_attr: | |||
773 | sysfs_remove_file(&pdev->dev.kobj, &dev_attr_pch_mac.attr); | 812 | sysfs_remove_file(&pdev->dev.kobj, &dev_attr_pch_mac.attr); |
774 | 813 | ||
775 | err_sysfs_create: | 814 | err_sysfs_create: |
776 | pci_unmap_rom(pdev, chip->pch_phub_extrom_base_address); | ||
777 | err_pci_map: | ||
778 | pci_iounmap(pdev, chip->pch_phub_base_address); | 815 | pci_iounmap(pdev, chip->pch_phub_base_address); |
779 | err_pci_iomap: | 816 | err_pci_iomap: |
780 | pci_release_regions(pdev); | 817 | pci_release_regions(pdev); |
@@ -792,7 +829,6 @@ static void __devexit pch_phub_remove(struct pci_dev *pdev) | |||
792 | 829 | ||
793 | sysfs_remove_file(&pdev->dev.kobj, &dev_attr_pch_mac.attr); | 830 | sysfs_remove_file(&pdev->dev.kobj, &dev_attr_pch_mac.attr); |
794 | sysfs_remove_bin_file(&pdev->dev.kobj, &pch_bin_attr); | 831 | sysfs_remove_bin_file(&pdev->dev.kobj, &pch_bin_attr); |
795 | pci_unmap_rom(pdev, chip->pch_phub_extrom_base_address); | ||
796 | pci_iounmap(pdev, chip->pch_phub_base_address); | 832 | pci_iounmap(pdev, chip->pch_phub_base_address); |
797 | pci_release_regions(pdev); | 833 | pci_release_regions(pdev); |
798 | pci_disable_device(pdev); | 834 | pci_disable_device(pdev); |
@@ -847,6 +883,7 @@ static struct pci_device_id pch_phub_pcidev_id[] = { | |||
847 | { PCI_VDEVICE(ROHM, PCI_DEVICE_ID_ROHM_ML7213_PHUB), 2, }, | 883 | { PCI_VDEVICE(ROHM, PCI_DEVICE_ID_ROHM_ML7213_PHUB), 2, }, |
848 | { PCI_VDEVICE(ROHM, PCI_DEVICE_ID_ROHM_ML7223_mPHUB), 3, }, | 884 | { PCI_VDEVICE(ROHM, PCI_DEVICE_ID_ROHM_ML7223_mPHUB), 3, }, |
849 | { PCI_VDEVICE(ROHM, PCI_DEVICE_ID_ROHM_ML7223_nPHUB), 4, }, | 885 | { PCI_VDEVICE(ROHM, PCI_DEVICE_ID_ROHM_ML7223_nPHUB), 4, }, |
886 | { PCI_VDEVICE(ROHM, PCI_DEVICE_ID_ROHM_ML7831_PHUB), 5, }, | ||
850 | { } | 887 | { } |
851 | }; | 888 | }; |
852 | MODULE_DEVICE_TABLE(pci, pch_phub_pcidev_id); | 889 | MODULE_DEVICE_TABLE(pci, pch_phub_pcidev_id); |
@@ -873,5 +910,5 @@ static void __exit pch_phub_pci_exit(void) | |||
873 | module_init(pch_phub_pci_init); | 910 | module_init(pch_phub_pci_init); |
874 | module_exit(pch_phub_pci_exit); | 911 | module_exit(pch_phub_pci_exit); |
875 | 912 | ||
876 | MODULE_DESCRIPTION("Intel EG20T PCH/OKI SEMICONDUCTOR IOH(ML7213/ML7223) PHUB"); | 913 | MODULE_DESCRIPTION("Intel EG20T PCH/LAPIS Semiconductor IOH(ML7213/ML7223) PHUB"); |
877 | MODULE_LICENSE("GPL"); | 914 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/misc/spear13xx_pcie_gadget.c b/drivers/misc/spear13xx_pcie_gadget.c index cfbddbef11de..43d073bc1d9c 100644 --- a/drivers/misc/spear13xx_pcie_gadget.c +++ b/drivers/misc/spear13xx_pcie_gadget.c | |||
@@ -903,6 +903,6 @@ static void __exit spear_pcie_gadget_exit(void) | |||
903 | } | 903 | } |
904 | module_exit(spear_pcie_gadget_exit); | 904 | module_exit(spear_pcie_gadget_exit); |
905 | 905 | ||
906 | MODULE_ALIAS("pcie-gadget-spear"); | 906 | MODULE_ALIAS("platform:pcie-gadget-spear"); |
907 | MODULE_AUTHOR("Pratyush Anand"); | 907 | MODULE_AUTHOR("Pratyush Anand"); |
908 | MODULE_LICENSE("GPL"); | 908 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index 25a44d94be17..3216c514fdc8 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c | |||
@@ -2554,30 +2554,6 @@ re_arm: | |||
2554 | } | 2554 | } |
2555 | } | 2555 | } |
2556 | 2556 | ||
2557 | static __be32 bond_glean_dev_ip(struct net_device *dev) | ||
2558 | { | ||
2559 | struct in_device *idev; | ||
2560 | struct in_ifaddr *ifa; | ||
2561 | __be32 addr = 0; | ||
2562 | |||
2563 | if (!dev) | ||
2564 | return 0; | ||
2565 | |||
2566 | rcu_read_lock(); | ||
2567 | idev = __in_dev_get_rcu(dev); | ||
2568 | if (!idev) | ||
2569 | goto out; | ||
2570 | |||
2571 | ifa = idev->ifa_list; | ||
2572 | if (!ifa) | ||
2573 | goto out; | ||
2574 | |||
2575 | addr = ifa->ifa_local; | ||
2576 | out: | ||
2577 | rcu_read_unlock(); | ||
2578 | return addr; | ||
2579 | } | ||
2580 | |||
2581 | static int bond_has_this_ip(struct bonding *bond, __be32 ip) | 2557 | static int bond_has_this_ip(struct bonding *bond, __be32 ip) |
2582 | { | 2558 | { |
2583 | struct vlan_entry *vlan; | 2559 | struct vlan_entry *vlan; |
@@ -3323,6 +3299,10 @@ static int bond_inetaddr_event(struct notifier_block *this, unsigned long event, | |||
3323 | struct bonding *bond; | 3299 | struct bonding *bond; |
3324 | struct vlan_entry *vlan; | 3300 | struct vlan_entry *vlan; |
3325 | 3301 | ||
3302 | /* we only care about primary address */ | ||
3303 | if(ifa->ifa_flags & IFA_F_SECONDARY) | ||
3304 | return NOTIFY_DONE; | ||
3305 | |||
3326 | list_for_each_entry(bond, &bn->dev_list, bond_list) { | 3306 | list_for_each_entry(bond, &bn->dev_list, bond_list) { |
3327 | if (bond->dev == event_dev) { | 3307 | if (bond->dev == event_dev) { |
3328 | switch (event) { | 3308 | switch (event) { |
@@ -3330,7 +3310,7 @@ static int bond_inetaddr_event(struct notifier_block *this, unsigned long event, | |||
3330 | bond->master_ip = ifa->ifa_local; | 3310 | bond->master_ip = ifa->ifa_local; |
3331 | return NOTIFY_OK; | 3311 | return NOTIFY_OK; |
3332 | case NETDEV_DOWN: | 3312 | case NETDEV_DOWN: |
3333 | bond->master_ip = bond_glean_dev_ip(bond->dev); | 3313 | bond->master_ip = 0; |
3334 | return NOTIFY_OK; | 3314 | return NOTIFY_OK; |
3335 | default: | 3315 | default: |
3336 | return NOTIFY_DONE; | 3316 | return NOTIFY_DONE; |
@@ -3346,8 +3326,7 @@ static int bond_inetaddr_event(struct notifier_block *this, unsigned long event, | |||
3346 | vlan->vlan_ip = ifa->ifa_local; | 3326 | vlan->vlan_ip = ifa->ifa_local; |
3347 | return NOTIFY_OK; | 3327 | return NOTIFY_OK; |
3348 | case NETDEV_DOWN: | 3328 | case NETDEV_DOWN: |
3349 | vlan->vlan_ip = | 3329 | vlan->vlan_ip = 0; |
3350 | bond_glean_dev_ip(vlan_dev); | ||
3351 | return NOTIFY_OK; | 3330 | return NOTIFY_OK; |
3352 | default: | 3331 | default: |
3353 | return NOTIFY_DONE; | 3332 | return NOTIFY_DONE; |
diff --git a/drivers/net/ethernet/davicom/dm9000.c b/drivers/net/ethernet/davicom/dm9000.c index 26be1dfc1577..f801754c71a7 100644 --- a/drivers/net/ethernet/davicom/dm9000.c +++ b/drivers/net/ethernet/davicom/dm9000.c | |||
@@ -614,7 +614,7 @@ static int dm9000_set_wol(struct net_device *dev, struct ethtool_wolinfo *w) | |||
614 | 614 | ||
615 | if (!dm->wake_state) | 615 | if (!dm->wake_state) |
616 | irq_set_irq_wake(dm->irq_wake, 1); | 616 | irq_set_irq_wake(dm->irq_wake, 1); |
617 | else if (dm->wake_state & !opts) | 617 | else if (dm->wake_state && !opts) |
618 | irq_set_irq_wake(dm->irq_wake, 0); | 618 | irq_set_irq_wake(dm->irq_wake, 0); |
619 | } | 619 | } |
620 | 620 | ||
diff --git a/drivers/net/ethernet/freescale/Kconfig b/drivers/net/ethernet/freescale/Kconfig index c520cfd3b298..5272f9d4dda9 100644 --- a/drivers/net/ethernet/freescale/Kconfig +++ b/drivers/net/ethernet/freescale/Kconfig | |||
@@ -24,6 +24,7 @@ config FEC | |||
24 | bool "FEC ethernet controller (of ColdFire and some i.MX CPUs)" | 24 | bool "FEC ethernet controller (of ColdFire and some i.MX CPUs)" |
25 | depends on (M523x || M527x || M5272 || M528x || M520x || M532x || \ | 25 | depends on (M523x || M527x || M5272 || M528x || M520x || M532x || \ |
26 | ARCH_MXC || ARCH_MXS) | 26 | ARCH_MXC || ARCH_MXS) |
27 | default ARCH_MXC || ARCH_MXS if ARM | ||
27 | select PHYLIB | 28 | select PHYLIB |
28 | ---help--- | 29 | ---help--- |
29 | Say Y here if you want to use the built-in 10/100 Fast ethernet | 30 | Say Y here if you want to use the built-in 10/100 Fast ethernet |
diff --git a/drivers/net/ethernet/jme.c b/drivers/net/ethernet/jme.c index 5c0b531949e2..27d651a80f3f 100644 --- a/drivers/net/ethernet/jme.c +++ b/drivers/net/ethernet/jme.c | |||
@@ -1745,6 +1745,112 @@ jme_phy_off(struct jme_adapter *jme) | |||
1745 | } | 1745 | } |
1746 | 1746 | ||
1747 | static int | 1747 | static int |
1748 | jme_phy_specreg_read(struct jme_adapter *jme, u32 specreg) | ||
1749 | { | ||
1750 | u32 phy_addr; | ||
1751 | |||
1752 | phy_addr = JM_PHY_SPEC_REG_READ | specreg; | ||
1753 | jme_mdio_write(jme->dev, jme->mii_if.phy_id, JM_PHY_SPEC_ADDR_REG, | ||
1754 | phy_addr); | ||
1755 | return jme_mdio_read(jme->dev, jme->mii_if.phy_id, | ||
1756 | JM_PHY_SPEC_DATA_REG); | ||
1757 | } | ||
1758 | |||
1759 | static void | ||
1760 | jme_phy_specreg_write(struct jme_adapter *jme, u32 ext_reg, u32 phy_data) | ||
1761 | { | ||
1762 | u32 phy_addr; | ||
1763 | |||
1764 | phy_addr = JM_PHY_SPEC_REG_WRITE | ext_reg; | ||
1765 | jme_mdio_write(jme->dev, jme->mii_if.phy_id, JM_PHY_SPEC_DATA_REG, | ||
1766 | phy_data); | ||
1767 | jme_mdio_write(jme->dev, jme->mii_if.phy_id, JM_PHY_SPEC_ADDR_REG, | ||
1768 | phy_addr); | ||
1769 | } | ||
1770 | |||
1771 | static int | ||
1772 | jme_phy_calibration(struct jme_adapter *jme) | ||
1773 | { | ||
1774 | u32 ctrl1000, phy_data; | ||
1775 | |||
1776 | jme_phy_off(jme); | ||
1777 | jme_phy_on(jme); | ||
1778 | /* Enabel PHY test mode 1 */ | ||
1779 | ctrl1000 = jme_mdio_read(jme->dev, jme->mii_if.phy_id, MII_CTRL1000); | ||
1780 | ctrl1000 &= ~PHY_GAD_TEST_MODE_MSK; | ||
1781 | ctrl1000 |= PHY_GAD_TEST_MODE_1; | ||
1782 | jme_mdio_write(jme->dev, jme->mii_if.phy_id, MII_CTRL1000, ctrl1000); | ||
1783 | |||
1784 | phy_data = jme_phy_specreg_read(jme, JM_PHY_EXT_COMM_2_REG); | ||
1785 | phy_data &= ~JM_PHY_EXT_COMM_2_CALI_MODE_0; | ||
1786 | phy_data |= JM_PHY_EXT_COMM_2_CALI_LATCH | | ||
1787 | JM_PHY_EXT_COMM_2_CALI_ENABLE; | ||
1788 | jme_phy_specreg_write(jme, JM_PHY_EXT_COMM_2_REG, phy_data); | ||
1789 | msleep(20); | ||
1790 | phy_data = jme_phy_specreg_read(jme, JM_PHY_EXT_COMM_2_REG); | ||
1791 | phy_data &= ~(JM_PHY_EXT_COMM_2_CALI_ENABLE | | ||
1792 | JM_PHY_EXT_COMM_2_CALI_MODE_0 | | ||
1793 | JM_PHY_EXT_COMM_2_CALI_LATCH); | ||
1794 | jme_phy_specreg_write(jme, JM_PHY_EXT_COMM_2_REG, phy_data); | ||
1795 | |||
1796 | /* Disable PHY test mode */ | ||
1797 | ctrl1000 = jme_mdio_read(jme->dev, jme->mii_if.phy_id, MII_CTRL1000); | ||
1798 | ctrl1000 &= ~PHY_GAD_TEST_MODE_MSK; | ||
1799 | jme_mdio_write(jme->dev, jme->mii_if.phy_id, MII_CTRL1000, ctrl1000); | ||
1800 | return 0; | ||
1801 | } | ||
1802 | |||
1803 | static int | ||
1804 | jme_phy_setEA(struct jme_adapter *jme) | ||
1805 | { | ||
1806 | u32 phy_comm0 = 0, phy_comm1 = 0; | ||
1807 | u8 nic_ctrl; | ||
1808 | |||
1809 | pci_read_config_byte(jme->pdev, PCI_PRIV_SHARE_NICCTRL, &nic_ctrl); | ||
1810 | if ((nic_ctrl & 0x3) == JME_FLAG_PHYEA_ENABLE) | ||
1811 | return 0; | ||
1812 | |||
1813 | switch (jme->pdev->device) { | ||
1814 | case PCI_DEVICE_ID_JMICRON_JMC250: | ||
1815 | if (((jme->chip_main_rev == 5) && | ||
1816 | ((jme->chip_sub_rev == 0) || (jme->chip_sub_rev == 1) || | ||
1817 | (jme->chip_sub_rev == 3))) || | ||
1818 | (jme->chip_main_rev >= 6)) { | ||
1819 | phy_comm0 = 0x008A; | ||
1820 | phy_comm1 = 0x4109; | ||
1821 | } | ||
1822 | if ((jme->chip_main_rev == 3) && | ||
1823 | ((jme->chip_sub_rev == 1) || (jme->chip_sub_rev == 2))) | ||
1824 | phy_comm0 = 0xE088; | ||
1825 | break; | ||
1826 | case PCI_DEVICE_ID_JMICRON_JMC260: | ||
1827 | if (((jme->chip_main_rev == 5) && | ||
1828 | ((jme->chip_sub_rev == 0) || (jme->chip_sub_rev == 1) || | ||
1829 | (jme->chip_sub_rev == 3))) || | ||
1830 | (jme->chip_main_rev >= 6)) { | ||
1831 | phy_comm0 = 0x008A; | ||
1832 | phy_comm1 = 0x4109; | ||
1833 | } | ||
1834 | if ((jme->chip_main_rev == 3) && | ||
1835 | ((jme->chip_sub_rev == 1) || (jme->chip_sub_rev == 2))) | ||
1836 | phy_comm0 = 0xE088; | ||
1837 | if ((jme->chip_main_rev == 2) && (jme->chip_sub_rev == 0)) | ||
1838 | phy_comm0 = 0x608A; | ||
1839 | if ((jme->chip_main_rev == 2) && (jme->chip_sub_rev == 2)) | ||
1840 | phy_comm0 = 0x408A; | ||
1841 | break; | ||
1842 | default: | ||
1843 | return -ENODEV; | ||
1844 | } | ||
1845 | if (phy_comm0) | ||
1846 | jme_phy_specreg_write(jme, JM_PHY_EXT_COMM_0_REG, phy_comm0); | ||
1847 | if (phy_comm1) | ||
1848 | jme_phy_specreg_write(jme, JM_PHY_EXT_COMM_1_REG, phy_comm1); | ||
1849 | |||
1850 | return 0; | ||
1851 | } | ||
1852 | |||
1853 | static int | ||
1748 | jme_open(struct net_device *netdev) | 1854 | jme_open(struct net_device *netdev) |
1749 | { | 1855 | { |
1750 | struct jme_adapter *jme = netdev_priv(netdev); | 1856 | struct jme_adapter *jme = netdev_priv(netdev); |
@@ -1769,7 +1875,8 @@ jme_open(struct net_device *netdev) | |||
1769 | jme_set_settings(netdev, &jme->old_ecmd); | 1875 | jme_set_settings(netdev, &jme->old_ecmd); |
1770 | else | 1876 | else |
1771 | jme_reset_phy_processor(jme); | 1877 | jme_reset_phy_processor(jme); |
1772 | 1878 | jme_phy_calibration(jme); | |
1879 | jme_phy_setEA(jme); | ||
1773 | jme_reset_link(jme); | 1880 | jme_reset_link(jme); |
1774 | 1881 | ||
1775 | return 0; | 1882 | return 0; |
@@ -3184,7 +3291,8 @@ jme_resume(struct device *dev) | |||
3184 | jme_set_settings(netdev, &jme->old_ecmd); | 3291 | jme_set_settings(netdev, &jme->old_ecmd); |
3185 | else | 3292 | else |
3186 | jme_reset_phy_processor(jme); | 3293 | jme_reset_phy_processor(jme); |
3187 | 3294 | jme_phy_calibration(jme); | |
3295 | jme_phy_setEA(jme); | ||
3188 | jme_start_irq(jme); | 3296 | jme_start_irq(jme); |
3189 | netif_device_attach(netdev); | 3297 | netif_device_attach(netdev); |
3190 | 3298 | ||
@@ -3239,4 +3347,3 @@ MODULE_DESCRIPTION("JMicron JMC2x0 PCI Express Ethernet driver"); | |||
3239 | MODULE_LICENSE("GPL"); | 3347 | MODULE_LICENSE("GPL"); |
3240 | MODULE_VERSION(DRV_VERSION); | 3348 | MODULE_VERSION(DRV_VERSION); |
3241 | MODULE_DEVICE_TABLE(pci, jme_pci_tbl); | 3349 | MODULE_DEVICE_TABLE(pci, jme_pci_tbl); |
3242 | |||
diff --git a/drivers/net/ethernet/jme.h b/drivers/net/ethernet/jme.h index 02ea27c1dcb5..4304072bd3c5 100644 --- a/drivers/net/ethernet/jme.h +++ b/drivers/net/ethernet/jme.h | |||
@@ -760,6 +760,25 @@ enum jme_rxmcs_bits { | |||
760 | RXMCS_CHECKSUM, | 760 | RXMCS_CHECKSUM, |
761 | }; | 761 | }; |
762 | 762 | ||
763 | /* Extern PHY common register 2 */ | ||
764 | |||
765 | #define PHY_GAD_TEST_MODE_1 0x00002000 | ||
766 | #define PHY_GAD_TEST_MODE_MSK 0x0000E000 | ||
767 | #define JM_PHY_SPEC_REG_READ 0x00004000 | ||
768 | #define JM_PHY_SPEC_REG_WRITE 0x00008000 | ||
769 | #define PHY_CALIBRATION_DELAY 20 | ||
770 | #define JM_PHY_SPEC_ADDR_REG 0x1E | ||
771 | #define JM_PHY_SPEC_DATA_REG 0x1F | ||
772 | |||
773 | #define JM_PHY_EXT_COMM_0_REG 0x30 | ||
774 | #define JM_PHY_EXT_COMM_1_REG 0x31 | ||
775 | #define JM_PHY_EXT_COMM_2_REG 0x32 | ||
776 | #define JM_PHY_EXT_COMM_2_CALI_ENABLE 0x01 | ||
777 | #define JM_PHY_EXT_COMM_2_CALI_MODE_0 0x02 | ||
778 | #define JM_PHY_EXT_COMM_2_CALI_LATCH 0x10 | ||
779 | #define PCI_PRIV_SHARE_NICCTRL 0xF5 | ||
780 | #define JME_FLAG_PHYEA_ENABLE 0x2 | ||
781 | |||
763 | /* | 782 | /* |
764 | * Wakeup Frame setup interface registers | 783 | * Wakeup Frame setup interface registers |
765 | */ | 784 | */ |
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c index 662ab7e9a0f0..8876134b35bd 100644 --- a/drivers/net/wireless/ath/ath9k/hw.c +++ b/drivers/net/wireless/ath/ath9k/hw.c | |||
@@ -1827,7 +1827,8 @@ static void ath9k_set_power_sleep(struct ath_hw *ah, int setChip) | |||
1827 | } | 1827 | } |
1828 | 1828 | ||
1829 | /* Clear Bit 14 of AR_WA after putting chip into Full Sleep mode. */ | 1829 | /* Clear Bit 14 of AR_WA after putting chip into Full Sleep mode. */ |
1830 | REG_WRITE(ah, AR_WA, ah->WARegVal & ~AR_WA_D3_L1_DISABLE); | 1830 | if (AR_SREV_9300_20_OR_LATER(ah)) |
1831 | REG_WRITE(ah, AR_WA, ah->WARegVal & ~AR_WA_D3_L1_DISABLE); | ||
1831 | } | 1832 | } |
1832 | 1833 | ||
1833 | /* | 1834 | /* |
diff --git a/drivers/net/wireless/rtlwifi/ps.c b/drivers/net/wireless/rtlwifi/ps.c index db5262844543..55c8e50f45fd 100644 --- a/drivers/net/wireless/rtlwifi/ps.c +++ b/drivers/net/wireless/rtlwifi/ps.c | |||
@@ -395,7 +395,7 @@ void rtl_lps_enter(struct ieee80211_hw *hw) | |||
395 | if (mac->link_state != MAC80211_LINKED) | 395 | if (mac->link_state != MAC80211_LINKED) |
396 | return; | 396 | return; |
397 | 397 | ||
398 | spin_lock(&rtlpriv->locks.lps_lock); | 398 | spin_lock_irq(&rtlpriv->locks.lps_lock); |
399 | 399 | ||
400 | /* Idle for a while if we connect to AP a while ago. */ | 400 | /* Idle for a while if we connect to AP a while ago. */ |
401 | if (mac->cnt_after_linked >= 2) { | 401 | if (mac->cnt_after_linked >= 2) { |
@@ -407,7 +407,7 @@ void rtl_lps_enter(struct ieee80211_hw *hw) | |||
407 | } | 407 | } |
408 | } | 408 | } |
409 | 409 | ||
410 | spin_unlock(&rtlpriv->locks.lps_lock); | 410 | spin_unlock_irq(&rtlpriv->locks.lps_lock); |
411 | } | 411 | } |
412 | 412 | ||
413 | /*Leave the leisure power save mode.*/ | 413 | /*Leave the leisure power save mode.*/ |
@@ -416,8 +416,9 @@ void rtl_lps_leave(struct ieee80211_hw *hw) | |||
416 | struct rtl_priv *rtlpriv = rtl_priv(hw); | 416 | struct rtl_priv *rtlpriv = rtl_priv(hw); |
417 | struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); | 417 | struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); |
418 | struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); | 418 | struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); |
419 | unsigned long flags; | ||
419 | 420 | ||
420 | spin_lock(&rtlpriv->locks.lps_lock); | 421 | spin_lock_irqsave(&rtlpriv->locks.lps_lock, flags); |
421 | 422 | ||
422 | if (ppsc->fwctrl_lps) { | 423 | if (ppsc->fwctrl_lps) { |
423 | if (ppsc->dot11_psmode != EACTIVE) { | 424 | if (ppsc->dot11_psmode != EACTIVE) { |
@@ -438,7 +439,7 @@ void rtl_lps_leave(struct ieee80211_hw *hw) | |||
438 | rtl_lps_set_psmode(hw, EACTIVE); | 439 | rtl_lps_set_psmode(hw, EACTIVE); |
439 | } | 440 | } |
440 | } | 441 | } |
441 | spin_unlock(&rtlpriv->locks.lps_lock); | 442 | spin_unlock_irqrestore(&rtlpriv->locks.lps_lock, flags); |
442 | } | 443 | } |
443 | 444 | ||
444 | /* For sw LPS*/ | 445 | /* For sw LPS*/ |
@@ -539,9 +540,9 @@ void rtl_swlps_rf_awake(struct ieee80211_hw *hw) | |||
539 | RT_CLEAR_PS_LEVEL(ppsc, RT_PS_LEVEL_ASPM); | 540 | RT_CLEAR_PS_LEVEL(ppsc, RT_PS_LEVEL_ASPM); |
540 | } | 541 | } |
541 | 542 | ||
542 | spin_lock(&rtlpriv->locks.lps_lock); | 543 | spin_lock_irq(&rtlpriv->locks.lps_lock); |
543 | rtl_ps_set_rf_state(hw, ERFON, RF_CHANGE_BY_PS); | 544 | rtl_ps_set_rf_state(hw, ERFON, RF_CHANGE_BY_PS); |
544 | spin_unlock(&rtlpriv->locks.lps_lock); | 545 | spin_unlock_irq(&rtlpriv->locks.lps_lock); |
545 | } | 546 | } |
546 | 547 | ||
547 | void rtl_swlps_rfon_wq_callback(void *data) | 548 | void rtl_swlps_rfon_wq_callback(void *data) |
@@ -574,9 +575,9 @@ void rtl_swlps_rf_sleep(struct ieee80211_hw *hw) | |||
574 | if (rtlpriv->link_info.busytraffic) | 575 | if (rtlpriv->link_info.busytraffic) |
575 | return; | 576 | return; |
576 | 577 | ||
577 | spin_lock(&rtlpriv->locks.lps_lock); | 578 | spin_lock_irq(&rtlpriv->locks.lps_lock); |
578 | rtl_ps_set_rf_state(hw, ERFSLEEP, RF_CHANGE_BY_PS); | 579 | rtl_ps_set_rf_state(hw, ERFSLEEP, RF_CHANGE_BY_PS); |
579 | spin_unlock(&rtlpriv->locks.lps_lock); | 580 | spin_unlock_irq(&rtlpriv->locks.lps_lock); |
580 | 581 | ||
581 | if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_ASPM && | 582 | if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_ASPM && |
582 | !RT_IN_PS_LEVEL(ppsc, RT_PS_LEVEL_ASPM)) { | 583 | !RT_IN_PS_LEVEL(ppsc, RT_PS_LEVEL_ASPM)) { |
diff --git a/drivers/of/irq.c b/drivers/of/irq.c index 6d3dd3988d0f..19c0115092dd 100644 --- a/drivers/of/irq.c +++ b/drivers/of/irq.c | |||
@@ -60,27 +60,27 @@ EXPORT_SYMBOL_GPL(irq_of_parse_and_map); | |||
60 | */ | 60 | */ |
61 | struct device_node *of_irq_find_parent(struct device_node *child) | 61 | struct device_node *of_irq_find_parent(struct device_node *child) |
62 | { | 62 | { |
63 | struct device_node *p, *c = child; | 63 | struct device_node *p; |
64 | const __be32 *parp; | 64 | const __be32 *parp; |
65 | 65 | ||
66 | if (!of_node_get(c)) | 66 | if (!of_node_get(child)) |
67 | return NULL; | 67 | return NULL; |
68 | 68 | ||
69 | do { | 69 | do { |
70 | parp = of_get_property(c, "interrupt-parent", NULL); | 70 | parp = of_get_property(child, "interrupt-parent", NULL); |
71 | if (parp == NULL) | 71 | if (parp == NULL) |
72 | p = of_get_parent(c); | 72 | p = of_get_parent(child); |
73 | else { | 73 | else { |
74 | if (of_irq_workarounds & OF_IMAP_NO_PHANDLE) | 74 | if (of_irq_workarounds & OF_IMAP_NO_PHANDLE) |
75 | p = of_node_get(of_irq_dflt_pic); | 75 | p = of_node_get(of_irq_dflt_pic); |
76 | else | 76 | else |
77 | p = of_find_node_by_phandle(be32_to_cpup(parp)); | 77 | p = of_find_node_by_phandle(be32_to_cpup(parp)); |
78 | } | 78 | } |
79 | of_node_put(c); | 79 | of_node_put(child); |
80 | c = p; | 80 | child = p; |
81 | } while (p && of_get_property(p, "#interrupt-cells", NULL) == NULL); | 81 | } while (p && of_get_property(p, "#interrupt-cells", NULL) == NULL); |
82 | 82 | ||
83 | return (p == child) ? NULL : p; | 83 | return p; |
84 | } | 84 | } |
85 | 85 | ||
86 | /** | 86 | /** |
@@ -424,6 +424,8 @@ void __init of_irq_init(const struct of_device_id *matches) | |||
424 | 424 | ||
425 | desc->dev = np; | 425 | desc->dev = np; |
426 | desc->interrupt_parent = of_irq_find_parent(np); | 426 | desc->interrupt_parent = of_irq_find_parent(np); |
427 | if (desc->interrupt_parent == np) | ||
428 | desc->interrupt_parent = NULL; | ||
427 | list_add_tail(&desc->list, &intc_desc_list); | 429 | list_add_tail(&desc->list, &intc_desc_list); |
428 | } | 430 | } |
429 | 431 | ||
diff --git a/drivers/pci/Kconfig b/drivers/pci/Kconfig index b6f9749b4fa7..f02b5235056d 100644 --- a/drivers/pci/Kconfig +++ b/drivers/pci/Kconfig | |||
@@ -76,6 +76,7 @@ config PCI_IOV | |||
76 | 76 | ||
77 | config PCI_PRI | 77 | config PCI_PRI |
78 | bool "PCI PRI support" | 78 | bool "PCI PRI support" |
79 | depends on PCI | ||
79 | select PCI_ATS | 80 | select PCI_ATS |
80 | help | 81 | help |
81 | PRI is the PCI Page Request Interface. It allows PCI devices that are | 82 | PRI is the PCI Page Request Interface. It allows PCI devices that are |
diff --git a/drivers/pci/hotplug/acpiphp_glue.c b/drivers/pci/hotplug/acpiphp_glue.c index 596172b4ae95..fce1c54a0c8d 100644 --- a/drivers/pci/hotplug/acpiphp_glue.c +++ b/drivers/pci/hotplug/acpiphp_glue.c | |||
@@ -459,8 +459,17 @@ static int add_bridge(acpi_handle handle) | |||
459 | { | 459 | { |
460 | acpi_status status; | 460 | acpi_status status; |
461 | unsigned long long tmp; | 461 | unsigned long long tmp; |
462 | struct acpi_pci_root *root; | ||
462 | acpi_handle dummy_handle; | 463 | acpi_handle dummy_handle; |
463 | 464 | ||
465 | /* | ||
466 | * We shouldn't use this bridge if PCIe native hotplug control has been | ||
467 | * granted by the BIOS for it. | ||
468 | */ | ||
469 | root = acpi_pci_find_root(handle); | ||
470 | if (root && (root->osc_control_set & OSC_PCI_EXPRESS_NATIVE_HP_CONTROL)) | ||
471 | return -ENODEV; | ||
472 | |||
464 | /* if the bridge doesn't have _STA, we assume it is always there */ | 473 | /* if the bridge doesn't have _STA, we assume it is always there */ |
465 | status = acpi_get_handle(handle, "_STA", &dummy_handle); | 474 | status = acpi_get_handle(handle, "_STA", &dummy_handle); |
466 | if (ACPI_SUCCESS(status)) { | 475 | if (ACPI_SUCCESS(status)) { |
@@ -1376,13 +1385,23 @@ static void handle_hotplug_event_func(acpi_handle handle, u32 type, | |||
1376 | static acpi_status | 1385 | static acpi_status |
1377 | find_root_bridges(acpi_handle handle, u32 lvl, void *context, void **rv) | 1386 | find_root_bridges(acpi_handle handle, u32 lvl, void *context, void **rv) |
1378 | { | 1387 | { |
1388 | struct acpi_pci_root *root; | ||
1379 | int *count = (int *)context; | 1389 | int *count = (int *)context; |
1380 | 1390 | ||
1381 | if (acpi_is_root_bridge(handle)) { | 1391 | if (!acpi_is_root_bridge(handle)) |
1382 | acpi_install_notify_handler(handle, ACPI_SYSTEM_NOTIFY, | 1392 | return AE_OK; |
1383 | handle_hotplug_event_bridge, NULL); | 1393 | |
1384 | (*count)++; | 1394 | root = acpi_pci_find_root(handle); |
1385 | } | 1395 | if (!root) |
1396 | return AE_OK; | ||
1397 | |||
1398 | if (root->osc_control_set & OSC_PCI_EXPRESS_NATIVE_HP_CONTROL) | ||
1399 | return AE_OK; | ||
1400 | |||
1401 | (*count)++; | ||
1402 | acpi_install_notify_handler(handle, ACPI_SYSTEM_NOTIFY, | ||
1403 | handle_hotplug_event_bridge, NULL); | ||
1404 | |||
1386 | return AE_OK ; | 1405 | return AE_OK ; |
1387 | } | 1406 | } |
1388 | 1407 | ||
diff --git a/drivers/pci/hotplug/pciehp_ctrl.c b/drivers/pci/hotplug/pciehp_ctrl.c index 1e9c9aacc3a6..085dbb5fc168 100644 --- a/drivers/pci/hotplug/pciehp_ctrl.c +++ b/drivers/pci/hotplug/pciehp_ctrl.c | |||
@@ -213,9 +213,6 @@ static int board_added(struct slot *p_slot) | |||
213 | goto err_exit; | 213 | goto err_exit; |
214 | } | 214 | } |
215 | 215 | ||
216 | /* Wait for 1 second after checking link training status */ | ||
217 | msleep(1000); | ||
218 | |||
219 | /* Check for a power fault */ | 216 | /* Check for a power fault */ |
220 | if (ctrl->power_fault_detected || pciehp_query_power_fault(p_slot)) { | 217 | if (ctrl->power_fault_detected || pciehp_query_power_fault(p_slot)) { |
221 | ctrl_err(ctrl, "Power fault on slot %s\n", slot_name(p_slot)); | 218 | ctrl_err(ctrl, "Power fault on slot %s\n", slot_name(p_slot)); |
diff --git a/drivers/pci/hotplug/pciehp_hpc.c b/drivers/pci/hotplug/pciehp_hpc.c index 96dc4734e4af..7b1414810ae3 100644 --- a/drivers/pci/hotplug/pciehp_hpc.c +++ b/drivers/pci/hotplug/pciehp_hpc.c | |||
@@ -280,6 +280,14 @@ int pciehp_check_link_status(struct controller *ctrl) | |||
280 | else | 280 | else |
281 | msleep(1000); | 281 | msleep(1000); |
282 | 282 | ||
283 | /* | ||
284 | * Need to wait for 1000 ms after Data Link Layer Link Active | ||
285 | * (DLLLA) bit reads 1b before sending configuration request. | ||
286 | * We need it before checking Link Training (LT) bit becuase | ||
287 | * LT is still set even after DLLLA bit is set on some platform. | ||
288 | */ | ||
289 | msleep(1000); | ||
290 | |||
283 | retval = pciehp_readw(ctrl, PCI_EXP_LNKSTA, &lnk_status); | 291 | retval = pciehp_readw(ctrl, PCI_EXP_LNKSTA, &lnk_status); |
284 | if (retval) { | 292 | if (retval) { |
285 | ctrl_err(ctrl, "Cannot read LNKSTATUS register\n"); | 293 | ctrl_err(ctrl, "Cannot read LNKSTATUS register\n"); |
@@ -294,6 +302,16 @@ int pciehp_check_link_status(struct controller *ctrl) | |||
294 | return retval; | 302 | return retval; |
295 | } | 303 | } |
296 | 304 | ||
305 | /* | ||
306 | * If the port supports Link speeds greater than 5.0 GT/s, we | ||
307 | * must wait for 100 ms after Link training completes before | ||
308 | * sending configuration request. | ||
309 | */ | ||
310 | if (ctrl->pcie->port->subordinate->max_bus_speed > PCIE_SPEED_5_0GT) | ||
311 | msleep(100); | ||
312 | |||
313 | pcie_update_link_speed(ctrl->pcie->port->subordinate, lnk_status); | ||
314 | |||
297 | return retval; | 315 | return retval; |
298 | } | 316 | } |
299 | 317 | ||
@@ -484,7 +502,6 @@ int pciehp_power_on_slot(struct slot * slot) | |||
484 | u16 slot_cmd; | 502 | u16 slot_cmd; |
485 | u16 cmd_mask; | 503 | u16 cmd_mask; |
486 | u16 slot_status; | 504 | u16 slot_status; |
487 | u16 lnk_status; | ||
488 | int retval = 0; | 505 | int retval = 0; |
489 | 506 | ||
490 | /* Clear sticky power-fault bit from previous power failures */ | 507 | /* Clear sticky power-fault bit from previous power failures */ |
@@ -516,14 +533,6 @@ int pciehp_power_on_slot(struct slot * slot) | |||
516 | ctrl_dbg(ctrl, "%s: SLOTCTRL %x write cmd %x\n", __func__, | 533 | ctrl_dbg(ctrl, "%s: SLOTCTRL %x write cmd %x\n", __func__, |
517 | pci_pcie_cap(ctrl->pcie->port) + PCI_EXP_SLTCTL, slot_cmd); | 534 | pci_pcie_cap(ctrl->pcie->port) + PCI_EXP_SLTCTL, slot_cmd); |
518 | 535 | ||
519 | retval = pciehp_readw(ctrl, PCI_EXP_LNKSTA, &lnk_status); | ||
520 | if (retval) { | ||
521 | ctrl_err(ctrl, "%s: Cannot read LNKSTA register\n", | ||
522 | __func__); | ||
523 | return retval; | ||
524 | } | ||
525 | pcie_update_link_speed(ctrl->pcie->port->subordinate, lnk_status); | ||
526 | |||
527 | return retval; | 536 | return retval; |
528 | } | 537 | } |
529 | 538 | ||
diff --git a/drivers/pci/hotplug/shpchp_core.c b/drivers/pci/hotplug/shpchp_core.c index aca972bbfb4c..dd7e0c51a33e 100644 --- a/drivers/pci/hotplug/shpchp_core.c +++ b/drivers/pci/hotplug/shpchp_core.c | |||
@@ -278,8 +278,8 @@ static int get_adapter_status (struct hotplug_slot *hotplug_slot, u8 *value) | |||
278 | 278 | ||
279 | static int is_shpc_capable(struct pci_dev *dev) | 279 | static int is_shpc_capable(struct pci_dev *dev) |
280 | { | 280 | { |
281 | if ((dev->vendor == PCI_VENDOR_ID_AMD) || (dev->device == | 281 | if (dev->vendor == PCI_VENDOR_ID_AMD && |
282 | PCI_DEVICE_ID_AMD_GOLAM_7450)) | 282 | dev->device == PCI_DEVICE_ID_AMD_GOLAM_7450) |
283 | return 1; | 283 | return 1; |
284 | if (!pci_find_capability(dev, PCI_CAP_ID_SHPC)) | 284 | if (!pci_find_capability(dev, PCI_CAP_ID_SHPC)) |
285 | return 0; | 285 | return 0; |
diff --git a/drivers/pci/hotplug/shpchp_hpc.c b/drivers/pci/hotplug/shpchp_hpc.c index 36547f0ce305..75ba2311b54f 100644 --- a/drivers/pci/hotplug/shpchp_hpc.c +++ b/drivers/pci/hotplug/shpchp_hpc.c | |||
@@ -944,8 +944,8 @@ int shpc_init(struct controller *ctrl, struct pci_dev *pdev) | |||
944 | ctrl->pci_dev = pdev; /* pci_dev of the P2P bridge */ | 944 | ctrl->pci_dev = pdev; /* pci_dev of the P2P bridge */ |
945 | ctrl_dbg(ctrl, "Hotplug Controller:\n"); | 945 | ctrl_dbg(ctrl, "Hotplug Controller:\n"); |
946 | 946 | ||
947 | if ((pdev->vendor == PCI_VENDOR_ID_AMD) || (pdev->device == | 947 | if (pdev->vendor == PCI_VENDOR_ID_AMD && |
948 | PCI_DEVICE_ID_AMD_GOLAM_7450)) { | 948 | pdev->device == PCI_DEVICE_ID_AMD_GOLAM_7450) { |
949 | /* amd shpc driver doesn't use Base Offset; assume 0 */ | 949 | /* amd shpc driver doesn't use Base Offset; assume 0 */ |
950 | ctrl->mmio_base = pci_resource_start(pdev, 0); | 950 | ctrl->mmio_base = pci_resource_start(pdev, 0); |
951 | ctrl->mmio_size = pci_resource_len(pdev, 0); | 951 | ctrl->mmio_size = pci_resource_len(pdev, 0); |
diff --git a/drivers/regulator/aat2870-regulator.c b/drivers/regulator/aat2870-regulator.c index 5abeb3ac3e8d..298c6c6a2795 100644 --- a/drivers/regulator/aat2870-regulator.c +++ b/drivers/regulator/aat2870-regulator.c | |||
@@ -160,7 +160,7 @@ static struct aat2870_regulator *aat2870_get_regulator(int id) | |||
160 | break; | 160 | break; |
161 | } | 161 | } |
162 | 162 | ||
163 | if (!ri) | 163 | if (i == ARRAY_SIZE(aat2870_regulators)) |
164 | return NULL; | 164 | return NULL; |
165 | 165 | ||
166 | ri->enable_addr = AAT2870_LDO_EN; | 166 | ri->enable_addr = AAT2870_LDO_EN; |
diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index 669d02160221..938398f3e869 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c | |||
@@ -2799,8 +2799,8 @@ void regulator_unregister(struct regulator_dev *rdev) | |||
2799 | list_del(&rdev->list); | 2799 | list_del(&rdev->list); |
2800 | if (rdev->supply) | 2800 | if (rdev->supply) |
2801 | regulator_put(rdev->supply); | 2801 | regulator_put(rdev->supply); |
2802 | device_unregister(&rdev->dev); | ||
2803 | kfree(rdev->constraints); | 2802 | kfree(rdev->constraints); |
2803 | device_unregister(&rdev->dev); | ||
2804 | mutex_unlock(®ulator_list_mutex); | 2804 | mutex_unlock(®ulator_list_mutex); |
2805 | } | 2805 | } |
2806 | EXPORT_SYMBOL_GPL(regulator_unregister); | 2806 | EXPORT_SYMBOL_GPL(regulator_unregister); |
diff --git a/drivers/regulator/tps65910-regulator.c b/drivers/regulator/tps65910-regulator.c index 66d2d60b436a..b552aae55b41 100644 --- a/drivers/regulator/tps65910-regulator.c +++ b/drivers/regulator/tps65910-regulator.c | |||
@@ -664,10 +664,10 @@ static int tps65910_set_voltage_dcdc(struct regulator_dev *dev, | |||
664 | 664 | ||
665 | switch (id) { | 665 | switch (id) { |
666 | case TPS65910_REG_VDD1: | 666 | case TPS65910_REG_VDD1: |
667 | dcdc_mult = (selector / VDD1_2_NUM_VOLTS) + 1; | 667 | dcdc_mult = (selector / VDD1_2_NUM_VOLT_FINE) + 1; |
668 | if (dcdc_mult == 1) | 668 | if (dcdc_mult == 1) |
669 | dcdc_mult--; | 669 | dcdc_mult--; |
670 | vsel = (selector % VDD1_2_NUM_VOLTS) + 3; | 670 | vsel = (selector % VDD1_2_NUM_VOLT_FINE) + 3; |
671 | 671 | ||
672 | tps65910_modify_bits(pmic, TPS65910_VDD1, | 672 | tps65910_modify_bits(pmic, TPS65910_VDD1, |
673 | (dcdc_mult << VDD1_VGAIN_SEL_SHIFT), | 673 | (dcdc_mult << VDD1_VGAIN_SEL_SHIFT), |
@@ -675,10 +675,10 @@ static int tps65910_set_voltage_dcdc(struct regulator_dev *dev, | |||
675 | tps65910_reg_write(pmic, TPS65910_VDD1_OP, vsel); | 675 | tps65910_reg_write(pmic, TPS65910_VDD1_OP, vsel); |
676 | break; | 676 | break; |
677 | case TPS65910_REG_VDD2: | 677 | case TPS65910_REG_VDD2: |
678 | dcdc_mult = (selector / VDD1_2_NUM_VOLTS) + 1; | 678 | dcdc_mult = (selector / VDD1_2_NUM_VOLT_FINE) + 1; |
679 | if (dcdc_mult == 1) | 679 | if (dcdc_mult == 1) |
680 | dcdc_mult--; | 680 | dcdc_mult--; |
681 | vsel = (selector % VDD1_2_NUM_VOLTS) + 3; | 681 | vsel = (selector % VDD1_2_NUM_VOLT_FINE) + 3; |
682 | 682 | ||
683 | tps65910_modify_bits(pmic, TPS65910_VDD2, | 683 | tps65910_modify_bits(pmic, TPS65910_VDD2, |
684 | (dcdc_mult << VDD2_VGAIN_SEL_SHIFT), | 684 | (dcdc_mult << VDD2_VGAIN_SEL_SHIFT), |
@@ -756,9 +756,9 @@ static int tps65910_list_voltage_dcdc(struct regulator_dev *dev, | |||
756 | switch (id) { | 756 | switch (id) { |
757 | case TPS65910_REG_VDD1: | 757 | case TPS65910_REG_VDD1: |
758 | case TPS65910_REG_VDD2: | 758 | case TPS65910_REG_VDD2: |
759 | mult = (selector / VDD1_2_NUM_VOLTS) + 1; | 759 | mult = (selector / VDD1_2_NUM_VOLT_FINE) + 1; |
760 | volt = VDD1_2_MIN_VOLT + | 760 | volt = VDD1_2_MIN_VOLT + |
761 | (selector % VDD1_2_NUM_VOLTS) * VDD1_2_OFFSET; | 761 | (selector % VDD1_2_NUM_VOLT_FINE) * VDD1_2_OFFSET; |
762 | break; | 762 | break; |
763 | case TPS65911_REG_VDDCTRL: | 763 | case TPS65911_REG_VDDCTRL: |
764 | volt = VDDCTRL_MIN_VOLT + (selector * VDDCTRL_OFFSET); | 764 | volt = VDDCTRL_MIN_VOLT + (selector * VDDCTRL_OFFSET); |
@@ -947,6 +947,8 @@ static __devinit int tps65910_probe(struct platform_device *pdev) | |||
947 | 947 | ||
948 | if (i == TPS65910_REG_VDD1 || i == TPS65910_REG_VDD2) { | 948 | if (i == TPS65910_REG_VDD1 || i == TPS65910_REG_VDD2) { |
949 | pmic->desc[i].ops = &tps65910_ops_dcdc; | 949 | pmic->desc[i].ops = &tps65910_ops_dcdc; |
950 | pmic->desc[i].n_voltages = VDD1_2_NUM_VOLT_FINE * | ||
951 | VDD1_2_NUM_VOLT_COARSE; | ||
950 | } else if (i == TPS65910_REG_VDD3) { | 952 | } else if (i == TPS65910_REG_VDD3) { |
951 | if (tps65910_chip_id(tps65910) == TPS65910) | 953 | if (tps65910_chip_id(tps65910) == TPS65910) |
952 | pmic->desc[i].ops = &tps65910_ops_vdd3; | 954 | pmic->desc[i].ops = &tps65910_ops_vdd3; |
diff --git a/drivers/regulator/twl-regulator.c b/drivers/regulator/twl-regulator.c index ee8747f4fa08..11cc308d66e9 100644 --- a/drivers/regulator/twl-regulator.c +++ b/drivers/regulator/twl-regulator.c | |||
@@ -71,6 +71,7 @@ struct twlreg_info { | |||
71 | #define VREG_TYPE 1 | 71 | #define VREG_TYPE 1 |
72 | #define VREG_REMAP 2 | 72 | #define VREG_REMAP 2 |
73 | #define VREG_DEDICATED 3 /* LDO control */ | 73 | #define VREG_DEDICATED 3 /* LDO control */ |
74 | #define VREG_VOLTAGE_SMPS_4030 9 | ||
74 | /* TWL6030 register offsets */ | 75 | /* TWL6030 register offsets */ |
75 | #define VREG_TRANS 1 | 76 | #define VREG_TRANS 1 |
76 | #define VREG_STATE 2 | 77 | #define VREG_STATE 2 |
@@ -514,6 +515,32 @@ static struct regulator_ops twl4030ldo_ops = { | |||
514 | .get_status = twl4030reg_get_status, | 515 | .get_status = twl4030reg_get_status, |
515 | }; | 516 | }; |
516 | 517 | ||
518 | static int | ||
519 | twl4030smps_set_voltage(struct regulator_dev *rdev, int min_uV, int max_uV, | ||
520 | unsigned *selector) | ||
521 | { | ||
522 | struct twlreg_info *info = rdev_get_drvdata(rdev); | ||
523 | int vsel = DIV_ROUND_UP(min_uV - 600000, 12500); | ||
524 | |||
525 | twlreg_write(info, TWL_MODULE_PM_RECEIVER, VREG_VOLTAGE_SMPS_4030, | ||
526 | vsel); | ||
527 | return 0; | ||
528 | } | ||
529 | |||
530 | static int twl4030smps_get_voltage(struct regulator_dev *rdev) | ||
531 | { | ||
532 | struct twlreg_info *info = rdev_get_drvdata(rdev); | ||
533 | int vsel = twlreg_read(info, TWL_MODULE_PM_RECEIVER, | ||
534 | VREG_VOLTAGE_SMPS_4030); | ||
535 | |||
536 | return vsel * 12500 + 600000; | ||
537 | } | ||
538 | |||
539 | static struct regulator_ops twl4030smps_ops = { | ||
540 | .set_voltage = twl4030smps_set_voltage, | ||
541 | .get_voltage = twl4030smps_get_voltage, | ||
542 | }; | ||
543 | |||
517 | static int twl6030ldo_list_voltage(struct regulator_dev *rdev, unsigned index) | 544 | static int twl6030ldo_list_voltage(struct regulator_dev *rdev, unsigned index) |
518 | { | 545 | { |
519 | struct twlreg_info *info = rdev_get_drvdata(rdev); | 546 | struct twlreg_info *info = rdev_get_drvdata(rdev); |
@@ -856,6 +883,21 @@ static struct regulator_ops twlsmps_ops = { | |||
856 | }, \ | 883 | }, \ |
857 | } | 884 | } |
858 | 885 | ||
886 | #define TWL4030_ADJUSTABLE_SMPS(label, offset, num, turnon_delay, remap_conf) \ | ||
887 | { \ | ||
888 | .base = offset, \ | ||
889 | .id = num, \ | ||
890 | .delay = turnon_delay, \ | ||
891 | .remap = remap_conf, \ | ||
892 | .desc = { \ | ||
893 | .name = #label, \ | ||
894 | .id = TWL4030_REG_##label, \ | ||
895 | .ops = &twl4030smps_ops, \ | ||
896 | .type = REGULATOR_VOLTAGE, \ | ||
897 | .owner = THIS_MODULE, \ | ||
898 | }, \ | ||
899 | } | ||
900 | |||
859 | #define TWL6030_ADJUSTABLE_LDO(label, offset, min_mVolts, max_mVolts) { \ | 901 | #define TWL6030_ADJUSTABLE_LDO(label, offset, min_mVolts, max_mVolts) { \ |
860 | .base = offset, \ | 902 | .base = offset, \ |
861 | .min_mV = min_mVolts, \ | 903 | .min_mV = min_mVolts, \ |
@@ -947,8 +989,8 @@ static struct twlreg_info twl_regs[] = { | |||
947 | TWL4030_ADJUSTABLE_LDO(VINTANA2, 0x43, 12, 100, 0x08), | 989 | TWL4030_ADJUSTABLE_LDO(VINTANA2, 0x43, 12, 100, 0x08), |
948 | TWL4030_FIXED_LDO(VINTDIG, 0x47, 1500, 13, 100, 0x08), | 990 | TWL4030_FIXED_LDO(VINTDIG, 0x47, 1500, 13, 100, 0x08), |
949 | TWL4030_ADJUSTABLE_LDO(VIO, 0x4b, 14, 1000, 0x08), | 991 | TWL4030_ADJUSTABLE_LDO(VIO, 0x4b, 14, 1000, 0x08), |
950 | TWL4030_ADJUSTABLE_LDO(VDD1, 0x55, 15, 1000, 0x08), | 992 | TWL4030_ADJUSTABLE_SMPS(VDD1, 0x55, 15, 1000, 0x08), |
951 | TWL4030_ADJUSTABLE_LDO(VDD2, 0x63, 16, 1000, 0x08), | 993 | TWL4030_ADJUSTABLE_SMPS(VDD2, 0x63, 16, 1000, 0x08), |
952 | TWL4030_FIXED_LDO(VUSB1V5, 0x71, 1500, 17, 100, 0x08), | 994 | TWL4030_FIXED_LDO(VUSB1V5, 0x71, 1500, 17, 100, 0x08), |
953 | TWL4030_FIXED_LDO(VUSB1V8, 0x74, 1800, 18, 100, 0x08), | 995 | TWL4030_FIXED_LDO(VUSB1V8, 0x74, 1800, 18, 100, 0x08), |
954 | TWL4030_FIXED_LDO(VUSB3V1, 0x77, 3100, 19, 150, 0x08), | 996 | TWL4030_FIXED_LDO(VUSB3V1, 0x77, 3100, 19, 150, 0x08), |
diff --git a/drivers/spi/spi-nuc900.c b/drivers/spi/spi-nuc900.c index e763254741c2..21c70b2b8311 100644 --- a/drivers/spi/spi-nuc900.c +++ b/drivers/spi/spi-nuc900.c | |||
@@ -426,7 +426,7 @@ static int __devinit nuc900_spi_probe(struct platform_device *pdev) | |||
426 | goto err_clk; | 426 | goto err_clk; |
427 | } | 427 | } |
428 | 428 | ||
429 | mfp_set_groupg(&pdev->dev); | 429 | mfp_set_groupg(&pdev->dev, NULL); |
430 | nuc900_init_spi(hw); | 430 | nuc900_init_spi(hw); |
431 | 431 | ||
432 | err = spi_bitbang_start(&hw->bitbang); | 432 | err = spi_bitbang_start(&hw->bitbang); |
diff --git a/drivers/staging/et131x/Kconfig b/drivers/staging/et131x/Kconfig index 9e1864c6dfd0..8190f2aaf53b 100644 --- a/drivers/staging/et131x/Kconfig +++ b/drivers/staging/et131x/Kconfig | |||
@@ -1,6 +1,7 @@ | |||
1 | config ET131X | 1 | config ET131X |
2 | tristate "Agere ET-1310 Gigabit Ethernet support" | 2 | tristate "Agere ET-1310 Gigabit Ethernet support" |
3 | depends on PCI | 3 | depends on PCI && NET && NETDEVICES |
4 | select PHYLIB | ||
4 | default n | 5 | default n |
5 | ---help--- | 6 | ---help--- |
6 | This driver supports Agere ET-1310 ethernet adapters. | 7 | This driver supports Agere ET-1310 ethernet adapters. |
diff --git a/drivers/staging/et131x/et131x.c b/drivers/staging/et131x/et131x.c index f5f44a02456f..0c1c6ca8c379 100644 --- a/drivers/staging/et131x/et131x.c +++ b/drivers/staging/et131x/et131x.c | |||
@@ -4469,6 +4469,12 @@ static int et131x_resume(struct device *dev) | |||
4469 | return 0; | 4469 | return 0; |
4470 | } | 4470 | } |
4471 | 4471 | ||
4472 | static SIMPLE_DEV_PM_OPS(et131x_pm_ops, et131x_suspend, et131x_resume); | ||
4473 | #define ET131X_PM_OPS (&et131x_pm_ops) | ||
4474 | #else | ||
4475 | #define ET131X_PM_OPS NULL | ||
4476 | #endif | ||
4477 | |||
4472 | /* ISR functions */ | 4478 | /* ISR functions */ |
4473 | 4479 | ||
4474 | /** | 4480 | /** |
@@ -5470,12 +5476,6 @@ err_out: | |||
5470 | return result; | 5476 | return result; |
5471 | } | 5477 | } |
5472 | 5478 | ||
5473 | static SIMPLE_DEV_PM_OPS(et131x_pm_ops, et131x_suspend, et131x_resume); | ||
5474 | #define ET131X_PM_OPS (&et131x_pm_ops) | ||
5475 | #else | ||
5476 | #define ET131X_PM_OPS NULL | ||
5477 | #endif | ||
5478 | |||
5479 | static DEFINE_PCI_DEVICE_TABLE(et131x_pci_table) = { | 5479 | static DEFINE_PCI_DEVICE_TABLE(et131x_pci_table) = { |
5480 | { PCI_VDEVICE(ATT, ET131X_PCI_DEVICE_ID_GIG), 0UL}, | 5480 | { PCI_VDEVICE(ATT, ET131X_PCI_DEVICE_ID_GIG), 0UL}, |
5481 | { PCI_VDEVICE(ATT, ET131X_PCI_DEVICE_ID_FAST), 0UL}, | 5481 | { PCI_VDEVICE(ATT, ET131X_PCI_DEVICE_ID_FAST), 0UL}, |
diff --git a/drivers/staging/iio/industrialio-core.c b/drivers/staging/iio/industrialio-core.c index 326e967d54ef..aec9311b108c 100644 --- a/drivers/staging/iio/industrialio-core.c +++ b/drivers/staging/iio/industrialio-core.c | |||
@@ -242,19 +242,26 @@ static const struct file_operations iio_event_chrdev_fileops = { | |||
242 | 242 | ||
243 | static int iio_event_getfd(struct iio_dev *indio_dev) | 243 | static int iio_event_getfd(struct iio_dev *indio_dev) |
244 | { | 244 | { |
245 | if (indio_dev->event_interface == NULL) | 245 | struct iio_event_interface *ev_int = indio_dev->event_interface; |
246 | int fd; | ||
247 | |||
248 | if (ev_int == NULL) | ||
246 | return -ENODEV; | 249 | return -ENODEV; |
247 | 250 | ||
248 | mutex_lock(&indio_dev->event_interface->event_list_lock); | 251 | mutex_lock(&ev_int->event_list_lock); |
249 | if (test_and_set_bit(IIO_BUSY_BIT_POS, | 252 | if (test_and_set_bit(IIO_BUSY_BIT_POS, &ev_int->flags)) { |
250 | &indio_dev->event_interface->flags)) { | 253 | mutex_unlock(&ev_int->event_list_lock); |
251 | mutex_unlock(&indio_dev->event_interface->event_list_lock); | ||
252 | return -EBUSY; | 254 | return -EBUSY; |
253 | } | 255 | } |
254 | mutex_unlock(&indio_dev->event_interface->event_list_lock); | 256 | mutex_unlock(&ev_int->event_list_lock); |
255 | return anon_inode_getfd("iio:event", | 257 | fd = anon_inode_getfd("iio:event", |
256 | &iio_event_chrdev_fileops, | 258 | &iio_event_chrdev_fileops, ev_int, O_RDONLY); |
257 | indio_dev->event_interface, O_RDONLY); | 259 | if (fd < 0) { |
260 | mutex_lock(&ev_int->event_list_lock); | ||
261 | clear_bit(IIO_BUSY_BIT_POS, &ev_int->flags); | ||
262 | mutex_unlock(&ev_int->event_list_lock); | ||
263 | } | ||
264 | return fd; | ||
258 | } | 265 | } |
259 | 266 | ||
260 | static int __init iio_init(void) | 267 | static int __init iio_init(void) |
diff --git a/drivers/staging/slicoss/Kconfig b/drivers/staging/slicoss/Kconfig index 5cde96b2e6e1..5c2a15b42dfe 100644 --- a/drivers/staging/slicoss/Kconfig +++ b/drivers/staging/slicoss/Kconfig | |||
@@ -1,6 +1,6 @@ | |||
1 | config SLICOSS | 1 | config SLICOSS |
2 | tristate "Alacritech Gigabit IS-NIC support" | 2 | tristate "Alacritech Gigabit IS-NIC support" |
3 | depends on PCI && X86 | 3 | depends on PCI && X86 && NET |
4 | default n | 4 | default n |
5 | help | 5 | help |
6 | This driver supports Alacritech's IS-NIC gigabit ethernet cards. | 6 | This driver supports Alacritech's IS-NIC gigabit ethernet cards. |
diff --git a/drivers/tty/hvc/hvc_dcc.c b/drivers/tty/hvc/hvc_dcc.c index 435f6facbc23..44fbebab5075 100644 --- a/drivers/tty/hvc/hvc_dcc.c +++ b/drivers/tty/hvc/hvc_dcc.c | |||
@@ -46,6 +46,7 @@ static inline char __dcc_getchar(void) | |||
46 | 46 | ||
47 | asm volatile("mrc p14, 0, %0, c0, c5, 0 @ read comms data reg" | 47 | asm volatile("mrc p14, 0, %0, c0, c5, 0 @ read comms data reg" |
48 | : "=r" (__c)); | 48 | : "=r" (__c)); |
49 | isb(); | ||
49 | 50 | ||
50 | return __c; | 51 | return __c; |
51 | } | 52 | } |
@@ -55,6 +56,7 @@ static inline void __dcc_putchar(char c) | |||
55 | asm volatile("mcr p14, 0, %0, c0, c5, 0 @ write a char" | 56 | asm volatile("mcr p14, 0, %0, c0, c5, 0 @ write a char" |
56 | : /* no output register */ | 57 | : /* no output register */ |
57 | : "r" (c)); | 58 | : "r" (c)); |
59 | isb(); | ||
58 | } | 60 | } |
59 | 61 | ||
60 | static int hvc_dcc_put_chars(uint32_t vt, const char *buf, int count) | 62 | static int hvc_dcc_put_chars(uint32_t vt, const char *buf, int count) |
diff --git a/drivers/tty/serial/Kconfig b/drivers/tty/serial/Kconfig index 5f479dada6f2..925a1e547a83 100644 --- a/drivers/tty/serial/Kconfig +++ b/drivers/tty/serial/Kconfig | |||
@@ -1560,7 +1560,7 @@ config SERIAL_IFX6X60 | |||
1560 | Support for the IFX6x60 modem devices on Intel MID platforms. | 1560 | Support for the IFX6x60 modem devices on Intel MID platforms. |
1561 | 1561 | ||
1562 | config SERIAL_PCH_UART | 1562 | config SERIAL_PCH_UART |
1563 | tristate "Intel EG20T PCH / OKI SEMICONDUCTOR IOH(ML7213/ML7223) UART" | 1563 | tristate "Intel EG20T PCH/LAPIS Semicon IOH(ML7213/ML7223/ML7831) UART" |
1564 | depends on PCI | 1564 | depends on PCI |
1565 | select SERIAL_CORE | 1565 | select SERIAL_CORE |
1566 | help | 1566 | help |
@@ -1568,12 +1568,12 @@ config SERIAL_PCH_UART | |||
1568 | which is an IOH(Input/Output Hub) for x86 embedded processor. | 1568 | which is an IOH(Input/Output Hub) for x86 embedded processor. |
1569 | Enabling PCH_DMA, this PCH UART works as DMA mode. | 1569 | Enabling PCH_DMA, this PCH UART works as DMA mode. |
1570 | 1570 | ||
1571 | This driver also can be used for OKI SEMICONDUCTOR IOH(Input/ | 1571 | This driver also can be used for LAPIS Semiconductor IOH(Input/ |
1572 | Output Hub), ML7213 and ML7223. | 1572 | Output Hub), ML7213, ML7223 and ML7831. |
1573 | ML7213 IOH is for IVI(In-Vehicle Infotainment) use and ML7223 IOH is | 1573 | ML7213 IOH is for IVI(In-Vehicle Infotainment) use, ML7223 IOH is |
1574 | for MP(Media Phone) use. | 1574 | for MP(Media Phone) use and ML7831 IOH is for general purpose use. |
1575 | ML7213/ML7223 is companion chip for Intel Atom E6xx series. | 1575 | ML7213/ML7223/ML7831 is companion chip for Intel Atom E6xx series. |
1576 | ML7213/ML7223 is completely compatible for Intel EG20T PCH. | 1576 | ML7213/ML7223/ML7831 is completely compatible for Intel EG20T PCH. |
1577 | 1577 | ||
1578 | config SERIAL_MSM_SMD | 1578 | config SERIAL_MSM_SMD |
1579 | bool "Enable tty device interface for some SMD ports" | 1579 | bool "Enable tty device interface for some SMD ports" |
diff --git a/drivers/tty/serial/atmel_serial.c b/drivers/tty/serial/atmel_serial.c index 4a0f86fa1e90..4c823f341d98 100644 --- a/drivers/tty/serial/atmel_serial.c +++ b/drivers/tty/serial/atmel_serial.c | |||
@@ -228,7 +228,7 @@ void atmel_config_rs485(struct uart_port *port, struct serial_rs485 *rs485conf) | |||
228 | if (rs485conf->flags & SER_RS485_ENABLED) { | 228 | if (rs485conf->flags & SER_RS485_ENABLED) { |
229 | dev_dbg(port->dev, "Setting UART to RS485\n"); | 229 | dev_dbg(port->dev, "Setting UART to RS485\n"); |
230 | atmel_port->tx_done_mask = ATMEL_US_TXEMPTY; | 230 | atmel_port->tx_done_mask = ATMEL_US_TXEMPTY; |
231 | if (rs485conf->flags & SER_RS485_RTS_AFTER_SEND) | 231 | if ((rs485conf->delay_rts_after_send) > 0) |
232 | UART_PUT_TTGR(port, rs485conf->delay_rts_after_send); | 232 | UART_PUT_TTGR(port, rs485conf->delay_rts_after_send); |
233 | mode |= ATMEL_US_USMODE_RS485; | 233 | mode |= ATMEL_US_USMODE_RS485; |
234 | } else { | 234 | } else { |
@@ -304,7 +304,7 @@ static void atmel_set_mctrl(struct uart_port *port, u_int mctrl) | |||
304 | 304 | ||
305 | if (atmel_port->rs485.flags & SER_RS485_ENABLED) { | 305 | if (atmel_port->rs485.flags & SER_RS485_ENABLED) { |
306 | dev_dbg(port->dev, "Setting UART to RS485\n"); | 306 | dev_dbg(port->dev, "Setting UART to RS485\n"); |
307 | if (atmel_port->rs485.flags & SER_RS485_RTS_AFTER_SEND) | 307 | if ((atmel_port->rs485.delay_rts_after_send) > 0) |
308 | UART_PUT_TTGR(port, | 308 | UART_PUT_TTGR(port, |
309 | atmel_port->rs485.delay_rts_after_send); | 309 | atmel_port->rs485.delay_rts_after_send); |
310 | mode |= ATMEL_US_USMODE_RS485; | 310 | mode |= ATMEL_US_USMODE_RS485; |
@@ -1228,7 +1228,7 @@ static void atmel_set_termios(struct uart_port *port, struct ktermios *termios, | |||
1228 | 1228 | ||
1229 | if (atmel_port->rs485.flags & SER_RS485_ENABLED) { | 1229 | if (atmel_port->rs485.flags & SER_RS485_ENABLED) { |
1230 | dev_dbg(port->dev, "Setting UART to RS485\n"); | 1230 | dev_dbg(port->dev, "Setting UART to RS485\n"); |
1231 | if (atmel_port->rs485.flags & SER_RS485_RTS_AFTER_SEND) | 1231 | if ((atmel_port->rs485.delay_rts_after_send) > 0) |
1232 | UART_PUT_TTGR(port, | 1232 | UART_PUT_TTGR(port, |
1233 | atmel_port->rs485.delay_rts_after_send); | 1233 | atmel_port->rs485.delay_rts_after_send); |
1234 | mode |= ATMEL_US_USMODE_RS485; | 1234 | mode |= ATMEL_US_USMODE_RS485; |
@@ -1447,16 +1447,6 @@ static void __devinit atmel_of_init_port(struct atmel_uart_port *atmel_port, | |||
1447 | rs485conf->delay_rts_after_send = rs485_delay[1]; | 1447 | rs485conf->delay_rts_after_send = rs485_delay[1]; |
1448 | rs485conf->flags = 0; | 1448 | rs485conf->flags = 0; |
1449 | 1449 | ||
1450 | if (rs485conf->delay_rts_before_send == 0 && | ||
1451 | rs485conf->delay_rts_after_send == 0) { | ||
1452 | rs485conf->flags |= SER_RS485_RTS_ON_SEND; | ||
1453 | } else { | ||
1454 | if (rs485conf->delay_rts_before_send) | ||
1455 | rs485conf->flags |= SER_RS485_RTS_BEFORE_SEND; | ||
1456 | if (rs485conf->delay_rts_after_send) | ||
1457 | rs485conf->flags |= SER_RS485_RTS_AFTER_SEND; | ||
1458 | } | ||
1459 | |||
1460 | if (of_get_property(np, "rs485-rx-during-tx", NULL)) | 1450 | if (of_get_property(np, "rs485-rx-during-tx", NULL)) |
1461 | rs485conf->flags |= SER_RS485_RX_DURING_TX; | 1451 | rs485conf->flags |= SER_RS485_RX_DURING_TX; |
1462 | 1452 | ||
diff --git a/drivers/tty/serial/crisv10.c b/drivers/tty/serial/crisv10.c index b7435043f2fe..1dfba7b779c8 100644 --- a/drivers/tty/serial/crisv10.c +++ b/drivers/tty/serial/crisv10.c | |||
@@ -3234,9 +3234,8 @@ rs_write(struct tty_struct *tty, | |||
3234 | e100_disable_rx(info); | 3234 | e100_disable_rx(info); |
3235 | e100_enable_rx_irq(info); | 3235 | e100_enable_rx_irq(info); |
3236 | #endif | 3236 | #endif |
3237 | if ((info->rs485.flags & SER_RS485_RTS_BEFORE_SEND) && | 3237 | if (info->rs485.delay_rts_before_send > 0) |
3238 | (info->rs485.delay_rts_before_send > 0)) | 3238 | msleep(info->rs485.delay_rts_before_send); |
3239 | msleep(info->rs485.delay_rts_before_send); | ||
3240 | } | 3239 | } |
3241 | #endif /* CONFIG_ETRAX_RS485 */ | 3240 | #endif /* CONFIG_ETRAX_RS485 */ |
3242 | 3241 | ||
@@ -3693,10 +3692,6 @@ rs_ioctl(struct tty_struct *tty, | |||
3693 | 3692 | ||
3694 | rs485data.delay_rts_before_send = rs485ctrl.delay_rts_before_send; | 3693 | rs485data.delay_rts_before_send = rs485ctrl.delay_rts_before_send; |
3695 | rs485data.flags = 0; | 3694 | rs485data.flags = 0; |
3696 | if (rs485data.delay_rts_before_send != 0) | ||
3697 | rs485data.flags |= SER_RS485_RTS_BEFORE_SEND; | ||
3698 | else | ||
3699 | rs485data.flags &= ~(SER_RS485_RTS_BEFORE_SEND); | ||
3700 | 3695 | ||
3701 | if (rs485ctrl.enabled) | 3696 | if (rs485ctrl.enabled) |
3702 | rs485data.flags |= SER_RS485_ENABLED; | 3697 | rs485data.flags |= SER_RS485_ENABLED; |
@@ -4531,7 +4526,6 @@ static int __init rs_init(void) | |||
4531 | /* Set sane defaults */ | 4526 | /* Set sane defaults */ |
4532 | info->rs485.flags &= ~(SER_RS485_RTS_ON_SEND); | 4527 | info->rs485.flags &= ~(SER_RS485_RTS_ON_SEND); |
4533 | info->rs485.flags |= SER_RS485_RTS_AFTER_SEND; | 4528 | info->rs485.flags |= SER_RS485_RTS_AFTER_SEND; |
4534 | info->rs485.flags &= ~(SER_RS485_RTS_BEFORE_SEND); | ||
4535 | info->rs485.delay_rts_before_send = 0; | 4529 | info->rs485.delay_rts_before_send = 0; |
4536 | info->rs485.flags &= ~(SER_RS485_ENABLED); | 4530 | info->rs485.flags &= ~(SER_RS485_ENABLED); |
4537 | #endif | 4531 | #endif |
diff --git a/drivers/tty/serial/mfd.c b/drivers/tty/serial/mfd.c index 286c386d9c46..e272d3919c67 100644 --- a/drivers/tty/serial/mfd.c +++ b/drivers/tty/serial/mfd.c | |||
@@ -884,7 +884,6 @@ serial_hsu_set_termios(struct uart_port *port, struct ktermios *termios, | |||
884 | { | 884 | { |
885 | struct uart_hsu_port *up = | 885 | struct uart_hsu_port *up = |
886 | container_of(port, struct uart_hsu_port, port); | 886 | container_of(port, struct uart_hsu_port, port); |
887 | struct tty_struct *tty = port->state->port.tty; | ||
888 | unsigned char cval, fcr = 0; | 887 | unsigned char cval, fcr = 0; |
889 | unsigned long flags; | 888 | unsigned long flags; |
890 | unsigned int baud, quot; | 889 | unsigned int baud, quot; |
@@ -907,8 +906,7 @@ serial_hsu_set_termios(struct uart_port *port, struct ktermios *termios, | |||
907 | } | 906 | } |
908 | 907 | ||
909 | /* CMSPAR isn't supported by this driver */ | 908 | /* CMSPAR isn't supported by this driver */ |
910 | if (tty) | 909 | termios->c_cflag &= ~CMSPAR; |
911 | tty->termios->c_cflag &= ~CMSPAR; | ||
912 | 910 | ||
913 | if (termios->c_cflag & CSTOPB) | 911 | if (termios->c_cflag & CSTOPB) |
914 | cval |= UART_LCR_STOP; | 912 | cval |= UART_LCR_STOP; |
diff --git a/drivers/tty/serial/pch_uart.c b/drivers/tty/serial/pch_uart.c index 21febef926aa..d6aba8c087e4 100644 --- a/drivers/tty/serial/pch_uart.c +++ b/drivers/tty/serial/pch_uart.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | *Copyright (C) 2010 OKI SEMICONDUCTOR CO., LTD. | 2 | *Copyright (C) 2011 LAPIS Semiconductor Co., Ltd. |
3 | * | 3 | * |
4 | *This program is free software; you can redistribute it and/or modify | 4 | *This program is free software; you can redistribute it and/or modify |
5 | *it under the terms of the GNU General Public License as published by | 5 | *it under the terms of the GNU General Public License as published by |
@@ -46,8 +46,8 @@ enum { | |||
46 | 46 | ||
47 | /* Set the max number of UART port | 47 | /* Set the max number of UART port |
48 | * Intel EG20T PCH: 4 port | 48 | * Intel EG20T PCH: 4 port |
49 | * OKI SEMICONDUCTOR ML7213 IOH: 3 port | 49 | * LAPIS Semiconductor ML7213 IOH: 3 port |
50 | * OKI SEMICONDUCTOR ML7223 IOH: 2 port | 50 | * LAPIS Semiconductor ML7223 IOH: 2 port |
51 | */ | 51 | */ |
52 | #define PCH_UART_NR 4 | 52 | #define PCH_UART_NR 4 |
53 | 53 | ||
@@ -258,6 +258,8 @@ enum pch_uart_num_t { | |||
258 | pch_ml7213_uart2, | 258 | pch_ml7213_uart2, |
259 | pch_ml7223_uart0, | 259 | pch_ml7223_uart0, |
260 | pch_ml7223_uart1, | 260 | pch_ml7223_uart1, |
261 | pch_ml7831_uart0, | ||
262 | pch_ml7831_uart1, | ||
261 | }; | 263 | }; |
262 | 264 | ||
263 | static struct pch_uart_driver_data drv_dat[] = { | 265 | static struct pch_uart_driver_data drv_dat[] = { |
@@ -270,6 +272,8 @@ static struct pch_uart_driver_data drv_dat[] = { | |||
270 | [pch_ml7213_uart2] = {PCH_UART_2LINE, 2}, | 272 | [pch_ml7213_uart2] = {PCH_UART_2LINE, 2}, |
271 | [pch_ml7223_uart0] = {PCH_UART_8LINE, 0}, | 273 | [pch_ml7223_uart0] = {PCH_UART_8LINE, 0}, |
272 | [pch_ml7223_uart1] = {PCH_UART_2LINE, 1}, | 274 | [pch_ml7223_uart1] = {PCH_UART_2LINE, 1}, |
275 | [pch_ml7831_uart0] = {PCH_UART_8LINE, 0}, | ||
276 | [pch_ml7831_uart1] = {PCH_UART_2LINE, 1}, | ||
273 | }; | 277 | }; |
274 | 278 | ||
275 | static unsigned int default_baud = 9600; | 279 | static unsigned int default_baud = 9600; |
@@ -628,6 +632,7 @@ static void pch_request_dma(struct uart_port *port) | |||
628 | dev_err(priv->port.dev, "%s:dma_request_channel FAILS(Rx)\n", | 632 | dev_err(priv->port.dev, "%s:dma_request_channel FAILS(Rx)\n", |
629 | __func__); | 633 | __func__); |
630 | dma_release_channel(priv->chan_tx); | 634 | dma_release_channel(priv->chan_tx); |
635 | priv->chan_tx = NULL; | ||
631 | return; | 636 | return; |
632 | } | 637 | } |
633 | 638 | ||
@@ -1215,8 +1220,7 @@ static void pch_uart_shutdown(struct uart_port *port) | |||
1215 | dev_err(priv->port.dev, | 1220 | dev_err(priv->port.dev, |
1216 | "pch_uart_hal_set_fifo Failed(ret=%d)\n", ret); | 1221 | "pch_uart_hal_set_fifo Failed(ret=%d)\n", ret); |
1217 | 1222 | ||
1218 | if (priv->use_dma_flag) | 1223 | pch_free_dma(port); |
1219 | pch_free_dma(port); | ||
1220 | 1224 | ||
1221 | free_irq(priv->port.irq, priv); | 1225 | free_irq(priv->port.irq, priv); |
1222 | } | 1226 | } |
@@ -1280,6 +1284,7 @@ static void pch_uart_set_termios(struct uart_port *port, | |||
1280 | if (rtn) | 1284 | if (rtn) |
1281 | goto out; | 1285 | goto out; |
1282 | 1286 | ||
1287 | pch_uart_set_mctrl(&priv->port, priv->port.mctrl); | ||
1283 | /* Don't rewrite B0 */ | 1288 | /* Don't rewrite B0 */ |
1284 | if (tty_termios_baud_rate(termios)) | 1289 | if (tty_termios_baud_rate(termios)) |
1285 | tty_termios_encode_baud_rate(termios, baud, baud); | 1290 | tty_termios_encode_baud_rate(termios, baud, baud); |
@@ -1552,6 +1557,10 @@ static DEFINE_PCI_DEVICE_TABLE(pch_uart_pci_id) = { | |||
1552 | .driver_data = pch_ml7223_uart0}, | 1557 | .driver_data = pch_ml7223_uart0}, |
1553 | {PCI_DEVICE(PCI_VENDOR_ID_ROHM, 0x800D), | 1558 | {PCI_DEVICE(PCI_VENDOR_ID_ROHM, 0x800D), |
1554 | .driver_data = pch_ml7223_uart1}, | 1559 | .driver_data = pch_ml7223_uart1}, |
1560 | {PCI_DEVICE(PCI_VENDOR_ID_ROHM, 0x8811), | ||
1561 | .driver_data = pch_ml7831_uart0}, | ||
1562 | {PCI_DEVICE(PCI_VENDOR_ID_ROHM, 0x8812), | ||
1563 | .driver_data = pch_ml7831_uart1}, | ||
1555 | {0,}, | 1564 | {0,}, |
1556 | }; | 1565 | }; |
1557 | 1566 | ||
diff --git a/drivers/tty/tty_ldisc.c b/drivers/tty/tty_ldisc.c index 512c49f98e85..8e0924f55446 100644 --- a/drivers/tty/tty_ldisc.c +++ b/drivers/tty/tty_ldisc.c | |||
@@ -36,6 +36,7 @@ | |||
36 | 36 | ||
37 | #include <linux/kmod.h> | 37 | #include <linux/kmod.h> |
38 | #include <linux/nsproxy.h> | 38 | #include <linux/nsproxy.h> |
39 | #include <linux/ratelimit.h> | ||
39 | 40 | ||
40 | /* | 41 | /* |
41 | * This guards the refcounted line discipline lists. The lock | 42 | * This guards the refcounted line discipline lists. The lock |
@@ -547,15 +548,16 @@ static void tty_ldisc_flush_works(struct tty_struct *tty) | |||
547 | /** | 548 | /** |
548 | * tty_ldisc_wait_idle - wait for the ldisc to become idle | 549 | * tty_ldisc_wait_idle - wait for the ldisc to become idle |
549 | * @tty: tty to wait for | 550 | * @tty: tty to wait for |
551 | * @timeout: for how long to wait at most | ||
550 | * | 552 | * |
551 | * Wait for the line discipline to become idle. The discipline must | 553 | * Wait for the line discipline to become idle. The discipline must |
552 | * have been halted for this to guarantee it remains idle. | 554 | * have been halted for this to guarantee it remains idle. |
553 | */ | 555 | */ |
554 | static int tty_ldisc_wait_idle(struct tty_struct *tty) | 556 | static int tty_ldisc_wait_idle(struct tty_struct *tty, long timeout) |
555 | { | 557 | { |
556 | int ret; | 558 | long ret; |
557 | ret = wait_event_timeout(tty_ldisc_idle, | 559 | ret = wait_event_timeout(tty_ldisc_idle, |
558 | atomic_read(&tty->ldisc->users) == 1, 5 * HZ); | 560 | atomic_read(&tty->ldisc->users) == 1, timeout); |
559 | if (ret < 0) | 561 | if (ret < 0) |
560 | return ret; | 562 | return ret; |
561 | return ret > 0 ? 0 : -EBUSY; | 563 | return ret > 0 ? 0 : -EBUSY; |
@@ -665,7 +667,7 @@ int tty_set_ldisc(struct tty_struct *tty, int ldisc) | |||
665 | 667 | ||
666 | tty_ldisc_flush_works(tty); | 668 | tty_ldisc_flush_works(tty); |
667 | 669 | ||
668 | retval = tty_ldisc_wait_idle(tty); | 670 | retval = tty_ldisc_wait_idle(tty, 5 * HZ); |
669 | 671 | ||
670 | tty_lock(); | 672 | tty_lock(); |
671 | mutex_lock(&tty->ldisc_mutex); | 673 | mutex_lock(&tty->ldisc_mutex); |
@@ -762,8 +764,6 @@ static int tty_ldisc_reinit(struct tty_struct *tty, int ldisc) | |||
762 | if (IS_ERR(ld)) | 764 | if (IS_ERR(ld)) |
763 | return -1; | 765 | return -1; |
764 | 766 | ||
765 | WARN_ON_ONCE(tty_ldisc_wait_idle(tty)); | ||
766 | |||
767 | tty_ldisc_close(tty, tty->ldisc); | 767 | tty_ldisc_close(tty, tty->ldisc); |
768 | tty_ldisc_put(tty->ldisc); | 768 | tty_ldisc_put(tty->ldisc); |
769 | tty->ldisc = NULL; | 769 | tty->ldisc = NULL; |
@@ -838,7 +838,7 @@ void tty_ldisc_hangup(struct tty_struct *tty) | |||
838 | tty_unlock(); | 838 | tty_unlock(); |
839 | cancel_work_sync(&tty->buf.work); | 839 | cancel_work_sync(&tty->buf.work); |
840 | mutex_unlock(&tty->ldisc_mutex); | 840 | mutex_unlock(&tty->ldisc_mutex); |
841 | 841 | retry: | |
842 | tty_lock(); | 842 | tty_lock(); |
843 | mutex_lock(&tty->ldisc_mutex); | 843 | mutex_lock(&tty->ldisc_mutex); |
844 | 844 | ||
@@ -847,6 +847,22 @@ void tty_ldisc_hangup(struct tty_struct *tty) | |||
847 | it means auditing a lot of other paths so this is | 847 | it means auditing a lot of other paths so this is |
848 | a FIXME */ | 848 | a FIXME */ |
849 | if (tty->ldisc) { /* Not yet closed */ | 849 | if (tty->ldisc) { /* Not yet closed */ |
850 | if (atomic_read(&tty->ldisc->users) != 1) { | ||
851 | char cur_n[TASK_COMM_LEN], tty_n[64]; | ||
852 | long timeout = 3 * HZ; | ||
853 | tty_unlock(); | ||
854 | |||
855 | while (tty_ldisc_wait_idle(tty, timeout) == -EBUSY) { | ||
856 | timeout = MAX_SCHEDULE_TIMEOUT; | ||
857 | printk_ratelimited(KERN_WARNING | ||
858 | "%s: waiting (%s) for %s took too long, but we keep waiting...\n", | ||
859 | __func__, get_task_comm(cur_n, current), | ||
860 | tty_name(tty, tty_n)); | ||
861 | } | ||
862 | mutex_unlock(&tty->ldisc_mutex); | ||
863 | goto retry; | ||
864 | } | ||
865 | |||
850 | if (reset == 0) { | 866 | if (reset == 0) { |
851 | 867 | ||
852 | if (!tty_ldisc_reinit(tty, tty->termios->c_line)) | 868 | if (!tty_ldisc_reinit(tty, tty->termios->c_line)) |
diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c index 6960715c5063..e8c564a53346 100644 --- a/drivers/usb/class/cdc-acm.c +++ b/drivers/usb/class/cdc-acm.c | |||
@@ -539,7 +539,6 @@ static void acm_port_down(struct acm *acm) | |||
539 | { | 539 | { |
540 | int i; | 540 | int i; |
541 | 541 | ||
542 | mutex_lock(&open_mutex); | ||
543 | if (acm->dev) { | 542 | if (acm->dev) { |
544 | usb_autopm_get_interface(acm->control); | 543 | usb_autopm_get_interface(acm->control); |
545 | acm_set_control(acm, acm->ctrlout = 0); | 544 | acm_set_control(acm, acm->ctrlout = 0); |
@@ -551,14 +550,15 @@ static void acm_port_down(struct acm *acm) | |||
551 | acm->control->needs_remote_wakeup = 0; | 550 | acm->control->needs_remote_wakeup = 0; |
552 | usb_autopm_put_interface(acm->control); | 551 | usb_autopm_put_interface(acm->control); |
553 | } | 552 | } |
554 | mutex_unlock(&open_mutex); | ||
555 | } | 553 | } |
556 | 554 | ||
557 | static void acm_tty_hangup(struct tty_struct *tty) | 555 | static void acm_tty_hangup(struct tty_struct *tty) |
558 | { | 556 | { |
559 | struct acm *acm = tty->driver_data; | 557 | struct acm *acm = tty->driver_data; |
560 | tty_port_hangup(&acm->port); | 558 | tty_port_hangup(&acm->port); |
559 | mutex_lock(&open_mutex); | ||
561 | acm_port_down(acm); | 560 | acm_port_down(acm); |
561 | mutex_unlock(&open_mutex); | ||
562 | } | 562 | } |
563 | 563 | ||
564 | static void acm_tty_close(struct tty_struct *tty, struct file *filp) | 564 | static void acm_tty_close(struct tty_struct *tty, struct file *filp) |
@@ -569,8 +569,9 @@ static void acm_tty_close(struct tty_struct *tty, struct file *filp) | |||
569 | shutdown */ | 569 | shutdown */ |
570 | if (!acm) | 570 | if (!acm) |
571 | return; | 571 | return; |
572 | |||
573 | mutex_lock(&open_mutex); | ||
572 | if (tty_port_close_start(&acm->port, tty, filp) == 0) { | 574 | if (tty_port_close_start(&acm->port, tty, filp) == 0) { |
573 | mutex_lock(&open_mutex); | ||
574 | if (!acm->dev) { | 575 | if (!acm->dev) { |
575 | tty_port_tty_set(&acm->port, NULL); | 576 | tty_port_tty_set(&acm->port, NULL); |
576 | acm_tty_unregister(acm); | 577 | acm_tty_unregister(acm); |
@@ -582,6 +583,7 @@ static void acm_tty_close(struct tty_struct *tty, struct file *filp) | |||
582 | acm_port_down(acm); | 583 | acm_port_down(acm); |
583 | tty_port_close_end(&acm->port, tty); | 584 | tty_port_close_end(&acm->port, tty); |
584 | tty_port_tty_set(&acm->port, NULL); | 585 | tty_port_tty_set(&acm->port, NULL); |
586 | mutex_unlock(&open_mutex); | ||
585 | } | 587 | } |
586 | 588 | ||
587 | static int acm_tty_write(struct tty_struct *tty, | 589 | static int acm_tty_write(struct tty_struct *tty, |
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index 96f05b29c9ad..79781461eec9 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c | |||
@@ -813,6 +813,12 @@ static void hub_activate(struct usb_hub *hub, enum hub_activation_type type) | |||
813 | USB_PORT_FEAT_C_PORT_LINK_STATE); | 813 | USB_PORT_FEAT_C_PORT_LINK_STATE); |
814 | } | 814 | } |
815 | 815 | ||
816 | if ((portchange & USB_PORT_STAT_C_BH_RESET) && | ||
817 | hub_is_superspeed(hub->hdev)) { | ||
818 | need_debounce_delay = true; | ||
819 | clear_port_feature(hub->hdev, port1, | ||
820 | USB_PORT_FEAT_C_BH_PORT_RESET); | ||
821 | } | ||
816 | /* We can forget about a "removed" device when there's a | 822 | /* We can forget about a "removed" device when there's a |
817 | * physical disconnect or the connect status changes. | 823 | * physical disconnect or the connect status changes. |
818 | */ | 824 | */ |
diff --git a/drivers/usb/core/quirks.c b/drivers/usb/core/quirks.c index d6a8d8269bfb..ecf12e15a7ef 100644 --- a/drivers/usb/core/quirks.c +++ b/drivers/usb/core/quirks.c | |||
@@ -50,15 +50,42 @@ static const struct usb_device_id usb_quirk_list[] = { | |||
50 | /* Logitech Webcam B/C500 */ | 50 | /* Logitech Webcam B/C500 */ |
51 | { USB_DEVICE(0x046d, 0x0807), .driver_info = USB_QUIRK_RESET_RESUME }, | 51 | { USB_DEVICE(0x046d, 0x0807), .driver_info = USB_QUIRK_RESET_RESUME }, |
52 | 52 | ||
53 | /* Logitech Webcam C600 */ | ||
54 | { USB_DEVICE(0x046d, 0x0808), .driver_info = USB_QUIRK_RESET_RESUME }, | ||
55 | |||
53 | /* Logitech Webcam Pro 9000 */ | 56 | /* Logitech Webcam Pro 9000 */ |
54 | { USB_DEVICE(0x046d, 0x0809), .driver_info = USB_QUIRK_RESET_RESUME }, | 57 | { USB_DEVICE(0x046d, 0x0809), .driver_info = USB_QUIRK_RESET_RESUME }, |
55 | 58 | ||
59 | /* Logitech Webcam C905 */ | ||
60 | { USB_DEVICE(0x046d, 0x080a), .driver_info = USB_QUIRK_RESET_RESUME }, | ||
61 | |||
62 | /* Logitech Webcam C210 */ | ||
63 | { USB_DEVICE(0x046d, 0x0819), .driver_info = USB_QUIRK_RESET_RESUME }, | ||
64 | |||
65 | /* Logitech Webcam C260 */ | ||
66 | { USB_DEVICE(0x046d, 0x081a), .driver_info = USB_QUIRK_RESET_RESUME }, | ||
67 | |||
56 | /* Logitech Webcam C310 */ | 68 | /* Logitech Webcam C310 */ |
57 | { USB_DEVICE(0x046d, 0x081b), .driver_info = USB_QUIRK_RESET_RESUME }, | 69 | { USB_DEVICE(0x046d, 0x081b), .driver_info = USB_QUIRK_RESET_RESUME }, |
58 | 70 | ||
71 | /* Logitech Webcam C910 */ | ||
72 | { USB_DEVICE(0x046d, 0x0821), .driver_info = USB_QUIRK_RESET_RESUME }, | ||
73 | |||
74 | /* Logitech Webcam C160 */ | ||
75 | { USB_DEVICE(0x046d, 0x0824), .driver_info = USB_QUIRK_RESET_RESUME }, | ||
76 | |||
59 | /* Logitech Webcam C270 */ | 77 | /* Logitech Webcam C270 */ |
60 | { USB_DEVICE(0x046d, 0x0825), .driver_info = USB_QUIRK_RESET_RESUME }, | 78 | { USB_DEVICE(0x046d, 0x0825), .driver_info = USB_QUIRK_RESET_RESUME }, |
61 | 79 | ||
80 | /* Logitech Quickcam Pro 9000 */ | ||
81 | { USB_DEVICE(0x046d, 0x0990), .driver_info = USB_QUIRK_RESET_RESUME }, | ||
82 | |||
83 | /* Logitech Quickcam E3500 */ | ||
84 | { USB_DEVICE(0x046d, 0x09a4), .driver_info = USB_QUIRK_RESET_RESUME }, | ||
85 | |||
86 | /* Logitech Quickcam Vision Pro */ | ||
87 | { USB_DEVICE(0x046d, 0x09a6), .driver_info = USB_QUIRK_RESET_RESUME }, | ||
88 | |||
62 | /* Logitech Harmony 700-series */ | 89 | /* Logitech Harmony 700-series */ |
63 | { USB_DEVICE(0x046d, 0xc122), .driver_info = USB_QUIRK_DELAY_INIT }, | 90 | { USB_DEVICE(0x046d, 0xc122), .driver_info = USB_QUIRK_DELAY_INIT }, |
64 | 91 | ||
diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index fa824cfdd2eb..25dbd8614e72 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c | |||
@@ -1284,6 +1284,7 @@ static int __devinit dwc3_gadget_init_endpoints(struct dwc3 *dwc) | |||
1284 | int ret; | 1284 | int ret; |
1285 | 1285 | ||
1286 | dep->endpoint.maxpacket = 1024; | 1286 | dep->endpoint.maxpacket = 1024; |
1287 | dep->endpoint.max_streams = 15; | ||
1287 | dep->endpoint.ops = &dwc3_gadget_ep_ops; | 1288 | dep->endpoint.ops = &dwc3_gadget_ep_ops; |
1288 | list_add_tail(&dep->endpoint.ep_list, | 1289 | list_add_tail(&dep->endpoint.ep_list, |
1289 | &dwc->gadget.ep_list); | 1290 | &dwc->gadget.ep_list); |
diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig index b21cd376c11a..23a447373c51 100644 --- a/drivers/usb/gadget/Kconfig +++ b/drivers/usb/gadget/Kconfig | |||
@@ -469,7 +469,7 @@ config USB_LANGWELL | |||
469 | gadget drivers to also be dynamically linked. | 469 | gadget drivers to also be dynamically linked. |
470 | 470 | ||
471 | config USB_EG20T | 471 | config USB_EG20T |
472 | tristate "Intel EG20T PCH/OKI SEMICONDUCTOR ML7213 IOH UDC" | 472 | tristate "Intel EG20T PCH/LAPIS Semiconductor IOH(ML7213/ML7831) UDC" |
473 | depends on PCI | 473 | depends on PCI |
474 | select USB_GADGET_DUALSPEED | 474 | select USB_GADGET_DUALSPEED |
475 | help | 475 | help |
@@ -485,10 +485,11 @@ config USB_EG20T | |||
485 | This driver dose not support interrupt transfer or isochronous | 485 | This driver dose not support interrupt transfer or isochronous |
486 | transfer modes. | 486 | transfer modes. |
487 | 487 | ||
488 | This driver also can be used for OKI SEMICONDUCTOR's ML7213 which is | 488 | This driver also can be used for LAPIS Semiconductor's ML7213 which is |
489 | for IVI(In-Vehicle Infotainment) use. | 489 | for IVI(In-Vehicle Infotainment) use. |
490 | ML7213 is companion chip for Intel Atom E6xx series. | 490 | ML7831 is for general purpose use. |
491 | ML7213 is completely compatible for Intel EG20T PCH. | 491 | ML7213/ML7831 is companion chip for Intel Atom E6xx series. |
492 | ML7213/ML7831 is completely compatible for Intel EG20T PCH. | ||
492 | 493 | ||
493 | config USB_CI13XXX_MSM | 494 | config USB_CI13XXX_MSM |
494 | tristate "MIPS USB CI13xxx for MSM" | 495 | tristate "MIPS USB CI13xxx for MSM" |
diff --git a/drivers/usb/gadget/ci13xxx_msm.c b/drivers/usb/gadget/ci13xxx_msm.c index 4eedfe557154..1fc612914c52 100644 --- a/drivers/usb/gadget/ci13xxx_msm.c +++ b/drivers/usb/gadget/ci13xxx_msm.c | |||
@@ -122,3 +122,5 @@ static int __init ci13xxx_msm_init(void) | |||
122 | return platform_driver_register(&ci13xxx_msm_driver); | 122 | return platform_driver_register(&ci13xxx_msm_driver); |
123 | } | 123 | } |
124 | module_init(ci13xxx_msm_init); | 124 | module_init(ci13xxx_msm_init); |
125 | |||
126 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/usb/gadget/ci13xxx_udc.c b/drivers/usb/gadget/ci13xxx_udc.c index 83428f56253b..9a0c3979ff43 100644 --- a/drivers/usb/gadget/ci13xxx_udc.c +++ b/drivers/usb/gadget/ci13xxx_udc.c | |||
@@ -71,6 +71,9 @@ | |||
71 | /****************************************************************************** | 71 | /****************************************************************************** |
72 | * DEFINE | 72 | * DEFINE |
73 | *****************************************************************************/ | 73 | *****************************************************************************/ |
74 | |||
75 | #define DMA_ADDR_INVALID (~(dma_addr_t)0) | ||
76 | |||
74 | /* ctrl register bank access */ | 77 | /* ctrl register bank access */ |
75 | static DEFINE_SPINLOCK(udc_lock); | 78 | static DEFINE_SPINLOCK(udc_lock); |
76 | 79 | ||
@@ -1434,7 +1437,7 @@ static int _hardware_enqueue(struct ci13xxx_ep *mEp, struct ci13xxx_req *mReq) | |||
1434 | return -EALREADY; | 1437 | return -EALREADY; |
1435 | 1438 | ||
1436 | mReq->req.status = -EALREADY; | 1439 | mReq->req.status = -EALREADY; |
1437 | if (length && !mReq->req.dma) { | 1440 | if (length && mReq->req.dma == DMA_ADDR_INVALID) { |
1438 | mReq->req.dma = \ | 1441 | mReq->req.dma = \ |
1439 | dma_map_single(mEp->device, mReq->req.buf, | 1442 | dma_map_single(mEp->device, mReq->req.buf, |
1440 | length, mEp->dir ? DMA_TO_DEVICE : | 1443 | length, mEp->dir ? DMA_TO_DEVICE : |
@@ -1453,7 +1456,7 @@ static int _hardware_enqueue(struct ci13xxx_ep *mEp, struct ci13xxx_req *mReq) | |||
1453 | dma_unmap_single(mEp->device, mReq->req.dma, | 1456 | dma_unmap_single(mEp->device, mReq->req.dma, |
1454 | length, mEp->dir ? DMA_TO_DEVICE : | 1457 | length, mEp->dir ? DMA_TO_DEVICE : |
1455 | DMA_FROM_DEVICE); | 1458 | DMA_FROM_DEVICE); |
1456 | mReq->req.dma = 0; | 1459 | mReq->req.dma = DMA_ADDR_INVALID; |
1457 | mReq->map = 0; | 1460 | mReq->map = 0; |
1458 | } | 1461 | } |
1459 | return -ENOMEM; | 1462 | return -ENOMEM; |
@@ -1549,7 +1552,7 @@ static int _hardware_dequeue(struct ci13xxx_ep *mEp, struct ci13xxx_req *mReq) | |||
1549 | if (mReq->map) { | 1552 | if (mReq->map) { |
1550 | dma_unmap_single(mEp->device, mReq->req.dma, mReq->req.length, | 1553 | dma_unmap_single(mEp->device, mReq->req.dma, mReq->req.length, |
1551 | mEp->dir ? DMA_TO_DEVICE : DMA_FROM_DEVICE); | 1554 | mEp->dir ? DMA_TO_DEVICE : DMA_FROM_DEVICE); |
1552 | mReq->req.dma = 0; | 1555 | mReq->req.dma = DMA_ADDR_INVALID; |
1553 | mReq->map = 0; | 1556 | mReq->map = 0; |
1554 | } | 1557 | } |
1555 | 1558 | ||
@@ -1610,7 +1613,6 @@ __acquires(mEp->lock) | |||
1610 | * @gadget: gadget | 1613 | * @gadget: gadget |
1611 | * | 1614 | * |
1612 | * This function returns an error code | 1615 | * This function returns an error code |
1613 | * Caller must hold lock | ||
1614 | */ | 1616 | */ |
1615 | static int _gadget_stop_activity(struct usb_gadget *gadget) | 1617 | static int _gadget_stop_activity(struct usb_gadget *gadget) |
1616 | { | 1618 | { |
@@ -2189,6 +2191,7 @@ static struct usb_request *ep_alloc_request(struct usb_ep *ep, gfp_t gfp_flags) | |||
2189 | mReq = kzalloc(sizeof(struct ci13xxx_req), gfp_flags); | 2191 | mReq = kzalloc(sizeof(struct ci13xxx_req), gfp_flags); |
2190 | if (mReq != NULL) { | 2192 | if (mReq != NULL) { |
2191 | INIT_LIST_HEAD(&mReq->queue); | 2193 | INIT_LIST_HEAD(&mReq->queue); |
2194 | mReq->req.dma = DMA_ADDR_INVALID; | ||
2192 | 2195 | ||
2193 | mReq->ptr = dma_pool_alloc(mEp->td_pool, gfp_flags, | 2196 | mReq->ptr = dma_pool_alloc(mEp->td_pool, gfp_flags, |
2194 | &mReq->dma); | 2197 | &mReq->dma); |
@@ -2328,7 +2331,7 @@ static int ep_dequeue(struct usb_ep *ep, struct usb_request *req) | |||
2328 | if (mReq->map) { | 2331 | if (mReq->map) { |
2329 | dma_unmap_single(mEp->device, mReq->req.dma, mReq->req.length, | 2332 | dma_unmap_single(mEp->device, mReq->req.dma, mReq->req.length, |
2330 | mEp->dir ? DMA_TO_DEVICE : DMA_FROM_DEVICE); | 2333 | mEp->dir ? DMA_TO_DEVICE : DMA_FROM_DEVICE); |
2331 | mReq->req.dma = 0; | 2334 | mReq->req.dma = DMA_ADDR_INVALID; |
2332 | mReq->map = 0; | 2335 | mReq->map = 0; |
2333 | } | 2336 | } |
2334 | req->status = -ECONNRESET; | 2337 | req->status = -ECONNRESET; |
@@ -2500,12 +2503,12 @@ static int ci13xxx_wakeup(struct usb_gadget *_gadget) | |||
2500 | spin_lock_irqsave(udc->lock, flags); | 2503 | spin_lock_irqsave(udc->lock, flags); |
2501 | if (!udc->remote_wakeup) { | 2504 | if (!udc->remote_wakeup) { |
2502 | ret = -EOPNOTSUPP; | 2505 | ret = -EOPNOTSUPP; |
2503 | dbg_trace("remote wakeup feature is not enabled\n"); | 2506 | trace("remote wakeup feature is not enabled\n"); |
2504 | goto out; | 2507 | goto out; |
2505 | } | 2508 | } |
2506 | if (!hw_cread(CAP_PORTSC, PORTSC_SUSP)) { | 2509 | if (!hw_cread(CAP_PORTSC, PORTSC_SUSP)) { |
2507 | ret = -EINVAL; | 2510 | ret = -EINVAL; |
2508 | dbg_trace("port is not suspended\n"); | 2511 | trace("port is not suspended\n"); |
2509 | goto out; | 2512 | goto out; |
2510 | } | 2513 | } |
2511 | hw_cwrite(CAP_PORTSC, PORTSC_FPR, PORTSC_FPR); | 2514 | hw_cwrite(CAP_PORTSC, PORTSC_FPR, PORTSC_FPR); |
@@ -2703,7 +2706,9 @@ static int ci13xxx_stop(struct usb_gadget_driver *driver) | |||
2703 | if (udc->udc_driver->notify_event) | 2706 | if (udc->udc_driver->notify_event) |
2704 | udc->udc_driver->notify_event(udc, | 2707 | udc->udc_driver->notify_event(udc, |
2705 | CI13XXX_CONTROLLER_STOPPED_EVENT); | 2708 | CI13XXX_CONTROLLER_STOPPED_EVENT); |
2709 | spin_unlock_irqrestore(udc->lock, flags); | ||
2706 | _gadget_stop_activity(&udc->gadget); | 2710 | _gadget_stop_activity(&udc->gadget); |
2711 | spin_lock_irqsave(udc->lock, flags); | ||
2707 | pm_runtime_put(&udc->gadget.dev); | 2712 | pm_runtime_put(&udc->gadget.dev); |
2708 | } | 2713 | } |
2709 | 2714 | ||
@@ -2850,7 +2855,7 @@ static int udc_probe(struct ci13xxx_udc_driver *driver, struct device *dev, | |||
2850 | struct ci13xxx *udc; | 2855 | struct ci13xxx *udc; |
2851 | int retval = 0; | 2856 | int retval = 0; |
2852 | 2857 | ||
2853 | trace("%p, %p, %p", dev, regs, name); | 2858 | trace("%p, %p, %p", dev, regs, driver->name); |
2854 | 2859 | ||
2855 | if (dev == NULL || regs == NULL || driver == NULL || | 2860 | if (dev == NULL || regs == NULL || driver == NULL || |
2856 | driver->name == NULL) | 2861 | driver->name == NULL) |
diff --git a/drivers/usb/gadget/f_mass_storage.c b/drivers/usb/gadget/f_mass_storage.c index 52583a235330..c39d58860fa0 100644 --- a/drivers/usb/gadget/f_mass_storage.c +++ b/drivers/usb/gadget/f_mass_storage.c | |||
@@ -624,7 +624,8 @@ static int fsg_setup(struct usb_function *f, | |||
624 | if (ctrl->bRequestType != | 624 | if (ctrl->bRequestType != |
625 | (USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE)) | 625 | (USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE)) |
626 | break; | 626 | break; |
627 | if (w_index != fsg->interface_number || w_value != 0) | 627 | if (w_index != fsg->interface_number || w_value != 0 || |
628 | w_length != 0) | ||
628 | return -EDOM; | 629 | return -EDOM; |
629 | 630 | ||
630 | /* | 631 | /* |
@@ -639,7 +640,8 @@ static int fsg_setup(struct usb_function *f, | |||
639 | if (ctrl->bRequestType != | 640 | if (ctrl->bRequestType != |
640 | (USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE)) | 641 | (USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE)) |
641 | break; | 642 | break; |
642 | if (w_index != fsg->interface_number || w_value != 0) | 643 | if (w_index != fsg->interface_number || w_value != 0 || |
644 | w_length != 1) | ||
643 | return -EDOM; | 645 | return -EDOM; |
644 | VDBG(fsg, "get max LUN\n"); | 646 | VDBG(fsg, "get max LUN\n"); |
645 | *(u8 *)req->buf = fsg->common->nluns - 1; | 647 | *(u8 *)req->buf = fsg->common->nluns - 1; |
diff --git a/drivers/usb/gadget/f_midi.c b/drivers/usb/gadget/f_midi.c index 67b222908cf9..3797b3d6c622 100644 --- a/drivers/usb/gadget/f_midi.c +++ b/drivers/usb/gadget/f_midi.c | |||
@@ -95,7 +95,6 @@ static void f_midi_transmit(struct f_midi *midi, struct usb_request *req); | |||
95 | 95 | ||
96 | DECLARE_UAC_AC_HEADER_DESCRIPTOR(1); | 96 | DECLARE_UAC_AC_HEADER_DESCRIPTOR(1); |
97 | DECLARE_USB_MIDI_OUT_JACK_DESCRIPTOR(1); | 97 | DECLARE_USB_MIDI_OUT_JACK_DESCRIPTOR(1); |
98 | DECLARE_USB_MIDI_OUT_JACK_DESCRIPTOR(16); | ||
99 | DECLARE_USB_MS_ENDPOINT_DESCRIPTOR(16); | 98 | DECLARE_USB_MS_ENDPOINT_DESCRIPTOR(16); |
100 | 99 | ||
101 | /* B.3.1 Standard AC Interface Descriptor */ | 100 | /* B.3.1 Standard AC Interface Descriptor */ |
@@ -140,26 +139,6 @@ static struct usb_ms_header_descriptor ms_header_desc __initdata = { | |||
140 | /* .wTotalLength = DYNAMIC */ | 139 | /* .wTotalLength = DYNAMIC */ |
141 | }; | 140 | }; |
142 | 141 | ||
143 | /* B.4.3 Embedded MIDI IN Jack Descriptor */ | ||
144 | static struct usb_midi_in_jack_descriptor jack_in_emb_desc = { | ||
145 | .bLength = USB_DT_MIDI_IN_SIZE, | ||
146 | .bDescriptorType = USB_DT_CS_INTERFACE, | ||
147 | .bDescriptorSubtype = USB_MS_MIDI_IN_JACK, | ||
148 | .bJackType = USB_MS_EMBEDDED, | ||
149 | /* .bJackID = DYNAMIC */ | ||
150 | }; | ||
151 | |||
152 | /* B.4.4 Embedded MIDI OUT Jack Descriptor */ | ||
153 | static struct usb_midi_out_jack_descriptor_16 jack_out_emb_desc = { | ||
154 | /* .bLength = DYNAMIC */ | ||
155 | .bDescriptorType = USB_DT_CS_INTERFACE, | ||
156 | .bDescriptorSubtype = USB_MS_MIDI_OUT_JACK, | ||
157 | .bJackType = USB_MS_EMBEDDED, | ||
158 | /* .bJackID = DYNAMIC */ | ||
159 | /* .bNrInputPins = DYNAMIC */ | ||
160 | /* .pins = DYNAMIC */ | ||
161 | }; | ||
162 | |||
163 | /* B.5.1 Standard Bulk OUT Endpoint Descriptor */ | 142 | /* B.5.1 Standard Bulk OUT Endpoint Descriptor */ |
164 | static struct usb_endpoint_descriptor bulk_out_desc = { | 143 | static struct usb_endpoint_descriptor bulk_out_desc = { |
165 | .bLength = USB_DT_ENDPOINT_AUDIO_SIZE, | 144 | .bLength = USB_DT_ENDPOINT_AUDIO_SIZE, |
@@ -758,9 +737,11 @@ fail: | |||
758 | static int __init | 737 | static int __init |
759 | f_midi_bind(struct usb_configuration *c, struct usb_function *f) | 738 | f_midi_bind(struct usb_configuration *c, struct usb_function *f) |
760 | { | 739 | { |
761 | struct usb_descriptor_header *midi_function[(MAX_PORTS * 2) + 12]; | 740 | struct usb_descriptor_header **midi_function; |
762 | struct usb_midi_in_jack_descriptor jack_in_ext_desc[MAX_PORTS]; | 741 | struct usb_midi_in_jack_descriptor jack_in_ext_desc[MAX_PORTS]; |
742 | struct usb_midi_in_jack_descriptor jack_in_emb_desc[MAX_PORTS]; | ||
763 | struct usb_midi_out_jack_descriptor_1 jack_out_ext_desc[MAX_PORTS]; | 743 | struct usb_midi_out_jack_descriptor_1 jack_out_ext_desc[MAX_PORTS]; |
744 | struct usb_midi_out_jack_descriptor_1 jack_out_emb_desc[MAX_PORTS]; | ||
764 | struct usb_composite_dev *cdev = c->cdev; | 745 | struct usb_composite_dev *cdev = c->cdev; |
765 | struct f_midi *midi = func_to_midi(f); | 746 | struct f_midi *midi = func_to_midi(f); |
766 | int status, n, jack = 1, i = 0; | 747 | int status, n, jack = 1, i = 0; |
@@ -798,6 +779,14 @@ f_midi_bind(struct usb_configuration *c, struct usb_function *f) | |||
798 | goto fail; | 779 | goto fail; |
799 | midi->out_ep->driver_data = cdev; /* claim */ | 780 | midi->out_ep->driver_data = cdev; /* claim */ |
800 | 781 | ||
782 | /* allocate temporary function list */ | ||
783 | midi_function = kcalloc((MAX_PORTS * 4) + 9, sizeof(midi_function), | ||
784 | GFP_KERNEL); | ||
785 | if (!midi_function) { | ||
786 | status = -ENOMEM; | ||
787 | goto fail; | ||
788 | } | ||
789 | |||
801 | /* | 790 | /* |
802 | * construct the function's descriptor set. As the number of | 791 | * construct the function's descriptor set. As the number of |
803 | * input and output MIDI ports is configurable, we have to do | 792 | * input and output MIDI ports is configurable, we have to do |
@@ -811,73 +800,74 @@ f_midi_bind(struct usb_configuration *c, struct usb_function *f) | |||
811 | 800 | ||
812 | /* calculate the header's wTotalLength */ | 801 | /* calculate the header's wTotalLength */ |
813 | n = USB_DT_MS_HEADER_SIZE | 802 | n = USB_DT_MS_HEADER_SIZE |
814 | + (1 + midi->in_ports) * USB_DT_MIDI_IN_SIZE | 803 | + (midi->in_ports + midi->out_ports) * |
815 | + (1 + midi->out_ports) * USB_DT_MIDI_OUT_SIZE(1); | 804 | (USB_DT_MIDI_IN_SIZE + USB_DT_MIDI_OUT_SIZE(1)); |
816 | ms_header_desc.wTotalLength = cpu_to_le16(n); | 805 | ms_header_desc.wTotalLength = cpu_to_le16(n); |
817 | 806 | ||
818 | midi_function[i++] = (struct usb_descriptor_header *) &ms_header_desc; | 807 | midi_function[i++] = (struct usb_descriptor_header *) &ms_header_desc; |
819 | 808 | ||
820 | /* we have one embedded IN jack */ | 809 | /* configure the external IN jacks, each linked to an embedded OUT jack */ |
821 | jack_in_emb_desc.bJackID = jack++; | ||
822 | midi_function[i++] = (struct usb_descriptor_header *) &jack_in_emb_desc; | ||
823 | |||
824 | /* and a dynamic amount of external IN jacks */ | ||
825 | for (n = 0; n < midi->in_ports; n++) { | ||
826 | struct usb_midi_in_jack_descriptor *ext = &jack_in_ext_desc[n]; | ||
827 | |||
828 | ext->bLength = USB_DT_MIDI_IN_SIZE; | ||
829 | ext->bDescriptorType = USB_DT_CS_INTERFACE; | ||
830 | ext->bDescriptorSubtype = USB_MS_MIDI_IN_JACK; | ||
831 | ext->bJackType = USB_MS_EXTERNAL; | ||
832 | ext->bJackID = jack++; | ||
833 | ext->iJack = 0; | ||
834 | |||
835 | midi_function[i++] = (struct usb_descriptor_header *) ext; | ||
836 | } | ||
837 | |||
838 | /* one embedded OUT jack ... */ | ||
839 | jack_out_emb_desc.bLength = USB_DT_MIDI_OUT_SIZE(midi->in_ports); | ||
840 | jack_out_emb_desc.bJackID = jack++; | ||
841 | jack_out_emb_desc.bNrInputPins = midi->in_ports; | ||
842 | /* ... which referencess all external IN jacks */ | ||
843 | for (n = 0; n < midi->in_ports; n++) { | 810 | for (n = 0; n < midi->in_ports; n++) { |
844 | jack_out_emb_desc.pins[n].baSourceID = jack_in_ext_desc[n].bJackID; | 811 | struct usb_midi_in_jack_descriptor *in_ext = &jack_in_ext_desc[n]; |
845 | jack_out_emb_desc.pins[n].baSourcePin = 1; | 812 | struct usb_midi_out_jack_descriptor_1 *out_emb = &jack_out_emb_desc[n]; |
813 | |||
814 | in_ext->bLength = USB_DT_MIDI_IN_SIZE; | ||
815 | in_ext->bDescriptorType = USB_DT_CS_INTERFACE; | ||
816 | in_ext->bDescriptorSubtype = USB_MS_MIDI_IN_JACK; | ||
817 | in_ext->bJackType = USB_MS_EXTERNAL; | ||
818 | in_ext->bJackID = jack++; | ||
819 | in_ext->iJack = 0; | ||
820 | midi_function[i++] = (struct usb_descriptor_header *) in_ext; | ||
821 | |||
822 | out_emb->bLength = USB_DT_MIDI_OUT_SIZE(1); | ||
823 | out_emb->bDescriptorType = USB_DT_CS_INTERFACE; | ||
824 | out_emb->bDescriptorSubtype = USB_MS_MIDI_OUT_JACK; | ||
825 | out_emb->bJackType = USB_MS_EMBEDDED; | ||
826 | out_emb->bJackID = jack++; | ||
827 | out_emb->bNrInputPins = 1; | ||
828 | out_emb->pins[0].baSourcePin = 1; | ||
829 | out_emb->pins[0].baSourceID = in_ext->bJackID; | ||
830 | out_emb->iJack = 0; | ||
831 | midi_function[i++] = (struct usb_descriptor_header *) out_emb; | ||
832 | |||
833 | /* link it to the endpoint */ | ||
834 | ms_in_desc.baAssocJackID[n] = out_emb->bJackID; | ||
846 | } | 835 | } |
847 | 836 | ||
848 | midi_function[i++] = (struct usb_descriptor_header *) &jack_out_emb_desc; | 837 | /* configure the external OUT jacks, each linked to an embedded IN jack */ |
849 | |||
850 | /* and multiple external OUT jacks ... */ | ||
851 | for (n = 0; n < midi->out_ports; n++) { | 838 | for (n = 0; n < midi->out_ports; n++) { |
852 | struct usb_midi_out_jack_descriptor_1 *ext = &jack_out_ext_desc[n]; | 839 | struct usb_midi_in_jack_descriptor *in_emb = &jack_in_emb_desc[n]; |
853 | int m; | 840 | struct usb_midi_out_jack_descriptor_1 *out_ext = &jack_out_ext_desc[n]; |
854 | 841 | ||
855 | ext->bLength = USB_DT_MIDI_OUT_SIZE(1); | 842 | in_emb->bLength = USB_DT_MIDI_IN_SIZE; |
856 | ext->bDescriptorType = USB_DT_CS_INTERFACE; | 843 | in_emb->bDescriptorType = USB_DT_CS_INTERFACE; |
857 | ext->bDescriptorSubtype = USB_MS_MIDI_OUT_JACK; | 844 | in_emb->bDescriptorSubtype = USB_MS_MIDI_IN_JACK; |
858 | ext->bJackType = USB_MS_EXTERNAL; | 845 | in_emb->bJackType = USB_MS_EMBEDDED; |
859 | ext->bJackID = jack++; | 846 | in_emb->bJackID = jack++; |
860 | ext->bNrInputPins = 1; | 847 | in_emb->iJack = 0; |
861 | ext->iJack = 0; | 848 | midi_function[i++] = (struct usb_descriptor_header *) in_emb; |
862 | /* ... which all reference the same embedded IN jack */ | 849 | |
863 | for (m = 0; m < midi->out_ports; m++) { | 850 | out_ext->bLength = USB_DT_MIDI_OUT_SIZE(1); |
864 | ext->pins[m].baSourceID = jack_in_emb_desc.bJackID; | 851 | out_ext->bDescriptorType = USB_DT_CS_INTERFACE; |
865 | ext->pins[m].baSourcePin = 1; | 852 | out_ext->bDescriptorSubtype = USB_MS_MIDI_OUT_JACK; |
866 | } | 853 | out_ext->bJackType = USB_MS_EXTERNAL; |
867 | 854 | out_ext->bJackID = jack++; | |
868 | midi_function[i++] = (struct usb_descriptor_header *) ext; | 855 | out_ext->bNrInputPins = 1; |
856 | out_ext->iJack = 0; | ||
857 | out_ext->pins[0].baSourceID = in_emb->bJackID; | ||
858 | out_ext->pins[0].baSourcePin = 1; | ||
859 | midi_function[i++] = (struct usb_descriptor_header *) out_ext; | ||
860 | |||
861 | /* link it to the endpoint */ | ||
862 | ms_out_desc.baAssocJackID[n] = in_emb->bJackID; | ||
869 | } | 863 | } |
870 | 864 | ||
871 | /* configure the endpoint descriptors ... */ | 865 | /* configure the endpoint descriptors ... */ |
872 | ms_out_desc.bLength = USB_DT_MS_ENDPOINT_SIZE(midi->in_ports); | 866 | ms_out_desc.bLength = USB_DT_MS_ENDPOINT_SIZE(midi->in_ports); |
873 | ms_out_desc.bNumEmbMIDIJack = midi->in_ports; | 867 | ms_out_desc.bNumEmbMIDIJack = midi->in_ports; |
874 | for (n = 0; n < midi->in_ports; n++) | ||
875 | ms_out_desc.baAssocJackID[n] = jack_in_emb_desc.bJackID; | ||
876 | 868 | ||
877 | ms_in_desc.bLength = USB_DT_MS_ENDPOINT_SIZE(midi->out_ports); | 869 | ms_in_desc.bLength = USB_DT_MS_ENDPOINT_SIZE(midi->out_ports); |
878 | ms_in_desc.bNumEmbMIDIJack = midi->out_ports; | 870 | ms_in_desc.bNumEmbMIDIJack = midi->out_ports; |
879 | for (n = 0; n < midi->out_ports; n++) | ||
880 | ms_in_desc.baAssocJackID[n] = jack_out_emb_desc.bJackID; | ||
881 | 871 | ||
882 | /* ... and add them to the list */ | 872 | /* ... and add them to the list */ |
883 | midi_function[i++] = (struct usb_descriptor_header *) &bulk_out_desc; | 873 | midi_function[i++] = (struct usb_descriptor_header *) &bulk_out_desc; |
@@ -901,6 +891,8 @@ f_midi_bind(struct usb_configuration *c, struct usb_function *f) | |||
901 | f->descriptors = usb_copy_descriptors(midi_function); | 891 | f->descriptors = usb_copy_descriptors(midi_function); |
902 | } | 892 | } |
903 | 893 | ||
894 | kfree(midi_function); | ||
895 | |||
904 | return 0; | 896 | return 0; |
905 | 897 | ||
906 | fail: | 898 | fail: |
diff --git a/drivers/usb/gadget/file_storage.c b/drivers/usb/gadget/file_storage.c index f7e39b0365ce..11b5196284ae 100644 --- a/drivers/usb/gadget/file_storage.c +++ b/drivers/usb/gadget/file_storage.c | |||
@@ -859,7 +859,7 @@ static int class_setup_req(struct fsg_dev *fsg, | |||
859 | if (ctrl->bRequestType != (USB_DIR_OUT | | 859 | if (ctrl->bRequestType != (USB_DIR_OUT | |
860 | USB_TYPE_CLASS | USB_RECIP_INTERFACE)) | 860 | USB_TYPE_CLASS | USB_RECIP_INTERFACE)) |
861 | break; | 861 | break; |
862 | if (w_index != 0 || w_value != 0) { | 862 | if (w_index != 0 || w_value != 0 || w_length != 0) { |
863 | value = -EDOM; | 863 | value = -EDOM; |
864 | break; | 864 | break; |
865 | } | 865 | } |
@@ -875,7 +875,7 @@ static int class_setup_req(struct fsg_dev *fsg, | |||
875 | if (ctrl->bRequestType != (USB_DIR_IN | | 875 | if (ctrl->bRequestType != (USB_DIR_IN | |
876 | USB_TYPE_CLASS | USB_RECIP_INTERFACE)) | 876 | USB_TYPE_CLASS | USB_RECIP_INTERFACE)) |
877 | break; | 877 | break; |
878 | if (w_index != 0 || w_value != 0) { | 878 | if (w_index != 0 || w_value != 0 || w_length != 1) { |
879 | value = -EDOM; | 879 | value = -EDOM; |
880 | break; | 880 | break; |
881 | } | 881 | } |
diff --git a/drivers/usb/gadget/fsl_udc_core.c b/drivers/usb/gadget/fsl_udc_core.c index d786ba31fc07..b3b3d83b7c33 100644 --- a/drivers/usb/gadget/fsl_udc_core.c +++ b/drivers/usb/gadget/fsl_udc_core.c | |||
@@ -2480,8 +2480,7 @@ static int __init fsl_udc_probe(struct platform_device *pdev) | |||
2480 | 2480 | ||
2481 | #ifndef CONFIG_ARCH_MXC | 2481 | #ifndef CONFIG_ARCH_MXC |
2482 | if (pdata->have_sysif_regs) | 2482 | if (pdata->have_sysif_regs) |
2483 | usb_sys_regs = (struct usb_sys_interface *) | 2483 | usb_sys_regs = (void *)dr_regs + USB_DR_SYS_OFFSET; |
2484 | ((u32)dr_regs + USB_DR_SYS_OFFSET); | ||
2485 | #endif | 2484 | #endif |
2486 | 2485 | ||
2487 | /* Initialize USB clocks */ | 2486 | /* Initialize USB clocks */ |
diff --git a/drivers/usb/gadget/inode.c b/drivers/usb/gadget/inode.c index a392ec0d2d51..6ccae2707e59 100644 --- a/drivers/usb/gadget/inode.c +++ b/drivers/usb/gadget/inode.c | |||
@@ -1730,8 +1730,9 @@ static void | |||
1730 | gadgetfs_disconnect (struct usb_gadget *gadget) | 1730 | gadgetfs_disconnect (struct usb_gadget *gadget) |
1731 | { | 1731 | { |
1732 | struct dev_data *dev = get_gadget_data (gadget); | 1732 | struct dev_data *dev = get_gadget_data (gadget); |
1733 | unsigned long flags; | ||
1733 | 1734 | ||
1734 | spin_lock (&dev->lock); | 1735 | spin_lock_irqsave (&dev->lock, flags); |
1735 | if (dev->state == STATE_DEV_UNCONNECTED) | 1736 | if (dev->state == STATE_DEV_UNCONNECTED) |
1736 | goto exit; | 1737 | goto exit; |
1737 | dev->state = STATE_DEV_UNCONNECTED; | 1738 | dev->state = STATE_DEV_UNCONNECTED; |
@@ -1740,7 +1741,7 @@ gadgetfs_disconnect (struct usb_gadget *gadget) | |||
1740 | next_event (dev, GADGETFS_DISCONNECT); | 1741 | next_event (dev, GADGETFS_DISCONNECT); |
1741 | ep0_readable (dev); | 1742 | ep0_readable (dev); |
1742 | exit: | 1743 | exit: |
1743 | spin_unlock (&dev->lock); | 1744 | spin_unlock_irqrestore (&dev->lock, flags); |
1744 | } | 1745 | } |
1745 | 1746 | ||
1746 | static void | 1747 | static void |
diff --git a/drivers/usb/gadget/pch_udc.c b/drivers/usb/gadget/pch_udc.c index 550d6dcdf104..5048a0c07640 100644 --- a/drivers/usb/gadget/pch_udc.c +++ b/drivers/usb/gadget/pch_udc.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (C) 2010 OKI SEMICONDUCTOR CO., LTD. | 2 | * Copyright (C) 2011 LAPIS Semiconductor Co., Ltd. |
3 | * | 3 | * |
4 | * This program is free software; you can redistribute it and/or modify | 4 | * This program is free software; you can redistribute it and/or modify |
5 | * it under the terms of the GNU General Public License as published by | 5 | * it under the terms of the GNU General Public License as published by |
@@ -354,6 +354,7 @@ struct pch_udc_dev { | |||
354 | #define PCI_DEVICE_ID_INTEL_EG20T_UDC 0x8808 | 354 | #define PCI_DEVICE_ID_INTEL_EG20T_UDC 0x8808 |
355 | #define PCI_VENDOR_ID_ROHM 0x10DB | 355 | #define PCI_VENDOR_ID_ROHM 0x10DB |
356 | #define PCI_DEVICE_ID_ML7213_IOH_UDC 0x801D | 356 | #define PCI_DEVICE_ID_ML7213_IOH_UDC 0x801D |
357 | #define PCI_DEVICE_ID_ML7831_IOH_UDC 0x8808 | ||
357 | 358 | ||
358 | static const char ep0_string[] = "ep0in"; | 359 | static const char ep0_string[] = "ep0in"; |
359 | static DEFINE_SPINLOCK(udc_stall_spinlock); /* stall spin lock */ | 360 | static DEFINE_SPINLOCK(udc_stall_spinlock); /* stall spin lock */ |
@@ -2970,6 +2971,11 @@ static DEFINE_PCI_DEVICE_TABLE(pch_udc_pcidev_id) = { | |||
2970 | .class = (PCI_CLASS_SERIAL_USB << 8) | 0xfe, | 2971 | .class = (PCI_CLASS_SERIAL_USB << 8) | 0xfe, |
2971 | .class_mask = 0xffffffff, | 2972 | .class_mask = 0xffffffff, |
2972 | }, | 2973 | }, |
2974 | { | ||
2975 | PCI_DEVICE(PCI_VENDOR_ID_ROHM, PCI_DEVICE_ID_ML7831_IOH_UDC), | ||
2976 | .class = (PCI_CLASS_SERIAL_USB << 8) | 0xfe, | ||
2977 | .class_mask = 0xffffffff, | ||
2978 | }, | ||
2973 | { 0 }, | 2979 | { 0 }, |
2974 | }; | 2980 | }; |
2975 | 2981 | ||
@@ -2999,5 +3005,5 @@ static void __exit pch_udc_pci_exit(void) | |||
2999 | module_exit(pch_udc_pci_exit); | 3005 | module_exit(pch_udc_pci_exit); |
3000 | 3006 | ||
3001 | MODULE_DESCRIPTION("Intel EG20T USB Device Controller"); | 3007 | MODULE_DESCRIPTION("Intel EG20T USB Device Controller"); |
3002 | MODULE_AUTHOR("OKI SEMICONDUCTOR, <toshiharu-linux@dsn.okisemi.com>"); | 3008 | MODULE_AUTHOR("LAPIS Semiconductor, <tomoya-linux@dsn.lapis-semi.com>"); |
3003 | MODULE_LICENSE("GPL"); | 3009 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/usb/gadget/r8a66597-udc.c b/drivers/usb/gadget/r8a66597-udc.c index 68a826a1b866..24f84b210ce1 100644 --- a/drivers/usb/gadget/r8a66597-udc.c +++ b/drivers/usb/gadget/r8a66597-udc.c | |||
@@ -1718,6 +1718,8 @@ static void r8a66597_fifo_flush(struct usb_ep *_ep) | |||
1718 | if (list_empty(&ep->queue) && !ep->busy) { | 1718 | if (list_empty(&ep->queue) && !ep->busy) { |
1719 | pipe_stop(ep->r8a66597, ep->pipenum); | 1719 | pipe_stop(ep->r8a66597, ep->pipenum); |
1720 | r8a66597_bclr(ep->r8a66597, BCLR, ep->fifoctr); | 1720 | r8a66597_bclr(ep->r8a66597, BCLR, ep->fifoctr); |
1721 | r8a66597_write(ep->r8a66597, ACLRM, ep->pipectr); | ||
1722 | r8a66597_write(ep->r8a66597, 0, ep->pipectr); | ||
1721 | } | 1723 | } |
1722 | spin_unlock_irqrestore(&ep->r8a66597->lock, flags); | 1724 | spin_unlock_irqrestore(&ep->r8a66597->lock, flags); |
1723 | } | 1725 | } |
@@ -1742,7 +1744,6 @@ static int r8a66597_start(struct usb_gadget *gadget, | |||
1742 | struct usb_gadget_driver *driver) | 1744 | struct usb_gadget_driver *driver) |
1743 | { | 1745 | { |
1744 | struct r8a66597 *r8a66597 = gadget_to_r8a66597(gadget); | 1746 | struct r8a66597 *r8a66597 = gadget_to_r8a66597(gadget); |
1745 | int retval; | ||
1746 | 1747 | ||
1747 | if (!driver | 1748 | if (!driver |
1748 | || driver->speed != USB_SPEED_HIGH | 1749 | || driver->speed != USB_SPEED_HIGH |
@@ -1752,16 +1753,7 @@ static int r8a66597_start(struct usb_gadget *gadget, | |||
1752 | return -ENODEV; | 1753 | return -ENODEV; |
1753 | 1754 | ||
1754 | /* hook up the driver */ | 1755 | /* hook up the driver */ |
1755 | driver->driver.bus = NULL; | ||
1756 | r8a66597->driver = driver; | 1756 | r8a66597->driver = driver; |
1757 | r8a66597->gadget.dev.driver = &driver->driver; | ||
1758 | |||
1759 | retval = device_add(&r8a66597->gadget.dev); | ||
1760 | if (retval) { | ||
1761 | dev_err(r8a66597_to_dev(r8a66597), "device_add error (%d)\n", | ||
1762 | retval); | ||
1763 | goto error; | ||
1764 | } | ||
1765 | 1757 | ||
1766 | init_controller(r8a66597); | 1758 | init_controller(r8a66597); |
1767 | r8a66597_bset(r8a66597, VBSE, INTENB0); | 1759 | r8a66597_bset(r8a66597, VBSE, INTENB0); |
@@ -1775,12 +1767,6 @@ static int r8a66597_start(struct usb_gadget *gadget, | |||
1775 | } | 1767 | } |
1776 | 1768 | ||
1777 | return 0; | 1769 | return 0; |
1778 | |||
1779 | error: | ||
1780 | r8a66597->driver = NULL; | ||
1781 | r8a66597->gadget.dev.driver = NULL; | ||
1782 | |||
1783 | return retval; | ||
1784 | } | 1770 | } |
1785 | 1771 | ||
1786 | static int r8a66597_stop(struct usb_gadget *gadget, | 1772 | static int r8a66597_stop(struct usb_gadget *gadget, |
@@ -1794,7 +1780,6 @@ static int r8a66597_stop(struct usb_gadget *gadget, | |||
1794 | disable_controller(r8a66597); | 1780 | disable_controller(r8a66597); |
1795 | spin_unlock_irqrestore(&r8a66597->lock, flags); | 1781 | spin_unlock_irqrestore(&r8a66597->lock, flags); |
1796 | 1782 | ||
1797 | device_del(&r8a66597->gadget.dev); | ||
1798 | r8a66597->driver = NULL; | 1783 | r8a66597->driver = NULL; |
1799 | return 0; | 1784 | return 0; |
1800 | } | 1785 | } |
@@ -1845,6 +1830,7 @@ static int __exit r8a66597_remove(struct platform_device *pdev) | |||
1845 | clk_put(r8a66597->clk); | 1830 | clk_put(r8a66597->clk); |
1846 | } | 1831 | } |
1847 | #endif | 1832 | #endif |
1833 | device_unregister(&r8a66597->gadget.dev); | ||
1848 | kfree(r8a66597); | 1834 | kfree(r8a66597); |
1849 | return 0; | 1835 | return 0; |
1850 | } | 1836 | } |
@@ -1924,13 +1910,17 @@ static int __init r8a66597_probe(struct platform_device *pdev) | |||
1924 | r8a66597->irq_sense_low = irq_trigger == IRQF_TRIGGER_LOW; | 1910 | r8a66597->irq_sense_low = irq_trigger == IRQF_TRIGGER_LOW; |
1925 | 1911 | ||
1926 | r8a66597->gadget.ops = &r8a66597_gadget_ops; | 1912 | r8a66597->gadget.ops = &r8a66597_gadget_ops; |
1927 | device_initialize(&r8a66597->gadget.dev); | ||
1928 | dev_set_name(&r8a66597->gadget.dev, "gadget"); | 1913 | dev_set_name(&r8a66597->gadget.dev, "gadget"); |
1929 | r8a66597->gadget.is_dualspeed = 1; | 1914 | r8a66597->gadget.is_dualspeed = 1; |
1930 | r8a66597->gadget.dev.parent = &pdev->dev; | 1915 | r8a66597->gadget.dev.parent = &pdev->dev; |
1931 | r8a66597->gadget.dev.dma_mask = pdev->dev.dma_mask; | 1916 | r8a66597->gadget.dev.dma_mask = pdev->dev.dma_mask; |
1932 | r8a66597->gadget.dev.release = pdev->dev.release; | 1917 | r8a66597->gadget.dev.release = pdev->dev.release; |
1933 | r8a66597->gadget.name = udc_name; | 1918 | r8a66597->gadget.name = udc_name; |
1919 | ret = device_register(&r8a66597->gadget.dev); | ||
1920 | if (ret < 0) { | ||
1921 | dev_err(&pdev->dev, "device_register failed\n"); | ||
1922 | goto clean_up; | ||
1923 | } | ||
1934 | 1924 | ||
1935 | init_timer(&r8a66597->timer); | 1925 | init_timer(&r8a66597->timer); |
1936 | r8a66597->timer.function = r8a66597_timer; | 1926 | r8a66597->timer.function = r8a66597_timer; |
@@ -1945,7 +1935,7 @@ static int __init r8a66597_probe(struct platform_device *pdev) | |||
1945 | dev_err(&pdev->dev, "cannot get clock \"%s\"\n", | 1935 | dev_err(&pdev->dev, "cannot get clock \"%s\"\n", |
1946 | clk_name); | 1936 | clk_name); |
1947 | ret = PTR_ERR(r8a66597->clk); | 1937 | ret = PTR_ERR(r8a66597->clk); |
1948 | goto clean_up; | 1938 | goto clean_up_dev; |
1949 | } | 1939 | } |
1950 | clk_enable(r8a66597->clk); | 1940 | clk_enable(r8a66597->clk); |
1951 | } | 1941 | } |
@@ -2014,7 +2004,9 @@ clean_up2: | |||
2014 | clk_disable(r8a66597->clk); | 2004 | clk_disable(r8a66597->clk); |
2015 | clk_put(r8a66597->clk); | 2005 | clk_put(r8a66597->clk); |
2016 | } | 2006 | } |
2007 | clean_up_dev: | ||
2017 | #endif | 2008 | #endif |
2009 | device_unregister(&r8a66597->gadget.dev); | ||
2018 | clean_up: | 2010 | clean_up: |
2019 | if (r8a66597) { | 2011 | if (r8a66597) { |
2020 | if (r8a66597->sudmac_reg) | 2012 | if (r8a66597->sudmac_reg) |
diff --git a/drivers/usb/gadget/udc-core.c b/drivers/usb/gadget/udc-core.c index 022baeca7c94..6939e17f4580 100644 --- a/drivers/usb/gadget/udc-core.c +++ b/drivers/usb/gadget/udc-core.c | |||
@@ -210,10 +210,10 @@ static void usb_gadget_remove_driver(struct usb_udc *udc) | |||
210 | kobject_uevent(&udc->dev.kobj, KOBJ_CHANGE); | 210 | kobject_uevent(&udc->dev.kobj, KOBJ_CHANGE); |
211 | 211 | ||
212 | if (udc_is_newstyle(udc)) { | 212 | if (udc_is_newstyle(udc)) { |
213 | usb_gadget_disconnect(udc->gadget); | 213 | udc->driver->disconnect(udc->gadget); |
214 | udc->driver->unbind(udc->gadget); | 214 | udc->driver->unbind(udc->gadget); |
215 | usb_gadget_udc_stop(udc->gadget, udc->driver); | 215 | usb_gadget_udc_stop(udc->gadget, udc->driver); |
216 | 216 | usb_gadget_disconnect(udc->gadget); | |
217 | } else { | 217 | } else { |
218 | usb_gadget_stop(udc->gadget, udc->driver); | 218 | usb_gadget_stop(udc->gadget, udc->driver); |
219 | } | 219 | } |
@@ -344,7 +344,7 @@ EXPORT_SYMBOL_GPL(usb_gadget_unregister_driver); | |||
344 | static ssize_t usb_udc_srp_store(struct device *dev, | 344 | static ssize_t usb_udc_srp_store(struct device *dev, |
345 | struct device_attribute *attr, const char *buf, size_t n) | 345 | struct device_attribute *attr, const char *buf, size_t n) |
346 | { | 346 | { |
347 | struct usb_udc *udc = dev_get_drvdata(dev); | 347 | struct usb_udc *udc = container_of(dev, struct usb_udc, dev); |
348 | 348 | ||
349 | if (sysfs_streq(buf, "1")) | 349 | if (sysfs_streq(buf, "1")) |
350 | usb_gadget_wakeup(udc->gadget); | 350 | usb_gadget_wakeup(udc->gadget); |
@@ -378,7 +378,7 @@ static ssize_t usb_udc_speed_show(struct device *dev, | |||
378 | return snprintf(buf, PAGE_SIZE, "%s\n", | 378 | return snprintf(buf, PAGE_SIZE, "%s\n", |
379 | usb_speed_string(udc->gadget->speed)); | 379 | usb_speed_string(udc->gadget->speed)); |
380 | } | 380 | } |
381 | static DEVICE_ATTR(speed, S_IRUSR, usb_udc_speed_show, NULL); | 381 | static DEVICE_ATTR(speed, S_IRUGO, usb_udc_speed_show, NULL); |
382 | 382 | ||
383 | #define USB_UDC_ATTR(name) \ | 383 | #define USB_UDC_ATTR(name) \ |
384 | ssize_t usb_udc_##name##_show(struct device *dev, \ | 384 | ssize_t usb_udc_##name##_show(struct device *dev, \ |
@@ -389,7 +389,7 @@ ssize_t usb_udc_##name##_show(struct device *dev, \ | |||
389 | \ | 389 | \ |
390 | return snprintf(buf, PAGE_SIZE, "%d\n", gadget->name); \ | 390 | return snprintf(buf, PAGE_SIZE, "%d\n", gadget->name); \ |
391 | } \ | 391 | } \ |
392 | static DEVICE_ATTR(name, S_IRUSR, usb_udc_##name##_show, NULL) | 392 | static DEVICE_ATTR(name, S_IRUGO, usb_udc_##name##_show, NULL) |
393 | 393 | ||
394 | static USB_UDC_ATTR(is_dualspeed); | 394 | static USB_UDC_ATTR(is_dualspeed); |
395 | static USB_UDC_ATTR(is_otg); | 395 | static USB_UDC_ATTR(is_otg); |
diff --git a/drivers/usb/host/ehci-sched.c b/drivers/usb/host/ehci-sched.c index 2e829fae6482..56a32033adb3 100644 --- a/drivers/usb/host/ehci-sched.c +++ b/drivers/usb/host/ehci-sched.c | |||
@@ -1479,10 +1479,15 @@ iso_stream_schedule ( | |||
1479 | 1479 | ||
1480 | /* NOTE: assumes URB_ISO_ASAP, to limit complexity/bugs */ | 1480 | /* NOTE: assumes URB_ISO_ASAP, to limit complexity/bugs */ |
1481 | 1481 | ||
1482 | /* find a uframe slot with enough bandwidth */ | 1482 | /* find a uframe slot with enough bandwidth. |
1483 | next = start + period; | 1483 | * Early uframes are more precious because full-speed |
1484 | for (; start < next; start++) { | 1484 | * iso IN transfers can't use late uframes, |
1485 | 1485 | * and therefore they should be allocated last. | |
1486 | */ | ||
1487 | next = start; | ||
1488 | start += period; | ||
1489 | do { | ||
1490 | start--; | ||
1486 | /* check schedule: enough space? */ | 1491 | /* check schedule: enough space? */ |
1487 | if (stream->highspeed) { | 1492 | if (stream->highspeed) { |
1488 | if (itd_slot_ok(ehci, mod, start, | 1493 | if (itd_slot_ok(ehci, mod, start, |
@@ -1495,7 +1500,7 @@ iso_stream_schedule ( | |||
1495 | start, sched, period)) | 1500 | start, sched, period)) |
1496 | break; | 1501 | break; |
1497 | } | 1502 | } |
1498 | } | 1503 | } while (start > next); |
1499 | 1504 | ||
1500 | /* no room in the schedule */ | 1505 | /* no room in the schedule */ |
1501 | if (start == next) { | 1506 | if (start == next) { |
diff --git a/drivers/usb/host/ehci-xls.c b/drivers/usb/host/ehci-xls.c index fe74bd676018..b4fb511d24bc 100644 --- a/drivers/usb/host/ehci-xls.c +++ b/drivers/usb/host/ehci-xls.c | |||
@@ -19,7 +19,7 @@ static int ehci_xls_setup(struct usb_hcd *hcd) | |||
19 | 19 | ||
20 | ehci->caps = hcd->regs; | 20 | ehci->caps = hcd->regs; |
21 | ehci->regs = hcd->regs + | 21 | ehci->regs = hcd->regs + |
22 | HC_LENGTH(ehci_readl(ehci, &ehci->caps->hc_capbase)); | 22 | HC_LENGTH(ehci, ehci_readl(ehci, &ehci->caps->hc_capbase)); |
23 | dbg_hcs_params(ehci, "reset"); | 23 | dbg_hcs_params(ehci, "reset"); |
24 | dbg_hcc_params(ehci, "reset"); | 24 | dbg_hcc_params(ehci, "reset"); |
25 | 25 | ||
diff --git a/drivers/usb/host/ohci-at91.c b/drivers/usb/host/ohci-at91.c index ba3a46b78b75..95a9fec38e89 100644 --- a/drivers/usb/host/ohci-at91.c +++ b/drivers/usb/host/ohci-at91.c | |||
@@ -223,6 +223,9 @@ static void ohci_at91_usb_set_power(struct at91_usbh_data *pdata, int port, int | |||
223 | if (port < 0 || port >= 2) | 223 | if (port < 0 || port >= 2) |
224 | return; | 224 | return; |
225 | 225 | ||
226 | if (pdata->vbus_pin[port] <= 0) | ||
227 | return; | ||
228 | |||
226 | gpio_set_value(pdata->vbus_pin[port], !pdata->vbus_pin_inverted ^ enable); | 229 | gpio_set_value(pdata->vbus_pin[port], !pdata->vbus_pin_inverted ^ enable); |
227 | } | 230 | } |
228 | 231 | ||
@@ -231,6 +234,9 @@ static int ohci_at91_usb_get_power(struct at91_usbh_data *pdata, int port) | |||
231 | if (port < 0 || port >= 2) | 234 | if (port < 0 || port >= 2) |
232 | return -EINVAL; | 235 | return -EINVAL; |
233 | 236 | ||
237 | if (pdata->vbus_pin[port] <= 0) | ||
238 | return -EINVAL; | ||
239 | |||
234 | return gpio_get_value(pdata->vbus_pin[port]) ^ !pdata->vbus_pin_inverted; | 240 | return gpio_get_value(pdata->vbus_pin[port]) ^ !pdata->vbus_pin_inverted; |
235 | } | 241 | } |
236 | 242 | ||
diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c index 34efd479e068..b2639191549e 100644 --- a/drivers/usb/host/ohci-hcd.c +++ b/drivers/usb/host/ohci-hcd.c | |||
@@ -389,17 +389,14 @@ ohci_shutdown (struct usb_hcd *hcd) | |||
389 | struct ohci_hcd *ohci; | 389 | struct ohci_hcd *ohci; |
390 | 390 | ||
391 | ohci = hcd_to_ohci (hcd); | 391 | ohci = hcd_to_ohci (hcd); |
392 | ohci_writel (ohci, OHCI_INTR_MIE, &ohci->regs->intrdisable); | 392 | ohci_writel(ohci, (u32) ~0, &ohci->regs->intrdisable); |
393 | ohci->hc_control = ohci_readl(ohci, &ohci->regs->control); | ||
394 | 393 | ||
395 | /* If the SHUTDOWN quirk is set, don't put the controller in RESET */ | 394 | /* Software reset, after which the controller goes into SUSPEND */ |
396 | ohci->hc_control &= (ohci->flags & OHCI_QUIRK_SHUTDOWN ? | 395 | ohci_writel(ohci, OHCI_HCR, &ohci->regs->cmdstatus); |
397 | OHCI_CTRL_RWC | OHCI_CTRL_HCFS : | 396 | ohci_readl(ohci, &ohci->regs->cmdstatus); /* flush the writes */ |
398 | OHCI_CTRL_RWC); | 397 | udelay(10); |
399 | ohci_writel(ohci, ohci->hc_control, &ohci->regs->control); | ||
400 | 398 | ||
401 | /* flush the writes */ | 399 | ohci_writel(ohci, ohci->fminterval, &ohci->regs->fminterval); |
402 | (void) ohci_readl (ohci, &ohci->regs->control); | ||
403 | } | 400 | } |
404 | 401 | ||
405 | static int check_ed(struct ohci_hcd *ohci, struct ed *ed) | 402 | static int check_ed(struct ohci_hcd *ohci, struct ed *ed) |
diff --git a/drivers/usb/host/ohci-pci.c b/drivers/usb/host/ohci-pci.c index ad8166c681e2..bc01b064585a 100644 --- a/drivers/usb/host/ohci-pci.c +++ b/drivers/usb/host/ohci-pci.c | |||
@@ -175,28 +175,6 @@ static int ohci_quirk_amd700(struct usb_hcd *hcd) | |||
175 | return 0; | 175 | return 0; |
176 | } | 176 | } |
177 | 177 | ||
178 | /* nVidia controllers continue to drive Reset signalling on the bus | ||
179 | * even after system shutdown, wasting power. This flag tells the | ||
180 | * shutdown routine to leave the controller OPERATIONAL instead of RESET. | ||
181 | */ | ||
182 | static int ohci_quirk_nvidia_shutdown(struct usb_hcd *hcd) | ||
183 | { | ||
184 | struct pci_dev *pdev = to_pci_dev(hcd->self.controller); | ||
185 | struct ohci_hcd *ohci = hcd_to_ohci(hcd); | ||
186 | |||
187 | /* Evidently nVidia fixed their later hardware; this is a guess at | ||
188 | * the changeover point. | ||
189 | */ | ||
190 | #define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP51_USB 0x026d | ||
191 | |||
192 | if (pdev->device < PCI_DEVICE_ID_NVIDIA_NFORCE_MCP51_USB) { | ||
193 | ohci->flags |= OHCI_QUIRK_SHUTDOWN; | ||
194 | ohci_dbg(ohci, "enabled nVidia shutdown quirk\n"); | ||
195 | } | ||
196 | |||
197 | return 0; | ||
198 | } | ||
199 | |||
200 | static void sb800_prefetch(struct ohci_hcd *ohci, int on) | 178 | static void sb800_prefetch(struct ohci_hcd *ohci, int on) |
201 | { | 179 | { |
202 | struct pci_dev *pdev; | 180 | struct pci_dev *pdev; |
@@ -260,10 +238,6 @@ static const struct pci_device_id ohci_pci_quirks[] = { | |||
260 | PCI_DEVICE(PCI_VENDOR_ID_ATI, 0x4399), | 238 | PCI_DEVICE(PCI_VENDOR_ID_ATI, 0x4399), |
261 | .driver_data = (unsigned long)ohci_quirk_amd700, | 239 | .driver_data = (unsigned long)ohci_quirk_amd700, |
262 | }, | 240 | }, |
263 | { | ||
264 | PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_ANY_ID), | ||
265 | .driver_data = (unsigned long) ohci_quirk_nvidia_shutdown, | ||
266 | }, | ||
267 | 241 | ||
268 | /* FIXME for some of the early AMD 760 southbridges, OHCI | 242 | /* FIXME for some of the early AMD 760 southbridges, OHCI |
269 | * won't work at all. blacklist them. | 243 | * won't work at all. blacklist them. |
diff --git a/drivers/usb/host/ohci.h b/drivers/usb/host/ohci.h index 35e5fd640ce7..0795b934d00c 100644 --- a/drivers/usb/host/ohci.h +++ b/drivers/usb/host/ohci.h | |||
@@ -403,7 +403,6 @@ struct ohci_hcd { | |||
403 | #define OHCI_QUIRK_HUB_POWER 0x100 /* distrust firmware power/oc setup */ | 403 | #define OHCI_QUIRK_HUB_POWER 0x100 /* distrust firmware power/oc setup */ |
404 | #define OHCI_QUIRK_AMD_PLL 0x200 /* AMD PLL quirk*/ | 404 | #define OHCI_QUIRK_AMD_PLL 0x200 /* AMD PLL quirk*/ |
405 | #define OHCI_QUIRK_AMD_PREFETCH 0x400 /* pre-fetch for ISO transfer */ | 405 | #define OHCI_QUIRK_AMD_PREFETCH 0x400 /* pre-fetch for ISO transfer */ |
406 | #define OHCI_QUIRK_SHUTDOWN 0x800 /* nVidia power bug */ | ||
407 | // there are also chip quirks/bugs in init logic | 406 | // there are also chip quirks/bugs in init logic |
408 | 407 | ||
409 | struct work_struct nec_work; /* Worker for NEC quirk */ | 408 | struct work_struct nec_work; /* Worker for NEC quirk */ |
diff --git a/drivers/usb/host/pci-quirks.c b/drivers/usb/host/pci-quirks.c index 27a3dec32fa2..caf87428ca43 100644 --- a/drivers/usb/host/pci-quirks.c +++ b/drivers/usb/host/pci-quirks.c | |||
@@ -37,6 +37,7 @@ | |||
37 | #define OHCI_INTRENABLE 0x10 | 37 | #define OHCI_INTRENABLE 0x10 |
38 | #define OHCI_INTRDISABLE 0x14 | 38 | #define OHCI_INTRDISABLE 0x14 |
39 | #define OHCI_FMINTERVAL 0x34 | 39 | #define OHCI_FMINTERVAL 0x34 |
40 | #define OHCI_HCFS (3 << 6) /* hc functional state */ | ||
40 | #define OHCI_HCR (1 << 0) /* host controller reset */ | 41 | #define OHCI_HCR (1 << 0) /* host controller reset */ |
41 | #define OHCI_OCR (1 << 3) /* ownership change request */ | 42 | #define OHCI_OCR (1 << 3) /* ownership change request */ |
42 | #define OHCI_CTRL_RWC (1 << 9) /* remote wakeup connected */ | 43 | #define OHCI_CTRL_RWC (1 << 9) /* remote wakeup connected */ |
@@ -466,6 +467,8 @@ static void __devinit quirk_usb_handoff_ohci(struct pci_dev *pdev) | |||
466 | { | 467 | { |
467 | void __iomem *base; | 468 | void __iomem *base; |
468 | u32 control; | 469 | u32 control; |
470 | u32 fminterval; | ||
471 | int cnt; | ||
469 | 472 | ||
470 | if (!mmio_resource_enabled(pdev, 0)) | 473 | if (!mmio_resource_enabled(pdev, 0)) |
471 | return; | 474 | return; |
@@ -498,41 +501,32 @@ static void __devinit quirk_usb_handoff_ohci(struct pci_dev *pdev) | |||
498 | } | 501 | } |
499 | #endif | 502 | #endif |
500 | 503 | ||
501 | /* reset controller, preserving RWC (and possibly IR) */ | 504 | /* disable interrupts */ |
502 | writel(control & OHCI_CTRL_MASK, base + OHCI_CONTROL); | 505 | writel((u32) ~0, base + OHCI_INTRDISABLE); |
503 | readl(base + OHCI_CONTROL); | ||
504 | 506 | ||
505 | /* Some NVIDIA controllers stop working if kept in RESET for too long */ | 507 | /* Reset the USB bus, if the controller isn't already in RESET */ |
506 | if (pdev->vendor == PCI_VENDOR_ID_NVIDIA) { | 508 | if (control & OHCI_HCFS) { |
507 | u32 fminterval; | 509 | /* Go into RESET, preserving RWC (and possibly IR) */ |
508 | int cnt; | 510 | writel(control & OHCI_CTRL_MASK, base + OHCI_CONTROL); |
511 | readl(base + OHCI_CONTROL); | ||
509 | 512 | ||
510 | /* drive reset for at least 50 ms (7.1.7.5) */ | 513 | /* drive bus reset for at least 50 ms (7.1.7.5) */ |
511 | msleep(50); | 514 | msleep(50); |
515 | } | ||
512 | 516 | ||
513 | /* software reset of the controller, preserving HcFmInterval */ | 517 | /* software reset of the controller, preserving HcFmInterval */ |
514 | fminterval = readl(base + OHCI_FMINTERVAL); | 518 | fminterval = readl(base + OHCI_FMINTERVAL); |
515 | writel(OHCI_HCR, base + OHCI_CMDSTATUS); | 519 | writel(OHCI_HCR, base + OHCI_CMDSTATUS); |
516 | 520 | ||
517 | /* reset requires max 10 us delay */ | 521 | /* reset requires max 10 us delay */ |
518 | for (cnt = 30; cnt > 0; --cnt) { /* ... allow extra time */ | 522 | for (cnt = 30; cnt > 0; --cnt) { /* ... allow extra time */ |
519 | if ((readl(base + OHCI_CMDSTATUS) & OHCI_HCR) == 0) | 523 | if ((readl(base + OHCI_CMDSTATUS) & OHCI_HCR) == 0) |
520 | break; | 524 | break; |
521 | udelay(1); | 525 | udelay(1); |
522 | } | ||
523 | writel(fminterval, base + OHCI_FMINTERVAL); | ||
524 | |||
525 | /* Now we're in the SUSPEND state with all devices reset | ||
526 | * and wakeups and interrupts disabled | ||
527 | */ | ||
528 | } | 526 | } |
527 | writel(fminterval, base + OHCI_FMINTERVAL); | ||
529 | 528 | ||
530 | /* | 529 | /* Now the controller is safely in SUSPEND and nothing can wake it up */ |
531 | * disable interrupts | ||
532 | */ | ||
533 | writel(~(u32)0, base + OHCI_INTRDISABLE); | ||
534 | writel(~(u32)0, base + OHCI_INTRSTATUS); | ||
535 | |||
536 | iounmap(base); | 530 | iounmap(base); |
537 | } | 531 | } |
538 | 532 | ||
@@ -627,7 +621,7 @@ static void __devinit quirk_usb_disable_ehci(struct pci_dev *pdev) | |||
627 | void __iomem *base, *op_reg_base; | 621 | void __iomem *base, *op_reg_base; |
628 | u32 hcc_params, cap, val; | 622 | u32 hcc_params, cap, val; |
629 | u8 offset, cap_length; | 623 | u8 offset, cap_length; |
630 | int wait_time, delta, count = 256/4; | 624 | int wait_time, count = 256/4; |
631 | 625 | ||
632 | if (!mmio_resource_enabled(pdev, 0)) | 626 | if (!mmio_resource_enabled(pdev, 0)) |
633 | return; | 627 | return; |
@@ -673,11 +667,10 @@ static void __devinit quirk_usb_disable_ehci(struct pci_dev *pdev) | |||
673 | writel(val, op_reg_base + EHCI_USBCMD); | 667 | writel(val, op_reg_base + EHCI_USBCMD); |
674 | 668 | ||
675 | wait_time = 2000; | 669 | wait_time = 2000; |
676 | delta = 100; | ||
677 | do { | 670 | do { |
678 | writel(0x3f, op_reg_base + EHCI_USBSTS); | 671 | writel(0x3f, op_reg_base + EHCI_USBSTS); |
679 | udelay(delta); | 672 | udelay(100); |
680 | wait_time -= delta; | 673 | wait_time -= 100; |
681 | val = readl(op_reg_base + EHCI_USBSTS); | 674 | val = readl(op_reg_base + EHCI_USBSTS); |
682 | if ((val == ~(u32)0) || (val & EHCI_USBSTS_HALTED)) { | 675 | if ((val == ~(u32)0) || (val & EHCI_USBSTS_HALTED)) { |
683 | break; | 676 | break; |
diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c index 42a22b8e6922..0e4b25fa3bcd 100644 --- a/drivers/usb/host/xhci-mem.c +++ b/drivers/usb/host/xhci-mem.c | |||
@@ -982,7 +982,6 @@ int xhci_setup_addressable_virt_dev(struct xhci_hcd *xhci, struct usb_device *ud | |||
982 | struct xhci_virt_device *dev; | 982 | struct xhci_virt_device *dev; |
983 | struct xhci_ep_ctx *ep0_ctx; | 983 | struct xhci_ep_ctx *ep0_ctx; |
984 | struct xhci_slot_ctx *slot_ctx; | 984 | struct xhci_slot_ctx *slot_ctx; |
985 | struct xhci_input_control_ctx *ctrl_ctx; | ||
986 | u32 port_num; | 985 | u32 port_num; |
987 | struct usb_device *top_dev; | 986 | struct usb_device *top_dev; |
988 | 987 | ||
@@ -994,12 +993,8 @@ int xhci_setup_addressable_virt_dev(struct xhci_hcd *xhci, struct usb_device *ud | |||
994 | return -EINVAL; | 993 | return -EINVAL; |
995 | } | 994 | } |
996 | ep0_ctx = xhci_get_ep_ctx(xhci, dev->in_ctx, 0); | 995 | ep0_ctx = xhci_get_ep_ctx(xhci, dev->in_ctx, 0); |
997 | ctrl_ctx = xhci_get_input_control_ctx(xhci, dev->in_ctx); | ||
998 | slot_ctx = xhci_get_slot_ctx(xhci, dev->in_ctx); | 996 | slot_ctx = xhci_get_slot_ctx(xhci, dev->in_ctx); |
999 | 997 | ||
1000 | /* 2) New slot context and endpoint 0 context are valid*/ | ||
1001 | ctrl_ctx->add_flags = cpu_to_le32(SLOT_FLAG | EP0_FLAG); | ||
1002 | |||
1003 | /* 3) Only the control endpoint is valid - one endpoint context */ | 998 | /* 3) Only the control endpoint is valid - one endpoint context */ |
1004 | slot_ctx->dev_info |= cpu_to_le32(LAST_CTX(1) | udev->route); | 999 | slot_ctx->dev_info |= cpu_to_le32(LAST_CTX(1) | udev->route); |
1005 | switch (udev->speed) { | 1000 | switch (udev->speed) { |
diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c index 940321b3ec68..9f1d4b15d818 100644 --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c | |||
@@ -816,23 +816,24 @@ void xhci_stop_endpoint_command_watchdog(unsigned long arg) | |||
816 | struct xhci_ring *ring; | 816 | struct xhci_ring *ring; |
817 | struct xhci_td *cur_td; | 817 | struct xhci_td *cur_td; |
818 | int ret, i, j; | 818 | int ret, i, j; |
819 | unsigned long flags; | ||
819 | 820 | ||
820 | ep = (struct xhci_virt_ep *) arg; | 821 | ep = (struct xhci_virt_ep *) arg; |
821 | xhci = ep->xhci; | 822 | xhci = ep->xhci; |
822 | 823 | ||
823 | spin_lock(&xhci->lock); | 824 | spin_lock_irqsave(&xhci->lock, flags); |
824 | 825 | ||
825 | ep->stop_cmds_pending--; | 826 | ep->stop_cmds_pending--; |
826 | if (xhci->xhc_state & XHCI_STATE_DYING) { | 827 | if (xhci->xhc_state & XHCI_STATE_DYING) { |
827 | xhci_dbg(xhci, "Stop EP timer ran, but another timer marked " | 828 | xhci_dbg(xhci, "Stop EP timer ran, but another timer marked " |
828 | "xHCI as DYING, exiting.\n"); | 829 | "xHCI as DYING, exiting.\n"); |
829 | spin_unlock(&xhci->lock); | 830 | spin_unlock_irqrestore(&xhci->lock, flags); |
830 | return; | 831 | return; |
831 | } | 832 | } |
832 | if (!(ep->stop_cmds_pending == 0 && (ep->ep_state & EP_HALT_PENDING))) { | 833 | if (!(ep->stop_cmds_pending == 0 && (ep->ep_state & EP_HALT_PENDING))) { |
833 | xhci_dbg(xhci, "Stop EP timer ran, but no command pending, " | 834 | xhci_dbg(xhci, "Stop EP timer ran, but no command pending, " |
834 | "exiting.\n"); | 835 | "exiting.\n"); |
835 | spin_unlock(&xhci->lock); | 836 | spin_unlock_irqrestore(&xhci->lock, flags); |
836 | return; | 837 | return; |
837 | } | 838 | } |
838 | 839 | ||
@@ -844,11 +845,11 @@ void xhci_stop_endpoint_command_watchdog(unsigned long arg) | |||
844 | xhci->xhc_state |= XHCI_STATE_DYING; | 845 | xhci->xhc_state |= XHCI_STATE_DYING; |
845 | /* Disable interrupts from the host controller and start halting it */ | 846 | /* Disable interrupts from the host controller and start halting it */ |
846 | xhci_quiesce(xhci); | 847 | xhci_quiesce(xhci); |
847 | spin_unlock(&xhci->lock); | 848 | spin_unlock_irqrestore(&xhci->lock, flags); |
848 | 849 | ||
849 | ret = xhci_halt(xhci); | 850 | ret = xhci_halt(xhci); |
850 | 851 | ||
851 | spin_lock(&xhci->lock); | 852 | spin_lock_irqsave(&xhci->lock, flags); |
852 | if (ret < 0) { | 853 | if (ret < 0) { |
853 | /* This is bad; the host is not responding to commands and it's | 854 | /* This is bad; the host is not responding to commands and it's |
854 | * not allowing itself to be halted. At least interrupts are | 855 | * not allowing itself to be halted. At least interrupts are |
@@ -896,7 +897,7 @@ void xhci_stop_endpoint_command_watchdog(unsigned long arg) | |||
896 | } | 897 | } |
897 | } | 898 | } |
898 | } | 899 | } |
899 | spin_unlock(&xhci->lock); | 900 | spin_unlock_irqrestore(&xhci->lock, flags); |
900 | xhci_dbg(xhci, "Calling usb_hc_died()\n"); | 901 | xhci_dbg(xhci, "Calling usb_hc_died()\n"); |
901 | usb_hc_died(xhci_to_hcd(xhci)->primary_hcd); | 902 | usb_hc_died(xhci_to_hcd(xhci)->primary_hcd); |
902 | xhci_dbg(xhci, "xHCI host controller is dead.\n"); | 903 | xhci_dbg(xhci, "xHCI host controller is dead.\n"); |
diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index 1ff95a0df576..aa94c0195791 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c | |||
@@ -799,7 +799,7 @@ int xhci_resume(struct xhci_hcd *xhci, bool hibernated) | |||
799 | u32 command, temp = 0; | 799 | u32 command, temp = 0; |
800 | struct usb_hcd *hcd = xhci_to_hcd(xhci); | 800 | struct usb_hcd *hcd = xhci_to_hcd(xhci); |
801 | struct usb_hcd *secondary_hcd; | 801 | struct usb_hcd *secondary_hcd; |
802 | int retval; | 802 | int retval = 0; |
803 | 803 | ||
804 | /* Wait a bit if either of the roothubs need to settle from the | 804 | /* Wait a bit if either of the roothubs need to settle from the |
805 | * transition into bus suspend. | 805 | * transition into bus suspend. |
@@ -809,6 +809,9 @@ int xhci_resume(struct xhci_hcd *xhci, bool hibernated) | |||
809 | xhci->bus_state[1].next_statechange)) | 809 | xhci->bus_state[1].next_statechange)) |
810 | msleep(100); | 810 | msleep(100); |
811 | 811 | ||
812 | set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); | ||
813 | set_bit(HCD_FLAG_HW_ACCESSIBLE, &xhci->shared_hcd->flags); | ||
814 | |||
812 | spin_lock_irq(&xhci->lock); | 815 | spin_lock_irq(&xhci->lock); |
813 | if (xhci->quirks & XHCI_RESET_ON_RESUME) | 816 | if (xhci->quirks & XHCI_RESET_ON_RESUME) |
814 | hibernated = true; | 817 | hibernated = true; |
@@ -878,20 +881,13 @@ int xhci_resume(struct xhci_hcd *xhci, bool hibernated) | |||
878 | return retval; | 881 | return retval; |
879 | xhci_dbg(xhci, "Start the primary HCD\n"); | 882 | xhci_dbg(xhci, "Start the primary HCD\n"); |
880 | retval = xhci_run(hcd->primary_hcd); | 883 | retval = xhci_run(hcd->primary_hcd); |
881 | if (retval) | ||
882 | goto failed_restart; | ||
883 | |||
884 | xhci_dbg(xhci, "Start the secondary HCD\n"); | ||
885 | retval = xhci_run(secondary_hcd); | ||
886 | if (!retval) { | 884 | if (!retval) { |
887 | set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); | 885 | xhci_dbg(xhci, "Start the secondary HCD\n"); |
888 | set_bit(HCD_FLAG_HW_ACCESSIBLE, | 886 | retval = xhci_run(secondary_hcd); |
889 | &xhci->shared_hcd->flags); | ||
890 | } | 887 | } |
891 | failed_restart: | ||
892 | hcd->state = HC_STATE_SUSPENDED; | 888 | hcd->state = HC_STATE_SUSPENDED; |
893 | xhci->shared_hcd->state = HC_STATE_SUSPENDED; | 889 | xhci->shared_hcd->state = HC_STATE_SUSPENDED; |
894 | return retval; | 890 | goto done; |
895 | } | 891 | } |
896 | 892 | ||
897 | /* step 4: set Run/Stop bit */ | 893 | /* step 4: set Run/Stop bit */ |
@@ -910,11 +906,14 @@ failed_restart: | |||
910 | * Running endpoints by ringing their doorbells | 906 | * Running endpoints by ringing their doorbells |
911 | */ | 907 | */ |
912 | 908 | ||
913 | set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); | ||
914 | set_bit(HCD_FLAG_HW_ACCESSIBLE, &xhci->shared_hcd->flags); | ||
915 | |||
916 | spin_unlock_irq(&xhci->lock); | 909 | spin_unlock_irq(&xhci->lock); |
917 | return 0; | 910 | |
911 | done: | ||
912 | if (retval == 0) { | ||
913 | usb_hcd_resume_root_hub(hcd); | ||
914 | usb_hcd_resume_root_hub(xhci->shared_hcd); | ||
915 | } | ||
916 | return retval; | ||
918 | } | 917 | } |
919 | #endif /* CONFIG_PM */ | 918 | #endif /* CONFIG_PM */ |
920 | 919 | ||
@@ -3504,6 +3503,10 @@ int xhci_address_device(struct usb_hcd *hcd, struct usb_device *udev) | |||
3504 | /* Otherwise, update the control endpoint ring enqueue pointer. */ | 3503 | /* Otherwise, update the control endpoint ring enqueue pointer. */ |
3505 | else | 3504 | else |
3506 | xhci_copy_ep0_dequeue_into_input_ctx(xhci, udev); | 3505 | xhci_copy_ep0_dequeue_into_input_ctx(xhci, udev); |
3506 | ctrl_ctx = xhci_get_input_control_ctx(xhci, virt_dev->in_ctx); | ||
3507 | ctrl_ctx->add_flags = cpu_to_le32(SLOT_FLAG | EP0_FLAG); | ||
3508 | ctrl_ctx->drop_flags = 0; | ||
3509 | |||
3507 | xhci_dbg(xhci, "Slot ID %d Input Context:\n", udev->slot_id); | 3510 | xhci_dbg(xhci, "Slot ID %d Input Context:\n", udev->slot_id); |
3508 | xhci_dbg_ctx(xhci, virt_dev->in_ctx, 2); | 3511 | xhci_dbg_ctx(xhci, virt_dev->in_ctx, 2); |
3509 | 3512 | ||
@@ -3585,7 +3588,6 @@ int xhci_address_device(struct usb_hcd *hcd, struct usb_device *udev) | |||
3585 | virt_dev->address = (le32_to_cpu(slot_ctx->dev_state) & DEV_ADDR_MASK) | 3588 | virt_dev->address = (le32_to_cpu(slot_ctx->dev_state) & DEV_ADDR_MASK) |
3586 | + 1; | 3589 | + 1; |
3587 | /* Zero the input context control for later use */ | 3590 | /* Zero the input context control for later use */ |
3588 | ctrl_ctx = xhci_get_input_control_ctx(xhci, virt_dev->in_ctx); | ||
3589 | ctrl_ctx->add_flags = 0; | 3591 | ctrl_ctx->add_flags = 0; |
3590 | ctrl_ctx->drop_flags = 0; | 3592 | ctrl_ctx->drop_flags = 0; |
3591 | 3593 | ||
diff --git a/drivers/usb/musb/Kconfig b/drivers/usb/musb/Kconfig index fc34b8b11910..07a03460a598 100644 --- a/drivers/usb/musb/Kconfig +++ b/drivers/usb/musb/Kconfig | |||
@@ -11,6 +11,7 @@ config USB_MUSB_HDRC | |||
11 | select TWL4030_USB if MACH_OMAP_3430SDP | 11 | select TWL4030_USB if MACH_OMAP_3430SDP |
12 | select TWL6030_USB if MACH_OMAP_4430SDP || MACH_OMAP4_PANDA | 12 | select TWL6030_USB if MACH_OMAP_4430SDP || MACH_OMAP4_PANDA |
13 | select USB_OTG_UTILS | 13 | select USB_OTG_UTILS |
14 | select USB_GADGET_DUALSPEED | ||
14 | tristate 'Inventra Highspeed Dual Role Controller (TI, ADI, ...)' | 15 | tristate 'Inventra Highspeed Dual Role Controller (TI, ADI, ...)' |
15 | help | 16 | help |
16 | Say Y here if your system has a dual role high speed USB | 17 | Say Y here if your system has a dual role high speed USB |
@@ -60,7 +61,7 @@ config USB_MUSB_BLACKFIN | |||
60 | 61 | ||
61 | config USB_MUSB_UX500 | 62 | config USB_MUSB_UX500 |
62 | tristate "U8500 and U5500" | 63 | tristate "U8500 and U5500" |
63 | depends on (ARCH_U8500 && AB8500_USB) || (ARCH_U5500) | 64 | depends on (ARCH_U8500 && AB8500_USB) |
64 | 65 | ||
65 | endchoice | 66 | endchoice |
66 | 67 | ||
diff --git a/drivers/usb/musb/am35x.c b/drivers/usb/musb/am35x.c index 08f1d0b662a3..e233d2b7d335 100644 --- a/drivers/usb/musb/am35x.c +++ b/drivers/usb/musb/am35x.c | |||
@@ -27,6 +27,7 @@ | |||
27 | */ | 27 | */ |
28 | 28 | ||
29 | #include <linux/init.h> | 29 | #include <linux/init.h> |
30 | #include <linux/module.h> | ||
30 | #include <linux/clk.h> | 31 | #include <linux/clk.h> |
31 | #include <linux/io.h> | 32 | #include <linux/io.h> |
32 | #include <linux/platform_device.h> | 33 | #include <linux/platform_device.h> |
diff --git a/drivers/usb/musb/da8xx.c b/drivers/usb/musb/da8xx.c index 4da7492ddbdb..2613bfdb09b6 100644 --- a/drivers/usb/musb/da8xx.c +++ b/drivers/usb/musb/da8xx.c | |||
@@ -27,6 +27,7 @@ | |||
27 | */ | 27 | */ |
28 | 28 | ||
29 | #include <linux/init.h> | 29 | #include <linux/init.h> |
30 | #include <linux/module.h> | ||
30 | #include <linux/clk.h> | 31 | #include <linux/clk.h> |
31 | #include <linux/io.h> | 32 | #include <linux/io.h> |
32 | #include <linux/platform_device.h> | 33 | #include <linux/platform_device.h> |
diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c index 20a28731c338..c1fa12ec7a9a 100644 --- a/drivers/usb/musb/musb_core.c +++ b/drivers/usb/musb/musb_core.c | |||
@@ -1477,8 +1477,7 @@ static int __init musb_core_init(u16 musb_type, struct musb *musb) | |||
1477 | /*-------------------------------------------------------------------------*/ | 1477 | /*-------------------------------------------------------------------------*/ |
1478 | 1478 | ||
1479 | #if defined(CONFIG_SOC_OMAP2430) || defined(CONFIG_SOC_OMAP3430) || \ | 1479 | #if defined(CONFIG_SOC_OMAP2430) || defined(CONFIG_SOC_OMAP3430) || \ |
1480 | defined(CONFIG_ARCH_OMAP4) || defined(CONFIG_ARCH_U8500) || \ | 1480 | defined(CONFIG_ARCH_OMAP4) || defined(CONFIG_ARCH_U8500) |
1481 | defined(CONFIG_ARCH_U5500) | ||
1482 | 1481 | ||
1483 | static irqreturn_t generic_interrupt(int irq, void *__hci) | 1482 | static irqreturn_t generic_interrupt(int irq, void *__hci) |
1484 | { | 1483 | { |
diff --git a/drivers/usb/musb/musb_gadget.c b/drivers/usb/musb/musb_gadget.c index ae4a20acef6c..d51043acfe1a 100644 --- a/drivers/usb/musb/musb_gadget.c +++ b/drivers/usb/musb/musb_gadget.c | |||
@@ -1999,10 +1999,6 @@ static void stop_activity(struct musb *musb, struct usb_gadget_driver *driver) | |||
1999 | nuke(&hw_ep->ep_out, -ESHUTDOWN); | 1999 | nuke(&hw_ep->ep_out, -ESHUTDOWN); |
2000 | } | 2000 | } |
2001 | } | 2001 | } |
2002 | |||
2003 | spin_unlock(&musb->lock); | ||
2004 | driver->disconnect(&musb->g); | ||
2005 | spin_lock(&musb->lock); | ||
2006 | } | 2002 | } |
2007 | } | 2003 | } |
2008 | 2004 | ||
diff --git a/drivers/usb/renesas_usbhs/common.c b/drivers/usb/renesas_usbhs/common.c index d2e2efaba658..08c679c0dde5 100644 --- a/drivers/usb/renesas_usbhs/common.c +++ b/drivers/usb/renesas_usbhs/common.c | |||
@@ -405,7 +405,7 @@ int usbhsc_drvcllbck_notify_hotplug(struct platform_device *pdev) | |||
405 | /* | 405 | /* |
406 | * platform functions | 406 | * platform functions |
407 | */ | 407 | */ |
408 | static int __devinit usbhs_probe(struct platform_device *pdev) | 408 | static int usbhs_probe(struct platform_device *pdev) |
409 | { | 409 | { |
410 | struct renesas_usbhs_platform_info *info = pdev->dev.platform_data; | 410 | struct renesas_usbhs_platform_info *info = pdev->dev.platform_data; |
411 | struct renesas_usbhs_driver_callback *dfunc; | 411 | struct renesas_usbhs_driver_callback *dfunc; |
diff --git a/drivers/usb/renesas_usbhs/fifo.c b/drivers/usb/renesas_usbhs/fifo.c index 8da685e796d1..ffdf5d15085e 100644 --- a/drivers/usb/renesas_usbhs/fifo.c +++ b/drivers/usb/renesas_usbhs/fifo.c | |||
@@ -820,7 +820,7 @@ static int usbhsf_dma_prepare_push(struct usbhs_pkt *pkt, int *is_done) | |||
820 | if (len % 4) /* 32bit alignment */ | 820 | if (len % 4) /* 32bit alignment */ |
821 | goto usbhsf_pio_prepare_push; | 821 | goto usbhsf_pio_prepare_push; |
822 | 822 | ||
823 | if ((*(u32 *) pkt->buf + pkt->actual) & 0x7) /* 8byte alignment */ | 823 | if ((uintptr_t)(pkt->buf + pkt->actual) & 0x7) /* 8byte alignment */ |
824 | goto usbhsf_pio_prepare_push; | 824 | goto usbhsf_pio_prepare_push; |
825 | 825 | ||
826 | /* get enable DMA fifo */ | 826 | /* get enable DMA fifo */ |
@@ -897,7 +897,7 @@ static int usbhsf_dma_try_pop(struct usbhs_pkt *pkt, int *is_done) | |||
897 | if (!fifo) | 897 | if (!fifo) |
898 | goto usbhsf_pio_prepare_pop; | 898 | goto usbhsf_pio_prepare_pop; |
899 | 899 | ||
900 | if ((*(u32 *) pkt->buf + pkt->actual) & 0x7) /* 8byte alignment */ | 900 | if ((uintptr_t)(pkt->buf + pkt->actual) & 0x7) /* 8byte alignment */ |
901 | goto usbhsf_pio_prepare_pop; | 901 | goto usbhsf_pio_prepare_pop; |
902 | 902 | ||
903 | ret = usbhsf_fifo_select(pipe, fifo, 0); | 903 | ret = usbhsf_fifo_select(pipe, fifo, 0); |
diff --git a/drivers/usb/renesas_usbhs/mod.h b/drivers/usb/renesas_usbhs/mod.h index 8ae3733031cd..6c6875533f01 100644 --- a/drivers/usb/renesas_usbhs/mod.h +++ b/drivers/usb/renesas_usbhs/mod.h | |||
@@ -143,8 +143,8 @@ void usbhs_irq_callback_update(struct usbhs_priv *priv, struct usbhs_mod *mod); | |||
143 | */ | 143 | */ |
144 | #if defined(CONFIG_USB_RENESAS_USBHS_HCD) || \ | 144 | #if defined(CONFIG_USB_RENESAS_USBHS_HCD) || \ |
145 | defined(CONFIG_USB_RENESAS_USBHS_HCD_MODULE) | 145 | defined(CONFIG_USB_RENESAS_USBHS_HCD_MODULE) |
146 | extern int __devinit usbhs_mod_host_probe(struct usbhs_priv *priv); | 146 | extern int usbhs_mod_host_probe(struct usbhs_priv *priv); |
147 | extern int __devexit usbhs_mod_host_remove(struct usbhs_priv *priv); | 147 | extern int usbhs_mod_host_remove(struct usbhs_priv *priv); |
148 | #else | 148 | #else |
149 | static inline int usbhs_mod_host_probe(struct usbhs_priv *priv) | 149 | static inline int usbhs_mod_host_probe(struct usbhs_priv *priv) |
150 | { | 150 | { |
@@ -157,8 +157,8 @@ static inline void usbhs_mod_host_remove(struct usbhs_priv *priv) | |||
157 | 157 | ||
158 | #if defined(CONFIG_USB_RENESAS_USBHS_UDC) || \ | 158 | #if defined(CONFIG_USB_RENESAS_USBHS_UDC) || \ |
159 | defined(CONFIG_USB_RENESAS_USBHS_UDC_MODULE) | 159 | defined(CONFIG_USB_RENESAS_USBHS_UDC_MODULE) |
160 | extern int __devinit usbhs_mod_gadget_probe(struct usbhs_priv *priv); | 160 | extern int usbhs_mod_gadget_probe(struct usbhs_priv *priv); |
161 | extern void __devexit usbhs_mod_gadget_remove(struct usbhs_priv *priv); | 161 | extern void usbhs_mod_gadget_remove(struct usbhs_priv *priv); |
162 | #else | 162 | #else |
163 | static inline int usbhs_mod_gadget_probe(struct usbhs_priv *priv) | 163 | static inline int usbhs_mod_gadget_probe(struct usbhs_priv *priv) |
164 | { | 164 | { |
diff --git a/drivers/usb/renesas_usbhs/mod_gadget.c b/drivers/usb/renesas_usbhs/mod_gadget.c index 4cc7ee0babc6..d9717e0bc1ff 100644 --- a/drivers/usb/renesas_usbhs/mod_gadget.c +++ b/drivers/usb/renesas_usbhs/mod_gadget.c | |||
@@ -830,7 +830,7 @@ static int usbhsg_stop(struct usbhs_priv *priv) | |||
830 | return usbhsg_try_stop(priv, USBHSG_STATUS_STARTED); | 830 | return usbhsg_try_stop(priv, USBHSG_STATUS_STARTED); |
831 | } | 831 | } |
832 | 832 | ||
833 | int __devinit usbhs_mod_gadget_probe(struct usbhs_priv *priv) | 833 | int usbhs_mod_gadget_probe(struct usbhs_priv *priv) |
834 | { | 834 | { |
835 | struct usbhsg_gpriv *gpriv; | 835 | struct usbhsg_gpriv *gpriv; |
836 | struct usbhsg_uep *uep; | 836 | struct usbhsg_uep *uep; |
@@ -927,7 +927,7 @@ usbhs_mod_gadget_probe_err_gpriv: | |||
927 | return ret; | 927 | return ret; |
928 | } | 928 | } |
929 | 929 | ||
930 | void __devexit usbhs_mod_gadget_remove(struct usbhs_priv *priv) | 930 | void usbhs_mod_gadget_remove(struct usbhs_priv *priv) |
931 | { | 931 | { |
932 | struct usbhsg_gpriv *gpriv = usbhsg_priv_to_gpriv(priv); | 932 | struct usbhsg_gpriv *gpriv = usbhsg_priv_to_gpriv(priv); |
933 | 933 | ||
diff --git a/drivers/usb/renesas_usbhs/mod_host.c b/drivers/usb/renesas_usbhs/mod_host.c index 1a7208a50afc..bade761a1e52 100644 --- a/drivers/usb/renesas_usbhs/mod_host.c +++ b/drivers/usb/renesas_usbhs/mod_host.c | |||
@@ -103,7 +103,7 @@ struct usbhsh_hpriv { | |||
103 | 103 | ||
104 | u32 port_stat; /* USB_PORT_STAT_xxx */ | 104 | u32 port_stat; /* USB_PORT_STAT_xxx */ |
105 | 105 | ||
106 | struct completion *done; | 106 | struct completion setup_ack_done; |
107 | 107 | ||
108 | /* see usbhsh_req_alloc/free */ | 108 | /* see usbhsh_req_alloc/free */ |
109 | struct list_head ureq_link_active; | 109 | struct list_head ureq_link_active; |
@@ -355,6 +355,7 @@ static void usbhsh_device_free(struct usbhsh_hpriv *hpriv, | |||
355 | struct usbhsh_ep *usbhsh_endpoint_alloc(struct usbhsh_hpriv *hpriv, | 355 | struct usbhsh_ep *usbhsh_endpoint_alloc(struct usbhsh_hpriv *hpriv, |
356 | struct usbhsh_device *udev, | 356 | struct usbhsh_device *udev, |
357 | struct usb_host_endpoint *ep, | 357 | struct usb_host_endpoint *ep, |
358 | int dir_in_req, | ||
358 | gfp_t mem_flags) | 359 | gfp_t mem_flags) |
359 | { | 360 | { |
360 | struct usbhs_priv *priv = usbhsh_hpriv_to_priv(hpriv); | 361 | struct usbhs_priv *priv = usbhsh_hpriv_to_priv(hpriv); |
@@ -364,27 +365,38 @@ struct usbhsh_ep *usbhsh_endpoint_alloc(struct usbhsh_hpriv *hpriv, | |||
364 | struct usbhs_pipe *pipe, *best_pipe; | 365 | struct usbhs_pipe *pipe, *best_pipe; |
365 | struct device *dev = usbhsh_hcd_to_dev(hcd); | 366 | struct device *dev = usbhsh_hcd_to_dev(hcd); |
366 | struct usb_endpoint_descriptor *desc = &ep->desc; | 367 | struct usb_endpoint_descriptor *desc = &ep->desc; |
367 | int type, i; | 368 | int type, i, dir_in; |
368 | unsigned int min_usr; | 369 | unsigned int min_usr; |
369 | 370 | ||
371 | dir_in_req = !!dir_in_req; | ||
372 | |||
370 | uep = kzalloc(sizeof(struct usbhsh_ep), mem_flags); | 373 | uep = kzalloc(sizeof(struct usbhsh_ep), mem_flags); |
371 | if (!uep) { | 374 | if (!uep) { |
372 | dev_err(dev, "usbhsh_ep alloc fail\n"); | 375 | dev_err(dev, "usbhsh_ep alloc fail\n"); |
373 | return NULL; | 376 | return NULL; |
374 | } | 377 | } |
375 | type = usb_endpoint_type(desc); | 378 | |
379 | if (usb_endpoint_xfer_control(desc)) { | ||
380 | best_pipe = usbhsh_hpriv_to_dcp(hpriv); | ||
381 | goto usbhsh_endpoint_alloc_find_pipe; | ||
382 | } | ||
376 | 383 | ||
377 | /* | 384 | /* |
378 | * find best pipe for endpoint | 385 | * find best pipe for endpoint |
379 | * see | 386 | * see |
380 | * HARDWARE LIMITATION | 387 | * HARDWARE LIMITATION |
381 | */ | 388 | */ |
389 | type = usb_endpoint_type(desc); | ||
382 | min_usr = ~0; | 390 | min_usr = ~0; |
383 | best_pipe = NULL; | 391 | best_pipe = NULL; |
384 | usbhs_for_each_pipe_with_dcp(pipe, priv, i) { | 392 | usbhs_for_each_pipe(pipe, priv, i) { |
385 | if (!usbhs_pipe_type_is(pipe, type)) | 393 | if (!usbhs_pipe_type_is(pipe, type)) |
386 | continue; | 394 | continue; |
387 | 395 | ||
396 | dir_in = !!usbhs_pipe_is_dir_in(pipe); | ||
397 | if (0 != (dir_in - dir_in_req)) | ||
398 | continue; | ||
399 | |||
388 | info = usbhsh_pipe_info(pipe); | 400 | info = usbhsh_pipe_info(pipe); |
389 | 401 | ||
390 | if (min_usr > info->usr_cnt) { | 402 | if (min_usr > info->usr_cnt) { |
@@ -398,7 +410,7 @@ struct usbhsh_ep *usbhsh_endpoint_alloc(struct usbhsh_hpriv *hpriv, | |||
398 | kfree(uep); | 410 | kfree(uep); |
399 | return NULL; | 411 | return NULL; |
400 | } | 412 | } |
401 | 413 | usbhsh_endpoint_alloc_find_pipe: | |
402 | /* | 414 | /* |
403 | * init uep | 415 | * init uep |
404 | */ | 416 | */ |
@@ -423,6 +435,7 @@ struct usbhsh_ep *usbhsh_endpoint_alloc(struct usbhsh_hpriv *hpriv, | |||
423 | * see | 435 | * see |
424 | * DCPMAXP/PIPEMAXP | 436 | * DCPMAXP/PIPEMAXP |
425 | */ | 437 | */ |
438 | usbhs_pipe_sequence_data0(uep->pipe); | ||
426 | usbhs_pipe_config_update(uep->pipe, | 439 | usbhs_pipe_config_update(uep->pipe, |
427 | usbhsh_device_number(hpriv, udev), | 440 | usbhsh_device_number(hpriv, udev), |
428 | usb_endpoint_num(desc), | 441 | usb_endpoint_num(desc), |
@@ -430,7 +443,7 @@ struct usbhsh_ep *usbhsh_endpoint_alloc(struct usbhsh_hpriv *hpriv, | |||
430 | 443 | ||
431 | dev_dbg(dev, "%s [%d-%s](%p)\n", __func__, | 444 | dev_dbg(dev, "%s [%d-%s](%p)\n", __func__, |
432 | usbhsh_device_number(hpriv, udev), | 445 | usbhsh_device_number(hpriv, udev), |
433 | usbhs_pipe_name(pipe), uep); | 446 | usbhs_pipe_name(uep->pipe), uep); |
434 | 447 | ||
435 | return uep; | 448 | return uep; |
436 | } | 449 | } |
@@ -549,8 +562,7 @@ static void usbhsh_setup_stage_packet_push(struct usbhsh_hpriv *hpriv, | |||
549 | * usbhsh_irq_setup_ack() | 562 | * usbhsh_irq_setup_ack() |
550 | * usbhsh_irq_setup_err() | 563 | * usbhsh_irq_setup_err() |
551 | */ | 564 | */ |
552 | DECLARE_COMPLETION(done); | 565 | init_completion(&hpriv->setup_ack_done); |
553 | hpriv->done = &done; | ||
554 | 566 | ||
555 | /* copy original request */ | 567 | /* copy original request */ |
556 | memcpy(&req, urb->setup_packet, sizeof(struct usb_ctrlrequest)); | 568 | memcpy(&req, urb->setup_packet, sizeof(struct usb_ctrlrequest)); |
@@ -572,8 +584,7 @@ static void usbhsh_setup_stage_packet_push(struct usbhsh_hpriv *hpriv, | |||
572 | /* | 584 | /* |
573 | * wait setup packet ACK | 585 | * wait setup packet ACK |
574 | */ | 586 | */ |
575 | wait_for_completion(&done); | 587 | wait_for_completion(&hpriv->setup_ack_done); |
576 | hpriv->done = NULL; | ||
577 | 588 | ||
578 | dev_dbg(dev, "%s done\n", __func__); | 589 | dev_dbg(dev, "%s done\n", __func__); |
579 | } | 590 | } |
@@ -724,11 +735,11 @@ static int usbhsh_urb_enqueue(struct usb_hcd *hcd, | |||
724 | struct usbhsh_device *udev, *new_udev = NULL; | 735 | struct usbhsh_device *udev, *new_udev = NULL; |
725 | struct usbhs_pipe *pipe; | 736 | struct usbhs_pipe *pipe; |
726 | struct usbhsh_ep *uep; | 737 | struct usbhsh_ep *uep; |
738 | int is_dir_in = usb_pipein(urb->pipe); | ||
727 | 739 | ||
728 | int ret; | 740 | int ret; |
729 | 741 | ||
730 | dev_dbg(dev, "%s (%s)\n", | 742 | dev_dbg(dev, "%s (%s)\n", __func__, is_dir_in ? "in" : "out"); |
731 | __func__, usb_pipein(urb->pipe) ? "in" : "out"); | ||
732 | 743 | ||
733 | ret = usb_hcd_link_urb_to_ep(hcd, urb); | 744 | ret = usb_hcd_link_urb_to_ep(hcd, urb); |
734 | if (ret) | 745 | if (ret) |
@@ -751,7 +762,8 @@ static int usbhsh_urb_enqueue(struct usb_hcd *hcd, | |||
751 | */ | 762 | */ |
752 | uep = usbhsh_ep_to_uep(ep); | 763 | uep = usbhsh_ep_to_uep(ep); |
753 | if (!uep) { | 764 | if (!uep) { |
754 | uep = usbhsh_endpoint_alloc(hpriv, udev, ep, mem_flags); | 765 | uep = usbhsh_endpoint_alloc(hpriv, udev, ep, |
766 | is_dir_in, mem_flags); | ||
755 | if (!uep) | 767 | if (!uep) |
756 | goto usbhsh_urb_enqueue_error_free_device; | 768 | goto usbhsh_urb_enqueue_error_free_device; |
757 | } | 769 | } |
@@ -1095,10 +1107,7 @@ static int usbhsh_irq_setup_ack(struct usbhs_priv *priv, | |||
1095 | 1107 | ||
1096 | dev_dbg(dev, "setup packet OK\n"); | 1108 | dev_dbg(dev, "setup packet OK\n"); |
1097 | 1109 | ||
1098 | if (unlikely(!hpriv->done)) | 1110 | complete(&hpriv->setup_ack_done); /* see usbhsh_urb_enqueue() */ |
1099 | dev_err(dev, "setup ack happen without necessary data\n"); | ||
1100 | else | ||
1101 | complete(hpriv->done); /* see usbhsh_urb_enqueue() */ | ||
1102 | 1111 | ||
1103 | return 0; | 1112 | return 0; |
1104 | } | 1113 | } |
@@ -1111,10 +1120,7 @@ static int usbhsh_irq_setup_err(struct usbhs_priv *priv, | |||
1111 | 1120 | ||
1112 | dev_dbg(dev, "setup packet Err\n"); | 1121 | dev_dbg(dev, "setup packet Err\n"); |
1113 | 1122 | ||
1114 | if (unlikely(!hpriv->done)) | 1123 | complete(&hpriv->setup_ack_done); /* see usbhsh_urb_enqueue() */ |
1115 | dev_err(dev, "setup err happen without necessary data\n"); | ||
1116 | else | ||
1117 | complete(hpriv->done); /* see usbhsh_urb_enqueue() */ | ||
1118 | 1124 | ||
1119 | return 0; | 1125 | return 0; |
1120 | } | 1126 | } |
@@ -1221,8 +1227,18 @@ static int usbhsh_stop(struct usbhs_priv *priv) | |||
1221 | { | 1227 | { |
1222 | struct usbhsh_hpriv *hpriv = usbhsh_priv_to_hpriv(priv); | 1228 | struct usbhsh_hpriv *hpriv = usbhsh_priv_to_hpriv(priv); |
1223 | struct usb_hcd *hcd = usbhsh_hpriv_to_hcd(hpriv); | 1229 | struct usb_hcd *hcd = usbhsh_hpriv_to_hcd(hpriv); |
1230 | struct usbhs_mod *mod = usbhs_mod_get_current(priv); | ||
1224 | struct device *dev = usbhs_priv_to_dev(priv); | 1231 | struct device *dev = usbhs_priv_to_dev(priv); |
1225 | 1232 | ||
1233 | /* | ||
1234 | * disable irq callback | ||
1235 | */ | ||
1236 | mod->irq_attch = NULL; | ||
1237 | mod->irq_dtch = NULL; | ||
1238 | mod->irq_sack = NULL; | ||
1239 | mod->irq_sign = NULL; | ||
1240 | usbhs_irq_callback_update(priv, mod); | ||
1241 | |||
1226 | usb_remove_hcd(hcd); | 1242 | usb_remove_hcd(hcd); |
1227 | 1243 | ||
1228 | /* disable sys */ | 1244 | /* disable sys */ |
@@ -1235,7 +1251,7 @@ static int usbhsh_stop(struct usbhs_priv *priv) | |||
1235 | return 0; | 1251 | return 0; |
1236 | } | 1252 | } |
1237 | 1253 | ||
1238 | int __devinit usbhs_mod_host_probe(struct usbhs_priv *priv) | 1254 | int usbhs_mod_host_probe(struct usbhs_priv *priv) |
1239 | { | 1255 | { |
1240 | struct usbhsh_hpriv *hpriv; | 1256 | struct usbhsh_hpriv *hpriv; |
1241 | struct usb_hcd *hcd; | 1257 | struct usb_hcd *hcd; |
@@ -1279,7 +1295,6 @@ int __devinit usbhs_mod_host_probe(struct usbhs_priv *priv) | |||
1279 | hpriv->mod.stop = usbhsh_stop; | 1295 | hpriv->mod.stop = usbhsh_stop; |
1280 | hpriv->pipe_info = pipe_info; | 1296 | hpriv->pipe_info = pipe_info; |
1281 | hpriv->pipe_size = pipe_size; | 1297 | hpriv->pipe_size = pipe_size; |
1282 | hpriv->done = NULL; | ||
1283 | usbhsh_req_list_init(hpriv); | 1298 | usbhsh_req_list_init(hpriv); |
1284 | usbhsh_port_stat_init(hpriv); | 1299 | usbhsh_port_stat_init(hpriv); |
1285 | 1300 | ||
@@ -1299,7 +1314,7 @@ usbhs_mod_host_probe_err: | |||
1299 | return -ENOMEM; | 1314 | return -ENOMEM; |
1300 | } | 1315 | } |
1301 | 1316 | ||
1302 | int __devexit usbhs_mod_host_remove(struct usbhs_priv *priv) | 1317 | int usbhs_mod_host_remove(struct usbhs_priv *priv) |
1303 | { | 1318 | { |
1304 | struct usbhsh_hpriv *hpriv = usbhsh_priv_to_hpriv(priv); | 1319 | struct usbhsh_hpriv *hpriv = usbhsh_priv_to_hpriv(priv); |
1305 | struct usb_hcd *hcd = usbhsh_hpriv_to_hcd(hpriv); | 1320 | struct usb_hcd *hcd = usbhsh_hpriv_to_hcd(hpriv); |
diff --git a/drivers/usb/serial/ark3116.c b/drivers/usb/serial/ark3116.c index 5cdb9d912275..18e875b92e00 100644 --- a/drivers/usb/serial/ark3116.c +++ b/drivers/usb/serial/ark3116.c | |||
@@ -42,7 +42,7 @@ static int debug; | |||
42 | * Version information | 42 | * Version information |
43 | */ | 43 | */ |
44 | 44 | ||
45 | #define DRIVER_VERSION "v0.6" | 45 | #define DRIVER_VERSION "v0.7" |
46 | #define DRIVER_AUTHOR "Bart Hartgers <bart.hartgers+ark3116@gmail.com>" | 46 | #define DRIVER_AUTHOR "Bart Hartgers <bart.hartgers+ark3116@gmail.com>" |
47 | #define DRIVER_DESC "USB ARK3116 serial/IrDA driver" | 47 | #define DRIVER_DESC "USB ARK3116 serial/IrDA driver" |
48 | #define DRIVER_DEV_DESC "ARK3116 RS232/IrDA" | 48 | #define DRIVER_DEV_DESC "ARK3116 RS232/IrDA" |
@@ -380,10 +380,6 @@ static int ark3116_open(struct tty_struct *tty, struct usb_serial_port *port) | |||
380 | goto err_out; | 380 | goto err_out; |
381 | } | 381 | } |
382 | 382 | ||
383 | /* setup termios */ | ||
384 | if (tty) | ||
385 | ark3116_set_termios(tty, port, NULL); | ||
386 | |||
387 | /* remove any data still left: also clears error state */ | 383 | /* remove any data still left: also clears error state */ |
388 | ark3116_read_reg(serial, UART_RX, buf); | 384 | ark3116_read_reg(serial, UART_RX, buf); |
389 | 385 | ||
@@ -406,6 +402,10 @@ static int ark3116_open(struct tty_struct *tty, struct usb_serial_port *port) | |||
406 | /* enable DMA */ | 402 | /* enable DMA */ |
407 | ark3116_write_reg(port->serial, UART_FCR, UART_FCR_DMA_SELECT); | 403 | ark3116_write_reg(port->serial, UART_FCR, UART_FCR_DMA_SELECT); |
408 | 404 | ||
405 | /* setup termios */ | ||
406 | if (tty) | ||
407 | ark3116_set_termios(tty, port, NULL); | ||
408 | |||
409 | err_out: | 409 | err_out: |
410 | kfree(buf); | 410 | kfree(buf); |
411 | return result; | 411 | return result; |
diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index 8fe034d2d3e7..bd4298bb6750 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c | |||
@@ -2104,13 +2104,19 @@ static void ftdi_set_termios(struct tty_struct *tty, | |||
2104 | 2104 | ||
2105 | cflag = termios->c_cflag; | 2105 | cflag = termios->c_cflag; |
2106 | 2106 | ||
2107 | /* FIXME -For this cut I don't care if the line is really changing or | 2107 | if (old_termios->c_cflag == termios->c_cflag |
2108 | not - so just do the change regardless - should be able to | 2108 | && old_termios->c_ispeed == termios->c_ispeed |
2109 | compare old_termios and tty->termios */ | 2109 | && old_termios->c_ospeed == termios->c_ospeed) |
2110 | goto no_c_cflag_changes; | ||
2111 | |||
2110 | /* NOTE These routines can get interrupted by | 2112 | /* NOTE These routines can get interrupted by |
2111 | ftdi_sio_read_bulk_callback - need to examine what this means - | 2113 | ftdi_sio_read_bulk_callback - need to examine what this means - |
2112 | don't see any problems yet */ | 2114 | don't see any problems yet */ |
2113 | 2115 | ||
2116 | if ((old_termios->c_cflag & (CSIZE|PARODD|PARENB|CMSPAR|CSTOPB)) == | ||
2117 | (termios->c_cflag & (CSIZE|PARODD|PARENB|CMSPAR|CSTOPB))) | ||
2118 | goto no_data_parity_stop_changes; | ||
2119 | |||
2114 | /* Set number of data bits, parity, stop bits */ | 2120 | /* Set number of data bits, parity, stop bits */ |
2115 | 2121 | ||
2116 | urb_value = 0; | 2122 | urb_value = 0; |
@@ -2151,6 +2157,7 @@ static void ftdi_set_termios(struct tty_struct *tty, | |||
2151 | } | 2157 | } |
2152 | 2158 | ||
2153 | /* Now do the baudrate */ | 2159 | /* Now do the baudrate */ |
2160 | no_data_parity_stop_changes: | ||
2154 | if ((cflag & CBAUD) == B0) { | 2161 | if ((cflag & CBAUD) == B0) { |
2155 | /* Disable flow control */ | 2162 | /* Disable flow control */ |
2156 | if (usb_control_msg(dev, usb_sndctrlpipe(dev, 0), | 2163 | if (usb_control_msg(dev, usb_sndctrlpipe(dev, 0), |
@@ -2178,6 +2185,7 @@ static void ftdi_set_termios(struct tty_struct *tty, | |||
2178 | 2185 | ||
2179 | /* Set flow control */ | 2186 | /* Set flow control */ |
2180 | /* Note device also supports DTR/CD (ugh) and Xon/Xoff in hardware */ | 2187 | /* Note device also supports DTR/CD (ugh) and Xon/Xoff in hardware */ |
2188 | no_c_cflag_changes: | ||
2181 | if (cflag & CRTSCTS) { | 2189 | if (cflag & CRTSCTS) { |
2182 | dbg("%s Setting to CRTSCTS flow control", __func__); | 2190 | dbg("%s Setting to CRTSCTS flow control", __func__); |
2183 | if (usb_control_msg(dev, | 2191 | if (usb_control_msg(dev, |
diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index 89ae1f65e1b1..d865878c9f97 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c | |||
@@ -156,6 +156,7 @@ static void option_instat_callback(struct urb *urb); | |||
156 | #define HUAWEI_PRODUCT_K4511 0x14CC | 156 | #define HUAWEI_PRODUCT_K4511 0x14CC |
157 | #define HUAWEI_PRODUCT_ETS1220 0x1803 | 157 | #define HUAWEI_PRODUCT_ETS1220 0x1803 |
158 | #define HUAWEI_PRODUCT_E353 0x1506 | 158 | #define HUAWEI_PRODUCT_E353 0x1506 |
159 | #define HUAWEI_PRODUCT_E173S 0x1C05 | ||
159 | 160 | ||
160 | #define QUANTA_VENDOR_ID 0x0408 | 161 | #define QUANTA_VENDOR_ID 0x0408 |
161 | #define QUANTA_PRODUCT_Q101 0xEA02 | 162 | #define QUANTA_PRODUCT_Q101 0xEA02 |
@@ -316,6 +317,9 @@ static void option_instat_callback(struct urb *urb); | |||
316 | #define ZTE_PRODUCT_AC8710 0xfff1 | 317 | #define ZTE_PRODUCT_AC8710 0xfff1 |
317 | #define ZTE_PRODUCT_AC2726 0xfff5 | 318 | #define ZTE_PRODUCT_AC2726 0xfff5 |
318 | #define ZTE_PRODUCT_AC8710T 0xffff | 319 | #define ZTE_PRODUCT_AC8710T 0xffff |
320 | #define ZTE_PRODUCT_MC2718 0xffe8 | ||
321 | #define ZTE_PRODUCT_AD3812 0xffeb | ||
322 | #define ZTE_PRODUCT_MC2716 0xffed | ||
319 | 323 | ||
320 | #define BENQ_VENDOR_ID 0x04a5 | 324 | #define BENQ_VENDOR_ID 0x04a5 |
321 | #define BENQ_PRODUCT_H10 0x4068 | 325 | #define BENQ_PRODUCT_H10 0x4068 |
@@ -468,6 +472,10 @@ static void option_instat_callback(struct urb *urb); | |||
468 | #define YUGA_PRODUCT_CLU528 0x260D | 472 | #define YUGA_PRODUCT_CLU528 0x260D |
469 | #define YUGA_PRODUCT_CLU526 0x260F | 473 | #define YUGA_PRODUCT_CLU526 0x260F |
470 | 474 | ||
475 | /* Viettel products */ | ||
476 | #define VIETTEL_VENDOR_ID 0x2262 | ||
477 | #define VIETTEL_PRODUCT_VT1000 0x0002 | ||
478 | |||
471 | /* some devices interfaces need special handling due to a number of reasons */ | 479 | /* some devices interfaces need special handling due to a number of reasons */ |
472 | enum option_blacklist_reason { | 480 | enum option_blacklist_reason { |
473 | OPTION_BLACKLIST_NONE = 0, | 481 | OPTION_BLACKLIST_NONE = 0, |
@@ -500,6 +508,18 @@ static const struct option_blacklist_info zte_k3765_z_blacklist = { | |||
500 | .reserved = BIT(4), | 508 | .reserved = BIT(4), |
501 | }; | 509 | }; |
502 | 510 | ||
511 | static const struct option_blacklist_info zte_ad3812_z_blacklist = { | ||
512 | .sendsetup = BIT(0) | BIT(1) | BIT(2), | ||
513 | }; | ||
514 | |||
515 | static const struct option_blacklist_info zte_mc2718_z_blacklist = { | ||
516 | .sendsetup = BIT(1) | BIT(2) | BIT(3) | BIT(4), | ||
517 | }; | ||
518 | |||
519 | static const struct option_blacklist_info zte_mc2716_z_blacklist = { | ||
520 | .sendsetup = BIT(1) | BIT(2) | BIT(3), | ||
521 | }; | ||
522 | |||
503 | static const struct option_blacklist_info huawei_cdc12_blacklist = { | 523 | static const struct option_blacklist_info huawei_cdc12_blacklist = { |
504 | .reserved = BIT(1) | BIT(2), | 524 | .reserved = BIT(1) | BIT(2), |
505 | }; | 525 | }; |
@@ -622,6 +642,7 @@ static const struct usb_device_id option_ids[] = { | |||
622 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E143D, 0xff, 0xff, 0xff) }, | 642 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E143D, 0xff, 0xff, 0xff) }, |
623 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E143E, 0xff, 0xff, 0xff) }, | 643 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E143E, 0xff, 0xff, 0xff) }, |
624 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E143F, 0xff, 0xff, 0xff) }, | 644 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E143F, 0xff, 0xff, 0xff) }, |
645 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E173S, 0xff, 0xff, 0xff) }, | ||
625 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K4505, 0xff, 0xff, 0xff), | 646 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K4505, 0xff, 0xff, 0xff), |
626 | .driver_info = (kernel_ulong_t) &huawei_cdc12_blacklist }, | 647 | .driver_info = (kernel_ulong_t) &huawei_cdc12_blacklist }, |
627 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K3765, 0xff, 0xff, 0xff), | 648 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K3765, 0xff, 0xff, 0xff), |
@@ -1043,6 +1064,12 @@ static const struct usb_device_id option_ids[] = { | |||
1043 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_AC8710, 0xff, 0xff, 0xff) }, | 1064 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_AC8710, 0xff, 0xff, 0xff) }, |
1044 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_AC2726, 0xff, 0xff, 0xff) }, | 1065 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_AC2726, 0xff, 0xff, 0xff) }, |
1045 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_AC8710T, 0xff, 0xff, 0xff) }, | 1066 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_AC8710T, 0xff, 0xff, 0xff) }, |
1067 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_MC2718, 0xff, 0xff, 0xff), | ||
1068 | .driver_info = (kernel_ulong_t)&zte_mc2718_z_blacklist }, | ||
1069 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_AD3812, 0xff, 0xff, 0xff), | ||
1070 | .driver_info = (kernel_ulong_t)&zte_ad3812_z_blacklist }, | ||
1071 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_MC2716, 0xff, 0xff, 0xff), | ||
1072 | .driver_info = (kernel_ulong_t)&zte_mc2716_z_blacklist }, | ||
1046 | { USB_DEVICE(BENQ_VENDOR_ID, BENQ_PRODUCT_H10) }, | 1073 | { USB_DEVICE(BENQ_VENDOR_ID, BENQ_PRODUCT_H10) }, |
1047 | { USB_DEVICE(DLINK_VENDOR_ID, DLINK_PRODUCT_DWM_652) }, | 1074 | { USB_DEVICE(DLINK_VENDOR_ID, DLINK_PRODUCT_DWM_652) }, |
1048 | { USB_DEVICE(ALINK_VENDOR_ID, DLINK_PRODUCT_DWM_652_U5) }, /* Yes, ALINK_VENDOR_ID */ | 1075 | { USB_DEVICE(ALINK_VENDOR_ID, DLINK_PRODUCT_DWM_652_U5) }, /* Yes, ALINK_VENDOR_ID */ |
@@ -1141,6 +1168,7 @@ static const struct usb_device_id option_ids[] = { | |||
1141 | { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CLU516) }, | 1168 | { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CLU516) }, |
1142 | { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CLU528) }, | 1169 | { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CLU528) }, |
1143 | { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CLU526) }, | 1170 | { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CLU526) }, |
1171 | { USB_DEVICE_AND_INTERFACE_INFO(VIETTEL_VENDOR_ID, VIETTEL_PRODUCT_VT1000, 0xff, 0xff, 0xff) }, | ||
1144 | { } /* Terminating entry */ | 1172 | { } /* Terminating entry */ |
1145 | }; | 1173 | }; |
1146 | MODULE_DEVICE_TABLE(usb, option_ids); | 1174 | MODULE_DEVICE_TABLE(usb, option_ids); |
diff --git a/drivers/usb/serial/pl2303.c b/drivers/usb/serial/pl2303.c index 9083d1e616b4..fc2d66f7f4eb 100644 --- a/drivers/usb/serial/pl2303.c +++ b/drivers/usb/serial/pl2303.c | |||
@@ -91,7 +91,6 @@ static const struct usb_device_id id_table[] = { | |||
91 | { USB_DEVICE(SONY_VENDOR_ID, SONY_QN3USB_PRODUCT_ID) }, | 91 | { USB_DEVICE(SONY_VENDOR_ID, SONY_QN3USB_PRODUCT_ID) }, |
92 | { USB_DEVICE(SANWA_VENDOR_ID, SANWA_PRODUCT_ID) }, | 92 | { USB_DEVICE(SANWA_VENDOR_ID, SANWA_PRODUCT_ID) }, |
93 | { USB_DEVICE(ADLINK_VENDOR_ID, ADLINK_ND6530_PRODUCT_ID) }, | 93 | { USB_DEVICE(ADLINK_VENDOR_ID, ADLINK_ND6530_PRODUCT_ID) }, |
94 | { USB_DEVICE(WINCHIPHEAD_VENDOR_ID, WINCHIPHEAD_USBSER_PRODUCT_ID) }, | ||
95 | { USB_DEVICE(SMART_VENDOR_ID, SMART_PRODUCT_ID) }, | 94 | { USB_DEVICE(SMART_VENDOR_ID, SMART_PRODUCT_ID) }, |
96 | { } /* Terminating entry */ | 95 | { } /* Terminating entry */ |
97 | }; | 96 | }; |
diff --git a/drivers/usb/serial/pl2303.h b/drivers/usb/serial/pl2303.h index 3d10d7f02072..c38b8c00c06f 100644 --- a/drivers/usb/serial/pl2303.h +++ b/drivers/usb/serial/pl2303.h | |||
@@ -145,10 +145,6 @@ | |||
145 | #define ADLINK_VENDOR_ID 0x0b63 | 145 | #define ADLINK_VENDOR_ID 0x0b63 |
146 | #define ADLINK_ND6530_PRODUCT_ID 0x6530 | 146 | #define ADLINK_ND6530_PRODUCT_ID 0x6530 |
147 | 147 | ||
148 | /* WinChipHead USB->RS 232 adapter */ | ||
149 | #define WINCHIPHEAD_VENDOR_ID 0x4348 | ||
150 | #define WINCHIPHEAD_USBSER_PRODUCT_ID 0x5523 | ||
151 | |||
152 | /* SMART USB Serial Adapter */ | 148 | /* SMART USB Serial Adapter */ |
153 | #define SMART_VENDOR_ID 0x0b8c | 149 | #define SMART_VENDOR_ID 0x0b8c |
154 | #define SMART_PRODUCT_ID 0x2303 | 150 | #define SMART_PRODUCT_ID 0x2303 |
diff --git a/drivers/usb/storage/ene_ub6250.c b/drivers/usb/storage/ene_ub6250.c index 4dca3ef0668c..9fbe742343c6 100644 --- a/drivers/usb/storage/ene_ub6250.c +++ b/drivers/usb/storage/ene_ub6250.c | |||
@@ -1762,10 +1762,9 @@ static int ms_scsi_write(struct us_data *us, struct scsi_cmnd *srb) | |||
1762 | result = ene_send_scsi_cmd(us, FDIR_WRITE, scsi_sglist(srb), 1); | 1762 | result = ene_send_scsi_cmd(us, FDIR_WRITE, scsi_sglist(srb), 1); |
1763 | } else { | 1763 | } else { |
1764 | void *buf; | 1764 | void *buf; |
1765 | int offset; | 1765 | int offset = 0; |
1766 | u16 PhyBlockAddr; | 1766 | u16 PhyBlockAddr; |
1767 | u8 PageNum; | 1767 | u8 PageNum; |
1768 | u32 result; | ||
1769 | u16 len, oldphy, newphy; | 1768 | u16 len, oldphy, newphy; |
1770 | 1769 | ||
1771 | buf = kmalloc(blenByte, GFP_KERNEL); | 1770 | buf = kmalloc(blenByte, GFP_KERNEL); |
diff --git a/drivers/usb/storage/protocol.c b/drivers/usb/storage/protocol.c index 93c1a4d86f51..82dd834709c7 100644 --- a/drivers/usb/storage/protocol.c +++ b/drivers/usb/storage/protocol.c | |||
@@ -59,7 +59,9 @@ | |||
59 | 59 | ||
60 | void usb_stor_pad12_command(struct scsi_cmnd *srb, struct us_data *us) | 60 | void usb_stor_pad12_command(struct scsi_cmnd *srb, struct us_data *us) |
61 | { | 61 | { |
62 | /* Pad the SCSI command with zeros out to 12 bytes | 62 | /* |
63 | * Pad the SCSI command with zeros out to 12 bytes. If the | ||
64 | * command already is 12 bytes or longer, leave it alone. | ||
63 | * | 65 | * |
64 | * NOTE: This only works because a scsi_cmnd struct field contains | 66 | * NOTE: This only works because a scsi_cmnd struct field contains |
65 | * a unsigned char cmnd[16], so we know we have storage available | 67 | * a unsigned char cmnd[16], so we know we have storage available |
@@ -67,9 +69,6 @@ void usb_stor_pad12_command(struct scsi_cmnd *srb, struct us_data *us) | |||
67 | for (; srb->cmd_len<12; srb->cmd_len++) | 69 | for (; srb->cmd_len<12; srb->cmd_len++) |
68 | srb->cmnd[srb->cmd_len] = 0; | 70 | srb->cmnd[srb->cmd_len] = 0; |
69 | 71 | ||
70 | /* set command length to 12 bytes */ | ||
71 | srb->cmd_len = 12; | ||
72 | |||
73 | /* send the command to the transport layer */ | 72 | /* send the command to the transport layer */ |
74 | usb_stor_invoke_transport(srb, us); | 73 | usb_stor_invoke_transport(srb, us); |
75 | } | 74 | } |
diff --git a/drivers/video/da8xx-fb.c b/drivers/video/da8xx-fb.c index 55f91d9ab00b..29577bf1f559 100644 --- a/drivers/video/da8xx-fb.c +++ b/drivers/video/da8xx-fb.c | |||
@@ -116,6 +116,7 @@ | |||
116 | /* Clock registers available only on Version 2 */ | 116 | /* Clock registers available only on Version 2 */ |
117 | #define LCD_CLK_ENABLE_REG 0x6c | 117 | #define LCD_CLK_ENABLE_REG 0x6c |
118 | #define LCD_CLK_RESET_REG 0x70 | 118 | #define LCD_CLK_RESET_REG 0x70 |
119 | #define LCD_CLK_MAIN_RESET BIT(3) | ||
119 | 120 | ||
120 | #define LCD_NUM_BUFFERS 2 | 121 | #define LCD_NUM_BUFFERS 2 |
121 | 122 | ||
@@ -244,6 +245,10 @@ static inline void lcd_enable_raster(void) | |||
244 | { | 245 | { |
245 | u32 reg; | 246 | u32 reg; |
246 | 247 | ||
248 | /* Bring LCDC out of reset */ | ||
249 | if (lcd_revision == LCD_VERSION_2) | ||
250 | lcdc_write(0, LCD_CLK_RESET_REG); | ||
251 | |||
247 | reg = lcdc_read(LCD_RASTER_CTRL_REG); | 252 | reg = lcdc_read(LCD_RASTER_CTRL_REG); |
248 | if (!(reg & LCD_RASTER_ENABLE)) | 253 | if (!(reg & LCD_RASTER_ENABLE)) |
249 | lcdc_write(reg | LCD_RASTER_ENABLE, LCD_RASTER_CTRL_REG); | 254 | lcdc_write(reg | LCD_RASTER_ENABLE, LCD_RASTER_CTRL_REG); |
@@ -257,6 +262,10 @@ static inline void lcd_disable_raster(void) | |||
257 | reg = lcdc_read(LCD_RASTER_CTRL_REG); | 262 | reg = lcdc_read(LCD_RASTER_CTRL_REG); |
258 | if (reg & LCD_RASTER_ENABLE) | 263 | if (reg & LCD_RASTER_ENABLE) |
259 | lcdc_write(reg & ~LCD_RASTER_ENABLE, LCD_RASTER_CTRL_REG); | 264 | lcdc_write(reg & ~LCD_RASTER_ENABLE, LCD_RASTER_CTRL_REG); |
265 | |||
266 | if (lcd_revision == LCD_VERSION_2) | ||
267 | /* Write 1 to reset LCDC */ | ||
268 | lcdc_write(LCD_CLK_MAIN_RESET, LCD_CLK_RESET_REG); | ||
260 | } | 269 | } |
261 | 270 | ||
262 | static void lcd_blit(int load_mode, struct da8xx_fb_par *par) | 271 | static void lcd_blit(int load_mode, struct da8xx_fb_par *par) |
@@ -584,8 +593,12 @@ static void lcd_reset(struct da8xx_fb_par *par) | |||
584 | lcdc_write(0, LCD_DMA_CTRL_REG); | 593 | lcdc_write(0, LCD_DMA_CTRL_REG); |
585 | lcdc_write(0, LCD_RASTER_CTRL_REG); | 594 | lcdc_write(0, LCD_RASTER_CTRL_REG); |
586 | 595 | ||
587 | if (lcd_revision == LCD_VERSION_2) | 596 | if (lcd_revision == LCD_VERSION_2) { |
588 | lcdc_write(0, LCD_INT_ENABLE_SET_REG); | 597 | lcdc_write(0, LCD_INT_ENABLE_SET_REG); |
598 | /* Write 1 to reset */ | ||
599 | lcdc_write(LCD_CLK_MAIN_RESET, LCD_CLK_RESET_REG); | ||
600 | lcdc_write(0, LCD_CLK_RESET_REG); | ||
601 | } | ||
589 | } | 602 | } |
590 | 603 | ||
591 | static void lcd_calc_clk_divider(struct da8xx_fb_par *par) | 604 | static void lcd_calc_clk_divider(struct da8xx_fb_par *par) |
diff --git a/drivers/video/omap/dispc.c b/drivers/video/omap/dispc.c index 0ccd7adf47bb..6f61e781f15a 100644 --- a/drivers/video/omap/dispc.c +++ b/drivers/video/omap/dispc.c | |||
@@ -19,6 +19,7 @@ | |||
19 | * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | 19 | * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. |
20 | */ | 20 | */ |
21 | #include <linux/kernel.h> | 21 | #include <linux/kernel.h> |
22 | #include <linux/module.h> | ||
22 | #include <linux/dma-mapping.h> | 23 | #include <linux/dma-mapping.h> |
23 | #include <linux/mm.h> | 24 | #include <linux/mm.h> |
24 | #include <linux/vmalloc.h> | 25 | #include <linux/vmalloc.h> |
diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c index 3532782551cb..5c81533eacaa 100644 --- a/drivers/video/omap2/dss/dispc.c +++ b/drivers/video/omap2/dss/dispc.c | |||
@@ -1720,12 +1720,11 @@ static int dispc_ovl_calc_scaling(enum omap_plane plane, | |||
1720 | const int maxdownscale = dss_feat_get_param_max(FEAT_PARAM_DOWNSCALE); | 1720 | const int maxdownscale = dss_feat_get_param_max(FEAT_PARAM_DOWNSCALE); |
1721 | unsigned long fclk = 0; | 1721 | unsigned long fclk = 0; |
1722 | 1722 | ||
1723 | if ((ovl->caps & OMAP_DSS_OVL_CAP_SCALE) == 0) { | 1723 | if (width == out_width && height == out_height) |
1724 | if (width != out_width || height != out_height) | 1724 | return 0; |
1725 | return -EINVAL; | 1725 | |
1726 | else | 1726 | if ((ovl->caps & OMAP_DSS_OVL_CAP_SCALE) == 0) |
1727 | return 0; | 1727 | return -EINVAL; |
1728 | } | ||
1729 | 1728 | ||
1730 | if (out_width < width / maxdownscale || | 1729 | if (out_width < width / maxdownscale || |
1731 | out_width > width * 8) | 1730 | out_width > width * 8) |
diff --git a/drivers/video/omap2/dss/hdmi.c b/drivers/video/omap2/dss/hdmi.c index 3262f0f1fa35..c56378c555b0 100644 --- a/drivers/video/omap2/dss/hdmi.c +++ b/drivers/video/omap2/dss/hdmi.c | |||
@@ -269,7 +269,7 @@ static void update_hdmi_timings(struct hdmi_config *cfg, | |||
269 | unsigned long hdmi_get_pixel_clock(void) | 269 | unsigned long hdmi_get_pixel_clock(void) |
270 | { | 270 | { |
271 | /* HDMI Pixel Clock in Mhz */ | 271 | /* HDMI Pixel Clock in Mhz */ |
272 | return hdmi.ip_data.cfg.timings.timings.pixel_clock * 10000; | 272 | return hdmi.ip_data.cfg.timings.timings.pixel_clock * 1000; |
273 | } | 273 | } |
274 | 274 | ||
275 | static void hdmi_compute_pll(struct omap_dss_device *dssdev, int phy, | 275 | static void hdmi_compute_pll(struct omap_dss_device *dssdev, int phy, |
diff --git a/drivers/video/via/share.h b/drivers/video/via/share.h index 69d882cbe709..c01c1c162726 100644 --- a/drivers/video/via/share.h +++ b/drivers/video/via/share.h | |||
@@ -559,8 +559,8 @@ | |||
559 | #define M1200X720_R60_VSP POSITIVE | 559 | #define M1200X720_R60_VSP POSITIVE |
560 | 560 | ||
561 | /* 1200x900@60 Sync Polarity (DCON) */ | 561 | /* 1200x900@60 Sync Polarity (DCON) */ |
562 | #define M1200X900_R60_HSP NEGATIVE | 562 | #define M1200X900_R60_HSP POSITIVE |
563 | #define M1200X900_R60_VSP NEGATIVE | 563 | #define M1200X900_R60_VSP POSITIVE |
564 | 564 | ||
565 | /* 1280x600@60 Sync Polarity (GTF Mode) */ | 565 | /* 1280x600@60 Sync Polarity (GTF Mode) */ |
566 | #define M1280x600_R60_HSP NEGATIVE | 566 | #define M1280x600_R60_HSP NEGATIVE |
diff --git a/drivers/virtio/Kconfig b/drivers/virtio/Kconfig index 816ed08e7cf3..1a61939b85fc 100644 --- a/drivers/virtio/Kconfig +++ b/drivers/virtio/Kconfig | |||
@@ -37,7 +37,7 @@ config VIRTIO_BALLOON | |||
37 | 37 | ||
38 | config VIRTIO_MMIO | 38 | config VIRTIO_MMIO |
39 | tristate "Platform bus driver for memory mapped virtio devices (EXPERIMENTAL)" | 39 | tristate "Platform bus driver for memory mapped virtio devices (EXPERIMENTAL)" |
40 | depends on EXPERIMENTAL | 40 | depends on HAS_IOMEM && EXPERIMENTAL |
41 | select VIRTIO | 41 | select VIRTIO |
42 | select VIRTIO_RING | 42 | select VIRTIO_RING |
43 | ---help--- | 43 | ---help--- |
diff --git a/drivers/virtio/virtio_mmio.c b/drivers/virtio/virtio_mmio.c index 2f57380d7ed4..0269717436af 100644 --- a/drivers/virtio/virtio_mmio.c +++ b/drivers/virtio/virtio_mmio.c | |||
@@ -118,7 +118,7 @@ static void vm_finalize_features(struct virtio_device *vdev) | |||
118 | vring_transport_features(vdev); | 118 | vring_transport_features(vdev); |
119 | 119 | ||
120 | for (i = 0; i < ARRAY_SIZE(vdev->features); i++) { | 120 | for (i = 0; i < ARRAY_SIZE(vdev->features); i++) { |
121 | writel(i, vm_dev->base + VIRTIO_MMIO_GUEST_FEATURES_SET); | 121 | writel(i, vm_dev->base + VIRTIO_MMIO_GUEST_FEATURES_SEL); |
122 | writel(vdev->features[i], | 122 | writel(vdev->features[i], |
123 | vm_dev->base + VIRTIO_MMIO_GUEST_FEATURES); | 123 | vm_dev->base + VIRTIO_MMIO_GUEST_FEATURES); |
124 | } | 124 | } |
diff --git a/drivers/virtio/virtio_pci.c b/drivers/virtio/virtio_pci.c index 91683e6e7af5..baabb7937ec2 100644 --- a/drivers/virtio/virtio_pci.c +++ b/drivers/virtio/virtio_pci.c | |||
@@ -169,11 +169,29 @@ static void vp_set_status(struct virtio_device *vdev, u8 status) | |||
169 | iowrite8(status, vp_dev->ioaddr + VIRTIO_PCI_STATUS); | 169 | iowrite8(status, vp_dev->ioaddr + VIRTIO_PCI_STATUS); |
170 | } | 170 | } |
171 | 171 | ||
172 | /* wait for pending irq handlers */ | ||
173 | static void vp_synchronize_vectors(struct virtio_device *vdev) | ||
174 | { | ||
175 | struct virtio_pci_device *vp_dev = to_vp_device(vdev); | ||
176 | int i; | ||
177 | |||
178 | if (vp_dev->intx_enabled) | ||
179 | synchronize_irq(vp_dev->pci_dev->irq); | ||
180 | |||
181 | for (i = 0; i < vp_dev->msix_vectors; ++i) | ||
182 | synchronize_irq(vp_dev->msix_entries[i].vector); | ||
183 | } | ||
184 | |||
172 | static void vp_reset(struct virtio_device *vdev) | 185 | static void vp_reset(struct virtio_device *vdev) |
173 | { | 186 | { |
174 | struct virtio_pci_device *vp_dev = to_vp_device(vdev); | 187 | struct virtio_pci_device *vp_dev = to_vp_device(vdev); |
175 | /* 0 status means a reset. */ | 188 | /* 0 status means a reset. */ |
176 | iowrite8(0, vp_dev->ioaddr + VIRTIO_PCI_STATUS); | 189 | iowrite8(0, vp_dev->ioaddr + VIRTIO_PCI_STATUS); |
190 | /* Flush out the status write, and flush in device writes, | ||
191 | * including MSi-X interrupts, if any. */ | ||
192 | ioread8(vp_dev->ioaddr + VIRTIO_PCI_STATUS); | ||
193 | /* Flush pending VQ/configuration callbacks. */ | ||
194 | vp_synchronize_vectors(vdev); | ||
177 | } | 195 | } |
178 | 196 | ||
179 | /* the notify function used when creating a virt queue */ | 197 | /* the notify function used when creating a virt queue */ |
diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig index 6285867a9356..79fd606b7cd5 100644 --- a/drivers/watchdog/Kconfig +++ b/drivers/watchdog/Kconfig | |||
@@ -314,13 +314,6 @@ config NUC900_WATCHDOG | |||
314 | To compile this driver as a module, choose M here: the | 314 | To compile this driver as a module, choose M here: the |
315 | module will be called nuc900_wdt. | 315 | module will be called nuc900_wdt. |
316 | 316 | ||
317 | config ADX_WATCHDOG | ||
318 | tristate "Avionic Design Xanthos watchdog" | ||
319 | depends on ARCH_PXA_ADX | ||
320 | help | ||
321 | Say Y here if you want support for the watchdog timer on Avionic | ||
322 | Design Xanthos boards. | ||
323 | |||
324 | config TS72XX_WATCHDOG | 317 | config TS72XX_WATCHDOG |
325 | tristate "TS-72XX SBC Watchdog" | 318 | tristate "TS-72XX SBC Watchdog" |
326 | depends on MACH_TS72XX | 319 | depends on MACH_TS72XX |
diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile index 55bd5740e910..fe893e91935b 100644 --- a/drivers/watchdog/Makefile +++ b/drivers/watchdog/Makefile | |||
@@ -51,7 +51,6 @@ obj-$(CONFIG_ORION_WATCHDOG) += orion_wdt.o | |||
51 | obj-$(CONFIG_COH901327_WATCHDOG) += coh901327_wdt.o | 51 | obj-$(CONFIG_COH901327_WATCHDOG) += coh901327_wdt.o |
52 | obj-$(CONFIG_STMP3XXX_WATCHDOG) += stmp3xxx_wdt.o | 52 | obj-$(CONFIG_STMP3XXX_WATCHDOG) += stmp3xxx_wdt.o |
53 | obj-$(CONFIG_NUC900_WATCHDOG) += nuc900_wdt.o | 53 | obj-$(CONFIG_NUC900_WATCHDOG) += nuc900_wdt.o |
54 | obj-$(CONFIG_ADX_WATCHDOG) += adx_wdt.o | ||
55 | obj-$(CONFIG_TS72XX_WATCHDOG) += ts72xx_wdt.o | 54 | obj-$(CONFIG_TS72XX_WATCHDOG) += ts72xx_wdt.o |
56 | obj-$(CONFIG_IMX2_WDT) += imx2_wdt.o | 55 | obj-$(CONFIG_IMX2_WDT) += imx2_wdt.o |
57 | 56 | ||
diff --git a/drivers/watchdog/adx_wdt.c b/drivers/watchdog/adx_wdt.c deleted file mode 100644 index af6e6b16475a..000000000000 --- a/drivers/watchdog/adx_wdt.c +++ /dev/null | |||
@@ -1,355 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2008-2009 Avionic Design GmbH | ||
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/fs.h> | ||
10 | #include <linux/gfp.h> | ||
11 | #include <linux/io.h> | ||
12 | #include <linux/miscdevice.h> | ||
13 | #include <linux/module.h> | ||
14 | #include <linux/platform_device.h> | ||
15 | #include <linux/types.h> | ||
16 | #include <linux/uaccess.h> | ||
17 | #include <linux/watchdog.h> | ||
18 | |||
19 | #define WATCHDOG_NAME "adx-wdt" | ||
20 | |||
21 | /* register offsets */ | ||
22 | #define ADX_WDT_CONTROL 0x00 | ||
23 | #define ADX_WDT_CONTROL_ENABLE (1 << 0) | ||
24 | #define ADX_WDT_CONTROL_nRESET (1 << 1) | ||
25 | #define ADX_WDT_TIMEOUT 0x08 | ||
26 | |||
27 | static struct platform_device *adx_wdt_dev; | ||
28 | static unsigned long driver_open; | ||
29 | |||
30 | #define WDT_STATE_STOP 0 | ||
31 | #define WDT_STATE_START 1 | ||
32 | |||
33 | struct adx_wdt { | ||
34 | void __iomem *base; | ||
35 | unsigned long timeout; | ||
36 | unsigned int state; | ||
37 | unsigned int wake; | ||
38 | spinlock_t lock; | ||
39 | }; | ||
40 | |||
41 | static const struct watchdog_info adx_wdt_info = { | ||
42 | .identity = "Avionic Design Xanthos Watchdog", | ||
43 | .options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING, | ||
44 | }; | ||
45 | |||
46 | static void adx_wdt_start_locked(struct adx_wdt *wdt) | ||
47 | { | ||
48 | u32 ctrl; | ||
49 | |||
50 | ctrl = readl(wdt->base + ADX_WDT_CONTROL); | ||
51 | ctrl |= ADX_WDT_CONTROL_ENABLE; | ||
52 | writel(ctrl, wdt->base + ADX_WDT_CONTROL); | ||
53 | wdt->state = WDT_STATE_START; | ||
54 | } | ||
55 | |||
56 | static void adx_wdt_start(struct adx_wdt *wdt) | ||
57 | { | ||
58 | unsigned long flags; | ||
59 | |||
60 | spin_lock_irqsave(&wdt->lock, flags); | ||
61 | adx_wdt_start_locked(wdt); | ||
62 | spin_unlock_irqrestore(&wdt->lock, flags); | ||
63 | } | ||
64 | |||
65 | static void adx_wdt_stop_locked(struct adx_wdt *wdt) | ||
66 | { | ||
67 | u32 ctrl; | ||
68 | |||
69 | ctrl = readl(wdt->base + ADX_WDT_CONTROL); | ||
70 | ctrl &= ~ADX_WDT_CONTROL_ENABLE; | ||
71 | writel(ctrl, wdt->base + ADX_WDT_CONTROL); | ||
72 | wdt->state = WDT_STATE_STOP; | ||
73 | } | ||
74 | |||
75 | static void adx_wdt_stop(struct adx_wdt *wdt) | ||
76 | { | ||
77 | unsigned long flags; | ||
78 | |||
79 | spin_lock_irqsave(&wdt->lock, flags); | ||
80 | adx_wdt_stop_locked(wdt); | ||
81 | spin_unlock_irqrestore(&wdt->lock, flags); | ||
82 | } | ||
83 | |||
84 | static void adx_wdt_set_timeout(struct adx_wdt *wdt, unsigned long seconds) | ||
85 | { | ||
86 | unsigned long timeout = seconds * 1000; | ||
87 | unsigned long flags; | ||
88 | unsigned int state; | ||
89 | |||
90 | spin_lock_irqsave(&wdt->lock, flags); | ||
91 | state = wdt->state; | ||
92 | adx_wdt_stop_locked(wdt); | ||
93 | writel(timeout, wdt->base + ADX_WDT_TIMEOUT); | ||
94 | |||
95 | if (state == WDT_STATE_START) | ||
96 | adx_wdt_start_locked(wdt); | ||
97 | |||
98 | wdt->timeout = timeout; | ||
99 | spin_unlock_irqrestore(&wdt->lock, flags); | ||
100 | } | ||
101 | |||
102 | static void adx_wdt_get_timeout(struct adx_wdt *wdt, unsigned long *seconds) | ||
103 | { | ||
104 | *seconds = wdt->timeout / 1000; | ||
105 | } | ||
106 | |||
107 | static void adx_wdt_keepalive(struct adx_wdt *wdt) | ||
108 | { | ||
109 | unsigned long flags; | ||
110 | |||
111 | spin_lock_irqsave(&wdt->lock, flags); | ||
112 | writel(wdt->timeout, wdt->base + ADX_WDT_TIMEOUT); | ||
113 | spin_unlock_irqrestore(&wdt->lock, flags); | ||
114 | } | ||
115 | |||
116 | static int adx_wdt_open(struct inode *inode, struct file *file) | ||
117 | { | ||
118 | struct adx_wdt *wdt = platform_get_drvdata(adx_wdt_dev); | ||
119 | |||
120 | if (test_and_set_bit(0, &driver_open)) | ||
121 | return -EBUSY; | ||
122 | |||
123 | file->private_data = wdt; | ||
124 | adx_wdt_set_timeout(wdt, 30); | ||
125 | adx_wdt_start(wdt); | ||
126 | |||
127 | return nonseekable_open(inode, file); | ||
128 | } | ||
129 | |||
130 | static int adx_wdt_release(struct inode *inode, struct file *file) | ||
131 | { | ||
132 | struct adx_wdt *wdt = file->private_data; | ||
133 | |||
134 | adx_wdt_stop(wdt); | ||
135 | clear_bit(0, &driver_open); | ||
136 | |||
137 | return 0; | ||
138 | } | ||
139 | |||
140 | static long adx_wdt_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | ||
141 | { | ||
142 | struct adx_wdt *wdt = file->private_data; | ||
143 | void __user *argp = (void __user *)arg; | ||
144 | unsigned long __user *p = argp; | ||
145 | unsigned long seconds = 0; | ||
146 | unsigned int options; | ||
147 | long ret = -EINVAL; | ||
148 | |||
149 | switch (cmd) { | ||
150 | case WDIOC_GETSUPPORT: | ||
151 | if (copy_to_user(argp, &adx_wdt_info, sizeof(adx_wdt_info))) | ||
152 | return -EFAULT; | ||
153 | else | ||
154 | return 0; | ||
155 | |||
156 | case WDIOC_GETSTATUS: | ||
157 | case WDIOC_GETBOOTSTATUS: | ||
158 | return put_user(0, p); | ||
159 | |||
160 | case WDIOC_KEEPALIVE: | ||
161 | adx_wdt_keepalive(wdt); | ||
162 | return 0; | ||
163 | |||
164 | case WDIOC_SETTIMEOUT: | ||
165 | if (get_user(seconds, p)) | ||
166 | return -EFAULT; | ||
167 | |||
168 | adx_wdt_set_timeout(wdt, seconds); | ||
169 | |||
170 | /* fallthrough */ | ||
171 | case WDIOC_GETTIMEOUT: | ||
172 | adx_wdt_get_timeout(wdt, &seconds); | ||
173 | return put_user(seconds, p); | ||
174 | |||
175 | case WDIOC_SETOPTIONS: | ||
176 | if (copy_from_user(&options, argp, sizeof(options))) | ||
177 | return -EFAULT; | ||
178 | |||
179 | if (options & WDIOS_DISABLECARD) { | ||
180 | adx_wdt_stop(wdt); | ||
181 | ret = 0; | ||
182 | } | ||
183 | |||
184 | if (options & WDIOS_ENABLECARD) { | ||
185 | adx_wdt_start(wdt); | ||
186 | ret = 0; | ||
187 | } | ||
188 | |||
189 | return ret; | ||
190 | |||
191 | default: | ||
192 | break; | ||
193 | } | ||
194 | |||
195 | return -ENOTTY; | ||
196 | } | ||
197 | |||
198 | static ssize_t adx_wdt_write(struct file *file, const char __user *data, | ||
199 | size_t len, loff_t *ppos) | ||
200 | { | ||
201 | struct adx_wdt *wdt = file->private_data; | ||
202 | |||
203 | if (len) | ||
204 | adx_wdt_keepalive(wdt); | ||
205 | |||
206 | return len; | ||
207 | } | ||
208 | |||
209 | static const struct file_operations adx_wdt_fops = { | ||
210 | .owner = THIS_MODULE, | ||
211 | .llseek = no_llseek, | ||
212 | .open = adx_wdt_open, | ||
213 | .release = adx_wdt_release, | ||
214 | .unlocked_ioctl = adx_wdt_ioctl, | ||
215 | .write = adx_wdt_write, | ||
216 | }; | ||
217 | |||
218 | static struct miscdevice adx_wdt_miscdev = { | ||
219 | .minor = WATCHDOG_MINOR, | ||
220 | .name = "watchdog", | ||
221 | .fops = &adx_wdt_fops, | ||
222 | }; | ||
223 | |||
224 | static int __devinit adx_wdt_probe(struct platform_device *pdev) | ||
225 | { | ||
226 | struct resource *res; | ||
227 | struct adx_wdt *wdt; | ||
228 | int ret = 0; | ||
229 | u32 ctrl; | ||
230 | |||
231 | wdt = devm_kzalloc(&pdev->dev, sizeof(*wdt), GFP_KERNEL); | ||
232 | if (!wdt) { | ||
233 | dev_err(&pdev->dev, "cannot allocate WDT structure\n"); | ||
234 | return -ENOMEM; | ||
235 | } | ||
236 | |||
237 | spin_lock_init(&wdt->lock); | ||
238 | |||
239 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
240 | if (!res) { | ||
241 | dev_err(&pdev->dev, "cannot obtain I/O memory region\n"); | ||
242 | return -ENXIO; | ||
243 | } | ||
244 | |||
245 | res = devm_request_mem_region(&pdev->dev, res->start, | ||
246 | resource_size(res), res->name); | ||
247 | if (!res) { | ||
248 | dev_err(&pdev->dev, "cannot request I/O memory region\n"); | ||
249 | return -ENXIO; | ||
250 | } | ||
251 | |||
252 | wdt->base = devm_ioremap_nocache(&pdev->dev, res->start, | ||
253 | resource_size(res)); | ||
254 | if (!wdt->base) { | ||
255 | dev_err(&pdev->dev, "cannot remap I/O memory region\n"); | ||
256 | return -ENXIO; | ||
257 | } | ||
258 | |||
259 | /* disable watchdog and reboot on timeout */ | ||
260 | ctrl = readl(wdt->base + ADX_WDT_CONTROL); | ||
261 | ctrl &= ~ADX_WDT_CONTROL_ENABLE; | ||
262 | ctrl &= ~ADX_WDT_CONTROL_nRESET; | ||
263 | writel(ctrl, wdt->base + ADX_WDT_CONTROL); | ||
264 | |||
265 | platform_set_drvdata(pdev, wdt); | ||
266 | adx_wdt_dev = pdev; | ||
267 | |||
268 | ret = misc_register(&adx_wdt_miscdev); | ||
269 | if (ret) { | ||
270 | dev_err(&pdev->dev, "cannot register miscdev on minor %d " | ||
271 | "(err=%d)\n", WATCHDOG_MINOR, ret); | ||
272 | return ret; | ||
273 | } | ||
274 | |||
275 | return 0; | ||
276 | } | ||
277 | |||
278 | static int __devexit adx_wdt_remove(struct platform_device *pdev) | ||
279 | { | ||
280 | struct adx_wdt *wdt = platform_get_drvdata(pdev); | ||
281 | |||
282 | misc_deregister(&adx_wdt_miscdev); | ||
283 | adx_wdt_stop(wdt); | ||
284 | platform_set_drvdata(pdev, NULL); | ||
285 | |||
286 | return 0; | ||
287 | } | ||
288 | |||
289 | static void adx_wdt_shutdown(struct platform_device *pdev) | ||
290 | { | ||
291 | struct adx_wdt *wdt = platform_get_drvdata(pdev); | ||
292 | adx_wdt_stop(wdt); | ||
293 | } | ||
294 | |||
295 | #ifdef CONFIG_PM | ||
296 | static int adx_wdt_suspend(struct device *dev) | ||
297 | { | ||
298 | struct platform_device *pdev = to_platform_device(dev); | ||
299 | struct adx_wdt *wdt = platform_get_drvdata(pdev); | ||
300 | |||
301 | wdt->wake = (wdt->state == WDT_STATE_START) ? 1 : 0; | ||
302 | adx_wdt_stop(wdt); | ||
303 | |||
304 | return 0; | ||
305 | } | ||
306 | |||
307 | static int adx_wdt_resume(struct device *dev) | ||
308 | { | ||
309 | struct platform_device *pdev = to_platform_device(dev); | ||
310 | struct adx_wdt *wdt = platform_get_drvdata(pdev); | ||
311 | |||
312 | if (wdt->wake) | ||
313 | adx_wdt_start(wdt); | ||
314 | |||
315 | return 0; | ||
316 | } | ||
317 | |||
318 | static const struct dev_pm_ops adx_wdt_pm_ops = { | ||
319 | .suspend = adx_wdt_suspend, | ||
320 | .resume = adx_wdt_resume, | ||
321 | }; | ||
322 | |||
323 | # define ADX_WDT_PM_OPS (&adx_wdt_pm_ops) | ||
324 | #else | ||
325 | # define ADX_WDT_PM_OPS NULL | ||
326 | #endif | ||
327 | |||
328 | static struct platform_driver adx_wdt_driver = { | ||
329 | .probe = adx_wdt_probe, | ||
330 | .remove = __devexit_p(adx_wdt_remove), | ||
331 | .shutdown = adx_wdt_shutdown, | ||
332 | .driver = { | ||
333 | .name = WATCHDOG_NAME, | ||
334 | .owner = THIS_MODULE, | ||
335 | .pm = ADX_WDT_PM_OPS, | ||
336 | }, | ||
337 | }; | ||
338 | |||
339 | static int __init adx_wdt_init(void) | ||
340 | { | ||
341 | return platform_driver_register(&adx_wdt_driver); | ||
342 | } | ||
343 | |||
344 | static void __exit adx_wdt_exit(void) | ||
345 | { | ||
346 | platform_driver_unregister(&adx_wdt_driver); | ||
347 | } | ||
348 | |||
349 | module_init(adx_wdt_init); | ||
350 | module_exit(adx_wdt_exit); | ||
351 | |||
352 | MODULE_DESCRIPTION("Avionic Design Xanthos Watchdog Driver"); | ||
353 | MODULE_LICENSE("GPL v2"); | ||
354 | MODULE_AUTHOR("Thierry Reding <thierry.reding@avionic-design.de>"); | ||
355 | MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR); | ||
diff --git a/drivers/watchdog/s3c2410_wdt.c b/drivers/watchdog/s3c2410_wdt.c index 5de7e4fa5b8a..a79e3840782a 100644 --- a/drivers/watchdog/s3c2410_wdt.c +++ b/drivers/watchdog/s3c2410_wdt.c | |||
@@ -401,8 +401,8 @@ static int __devinit s3c2410wdt_probe(struct platform_device *pdev) | |||
401 | 401 | ||
402 | dev_info(dev, "watchdog %sactive, reset %sabled, irq %sabled\n", | 402 | dev_info(dev, "watchdog %sactive, reset %sabled, irq %sabled\n", |
403 | (wtcon & S3C2410_WTCON_ENABLE) ? "" : "in", | 403 | (wtcon & S3C2410_WTCON_ENABLE) ? "" : "in", |
404 | (wtcon & S3C2410_WTCON_RSTEN) ? "" : "dis", | 404 | (wtcon & S3C2410_WTCON_RSTEN) ? "en" : "dis", |
405 | (wtcon & S3C2410_WTCON_INTEN) ? "" : "en"); | 405 | (wtcon & S3C2410_WTCON_INTEN) ? "en" : "dis"); |
406 | 406 | ||
407 | return 0; | 407 | return 0; |
408 | 408 | ||
diff --git a/drivers/watchdog/wm831x_wdt.c b/drivers/watchdog/wm831x_wdt.c index 7be38556aed0..e789a47db41f 100644 --- a/drivers/watchdog/wm831x_wdt.c +++ b/drivers/watchdog/wm831x_wdt.c | |||
@@ -150,7 +150,7 @@ static int wm831x_wdt_set_timeout(struct watchdog_device *wdt_dev, | |||
150 | if (wm831x_wdt_cfgs[i].time == timeout) | 150 | if (wm831x_wdt_cfgs[i].time == timeout) |
151 | break; | 151 | break; |
152 | if (i == ARRAY_SIZE(wm831x_wdt_cfgs)) | 152 | if (i == ARRAY_SIZE(wm831x_wdt_cfgs)) |
153 | ret = -EINVAL; | 153 | return -EINVAL; |
154 | 154 | ||
155 | ret = wm831x_reg_unlock(wm831x); | 155 | ret = wm831x_reg_unlock(wm831x); |
156 | if (ret == 0) { | 156 | if (ret == 0) { |