diff options
Diffstat (limited to 'drivers')
153 files changed, 1832 insertions, 1664 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/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 691276bafd78..e9cf51b1343b 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 7567b6000230..83695b48b010 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/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/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c index 2f91acccb7db..8873c6e6fb96 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/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/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 acc5e43c373e..7317dc2ec426 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 3d1bf41e8892..03d1984bd363 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) { |
