diff options
Diffstat (limited to 'drivers')
552 files changed, 7104 insertions, 5050 deletions
diff --git a/drivers/Makefile b/drivers/Makefile index 03da5b663aef..a16a8d001ae0 100644 --- a/drivers/Makefile +++ b/drivers/Makefile | |||
| @@ -17,6 +17,10 @@ obj-$(CONFIG_PARISC) += parisc/ | |||
| 17 | obj-$(CONFIG_RAPIDIO) += rapidio/ | 17 | obj-$(CONFIG_RAPIDIO) += rapidio/ |
| 18 | obj-y += video/ | 18 | obj-y += video/ |
| 19 | obj-y += idle/ | 19 | obj-y += idle/ |
| 20 | |||
| 21 | # IPMI must come before ACPI in order to provide IPMI opregion support | ||
| 22 | obj-$(CONFIG_IPMI_HANDLER) += char/ipmi/ | ||
| 23 | |||
| 20 | obj-$(CONFIG_ACPI) += acpi/ | 24 | obj-$(CONFIG_ACPI) += acpi/ |
| 21 | obj-$(CONFIG_SFI) += sfi/ | 25 | obj-$(CONFIG_SFI) += sfi/ |
| 22 | # PnP must come after ACPI since it will eventually need to check if acpi | 26 | # PnP must come after ACPI since it will eventually need to check if acpi |
diff --git a/drivers/acpi/Makefile b/drivers/acpi/Makefile index 47199e2a9130..82422fe90f81 100644 --- a/drivers/acpi/Makefile +++ b/drivers/acpi/Makefile | |||
| @@ -47,6 +47,10 @@ acpi-y += video_detect.o | |||
| 47 | endif | 47 | endif |
| 48 | 48 | ||
| 49 | # These are (potentially) separate modules | 49 | # These are (potentially) separate modules |
| 50 | |||
| 51 | # IPMI may be used by other drivers, so it has to initialise before them | ||
| 52 | obj-$(CONFIG_ACPI_IPMI) += acpi_ipmi.o | ||
| 53 | |||
| 50 | obj-$(CONFIG_ACPI_AC) += ac.o | 54 | obj-$(CONFIG_ACPI_AC) += ac.o |
| 51 | obj-$(CONFIG_ACPI_BUTTON) += button.o | 55 | obj-$(CONFIG_ACPI_BUTTON) += button.o |
| 52 | obj-$(CONFIG_ACPI_FAN) += fan.o | 56 | obj-$(CONFIG_ACPI_FAN) += fan.o |
| @@ -70,6 +74,5 @@ processor-y += processor_idle.o processor_thermal.o | |||
| 70 | processor-$(CONFIG_CPU_FREQ) += processor_perflib.o | 74 | processor-$(CONFIG_CPU_FREQ) += processor_perflib.o |
| 71 | 75 | ||
| 72 | obj-$(CONFIG_ACPI_PROCESSOR_AGGREGATOR) += acpi_pad.o | 76 | obj-$(CONFIG_ACPI_PROCESSOR_AGGREGATOR) += acpi_pad.o |
| 73 | obj-$(CONFIG_ACPI_IPMI) += acpi_ipmi.o | ||
| 74 | 77 | ||
| 75 | obj-$(CONFIG_ACPI_APEI) += apei/ | 78 | obj-$(CONFIG_ACPI_APEI) += apei/ |
diff --git a/drivers/acpi/glue.c b/drivers/acpi/glue.c index d1a2d74033e9..08373086cd7e 100644 --- a/drivers/acpi/glue.c +++ b/drivers/acpi/glue.c | |||
| @@ -159,6 +159,7 @@ static int acpi_bind_one(struct device *dev, acpi_handle handle) | |||
| 159 | if (physical_node->node_id >= ACPI_MAX_PHYSICAL_NODE) { | 159 | if (physical_node->node_id >= ACPI_MAX_PHYSICAL_NODE) { |
| 160 | retval = -ENOSPC; | 160 | retval = -ENOSPC; |
| 161 | mutex_unlock(&acpi_dev->physical_node_lock); | 161 | mutex_unlock(&acpi_dev->physical_node_lock); |
| 162 | kfree(physical_node); | ||
| 162 | goto err; | 163 | goto err; |
| 163 | } | 164 | } |
| 164 | 165 | ||
diff --git a/drivers/acpi/processor_driver.c b/drivers/acpi/processor_driver.c index e78c2a52ea46..bd4e5dca3ff7 100644 --- a/drivers/acpi/processor_driver.c +++ b/drivers/acpi/processor_driver.c | |||
| @@ -409,6 +409,7 @@ static void acpi_processor_notify(struct acpi_device *device, u32 event) | |||
| 409 | acpi_bus_generate_proc_event(device, event, 0); | 409 | acpi_bus_generate_proc_event(device, event, 0); |
| 410 | acpi_bus_generate_netlink_event(device->pnp.device_class, | 410 | acpi_bus_generate_netlink_event(device->pnp.device_class, |
| 411 | dev_name(&device->dev), event, 0); | 411 | dev_name(&device->dev), event, 0); |
| 412 | break; | ||
| 412 | default: | 413 | default: |
| 413 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, | 414 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, |
| 414 | "Unsupported event [0x%x]\n", event)); | 415 | "Unsupported event [0x%x]\n", event)); |
diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c index f94d4c818fc7..0230cb6cbb3a 100644 --- a/drivers/acpi/video.c +++ b/drivers/acpi/video.c | |||
| @@ -1345,12 +1345,15 @@ static int | |||
| 1345 | acpi_video_bus_get_devices(struct acpi_video_bus *video, | 1345 | acpi_video_bus_get_devices(struct acpi_video_bus *video, |
| 1346 | struct acpi_device *device) | 1346 | struct acpi_device *device) |
| 1347 | { | 1347 | { |
| 1348 | int status; | 1348 | int status = 0; |
| 1349 | struct acpi_device *dev; | 1349 | struct acpi_device *dev; |
| 1350 | 1350 | ||
| 1351 | status = acpi_video_device_enumerate(video); | 1351 | /* |
| 1352 | if (status) | 1352 | * There are systems where video module known to work fine regardless |
| 1353 | return status; | 1353 | * of broken _DOD and ignoring returned value here doesn't cause |
| 1354 | * any issues later. | ||
| 1355 | */ | ||
| 1356 | acpi_video_device_enumerate(video); | ||
| 1354 | 1357 | ||
| 1355 | list_for_each_entry(dev, &device->children, node) { | 1358 | list_for_each_entry(dev, &device->children, node) { |
| 1356 | 1359 | ||
diff --git a/drivers/ata/ahci_platform.c b/drivers/ata/ahci_platform.c index b1ae48054dc5..b7078afddb74 100644 --- a/drivers/ata/ahci_platform.c +++ b/drivers/ata/ahci_platform.c | |||
| @@ -238,7 +238,7 @@ static int __devexit ahci_remove(struct platform_device *pdev) | |||
| 238 | return 0; | 238 | return 0; |
| 239 | } | 239 | } |
| 240 | 240 | ||
| 241 | #ifdef CONFIG_PM | 241 | #ifdef CONFIG_PM_SLEEP |
| 242 | static int ahci_suspend(struct device *dev) | 242 | static int ahci_suspend(struct device *dev) |
| 243 | { | 243 | { |
| 244 | struct ahci_platform_data *pdata = dev_get_platdata(dev); | 244 | struct ahci_platform_data *pdata = dev_get_platdata(dev); |
diff --git a/drivers/ata/libata-acpi.c b/drivers/ata/libata-acpi.c index fd9ecf74e631..5b0ba3f20edc 100644 --- a/drivers/ata/libata-acpi.c +++ b/drivers/ata/libata-acpi.c | |||
| @@ -1105,10 +1105,15 @@ static int ata_acpi_bind_device(struct ata_port *ap, struct scsi_device *sdev, | |||
| 1105 | struct acpi_device *acpi_dev; | 1105 | struct acpi_device *acpi_dev; |
| 1106 | struct acpi_device_power_state *states; | 1106 | struct acpi_device_power_state *states; |
| 1107 | 1107 | ||
| 1108 | if (ap->flags & ATA_FLAG_ACPI_SATA) | 1108 | if (ap->flags & ATA_FLAG_ACPI_SATA) { |
| 1109 | ata_dev = &ap->link.device[sdev->channel]; | 1109 | if (!sata_pmp_attached(ap)) |
| 1110 | else | 1110 | ata_dev = &ap->link.device[sdev->id]; |
| 1111 | else | ||
| 1112 | ata_dev = &ap->pmp_link[sdev->channel].device[sdev->id]; | ||
| 1113 | } | ||
| 1114 | else { | ||
| 1111 | ata_dev = &ap->link.device[sdev->id]; | 1115 | ata_dev = &ap->link.device[sdev->id]; |
| 1116 | } | ||
| 1112 | 1117 | ||
| 1113 | *handle = ata_dev_acpi_handle(ata_dev); | 1118 | *handle = ata_dev_acpi_handle(ata_dev); |
| 1114 | 1119 | ||
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index 3cc7096cfda7..f46fbd3bd3fb 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c | |||
| @@ -2942,6 +2942,10 @@ const struct ata_timing *ata_timing_find_mode(u8 xfer_mode) | |||
| 2942 | 2942 | ||
| 2943 | if (xfer_mode == t->mode) | 2943 | if (xfer_mode == t->mode) |
| 2944 | return t; | 2944 | return t; |
| 2945 | |||
| 2946 | WARN_ONCE(true, "%s: unable to find timing for xfer_mode 0x%x\n", | ||
| 2947 | __func__, xfer_mode); | ||
| 2948 | |||
| 2945 | return NULL; | 2949 | return NULL; |
| 2946 | } | 2950 | } |
| 2947 | 2951 | ||
diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c index e3bda074fa12..a6df6a351d6e 100644 --- a/drivers/ata/libata-scsi.c +++ b/drivers/ata/libata-scsi.c | |||
| @@ -1052,6 +1052,8 @@ static void ata_scsi_sdev_config(struct scsi_device *sdev) | |||
| 1052 | { | 1052 | { |
| 1053 | sdev->use_10_for_rw = 1; | 1053 | sdev->use_10_for_rw = 1; |
| 1054 | sdev->use_10_for_ms = 1; | 1054 | sdev->use_10_for_ms = 1; |
| 1055 | sdev->no_report_opcodes = 1; | ||
| 1056 | sdev->no_write_same = 1; | ||
| 1055 | 1057 | ||
| 1056 | /* Schedule policy is determined by ->qc_defer() callback and | 1058 | /* Schedule policy is determined by ->qc_defer() callback and |
| 1057 | * it needs to see every deferred qc. Set dev_blocked to 1 to | 1059 | * it needs to see every deferred qc. Set dev_blocked to 1 to |
diff --git a/drivers/ata/pata_arasan_cf.c b/drivers/ata/pata_arasan_cf.c index 26201ebef3ca..371fd2c698b7 100644 --- a/drivers/ata/pata_arasan_cf.c +++ b/drivers/ata/pata_arasan_cf.c | |||
| @@ -317,6 +317,12 @@ static int cf_init(struct arasan_cf_dev *acdev) | |||
| 317 | return ret; | 317 | return ret; |
| 318 | } | 318 | } |
| 319 | 319 | ||
| 320 | ret = clk_set_rate(acdev->clk, 166000000); | ||
| 321 | if (ret) { | ||
| 322 | dev_warn(acdev->host->dev, "clock set rate failed"); | ||
| 323 | return ret; | ||
| 324 | } | ||
| 325 | |||
| 320 | spin_lock_irqsave(&acdev->host->lock, flags); | 326 | spin_lock_irqsave(&acdev->host->lock, flags); |
| 321 | /* configure CF interface clock */ | 327 | /* configure CF interface clock */ |
| 322 | writel((pdata->cf_if_clk <= CF_IF_CLK_200M) ? pdata->cf_if_clk : | 328 | writel((pdata->cf_if_clk <= CF_IF_CLK_200M) ? pdata->cf_if_clk : |
| @@ -908,7 +914,7 @@ static int __devexit arasan_cf_remove(struct platform_device *pdev) | |||
| 908 | return 0; | 914 | return 0; |
| 909 | } | 915 | } |
| 910 | 916 | ||
| 911 | #ifdef CONFIG_PM | 917 | #ifdef CONFIG_PM_SLEEP |
| 912 | static int arasan_cf_suspend(struct device *dev) | 918 | static int arasan_cf_suspend(struct device *dev) |
| 913 | { | 919 | { |
| 914 | struct ata_host *host = dev_get_drvdata(dev); | 920 | struct ata_host *host = dev_get_drvdata(dev); |
diff --git a/drivers/ata/sata_highbank.c b/drivers/ata/sata_highbank.c index 0d7c4c2cd26f..400bf1c3e982 100644 --- a/drivers/ata/sata_highbank.c +++ b/drivers/ata/sata_highbank.c | |||
| @@ -260,7 +260,7 @@ static const struct of_device_id ahci_of_match[] = { | |||
| 260 | }; | 260 | }; |
| 261 | MODULE_DEVICE_TABLE(of, ahci_of_match); | 261 | MODULE_DEVICE_TABLE(of, ahci_of_match); |
| 262 | 262 | ||
| 263 | static int __init ahci_highbank_probe(struct platform_device *pdev) | 263 | static int __devinit ahci_highbank_probe(struct platform_device *pdev) |
| 264 | { | 264 | { |
| 265 | struct device *dev = &pdev->dev; | 265 | struct device *dev = &pdev->dev; |
| 266 | struct ahci_host_priv *hpriv; | 266 | struct ahci_host_priv *hpriv; |
| @@ -378,7 +378,7 @@ static int __devexit ahci_highbank_remove(struct platform_device *pdev) | |||
| 378 | return 0; | 378 | return 0; |
| 379 | } | 379 | } |
| 380 | 380 | ||
| 381 | #ifdef CONFIG_PM | 381 | #ifdef CONFIG_PM_SLEEP |
| 382 | static int ahci_highbank_suspend(struct device *dev) | 382 | static int ahci_highbank_suspend(struct device *dev) |
| 383 | { | 383 | { |
| 384 | struct ata_host *host = dev_get_drvdata(dev); | 384 | struct ata_host *host = dev_get_drvdata(dev); |
diff --git a/drivers/ata/sata_svw.c b/drivers/ata/sata_svw.c index 44a4256533e1..08608de87e4e 100644 --- a/drivers/ata/sata_svw.c +++ b/drivers/ata/sata_svw.c | |||
| @@ -142,6 +142,39 @@ static int k2_sata_scr_write(struct ata_link *link, | |||
| 142 | return 0; | 142 | return 0; |
| 143 | } | 143 | } |
| 144 | 144 | ||
| 145 | static int k2_sata_softreset(struct ata_link *link, | ||
| 146 | unsigned int *class, unsigned long deadline) | ||
| 147 | { | ||
| 148 | u8 dmactl; | ||
| 149 | void __iomem *mmio = link->ap->ioaddr.bmdma_addr; | ||
| 150 | |||
| 151 | dmactl = readb(mmio + ATA_DMA_CMD); | ||
| 152 | |||
| 153 | /* Clear the start bit */ | ||
| 154 | if (dmactl & ATA_DMA_START) { | ||
| 155 | dmactl &= ~ATA_DMA_START; | ||
| 156 | writeb(dmactl, mmio + ATA_DMA_CMD); | ||
| 157 | } | ||
| 158 | |||
| 159 | return ata_sff_softreset(link, class, deadline); | ||
| 160 | } | ||
| 161 | |||
| 162 | static int k2_sata_hardreset(struct ata_link *link, | ||
| 163 | unsigned int *class, unsigned long deadline) | ||
| 164 | { | ||
| 165 | u8 dmactl; | ||
| 166 | void __iomem *mmio = link->ap->ioaddr.bmdma_addr; | ||
| 167 | |||
| 168 | dmactl = readb(mmio + ATA_DMA_CMD); | ||
| 169 | |||
| 170 | /* Clear the start bit */ | ||
| 171 | if (dmactl & ATA_DMA_START) { | ||
| 172 | dmactl &= ~ATA_DMA_START; | ||
| 173 | writeb(dmactl, mmio + ATA_DMA_CMD); | ||
| 174 | } | ||
| 175 | |||
| 176 | return sata_sff_hardreset(link, class, deadline); | ||
| 177 | } | ||
| 145 | 178 | ||
| 146 | static void k2_sata_tf_load(struct ata_port *ap, const struct ata_taskfile *tf) | 179 | static void k2_sata_tf_load(struct ata_port *ap, const struct ata_taskfile *tf) |
| 147 | { | 180 | { |
| @@ -346,6 +379,8 @@ static struct scsi_host_template k2_sata_sht = { | |||
| 346 | 379 | ||
| 347 | static struct ata_port_operations k2_sata_ops = { | 380 | static struct ata_port_operations k2_sata_ops = { |
| 348 | .inherits = &ata_bmdma_port_ops, | 381 | .inherits = &ata_bmdma_port_ops, |
| 382 | .softreset = k2_sata_softreset, | ||
| 383 | .hardreset = k2_sata_hardreset, | ||
| 349 | .sff_tf_load = k2_sata_tf_load, | 384 | .sff_tf_load = k2_sata_tf_load, |
| 350 | .sff_tf_read = k2_sata_tf_read, | 385 | .sff_tf_read = k2_sata_tf_read, |
| 351 | .sff_check_status = k2_stat_check_status, | 386 | .sff_check_status = k2_stat_check_status, |
diff --git a/drivers/atm/ambassador.c b/drivers/atm/ambassador.c index 89b30f32ba68..ff7bb8a42ed6 100644 --- a/drivers/atm/ambassador.c +++ b/drivers/atm/ambassador.c | |||
| @@ -1961,6 +1961,7 @@ static int __devinit ucode_init (loader_block * lb, amb_dev * dev) { | |||
| 1961 | res = loader_verify(lb, dev, rec); | 1961 | res = loader_verify(lb, dev, rec); |
| 1962 | if (res) | 1962 | if (res) |
| 1963 | break; | 1963 | break; |
| 1964 | rec = ihex_next_binrec(rec); | ||
| 1964 | } | 1965 | } |
| 1965 | release_firmware(fw); | 1966 | release_firmware(fw); |
| 1966 | if (!res) | 1967 | if (!res) |
diff --git a/drivers/base/Kconfig b/drivers/base/Kconfig index 08b4c5209384..b34b5cda5ae1 100644 --- a/drivers/base/Kconfig +++ b/drivers/base/Kconfig | |||
| @@ -236,7 +236,7 @@ config CMA_SIZE_PERCENTAGE | |||
| 236 | 236 | ||
| 237 | choice | 237 | choice |
| 238 | prompt "Selected region size" | 238 | prompt "Selected region size" |
| 239 | default CMA_SIZE_SEL_ABSOLUTE | 239 | default CMA_SIZE_SEL_MBYTES |
| 240 | 240 | ||
| 241 | config CMA_SIZE_SEL_MBYTES | 241 | config CMA_SIZE_SEL_MBYTES |
| 242 | bool "Use mega bytes value only" | 242 | bool "Use mega bytes value only" |
diff --git a/drivers/base/dma-coherent.c b/drivers/base/dma-coherent.c index 560a7173f810..bc256b641027 100644 --- a/drivers/base/dma-coherent.c +++ b/drivers/base/dma-coherent.c | |||
| @@ -191,9 +191,8 @@ EXPORT_SYMBOL(dma_release_from_coherent); | |||
| 191 | * This checks whether the memory was allocated from the per-device | 191 | * This checks whether the memory was allocated from the per-device |
| 192 | * coherent memory pool and if so, maps that memory to the provided vma. | 192 | * coherent memory pool and if so, maps that memory to the provided vma. |
| 193 | * | 193 | * |
| 194 | * Returns 1 if we correctly mapped the memory, or 0 if | 194 | * Returns 1 if we correctly mapped the memory, or 0 if the caller should |
| 195 | * dma_release_coherent() should proceed with mapping memory from | 195 | * proceed with mapping memory from generic pools. |
| 196 | * generic pools. | ||
| 197 | */ | 196 | */ |
| 198 | int dma_mmap_from_coherent(struct device *dev, struct vm_area_struct *vma, | 197 | int dma_mmap_from_coherent(struct device *dev, struct vm_area_struct *vma, |
| 199 | void *vaddr, size_t size, int *ret) | 198 | void *vaddr, size_t size, int *ret) |
diff --git a/drivers/base/dma-contiguous.c b/drivers/base/dma-contiguous.c index 9a1469474f55..612afcc5a938 100644 --- a/drivers/base/dma-contiguous.c +++ b/drivers/base/dma-contiguous.c | |||
| @@ -27,15 +27,12 @@ | |||
| 27 | #include <linux/mm.h> | 27 | #include <linux/mm.h> |
| 28 | #include <linux/mutex.h> | 28 | #include <linux/mutex.h> |
| 29 | #include <linux/page-isolation.h> | 29 | #include <linux/page-isolation.h> |
| 30 | #include <linux/sizes.h> | ||
| 30 | #include <linux/slab.h> | 31 | #include <linux/slab.h> |
| 31 | #include <linux/swap.h> | 32 | #include <linux/swap.h> |
| 32 | #include <linux/mm_types.h> | 33 | #include <linux/mm_types.h> |
| 33 | #include <linux/dma-contiguous.h> | 34 | #include <linux/dma-contiguous.h> |
| 34 | 35 | ||
| 35 | #ifndef SZ_1M | ||
| 36 | #define SZ_1M (1 << 20) | ||
| 37 | #endif | ||
| 38 | |||
| 39 | struct cma { | 36 | struct cma { |
| 40 | unsigned long base_pfn; | 37 | unsigned long base_pfn; |
| 41 | unsigned long count; | 38 | unsigned long count; |
diff --git a/drivers/base/firmware_class.c b/drivers/base/firmware_class.c index 81541452887b..8945f4e489ed 100644 --- a/drivers/base/firmware_class.c +++ b/drivers/base/firmware_class.c | |||
| @@ -36,68 +36,6 @@ MODULE_AUTHOR("Manuel Estrada Sainz"); | |||
| 36 | MODULE_DESCRIPTION("Multi purpose firmware loading support"); | 36 | MODULE_DESCRIPTION("Multi purpose firmware loading support"); |
| 37 | MODULE_LICENSE("GPL"); | 37 | MODULE_LICENSE("GPL"); |
| 38 | 38 | ||
| 39 | static const char *fw_path[] = { | ||
| 40 | "/lib/firmware/updates/" UTS_RELEASE, | ||
| 41 | "/lib/firmware/updates", | ||
| 42 | "/lib/firmware/" UTS_RELEASE, | ||
| 43 | "/lib/firmware" | ||
| 44 | }; | ||
| 45 | |||
| 46 | /* Don't inline this: 'struct kstat' is biggish */ | ||
| 47 | static noinline long fw_file_size(struct file *file) | ||
| 48 | { | ||
| 49 | struct kstat st; | ||
| 50 | if (vfs_getattr(file->f_path.mnt, file->f_path.dentry, &st)) | ||
| 51 | return -1; | ||
| 52 | if (!S_ISREG(st.mode)) | ||
| 53 | return -1; | ||
| 54 | if (st.size != (long)st.size) | ||
| 55 | return -1; | ||
| 56 | return st.size; | ||
| 57 | } | ||
| 58 | |||
| 59 | static bool fw_read_file_contents(struct file *file, struct firmware *fw) | ||
| 60 | { | ||
| 61 | long size; | ||
| 62 | char *buf; | ||
| 63 | |||
| 64 | size = fw_file_size(file); | ||
| 65 | if (size < 0) | ||
| 66 | return false; | ||
| 67 | buf = vmalloc(size); | ||
| 68 | if (!buf) | ||
| 69 | return false; | ||
| 70 | if (kernel_read(file, 0, buf, size) != size) { | ||
| 71 | vfree(buf); | ||
| 72 | return false; | ||
| 73 | } | ||
| 74 | fw->data = buf; | ||
| 75 | fw->size = size; | ||
| 76 | return true; | ||
| 77 | } | ||
| 78 | |||
| 79 | static bool fw_get_filesystem_firmware(struct firmware *fw, const char *name) | ||
| 80 | { | ||
| 81 | int i; | ||
| 82 | bool success = false; | ||
| 83 | char *path = __getname(); | ||
| 84 | |||
| 85 | for (i = 0; i < ARRAY_SIZE(fw_path); i++) { | ||
| 86 | struct file *file; | ||
| 87 | snprintf(path, PATH_MAX, "%s/%s", fw_path[i], name); | ||
| 88 | |||
| 89 | file = filp_open(path, O_RDONLY, 0); | ||
| 90 | if (IS_ERR(file)) | ||
| 91 | continue; | ||
| 92 | success = fw_read_file_contents(file, fw); | ||
| 93 | fput(file); | ||
| 94 | if (success) | ||
| 95 | break; | ||
| 96 | } | ||
| 97 | __putname(path); | ||
| 98 | return success; | ||
| 99 | } | ||
| 100 | |||
| 101 | /* Builtin firmware support */ | 39 | /* Builtin firmware support */ |
| 102 | 40 | ||
| 103 | #ifdef CONFIG_FW_LOADER | 41 | #ifdef CONFIG_FW_LOADER |
| @@ -150,6 +88,11 @@ enum { | |||
| 150 | FW_STATUS_ABORT, | 88 | FW_STATUS_ABORT, |
| 151 | }; | 89 | }; |
| 152 | 90 | ||
| 91 | enum fw_buf_fmt { | ||
| 92 | VMALLOC_BUF, /* used in direct loading */ | ||
| 93 | PAGE_BUF, /* used in loading via userspace */ | ||
| 94 | }; | ||
| 95 | |||
| 153 | static int loading_timeout = 60; /* In seconds */ | 96 | static int loading_timeout = 60; /* In seconds */ |
| 154 | 97 | ||
| 155 | static inline long firmware_loading_timeout(void) | 98 | static inline long firmware_loading_timeout(void) |
| @@ -173,8 +116,6 @@ struct firmware_cache { | |||
| 173 | spinlock_t name_lock; | 116 | spinlock_t name_lock; |
| 174 | struct list_head fw_names; | 117 | struct list_head fw_names; |
| 175 | 118 | ||
| 176 | wait_queue_head_t wait_queue; | ||
| 177 | int cnt; | ||
| 178 | struct delayed_work work; | 119 | struct delayed_work work; |
| 179 | 120 | ||
| 180 | struct notifier_block pm_notify; | 121 | struct notifier_block pm_notify; |
| @@ -187,6 +128,7 @@ struct firmware_buf { | |||
| 187 | struct completion completion; | 128 | struct completion completion; |
| 188 | struct firmware_cache *fwc; | 129 | struct firmware_cache *fwc; |
| 189 | unsigned long status; | 130 | unsigned long status; |
| 131 | enum fw_buf_fmt fmt; | ||
| 190 | void *data; | 132 | void *data; |
| 191 | size_t size; | 133 | size_t size; |
| 192 | struct page **pages; | 134 | struct page **pages; |
| @@ -240,6 +182,7 @@ static struct firmware_buf *__allocate_fw_buf(const char *fw_name, | |||
| 240 | strcpy(buf->fw_id, fw_name); | 182 | strcpy(buf->fw_id, fw_name); |
| 241 | buf->fwc = fwc; | 183 | buf->fwc = fwc; |
| 242 | init_completion(&buf->completion); | 184 | init_completion(&buf->completion); |
| 185 | buf->fmt = VMALLOC_BUF; | ||
| 243 | 186 | ||
| 244 | pr_debug("%s: fw-%s buf=%p\n", __func__, fw_name, buf); | 187 | pr_debug("%s: fw-%s buf=%p\n", __func__, fw_name, buf); |
| 245 | 188 | ||
| @@ -307,10 +250,14 @@ static void __fw_free_buf(struct kref *ref) | |||
| 307 | list_del(&buf->list); | 250 | list_del(&buf->list); |
| 308 | spin_unlock(&fwc->lock); | 251 | spin_unlock(&fwc->lock); |
| 309 | 252 | ||
| 310 | vunmap(buf->data); | 253 | |
| 311 | for (i = 0; i < buf->nr_pages; i++) | 254 | if (buf->fmt == PAGE_BUF) { |
| 312 | __free_page(buf->pages[i]); | 255 | vunmap(buf->data); |
| 313 | kfree(buf->pages); | 256 | for (i = 0; i < buf->nr_pages; i++) |
| 257 | __free_page(buf->pages[i]); | ||
| 258 | kfree(buf->pages); | ||
| 259 | } else | ||
| 260 | vfree(buf->data); | ||
| 314 | kfree(buf); | 261 | kfree(buf); |
| 315 | } | 262 | } |
| 316 | 263 | ||
| @@ -319,6 +266,69 @@ static void fw_free_buf(struct firmware_buf *buf) | |||
| 319 | kref_put(&buf->ref, __fw_free_buf); | 266 | kref_put(&buf->ref, __fw_free_buf); |
| 320 | } | 267 | } |
| 321 | 268 | ||
| 269 | /* direct firmware loading support */ | ||
| 270 | static const char *fw_path[] = { | ||
| 271 | "/lib/firmware/updates/" UTS_RELEASE, | ||
| 272 | "/lib/firmware/updates", | ||
| 273 | "/lib/firmware/" UTS_RELEASE, | ||
| 274 | "/lib/firmware" | ||
| 275 | }; | ||
| 276 | |||
| 277 | /* Don't inline this: 'struct kstat' is biggish */ | ||
| 278 | static noinline long fw_file_size(struct file *file) | ||
| 279 | { | ||
| 280 | struct kstat st; | ||
| 281 | if (vfs_getattr(file->f_path.mnt, file->f_path.dentry, &st)) | ||
| 282 | return -1; | ||
| 283 | if (!S_ISREG(st.mode)) | ||
| 284 | return -1; | ||
| 285 | if (st.size != (long)st.size) | ||
| 286 | return -1; | ||
| 287 | return st.size; | ||
| 288 | } | ||
| 289 | |||
| 290 | static bool fw_read_file_contents(struct file *file, struct firmware_buf *fw_buf) | ||
| 291 | { | ||
| 292 | long size; | ||
| 293 | char *buf; | ||
| 294 | |||
| 295 | size = fw_file_size(file); | ||
| 296 | if (size < 0) | ||
| 297 | return false; | ||
| 298 | buf = vmalloc(size); | ||
| 299 | if (!buf) | ||
| 300 | return false; | ||
| 301 | if (kernel_read(file, 0, buf, size) != size) { | ||
| 302 | vfree(buf); | ||
| 303 | return false; | ||
| 304 | } | ||
| 305 | fw_buf->data = buf; | ||
| 306 | fw_buf->size = size; | ||
| 307 | return true; | ||
| 308 | } | ||
| 309 | |||
| 310 | static bool fw_get_filesystem_firmware(struct firmware_buf *buf) | ||
| 311 | { | ||
| 312 | int i; | ||
| 313 | bool success = false; | ||
| 314 | char *path = __getname(); | ||
| 315 | |||
| 316 | for (i = 0; i < ARRAY_SIZE(fw_path); i++) { | ||
| 317 | struct file *file; | ||
| 318 | snprintf(path, PATH_MAX, "%s/%s", fw_path[i], buf->fw_id); | ||
| 319 | |||
| 320 | file = filp_open(path, O_RDONLY, 0); | ||
| 321 | if (IS_ERR(file)) | ||
| 322 | continue; | ||
| 323 | success = fw_read_file_contents(file, buf); | ||
| 324 | fput(file); | ||
| 325 | if (success) | ||
| 326 | break; | ||
| 327 | } | ||
| 328 | __putname(path); | ||
| 329 | return success; | ||
| 330 | } | ||
| 331 | |||
| 322 | static struct firmware_priv *to_firmware_priv(struct device *dev) | 332 | static struct firmware_priv *to_firmware_priv(struct device *dev) |
| 323 | { | 333 | { |
| 324 | return container_of(dev, struct firmware_priv, dev); | 334 | return container_of(dev, struct firmware_priv, dev); |
| @@ -423,6 +433,21 @@ static void firmware_free_data(const struct firmware *fw) | |||
| 423 | #ifndef PAGE_KERNEL_RO | 433 | #ifndef PAGE_KERNEL_RO |
| 424 | #define PAGE_KERNEL_RO PAGE_KERNEL | 434 | #define PAGE_KERNEL_RO PAGE_KERNEL |
| 425 | #endif | 435 | #endif |
| 436 | |||
| 437 | /* one pages buffer should be mapped/unmapped only once */ | ||
| 438 | static int fw_map_pages_buf(struct firmware_buf *buf) | ||
| 439 | { | ||
| 440 | if (buf->fmt != PAGE_BUF) | ||
| 441 | return 0; | ||
| 442 | |||
| 443 | if (buf->data) | ||
| 444 | vunmap(buf->data); | ||
| 445 | buf->data = vmap(buf->pages, buf->nr_pages, 0, PAGE_KERNEL_RO); | ||
| 446 | if (!buf->data) | ||
| 447 | return -ENOMEM; | ||
| 448 | return 0; | ||
| 449 | } | ||
| 450 | |||
| 426 | /** | 451 | /** |
| 427 | * firmware_loading_store - set value in the 'loading' control file | 452 | * firmware_loading_store - set value in the 'loading' control file |
| 428 | * @dev: device pointer | 453 | * @dev: device pointer |
| @@ -467,6 +492,14 @@ static ssize_t firmware_loading_store(struct device *dev, | |||
| 467 | if (test_bit(FW_STATUS_LOADING, &fw_buf->status)) { | 492 | if (test_bit(FW_STATUS_LOADING, &fw_buf->status)) { |
| 468 | set_bit(FW_STATUS_DONE, &fw_buf->status); | 493 | set_bit(FW_STATUS_DONE, &fw_buf->status); |
| 469 | clear_bit(FW_STATUS_LOADING, &fw_buf->status); | 494 | clear_bit(FW_STATUS_LOADING, &fw_buf->status); |
| 495 | |||
| 496 | /* | ||
| 497 | * Several loading requests may be pending on | ||
| 498 | * one same firmware buf, so let all requests | ||
| 499 | * see the mapped 'buf->data' once the loading | ||
| 500 | * is completed. | ||
| 501 | * */ | ||
| 502 | fw_map_pages_buf(fw_buf); | ||
| 470 | complete_all(&fw_buf->completion); | 503 | complete_all(&fw_buf->completion); |
| 471 | break; | 504 | break; |
| 472 | } | 505 | } |
| @@ -670,15 +703,6 @@ exit: | |||
| 670 | return fw_priv; | 703 | return fw_priv; |
| 671 | } | 704 | } |
| 672 | 705 | ||
| 673 | /* one pages buffer is mapped/unmapped only once */ | ||
| 674 | static int fw_map_pages_buf(struct firmware_buf *buf) | ||
| 675 | { | ||
| 676 | buf->data = vmap(buf->pages, buf->nr_pages, 0, PAGE_KERNEL_RO); | ||
| 677 | if (!buf->data) | ||
| 678 | return -ENOMEM; | ||
| 679 | return 0; | ||
| 680 | } | ||
| 681 | |||
| 682 | /* store the pages buffer info firmware from buf */ | 706 | /* store the pages buffer info firmware from buf */ |
| 683 | static void fw_set_page_data(struct firmware_buf *buf, struct firmware *fw) | 707 | static void fw_set_page_data(struct firmware_buf *buf, struct firmware *fw) |
| 684 | { | 708 | { |
| @@ -778,11 +802,6 @@ _request_firmware_prepare(const struct firmware **firmware_p, const char *name, | |||
| 778 | return NULL; | 802 | return NULL; |
| 779 | } | 803 | } |
| 780 | 804 | ||
| 781 | if (fw_get_filesystem_firmware(firmware, name)) { | ||
| 782 | dev_dbg(device, "firmware: direct-loading firmware %s\n", name); | ||
| 783 | return NULL; | ||
| 784 | } | ||
| 785 | |||
| 786 | ret = fw_lookup_and_allocate_buf(name, &fw_cache, &buf); | 805 | ret = fw_lookup_and_allocate_buf(name, &fw_cache, &buf); |
| 787 | if (!ret) | 806 | if (!ret) |
| 788 | fw_priv = fw_create_instance(firmware, name, device, | 807 | fw_priv = fw_create_instance(firmware, name, device, |
| @@ -832,6 +851,21 @@ static int _request_firmware_load(struct firmware_priv *fw_priv, bool uevent, | |||
| 832 | struct device *f_dev = &fw_priv->dev; | 851 | struct device *f_dev = &fw_priv->dev; |
| 833 | struct firmware_buf *buf = fw_priv->buf; | 852 | struct firmware_buf *buf = fw_priv->buf; |
| 834 | struct firmware_cache *fwc = &fw_cache; | 853 | struct firmware_cache *fwc = &fw_cache; |
| 854 | int direct_load = 0; | ||
| 855 | |||
| 856 | /* try direct loading from fs first */ | ||
| 857 | if (fw_get_filesystem_firmware(buf)) { | ||
| 858 | dev_dbg(f_dev->parent, "firmware: direct-loading" | ||
| 859 | " firmware %s\n", buf->fw_id); | ||
| 860 | |||
| 861 | set_bit(FW_STATUS_DONE, &buf->status); | ||
| 862 | complete_all(&buf->completion); | ||
| 863 | direct_load = 1; | ||
| 864 | goto handle_fw; | ||
| 865 | } | ||
| 866 | |||
| 867 | /* fall back on userspace loading */ | ||
| 868 | buf->fmt = PAGE_BUF; | ||
| 835 | 869 | ||
| 836 | dev_set_uevent_suppress(f_dev, true); | 870 | dev_set_uevent_suppress(f_dev, true); |
| 837 | 871 | ||
| @@ -870,6 +904,7 @@ static int _request_firmware_load(struct firmware_priv *fw_priv, bool uevent, | |||
| 870 | 904 | ||
| 871 | del_timer_sync(&fw_priv->timeout); | 905 | del_timer_sync(&fw_priv->timeout); |
| 872 | 906 | ||
| 907 | handle_fw: | ||
| 873 | mutex_lock(&fw_lock); | 908 | mutex_lock(&fw_lock); |
| 874 | if (!buf->size || test_bit(FW_STATUS_ABORT, &buf->status)) | 909 | if (!buf->size || test_bit(FW_STATUS_ABORT, &buf->status)) |
| 875 | retval = -ENOENT; | 910 | retval = -ENOENT; |
| @@ -884,9 +919,6 @@ static int _request_firmware_load(struct firmware_priv *fw_priv, bool uevent, | |||
| 884 | if (!retval && f_dev->parent) | 919 | if (!retval && f_dev->parent) |
| 885 | fw_add_devm_name(f_dev->parent, buf->fw_id); | 920 | fw_add_devm_name(f_dev->parent, buf->fw_id); |
| 886 | 921 | ||
| 887 | if (!retval) | ||
| 888 | retval = fw_map_pages_buf(buf); | ||
| 889 | |||
| 890 | /* | 922 | /* |
| 891 | * After caching firmware image is started, let it piggyback | 923 | * After caching firmware image is started, let it piggyback |
| 892 | * on request firmware. | 924 | * on request firmware. |
| @@ -902,6 +934,9 @@ static int _request_firmware_load(struct firmware_priv *fw_priv, bool uevent, | |||
| 902 | fw_priv->buf = NULL; | 934 | fw_priv->buf = NULL; |
| 903 | mutex_unlock(&fw_lock); | 935 | mutex_unlock(&fw_lock); |
| 904 | 936 | ||
| 937 | if (direct_load) | ||
| 938 | goto err_put_dev; | ||
| 939 | |||
| 905 | device_remove_file(f_dev, &dev_attr_loading); | 940 | device_remove_file(f_dev, &dev_attr_loading); |
| 906 | err_del_bin_attr: | 941 | err_del_bin_attr: |
| 907 | device_remove_bin_file(f_dev, &firmware_attr_data); | 942 | device_remove_bin_file(f_dev, &firmware_attr_data); |
| @@ -1129,6 +1164,8 @@ int uncache_firmware(const char *fw_name) | |||
| 1129 | } | 1164 | } |
| 1130 | 1165 | ||
| 1131 | #ifdef CONFIG_PM_SLEEP | 1166 | #ifdef CONFIG_PM_SLEEP |
| 1167 | static ASYNC_DOMAIN_EXCLUSIVE(fw_cache_domain); | ||
| 1168 | |||
| 1132 | static struct fw_cache_entry *alloc_fw_cache_entry(const char *name) | 1169 | static struct fw_cache_entry *alloc_fw_cache_entry(const char *name) |
| 1133 | { | 1170 | { |
| 1134 | struct fw_cache_entry *fce; | 1171 | struct fw_cache_entry *fce; |
| @@ -1142,17 +1179,27 @@ exit: | |||
| 1142 | return fce; | 1179 | return fce; |
| 1143 | } | 1180 | } |
| 1144 | 1181 | ||
| 1145 | static int fw_cache_piggyback_on_request(const char *name) | 1182 | static int __fw_entry_found(const char *name) |
| 1146 | { | 1183 | { |
| 1147 | struct firmware_cache *fwc = &fw_cache; | 1184 | struct firmware_cache *fwc = &fw_cache; |
| 1148 | struct fw_cache_entry *fce; | 1185 | struct fw_cache_entry *fce; |
| 1149 | int ret = 0; | ||
| 1150 | 1186 | ||
| 1151 | spin_lock(&fwc->name_lock); | ||
| 1152 | list_for_each_entry(fce, &fwc->fw_names, list) { | 1187 | list_for_each_entry(fce, &fwc->fw_names, list) { |
| 1153 | if (!strcmp(fce->name, name)) | 1188 | if (!strcmp(fce->name, name)) |
| 1154 | goto found; | 1189 | return 1; |
| 1155 | } | 1190 | } |
| 1191 | return 0; | ||
| 1192 | } | ||
| 1193 | |||
| 1194 | static int fw_cache_piggyback_on_request(const char *name) | ||
| 1195 | { | ||
| 1196 | struct firmware_cache *fwc = &fw_cache; | ||
| 1197 | struct fw_cache_entry *fce; | ||
| 1198 | int ret = 0; | ||
| 1199 | |||
| 1200 | spin_lock(&fwc->name_lock); | ||
| 1201 | if (__fw_entry_found(name)) | ||
| 1202 | goto found; | ||
| 1156 | 1203 | ||
| 1157 | fce = alloc_fw_cache_entry(name); | 1204 | fce = alloc_fw_cache_entry(name); |
| 1158 | if (fce) { | 1205 | if (fce) { |
| @@ -1185,12 +1232,6 @@ static void __async_dev_cache_fw_image(void *fw_entry, | |||
| 1185 | 1232 | ||
| 1186 | free_fw_cache_entry(fce); | 1233 | free_fw_cache_entry(fce); |
| 1187 | } | 1234 | } |
| 1188 | |||
| 1189 | spin_lock(&fwc->name_lock); | ||
| 1190 | fwc->cnt--; | ||
| 1191 | spin_unlock(&fwc->name_lock); | ||
| 1192 | |||
| 1193 | wake_up(&fwc->wait_queue); | ||
| 1194 | } | 1235 | } |
| 1195 | 1236 | ||
| 1196 | /* called with dev->devres_lock held */ | 1237 | /* called with dev->devres_lock held */ |
| @@ -1229,11 +1270,19 @@ static void dev_cache_fw_image(struct device *dev, void *data) | |||
| 1229 | list_del(&fce->list); | 1270 | list_del(&fce->list); |
| 1230 | 1271 | ||
| 1231 | spin_lock(&fwc->name_lock); | 1272 | spin_lock(&fwc->name_lock); |
| 1232 | fwc->cnt++; | 1273 | /* only one cache entry for one firmware */ |
| 1233 | list_add(&fce->list, &fwc->fw_names); | 1274 | if (!__fw_entry_found(fce->name)) { |
| 1275 | list_add(&fce->list, &fwc->fw_names); | ||
| 1276 | } else { | ||
| 1277 | free_fw_cache_entry(fce); | ||
| 1278 | fce = NULL; | ||
| 1279 | } | ||
| 1234 | spin_unlock(&fwc->name_lock); | 1280 | spin_unlock(&fwc->name_lock); |
| 1235 | 1281 | ||
| 1236 | async_schedule(__async_dev_cache_fw_image, (void *)fce); | 1282 | if (fce) |
| 1283 | async_schedule_domain(__async_dev_cache_fw_image, | ||
| 1284 | (void *)fce, | ||
| 1285 | &fw_cache_domain); | ||
| 1237 | } | 1286 | } |
| 1238 | } | 1287 | } |
| 1239 | 1288 | ||
| @@ -1275,6 +1324,9 @@ static void device_cache_fw_images(void) | |||
| 1275 | 1324 | ||
| 1276 | pr_debug("%s\n", __func__); | 1325 | pr_debug("%s\n", __func__); |
| 1277 | 1326 | ||
| 1327 | /* cancel uncache work */ | ||
| 1328 | cancel_delayed_work_sync(&fwc->work); | ||
| 1329 | |||
| 1278 | /* | 1330 | /* |
| 1279 | * use small loading timeout for caching devices' firmware | 1331 | * use small loading timeout for caching devices' firmware |
| 1280 | * because all these firmware images have been loaded | 1332 | * because all these firmware images have been loaded |
| @@ -1292,21 +1344,7 @@ static void device_cache_fw_images(void) | |||
| 1292 | mutex_unlock(&fw_lock); | 1344 | mutex_unlock(&fw_lock); |
| 1293 | 1345 | ||
| 1294 | /* wait for completion of caching firmware for all devices */ | 1346 | /* wait for completion of caching firmware for all devices */ |
| 1295 | spin_lock(&fwc->name_lock); | 1347 | async_synchronize_full_domain(&fw_cache_domain); |
| 1296 | for (;;) { | ||
| 1297 | prepare_to_wait(&fwc->wait_queue, &wait, | ||
| 1298 | TASK_UNINTERRUPTIBLE); | ||
| 1299 | if (!fwc->cnt) | ||
| 1300 | break; | ||
| 1301 | |||
| 1302 | spin_unlock(&fwc->name_lock); | ||
| 1303 | |||
| 1304 | schedule(); | ||
| 1305 | |||
| 1306 | spin_lock(&fwc->name_lock); | ||
| 1307 | } | ||
| 1308 | spin_unlock(&fwc->name_lock); | ||
| 1309 | finish_wait(&fwc->wait_queue, &wait); | ||
| 1310 | 1348 | ||
| 1311 | loading_timeout = old_timeout; | 1349 | loading_timeout = old_timeout; |
| 1312 | } | 1350 | } |
| @@ -1394,9 +1432,7 @@ static void __init fw_cache_init(void) | |||
| 1394 | #ifdef CONFIG_PM_SLEEP | 1432 | #ifdef CONFIG_PM_SLEEP |
| 1395 | spin_lock_init(&fw_cache.name_lock); | 1433 | spin_lock_init(&fw_cache.name_lock); |
| 1396 | INIT_LIST_HEAD(&fw_cache.fw_names); | 1434 | INIT_LIST_HEAD(&fw_cache.fw_names); |
| 1397 | fw_cache.cnt = 0; | ||
| 1398 | 1435 | ||
| 1399 | init_waitqueue_head(&fw_cache.wait_queue); | ||
| 1400 | INIT_DELAYED_WORK(&fw_cache.work, | 1436 | INIT_DELAYED_WORK(&fw_cache.work, |
| 1401 | device_uncache_fw_images_work); | 1437 | device_uncache_fw_images_work); |
| 1402 | 1438 | ||
diff --git a/drivers/base/platform.c b/drivers/base/platform.c index 8727e9c5eea4..72c776f2a1f5 100644 --- a/drivers/base/platform.c +++ b/drivers/base/platform.c | |||
| @@ -83,9 +83,16 @@ EXPORT_SYMBOL_GPL(platform_get_resource); | |||
| 83 | */ | 83 | */ |
| 84 | int platform_get_irq(struct platform_device *dev, unsigned int num) | 84 | int platform_get_irq(struct platform_device *dev, unsigned int num) |
| 85 | { | 85 | { |
| 86 | #ifdef CONFIG_SPARC | ||
| 87 | /* sparc does not have irqs represented as IORESOURCE_IRQ resources */ | ||
| 88 | if (!dev || num >= dev->archdata.num_irqs) | ||
| 89 | return -ENXIO; | ||
| 90 | return dev->archdata.irqs[num]; | ||
| 91 | #else | ||
| 86 | struct resource *r = platform_get_resource(dev, IORESOURCE_IRQ, num); | 92 | struct resource *r = platform_get_resource(dev, IORESOURCE_IRQ, num); |
| 87 | 93 | ||
| 88 | return r ? r->start : -ENXIO; | 94 | return r ? r->start : -ENXIO; |
| 95 | #endif | ||
| 89 | } | 96 | } |
| 90 | EXPORT_SYMBOL_GPL(platform_get_irq); | 97 | EXPORT_SYMBOL_GPL(platform_get_irq); |
| 91 | 98 | ||
diff --git a/drivers/base/power/domain.c b/drivers/base/power/domain.c index c22b869245d9..96b71b6536d6 100644 --- a/drivers/base/power/domain.c +++ b/drivers/base/power/domain.c | |||
| @@ -1862,7 +1862,7 @@ int pm_genpd_attach_cpuidle(struct generic_pm_domain *genpd, int state) | |||
| 1862 | cpuidle_drv = cpuidle_driver_ref(); | 1862 | cpuidle_drv = cpuidle_driver_ref(); |
| 1863 | if (!cpuidle_drv) { | 1863 | if (!cpuidle_drv) { |
| 1864 | ret = -ENODEV; | 1864 | ret = -ENODEV; |
| 1865 | goto out; | 1865 | goto err_drv; |
| 1866 | } | 1866 | } |
| 1867 | if (cpuidle_drv->state_count <= state) { | 1867 | if (cpuidle_drv->state_count <= state) { |
| 1868 | ret = -EINVAL; | 1868 | ret = -EINVAL; |
| @@ -1884,6 +1884,9 @@ int pm_genpd_attach_cpuidle(struct generic_pm_domain *genpd, int state) | |||
| 1884 | 1884 | ||
| 1885 | err: | 1885 | err: |
| 1886 | cpuidle_driver_unref(); | 1886 | cpuidle_driver_unref(); |
| 1887 | |||
| 1888 | err_drv: | ||
| 1889 | kfree(cpu_data); | ||
| 1887 | goto out; | 1890 | goto out; |
| 1888 | } | 1891 | } |
| 1889 | 1892 | ||
diff --git a/drivers/base/power/qos.c b/drivers/base/power/qos.c index 74a67e0019a2..fbbd4ed2edf2 100644 --- a/drivers/base/power/qos.c +++ b/drivers/base/power/qos.c | |||
| @@ -451,7 +451,7 @@ int dev_pm_qos_add_ancestor_request(struct device *dev, | |||
| 451 | if (ancestor) | 451 | if (ancestor) |
| 452 | error = dev_pm_qos_add_request(ancestor, req, value); | 452 | error = dev_pm_qos_add_request(ancestor, req, value); |
| 453 | 453 | ||
| 454 | if (error) | 454 | if (error < 0) |
| 455 | req->dev = NULL; | 455 | req->dev = NULL; |
| 456 | 456 | ||
| 457 | return error; | 457 | return error; |
diff --git a/drivers/base/regmap/Kconfig b/drivers/base/regmap/Kconfig index 6be390bd8bd1..f0d30543fcce 100644 --- a/drivers/base/regmap/Kconfig +++ b/drivers/base/regmap/Kconfig | |||
| @@ -3,7 +3,7 @@ | |||
| 3 | # subsystems should select the appropriate symbols. | 3 | # subsystems should select the appropriate symbols. |
| 4 | 4 | ||
| 5 | config REGMAP | 5 | config REGMAP |
| 6 | default y if (REGMAP_I2C || REGMAP_SPI) | 6 | default y if (REGMAP_I2C || REGMAP_SPI || REGMAP_MMIO || REGMAP_IRQ) |
| 7 | select LZO_COMPRESS | 7 | select LZO_COMPRESS |
| 8 | select LZO_DECOMPRESS | 8 | select LZO_DECOMPRESS |
| 9 | select IRQ_DOMAIN if REGMAP_IRQ | 9 | select IRQ_DOMAIN if REGMAP_IRQ |
diff --git a/drivers/bcma/main.c b/drivers/bcma/main.c index 432aeeedfd5e..d865470bc951 100644 --- a/drivers/bcma/main.c +++ b/drivers/bcma/main.c | |||
| @@ -158,9 +158,10 @@ static int bcma_register_cores(struct bcma_bus *bus) | |||
| 158 | 158 | ||
| 159 | static void bcma_unregister_cores(struct bcma_bus *bus) | 159 | static void bcma_unregister_cores(struct bcma_bus *bus) |
| 160 | { | 160 | { |
| 161 | struct bcma_device *core; | 161 | struct bcma_device *core, *tmp; |
| 162 | 162 | ||
| 163 | list_for_each_entry(core, &bus->cores, list) { | 163 | list_for_each_entry_safe(core, tmp, &bus->cores, list) { |
| 164 | list_del(&core->list); | ||
| 164 | if (core->dev_registered) | 165 | if (core->dev_registered) |
| 165 | device_unregister(&core->dev); | 166 | device_unregister(&core->dev); |
| 166 | } | 167 | } |
diff --git a/drivers/block/Kconfig b/drivers/block/Kconfig index f529407db93f..824e09c4d0d7 100644 --- a/drivers/block/Kconfig +++ b/drivers/block/Kconfig | |||
| @@ -131,6 +131,7 @@ config BLK_CPQ_DA | |||
| 131 | config BLK_CPQ_CISS_DA | 131 | config BLK_CPQ_CISS_DA |
| 132 | tristate "Compaq Smart Array 5xxx support" | 132 | tristate "Compaq Smart Array 5xxx support" |
| 133 | depends on PCI | 133 | depends on PCI |
| 134 | select CHECK_SIGNATURE | ||
| 134 | help | 135 | help |
| 135 | This is the driver for Compaq Smart Array 5xxx controllers. | 136 | This is the driver for Compaq Smart Array 5xxx controllers. |
| 136 | Everyone using these boards should say Y here. | 137 | Everyone using these boards should say Y here. |
| @@ -166,8 +167,8 @@ config BLK_DEV_DAC960 | |||
| 166 | module will be called DAC960. | 167 | module will be called DAC960. |
| 167 | 168 | ||
| 168 | config BLK_DEV_UMEM | 169 | config BLK_DEV_UMEM |
| 169 | tristate "Micro Memory MM5415 Battery Backed RAM support (EXPERIMENTAL)" | 170 | tristate "Micro Memory MM5415 Battery Backed RAM support" |
| 170 | depends on PCI && EXPERIMENTAL | 171 | depends on PCI |
| 171 | ---help--- | 172 | ---help--- |
| 172 | Saying Y here will include support for the MM5415 family of | 173 | Saying Y here will include support for the MM5415 family of |
| 173 | battery backed (Non-volatile) RAM cards. | 174 | battery backed (Non-volatile) RAM cards. |
| @@ -430,8 +431,8 @@ config CDROM_PKTCDVD_BUFFERS | |||
| 430 | a disc is opened for writing. | 431 | a disc is opened for writing. |
| 431 | 432 | ||
| 432 | config CDROM_PKTCDVD_WCACHE | 433 | config CDROM_PKTCDVD_WCACHE |
| 433 | bool "Enable write caching (EXPERIMENTAL)" | 434 | bool "Enable write caching" |
| 434 | depends on CDROM_PKTCDVD && EXPERIMENTAL | 435 | depends on CDROM_PKTCDVD |
| 435 | help | 436 | help |
| 436 | If enabled, write caching will be set for the CD-R/W device. For now | 437 | If enabled, write caching will be set for the CD-R/W device. For now |
| 437 | this option is dangerous unless the CD-RW media is known good, as we | 438 | this option is dangerous unless the CD-RW media is known good, as we |
| @@ -508,8 +509,8 @@ config XEN_BLKDEV_BACKEND | |||
| 508 | 509 | ||
| 509 | 510 | ||
| 510 | config VIRTIO_BLK | 511 | config VIRTIO_BLK |
| 511 | tristate "Virtio block driver (EXPERIMENTAL)" | 512 | tristate "Virtio block driver" |
| 512 | depends on EXPERIMENTAL && VIRTIO | 513 | depends on VIRTIO |
| 513 | ---help--- | 514 | ---help--- |
| 514 | This is the virtual block driver for virtio. It can be used with | 515 | This is the virtual block driver for virtio. It can be used with |
| 515 | lguest or QEMU based VMMs (like KVM or Xen). Say Y or M. | 516 | lguest or QEMU based VMMs (like KVM or Xen). Say Y or M. |
| @@ -528,7 +529,7 @@ config BLK_DEV_HD | |||
| 528 | 529 | ||
| 529 | config BLK_DEV_RBD | 530 | config BLK_DEV_RBD |
| 530 | tristate "Rados block device (RBD)" | 531 | tristate "Rados block device (RBD)" |
| 531 | depends on INET && EXPERIMENTAL && BLOCK | 532 | depends on INET && BLOCK |
| 532 | select CEPH_LIB | 533 | select CEPH_LIB |
| 533 | select LIBCRC32C | 534 | select LIBCRC32C |
| 534 | select CRYPTO_AES | 535 | select CRYPTO_AES |
diff --git a/drivers/block/aoe/aoecmd.c b/drivers/block/aoe/aoecmd.c index 3804a0af3ef1..9fe4f1865558 100644 --- a/drivers/block/aoe/aoecmd.c +++ b/drivers/block/aoe/aoecmd.c | |||
| @@ -935,7 +935,7 @@ aoe_end_request(struct aoedev *d, struct request *rq, int fastfail) | |||
| 935 | 935 | ||
| 936 | /* cf. http://lkml.org/lkml/2006/10/31/28 */ | 936 | /* cf. http://lkml.org/lkml/2006/10/31/28 */ |
| 937 | if (!fastfail) | 937 | if (!fastfail) |
| 938 | q->request_fn(q); | 938 | __blk_run_queue(q); |
| 939 | } | 939 | } |
| 940 | 940 | ||
| 941 | static void | 941 | static void |
diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c index b0f553b26d0f..ca83f96756ad 100644 --- a/drivers/block/cciss.c +++ b/drivers/block/cciss.c | |||
| @@ -5205,7 +5205,6 @@ static void cciss_shutdown(struct pci_dev *pdev) | |||
| 5205 | return; | 5205 | return; |
| 5206 | } | 5206 | } |
| 5207 | /* write all data in the battery backed cache to disk */ | 5207 | /* write all data in the battery backed cache to disk */ |
| 5208 | memset(flush_buf, 0, 4); | ||
| 5209 | return_code = sendcmd_withirq(h, CCISS_CACHE_FLUSH, flush_buf, | 5208 | return_code = sendcmd_withirq(h, CCISS_CACHE_FLUSH, flush_buf, |
| 5210 | 4, 0, CTLR_LUNID, TYPE_CMD); | 5209 | 4, 0, CTLR_LUNID, TYPE_CMD); |
| 5211 | kfree(flush_buf); | 5210 | kfree(flush_buf); |
diff --git a/drivers/block/floppy.c b/drivers/block/floppy.c index 17c675c52295..2ddd64a9ffde 100644 --- a/drivers/block/floppy.c +++ b/drivers/block/floppy.c | |||
| @@ -4109,12 +4109,19 @@ static struct platform_driver floppy_driver = { | |||
| 4109 | 4109 | ||
| 4110 | static struct platform_device floppy_device[N_DRIVE]; | 4110 | static struct platform_device floppy_device[N_DRIVE]; |
| 4111 | 4111 | ||
| 4112 | static bool floppy_available(int drive) | ||
| 4113 | { | ||
| 4114 | if (!(allowed_drive_mask & (1 << drive))) | ||
| 4115 | return false; | ||
| 4116 | if (fdc_state[FDC(drive)].version == FDC_NONE) | ||
| 4117 | return false; | ||
| 4118 | return true; | ||
| 4119 | } | ||
| 4120 | |||
| 4112 | static struct kobject *floppy_find(dev_t dev, int *part, void *data) | 4121 | static struct kobject *floppy_find(dev_t dev, int *part, void *data) |
| 4113 | { | 4122 | { |
| 4114 | int drive = (*part & 3) | ((*part & 0x80) >> 5); | 4123 | int drive = (*part & 3) | ((*part & 0x80) >> 5); |
| 4115 | if (drive >= N_DRIVE || | 4124 | if (drive >= N_DRIVE || !floppy_available(drive)) |
| 4116 | !(allowed_drive_mask & (1 << drive)) || | ||
| 4117 | fdc_state[FDC(drive)].version == FDC_NONE) | ||
| 4118 | return NULL; | 4125 | return NULL; |
| 4119 | if (((*part >> 2) & 0x1f) >= ARRAY_SIZE(floppy_type)) | 4126 | if (((*part >> 2) & 0x1f) >= ARRAY_SIZE(floppy_type)) |
| 4120 | return NULL; | 4127 | return NULL; |
| @@ -4124,8 +4131,7 @@ static struct kobject *floppy_find(dev_t dev, int *part, void *data) | |||
| 4124 | 4131 | ||
| 4125 | static int __init do_floppy_init(void) | 4132 | static int __init do_floppy_init(void) |
| 4126 | { | 4133 | { |
| 4127 | int i, unit, drive; | 4134 | int i, unit, drive, err; |
| 4128 | int err, dr; | ||
| 4129 | 4135 | ||
| 4130 | set_debugt(); | 4136 | set_debugt(); |
| 4131 | interruptjiffies = resultjiffies = jiffies; | 4137 | interruptjiffies = resultjiffies = jiffies; |
| @@ -4137,34 +4143,32 @@ static int __init do_floppy_init(void) | |||
| 4137 | 4143 | ||
| 4138 | raw_cmd = NULL; | 4144 | raw_cmd = NULL; |
| 4139 | 4145 | ||
| 4140 | for (dr = 0; dr < N_DRIVE; dr++) { | 4146 | floppy_wq = alloc_ordered_workqueue("floppy", 0); |
| 4141 | disks[dr] = alloc_disk(1); | 4147 | if (!floppy_wq) |
| 4142 | if (!disks[dr]) { | 4148 | return -ENOMEM; |
| 4143 | err = -ENOMEM; | ||
| 4144 | goto out_put_disk; | ||
| 4145 | } | ||
| 4146 | 4149 | ||
| 4147 | floppy_wq = alloc_ordered_workqueue("floppy", 0); | 4150 | for (drive = 0; drive < N_DRIVE; drive++) { |
| 4148 | if (!floppy_wq) { | 4151 | disks[drive] = alloc_disk(1); |
| 4152 | if (!disks[drive]) { | ||
| 4149 | err = -ENOMEM; | 4153 | err = -ENOMEM; |
| 4150 | goto out_put_disk; | 4154 | goto out_put_disk; |
| 4151 | } | 4155 | } |
| 4152 | 4156 | ||
| 4153 | disks[dr]->queue = blk_init_queue(do_fd_request, &floppy_lock); | 4157 | disks[drive]->queue = blk_init_queue(do_fd_request, &floppy_lock); |
| 4154 | if (!disks[dr]->queue) { | 4158 | if (!disks[drive]->queue) { |
| 4155 | err = -ENOMEM; | 4159 | err = -ENOMEM; |
| 4156 | goto out_destroy_workq; | 4160 | goto out_put_disk; |
| 4157 | } | 4161 | } |
| 4158 | 4162 | ||
| 4159 | blk_queue_max_hw_sectors(disks[dr]->queue, 64); | 4163 | blk_queue_max_hw_sectors(disks[drive]->queue, 64); |
| 4160 | disks[dr]->major = FLOPPY_MAJOR; | 4164 | disks[drive]->major = FLOPPY_MAJOR; |
| 4161 | disks[dr]->first_minor = TOMINOR(dr); | 4165 | disks[drive]->first_minor = TOMINOR(drive); |
| 4162 | disks[dr]->fops = &floppy_fops; | 4166 | disks[drive]->fops = &floppy_fops; |
| 4163 | sprintf(disks[dr]->disk_name, "fd%d", dr); | 4167 | sprintf(disks[drive]->disk_name, "fd%d", drive); |
| 4164 | 4168 | ||
| 4165 | init_timer(&motor_off_timer[dr]); | 4169 | init_timer(&motor_off_timer[drive]); |
| 4166 | motor_off_timer[dr].data = dr; | 4170 | motor_off_timer[drive].data = drive; |
| 4167 | motor_off_timer[dr].function = motor_off_callback; | 4171 | motor_off_timer[drive].function = motor_off_callback; |
| 4168 | } | 4172 | } |
| 4169 | 4173 | ||
| 4170 | err = register_blkdev(FLOPPY_MAJOR, "fd"); | 4174 | err = register_blkdev(FLOPPY_MAJOR, "fd"); |
| @@ -4282,9 +4286,7 @@ static int __init do_floppy_init(void) | |||
| 4282 | } | 4286 | } |
| 4283 | 4287 | ||
| 4284 | for (drive = 0; drive < N_DRIVE; drive++) { | 4288 | for (drive = 0; drive < N_DRIVE; drive++) { |
| 4285 | if (!(allowed_drive_mask & (1 << drive))) | 4289 | if (!floppy_available(drive)) |
| 4286 | continue; | ||
| 4287 | if (fdc_state[FDC(drive)].version == FDC_NONE) | ||
| 4288 | continue; | 4290 | continue; |
| 4289 | 4291 | ||
| 4290 | floppy_device[drive].name = floppy_device_name; | 4292 | floppy_device[drive].name = floppy_device_name; |
| @@ -4293,7 +4295,7 @@ static int __init do_floppy_init(void) | |||
| 4293 | 4295 | ||
| 4294 | err = platform_device_register(&floppy_device[drive]); | 4296 | err = platform_device_register(&floppy_device[drive]); |
| 4295 | if (err) | 4297 | if (err) |
| 4296 | goto out_release_dma; | 4298 | goto out_remove_drives; |
| 4297 | 4299 | ||
| 4298 | err = device_create_file(&floppy_device[drive].dev, | 4300 | err = device_create_file(&floppy_device[drive].dev, |
| 4299 | &dev_attr_cmos); | 4301 | &dev_attr_cmos); |
| @@ -4311,28 +4313,33 @@ static int __init do_floppy_init(void) | |||
| 4311 | 4313 | ||
| 4312 | out_unreg_platform_dev: | 4314 | out_unreg_platform_dev: |
| 4313 | platform_device_unregister(&floppy_device[drive]); | 4315 | platform_device_unregister(&floppy_device[drive]); |
| 4316 | out_remove_drives: | ||
| 4317 | while (drive--) { | ||
| 4318 | if (floppy_available(drive)) { | ||
| 4319 | del_gendisk(disks[drive]); | ||
| 4320 | device_remove_file(&floppy_device[drive].dev, &dev_attr_cmos); | ||
| 4321 | platform_device_unregister(&floppy_device[drive]); | ||
| 4322 | } | ||
| 4323 | } | ||
| 4314 | out_release_dma: | 4324 | out_release_dma: |
| 4315 | if (atomic_read(&usage_count)) | 4325 | if (atomic_read(&usage_count)) |
| 4316 | floppy_release_irq_and_dma(); | 4326 | floppy_release_irq_and_dma(); |
| 4317 | out_unreg_region: | 4327 | out_unreg_region: |
| 4318 | blk_unregister_region(MKDEV(FLOPPY_MAJOR, 0), 256); | 4328 | blk_unregister_region(MKDEV(FLOPPY_MAJOR, 0), 256); |
| 4319 | platform_driver_unregister(&floppy_driver); | 4329 | platform_driver_unregister(&floppy_driver); |
| 4320 | out_destroy_workq: | ||
| 4321 | destroy_workqueue(floppy_wq); | ||
| 4322 | out_unreg_blkdev: | 4330 | out_unreg_blkdev: |
| 4323 | unregister_blkdev(FLOPPY_MAJOR, "fd"); | 4331 | unregister_blkdev(FLOPPY_MAJOR, "fd"); |
| 4324 | out_put_disk: | 4332 | out_put_disk: |
| 4325 | while (dr--) { | 4333 | destroy_workqueue(floppy_wq); |
| 4326 | del_timer_sync(&motor_off_timer[dr]); | 4334 | for (drive = 0; drive < N_DRIVE; drive++) { |
| 4327 | if (disks[dr]->queue) { | 4335 | if (!disks[drive]) |
| 4328 | blk_cleanup_queue(disks[dr]->queue); | 4336 | break; |
| 4329 | /* | 4337 | if (disks[drive]->queue) { |
| 4330 | * put_disk() is not paired with add_disk() and | 4338 | del_timer_sync(&motor_off_timer[drive]); |
| 4331 | * will put queue reference one extra time. fix it. | 4339 | blk_cleanup_queue(disks[drive]->queue); |
| 4332 | */ | 4340 | disks[drive]->queue = NULL; |
| 4333 | disks[dr]->queue = NULL; | ||
| 4334 | } | 4341 | } |
| 4335 | put_disk(disks[dr]); | 4342 | put_disk(disks[drive]); |
| 4336 | } | 4343 | } |
| 4337 | return err; | 4344 | return err; |
| 4338 | } | 4345 | } |
| @@ -4548,11 +4555,12 @@ static void __exit floppy_module_exit(void) | |||
| 4548 | unregister_blkdev(FLOPPY_MAJOR, "fd"); | 4555 | unregister_blkdev(FLOPPY_MAJOR, "fd"); |
| 4549 | platform_driver_unregister(&floppy_driver); | 4556 | platform_driver_unregister(&floppy_driver); |
| 4550 | 4557 | ||
| 4558 | destroy_workqueue(floppy_wq); | ||
| 4559 | |||
| 4551 | for (drive = 0; drive < N_DRIVE; drive++) { | 4560 | for (drive = 0; drive < N_DRIVE; drive++) { |
| 4552 | del_timer_sync(&motor_off_timer[drive]); | 4561 | del_timer_sync(&motor_off_timer[drive]); |
| 4553 | 4562 | ||
| 4554 | if ((allowed_drive_mask & (1 << drive)) && | 4563 | if (floppy_available(drive)) { |
| 4555 | fdc_state[FDC(drive)].version != FDC_NONE) { | ||
| 4556 | del_gendisk(disks[drive]); | 4564 | del_gendisk(disks[drive]); |
| 4557 | device_remove_file(&floppy_device[drive].dev, &dev_attr_cmos); | 4565 | device_remove_file(&floppy_device[drive].dev, &dev_attr_cmos); |
| 4558 | platform_device_unregister(&floppy_device[drive]); | 4566 | platform_device_unregister(&floppy_device[drive]); |
| @@ -4572,7 +4580,6 @@ static void __exit floppy_module_exit(void) | |||
| 4572 | 4580 | ||
| 4573 | cancel_delayed_work_sync(&fd_timeout); | 4581 | cancel_delayed_work_sync(&fd_timeout); |
| 4574 | cancel_delayed_work_sync(&fd_timer); | 4582 | cancel_delayed_work_sync(&fd_timer); |
| 4575 | destroy_workqueue(floppy_wq); | ||
| 4576 | 4583 | ||
| 4577 | if (atomic_read(&usage_count)) | 4584 | if (atomic_read(&usage_count)) |
| 4578 | floppy_release_irq_and_dma(); | 4585 | floppy_release_irq_and_dma(); |
diff --git a/drivers/block/loop.c b/drivers/block/loop.c index e9d594fd12cb..54046e51160a 100644 --- a/drivers/block/loop.c +++ b/drivers/block/loop.c | |||
| @@ -976,8 +976,21 @@ static int loop_clr_fd(struct loop_device *lo) | |||
| 976 | if (lo->lo_state != Lo_bound) | 976 | if (lo->lo_state != Lo_bound) |
| 977 | return -ENXIO; | 977 | return -ENXIO; |
| 978 | 978 | ||
| 979 | if (lo->lo_refcnt > 1) /* we needed one fd for the ioctl */ | 979 | /* |
| 980 | return -EBUSY; | 980 | * If we've explicitly asked to tear down the loop device, |
| 981 | * and it has an elevated reference count, set it for auto-teardown when | ||
| 982 | * the last reference goes away. This stops $!~#$@ udev from | ||
| 983 | * preventing teardown because it decided that it needs to run blkid on | ||
| 984 | * the loopback device whenever they appear. xfstests is notorious for | ||
| 985 | * failing tests because blkid via udev races with a losetup | ||
| 986 | * <dev>/do something like mkfs/losetup -d <dev> causing the losetup -d | ||
| 987 | * command to fail with EBUSY. | ||
| 988 | */ | ||
| 989 | if (lo->lo_refcnt > 1) { | ||
| 990 | lo->lo_flags |= LO_FLAGS_AUTOCLEAR; | ||
| 991 | mutex_unlock(&lo->lo_ctl_mutex); | ||
| 992 | return 0; | ||
| 993 | } | ||
| 981 | 994 | ||
| 982 | if (filp == NULL) | 995 | if (filp == NULL) |
| 983 | return -EINVAL; | 996 | return -EINVAL; |
diff --git a/drivers/block/mtip32xx/mtip32xx.c b/drivers/block/mtip32xx/mtip32xx.c index f946d31d6917..9694dd99bbbc 100644 --- a/drivers/block/mtip32xx/mtip32xx.c +++ b/drivers/block/mtip32xx/mtip32xx.c | |||
| @@ -559,7 +559,7 @@ static void mtip_timeout_function(unsigned long int data) | |||
| 559 | struct mtip_cmd *command; | 559 | struct mtip_cmd *command; |
| 560 | int tag, cmdto_cnt = 0; | 560 | int tag, cmdto_cnt = 0; |
| 561 | unsigned int bit, group; | 561 | unsigned int bit, group; |
| 562 | unsigned int num_command_slots = port->dd->slot_groups * 32; | 562 | unsigned int num_command_slots; |
| 563 | unsigned long to, tagaccum[SLOTBITS_IN_LONGS]; | 563 | unsigned long to, tagaccum[SLOTBITS_IN_LONGS]; |
| 564 | 564 | ||
| 565 | if (unlikely(!port)) | 565 | if (unlikely(!port)) |
| @@ -572,6 +572,7 @@ static void mtip_timeout_function(unsigned long int data) | |||
| 572 | } | 572 | } |
| 573 | /* clear the tag accumulator */ | 573 | /* clear the tag accumulator */ |
| 574 | memset(tagaccum, 0, SLOTBITS_IN_LONGS * sizeof(long)); | 574 | memset(tagaccum, 0, SLOTBITS_IN_LONGS * sizeof(long)); |
| 575 | num_command_slots = port->dd->slot_groups * 32; | ||
| 575 | 576 | ||
| 576 | for (tag = 0; tag < num_command_slots; tag++) { | 577 | for (tag = 0; tag < num_command_slots; tag++) { |
| 577 | /* | 578 | /* |
| @@ -2035,8 +2036,9 @@ static unsigned int implicit_sector(unsigned char command, | |||
| 2035 | } | 2036 | } |
| 2036 | return rv; | 2037 | return rv; |
| 2037 | } | 2038 | } |
| 2038 | 2039 | static void mtip_set_timeout(struct driver_data *dd, | |
| 2039 | static void mtip_set_timeout(struct host_to_dev_fis *fis, unsigned int *timeout) | 2040 | struct host_to_dev_fis *fis, |
| 2041 | unsigned int *timeout, u8 erasemode) | ||
| 2040 | { | 2042 | { |
| 2041 | switch (fis->command) { | 2043 | switch (fis->command) { |
| 2042 | case ATA_CMD_DOWNLOAD_MICRO: | 2044 | case ATA_CMD_DOWNLOAD_MICRO: |
| @@ -2044,7 +2046,10 @@ static void mtip_set_timeout(struct host_to_dev_fis *fis, unsigned int *timeout) | |||
| 2044 | break; | 2046 | break; |
| 2045 | case ATA_CMD_SEC_ERASE_UNIT: | 2047 | case ATA_CMD_SEC_ERASE_UNIT: |
| 2046 | case 0xFC: | 2048 | case 0xFC: |
| 2047 | *timeout = 240000; /* 4 minutes */ | 2049 | if (erasemode) |
| 2050 | *timeout = ((*(dd->port->identify + 90) * 2) * 60000); | ||
| 2051 | else | ||
| 2052 | *timeout = ((*(dd->port->identify + 89) * 2) * 60000); | ||
| 2048 | break; | 2053 | break; |
| 2049 | case ATA_CMD_STANDBYNOW1: | 2054 | case ATA_CMD_STANDBYNOW1: |
| 2050 | *timeout = 120000; /* 2 minutes */ | 2055 | *timeout = 120000; /* 2 minutes */ |
| @@ -2087,6 +2092,7 @@ static int exec_drive_taskfile(struct driver_data *dd, | |||
| 2087 | unsigned int transfer_size; | 2092 | unsigned int transfer_size; |
| 2088 | unsigned long task_file_data; | 2093 | unsigned long task_file_data; |
| 2089 | int intotal = outtotal + req_task->out_size; | 2094 | int intotal = outtotal + req_task->out_size; |
| 2095 | int erasemode = 0; | ||
| 2090 | 2096 | ||
| 2091 | taskout = req_task->out_size; | 2097 | taskout = req_task->out_size; |
| 2092 | taskin = req_task->in_size; | 2098 | taskin = req_task->in_size; |
| @@ -2212,7 +2218,13 @@ static int exec_drive_taskfile(struct driver_data *dd, | |||
| 2212 | fis.lba_hi, | 2218 | fis.lba_hi, |
| 2213 | fis.device); | 2219 | fis.device); |
| 2214 | 2220 | ||
| 2215 | mtip_set_timeout(&fis, &timeout); | 2221 | /* check for erase mode support during secure erase.*/ |
| 2222 | if ((fis.command == ATA_CMD_SEC_ERASE_UNIT) && outbuf && | ||
| 2223 | (outbuf[0] & MTIP_SEC_ERASE_MODE)) { | ||
| 2224 | erasemode = 1; | ||
| 2225 | } | ||
| 2226 | |||
| 2227 | mtip_set_timeout(dd, &fis, &timeout, erasemode); | ||
| 2216 | 2228 | ||
| 2217 | /* Determine the correct transfer size.*/ | 2229 | /* Determine the correct transfer size.*/ |
| 2218 | if (force_single_sector) | 2230 | if (force_single_sector) |
| @@ -2428,7 +2440,7 @@ static int mtip_hw_ioctl(struct driver_data *dd, unsigned int cmd, | |||
| 2428 | * return value | 2440 | * return value |
| 2429 | * None | 2441 | * None |
| 2430 | */ | 2442 | */ |
| 2431 | static void mtip_hw_submit_io(struct driver_data *dd, sector_t start, | 2443 | static void mtip_hw_submit_io(struct driver_data *dd, sector_t sector, |
| 2432 | int nsect, int nents, int tag, void *callback, | 2444 | int nsect, int nents, int tag, void *callback, |
| 2433 | void *data, int dir) | 2445 | void *data, int dir) |
| 2434 | { | 2446 | { |
| @@ -2436,6 +2448,7 @@ static void mtip_hw_submit_io(struct driver_data *dd, sector_t start, | |||
| 2436 | struct mtip_port *port = dd->port; | 2448 | struct mtip_port *port = dd->port; |
| 2437 | struct mtip_cmd *command = &port->commands[tag]; | 2449 | struct mtip_cmd *command = &port->commands[tag]; |
| 2438 | int dma_dir = (dir == READ) ? DMA_FROM_DEVICE : DMA_TO_DEVICE; | 2450 | int dma_dir = (dir == READ) ? DMA_FROM_DEVICE : DMA_TO_DEVICE; |
| 2451 | u64 start = sector; | ||
| 2439 | 2452 | ||
| 2440 | /* Map the scatter list for DMA access */ | 2453 | /* Map the scatter list for DMA access */ |
| 2441 | nents = dma_map_sg(&dd->pdev->dev, command->sg, nents, dma_dir); | 2454 | nents = dma_map_sg(&dd->pdev->dev, command->sg, nents, dma_dir); |
| @@ -2454,8 +2467,12 @@ static void mtip_hw_submit_io(struct driver_data *dd, sector_t start, | |||
| 2454 | fis->opts = 1 << 7; | 2467 | fis->opts = 1 << 7; |
| 2455 | fis->command = | 2468 | fis->command = |
| 2456 | (dir == READ ? ATA_CMD_FPDMA_READ : ATA_CMD_FPDMA_WRITE); | 2469 | (dir == READ ? ATA_CMD_FPDMA_READ : ATA_CMD_FPDMA_WRITE); |
| 2457 | *((unsigned int *) &fis->lba_low) = (start & 0xFFFFFF); | 2470 | fis->lba_low = start & 0xFF; |
| 2458 | *((unsigned int *) &fis->lba_low_ex) = ((start >> 24) & 0xFFFFFF); | 2471 | fis->lba_mid = (start >> 8) & 0xFF; |
| 2472 | fis->lba_hi = (start >> 16) & 0xFF; | ||
| 2473 | fis->lba_low_ex = (start >> 24) & 0xFF; | ||
| 2474 | fis->lba_mid_ex = (start >> 32) & 0xFF; | ||
| 2475 | fis->lba_hi_ex = (start >> 40) & 0xFF; | ||
| 2459 | fis->device = 1 << 6; | 2476 | fis->device = 1 << 6; |
| 2460 | fis->features = nsect & 0xFF; | 2477 | fis->features = nsect & 0xFF; |
| 2461 | fis->features_ex = (nsect >> 8) & 0xFF; | 2478 | fis->features_ex = (nsect >> 8) & 0xFF; |
diff --git a/drivers/block/mtip32xx/mtip32xx.h b/drivers/block/mtip32xx/mtip32xx.h index 18627a1d04c5..b1742640556a 100644 --- a/drivers/block/mtip32xx/mtip32xx.h +++ b/drivers/block/mtip32xx/mtip32xx.h | |||
| @@ -33,6 +33,9 @@ | |||
| 33 | /* offset of Device Control register in PCIe extended capabilites space */ | 33 | /* offset of Device Control register in PCIe extended capabilites space */ |
| 34 | #define PCIE_CONFIG_EXT_DEVICE_CONTROL_OFFSET 0x48 | 34 | #define PCIE_CONFIG_EXT_DEVICE_CONTROL_OFFSET 0x48 |
| 35 | 35 | ||
| 36 | /* check for erase mode support during secure erase */ | ||
| 37 | #define MTIP_SEC_ERASE_MODE 0x2 | ||
| 38 | |||
| 36 | /* # of times to retry timed out/failed IOs */ | 39 | /* # of times to retry timed out/failed IOs */ |
| 37 | #define MTIP_MAX_RETRIES 2 | 40 | #define MTIP_MAX_RETRIES 2 |
| 38 | 41 | ||
| @@ -152,14 +155,14 @@ enum { | |||
| 152 | MTIP_DDF_REBUILD_FAILED_BIT = 8, | 155 | MTIP_DDF_REBUILD_FAILED_BIT = 8, |
| 153 | }; | 156 | }; |
| 154 | 157 | ||
| 155 | __packed struct smart_attr{ | 158 | struct smart_attr { |
| 156 | u8 attr_id; | 159 | u8 attr_id; |
| 157 | u16 flags; | 160 | u16 flags; |
| 158 | u8 cur; | 161 | u8 cur; |
| 159 | u8 worst; | 162 | u8 worst; |
| 160 | u32 data; | 163 | u32 data; |
| 161 | u8 res[3]; | 164 | u8 res[3]; |
| 162 | }; | 165 | } __packed; |
| 163 | 166 | ||
| 164 | /* Register Frame Information Structure (FIS), host to device. */ | 167 | /* Register Frame Information Structure (FIS), host to device. */ |
| 165 | struct host_to_dev_fis { | 168 | struct host_to_dev_fis { |
diff --git a/drivers/block/xen-blkback/common.h b/drivers/block/xen-blkback/common.h index 9ad3b5ec1dc1..9a54623e52d7 100644 --- a/drivers/block/xen-blkback/common.h +++ b/drivers/block/xen-blkback/common.h | |||
| @@ -158,8 +158,8 @@ struct xen_vbd { | |||
| 158 | struct block_device *bdev; | 158 | struct block_device *bdev; |
| 159 | /* Cached size parameter. */ | 159 | /* Cached size parameter. */ |
| 160 | sector_t size; | 160 | sector_t size; |
| 161 | bool flush_support; | 161 | unsigned int flush_support:1; |
| 162 | bool discard_secure; | 162 | unsigned int discard_secure:1; |
| 163 | }; | 163 | }; |
| 164 | 164 | ||
| 165 | struct backend_info; | 165 | struct backend_info; |
diff --git a/drivers/block/xen-blkback/xenbus.c b/drivers/block/xen-blkback/xenbus.c index 4f66171c6683..f58434c2617c 100644 --- a/drivers/block/xen-blkback/xenbus.c +++ b/drivers/block/xen-blkback/xenbus.c | |||
| @@ -105,11 +105,10 @@ static struct xen_blkif *xen_blkif_alloc(domid_t domid) | |||
| 105 | { | 105 | { |
| 106 | struct xen_blkif *blkif; | 106 | struct xen_blkif *blkif; |
| 107 | 107 | ||
| 108 | blkif = kmem_cache_alloc(xen_blkif_cachep, GFP_KERNEL); | 108 | blkif = kmem_cache_zalloc(xen_blkif_cachep, GFP_KERNEL); |
| 109 | if (!blkif) | 109 | if (!blkif) |
| 110 | return ERR_PTR(-ENOMEM); | 110 | return ERR_PTR(-ENOMEM); |
| 111 | 111 | ||
| 112 | memset(blkif, 0, sizeof(*blkif)); | ||
| 113 | blkif->domid = domid; | 112 | blkif->domid = domid; |
| 114 | spin_lock_init(&blkif->blk_ring_lock); | 113 | spin_lock_init(&blkif->blk_ring_lock); |
| 115 | atomic_set(&blkif->refcnt, 1); | 114 | atomic_set(&blkif->refcnt, 1); |
| @@ -196,7 +195,7 @@ static void xen_blkif_disconnect(struct xen_blkif *blkif) | |||
| 196 | } | 195 | } |
| 197 | } | 196 | } |
| 198 | 197 | ||
| 199 | void xen_blkif_free(struct xen_blkif *blkif) | 198 | static void xen_blkif_free(struct xen_blkif *blkif) |
| 200 | { | 199 | { |
| 201 | if (!atomic_dec_and_test(&blkif->refcnt)) | 200 | if (!atomic_dec_and_test(&blkif->refcnt)) |
| 202 | BUG(); | 201 | BUG(); |
| @@ -257,7 +256,7 @@ static struct attribute_group xen_vbdstat_group = { | |||
| 257 | VBD_SHOW(physical_device, "%x:%x\n", be->major, be->minor); | 256 | VBD_SHOW(physical_device, "%x:%x\n", be->major, be->minor); |
| 258 | VBD_SHOW(mode, "%s\n", be->mode); | 257 | VBD_SHOW(mode, "%s\n", be->mode); |
| 259 | 258 | ||
| 260 | int xenvbd_sysfs_addif(struct xenbus_device *dev) | 259 | static int xenvbd_sysfs_addif(struct xenbus_device *dev) |
| 261 | { | 260 | { |
| 262 | int error; | 261 | int error; |
| 263 | 262 | ||
| @@ -281,7 +280,7 @@ fail1: device_remove_file(&dev->dev, &dev_attr_physical_device); | |||
| 281 | return error; | 280 | return error; |
| 282 | } | 281 | } |
| 283 | 282 | ||
| 284 | void xenvbd_sysfs_delif(struct xenbus_device *dev) | 283 | static void xenvbd_sysfs_delif(struct xenbus_device *dev) |
| 285 | { | 284 | { |
| 286 | sysfs_remove_group(&dev->dev.kobj, &xen_vbdstat_group); | 285 | sysfs_remove_group(&dev->dev.kobj, &xen_vbdstat_group); |
| 287 | device_remove_file(&dev->dev, &dev_attr_mode); | 286 | device_remove_file(&dev->dev, &dev_attr_mode); |
diff --git a/drivers/bluetooth/ath3k.c b/drivers/bluetooth/ath3k.c index fc2de5528dcc..b00000e8aef6 100644 --- a/drivers/bluetooth/ath3k.c +++ b/drivers/bluetooth/ath3k.c | |||
| @@ -67,6 +67,7 @@ static struct usb_device_id ath3k_table[] = { | |||
| 67 | { USB_DEVICE(0x13d3, 0x3304) }, | 67 | { USB_DEVICE(0x13d3, 0x3304) }, |
| 68 | { USB_DEVICE(0x0930, 0x0215) }, | 68 | { USB_DEVICE(0x0930, 0x0215) }, |
| 69 | { USB_DEVICE(0x0489, 0xE03D) }, | 69 | { USB_DEVICE(0x0489, 0xE03D) }, |
| 70 | { USB_DEVICE(0x0489, 0xE027) }, | ||
| 70 | 71 | ||
| 71 | /* Atheros AR9285 Malbec with sflash firmware */ | 72 | /* Atheros AR9285 Malbec with sflash firmware */ |
| 72 | { USB_DEVICE(0x03F0, 0x311D) }, | 73 | { USB_DEVICE(0x03F0, 0x311D) }, |
diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c index debda27df9b0..ee82f2fb65f0 100644 --- a/drivers/bluetooth/btusb.c +++ b/drivers/bluetooth/btusb.c | |||
| @@ -124,6 +124,7 @@ static struct usb_device_id blacklist_table[] = { | |||
| 124 | { USB_DEVICE(0x13d3, 0x3304), .driver_info = BTUSB_IGNORE }, | 124 | { USB_DEVICE(0x13d3, 0x3304), .driver_info = BTUSB_IGNORE }, |
| 125 | { USB_DEVICE(0x0930, 0x0215), .driver_info = BTUSB_IGNORE }, | 125 | { USB_DEVICE(0x0930, 0x0215), .driver_info = BTUSB_IGNORE }, |
| 126 | { USB_DEVICE(0x0489, 0xe03d), .driver_info = BTUSB_IGNORE }, | 126 | { USB_DEVICE(0x0489, 0xe03d), .driver_info = BTUSB_IGNORE }, |
| 127 | { USB_DEVICE(0x0489, 0xe027), .driver_info = BTUSB_IGNORE }, | ||
| 127 | 128 | ||
| 128 | /* Atheros AR9285 Malbec with sflash firmware */ | 129 | /* Atheros AR9285 Malbec with sflash firmware */ |
| 129 | { USB_DEVICE(0x03f0, 0x311d), .driver_info = BTUSB_IGNORE }, | 130 | { USB_DEVICE(0x03f0, 0x311d), .driver_info = BTUSB_IGNORE }, |
diff --git a/drivers/bus/omap-ocp2scp.c b/drivers/bus/omap-ocp2scp.c index ff63560b8467..0c48b0e05ed6 100644 --- a/drivers/bus/omap-ocp2scp.c +++ b/drivers/bus/omap-ocp2scp.c | |||
| @@ -22,6 +22,26 @@ | |||
| 22 | #include <linux/pm_runtime.h> | 22 | #include <linux/pm_runtime.h> |
| 23 | #include <linux/of.h> | 23 | #include <linux/of.h> |
| 24 | #include <linux/of_platform.h> | 24 | #include <linux/of_platform.h> |
| 25 | #include <linux/platform_data/omap_ocp2scp.h> | ||
| 26 | |||
| 27 | /** | ||
| 28 | * _count_resources - count for the number of resources | ||
| 29 | * @res: struct resource * | ||
| 30 | * | ||
| 31 | * Count and return the number of resources populated for the device that is | ||
| 32 | * connected to ocp2scp. | ||
| 33 | */ | ||
| 34 | static unsigned _count_resources(struct resource *res) | ||
| 35 | { | ||
| 36 | int cnt = 0; | ||
| 37 | |||
| 38 | while (res->start != res->end) { | ||
| 39 | cnt++; | ||
| 40 | res++; | ||
| 41 | } | ||
| 42 | |||
| 43 | return cnt; | ||
| 44 | } | ||
| 25 | 45 | ||
| 26 | static int ocp2scp_remove_devices(struct device *dev, void *c) | 46 | static int ocp2scp_remove_devices(struct device *dev, void *c) |
| 27 | { | 47 | { |
| @@ -34,20 +54,62 @@ static int ocp2scp_remove_devices(struct device *dev, void *c) | |||
| 34 | 54 | ||
| 35 | static int __devinit omap_ocp2scp_probe(struct platform_device *pdev) | 55 | static int __devinit omap_ocp2scp_probe(struct platform_device *pdev) |
| 36 | { | 56 | { |
| 37 | int ret; | 57 | int ret; |
| 38 | struct device_node *np = pdev->dev.of_node; | 58 | unsigned res_cnt, i; |
| 59 | struct device_node *np = pdev->dev.of_node; | ||
| 60 | struct platform_device *pdev_child; | ||
| 61 | struct omap_ocp2scp_platform_data *pdata = pdev->dev.platform_data; | ||
| 62 | struct omap_ocp2scp_dev *dev; | ||
| 39 | 63 | ||
| 40 | if (np) { | 64 | if (np) { |
| 41 | ret = of_platform_populate(np, NULL, NULL, &pdev->dev); | 65 | ret = of_platform_populate(np, NULL, NULL, &pdev->dev); |
| 42 | if (ret) { | 66 | if (ret) { |
| 43 | dev_err(&pdev->dev, "failed to add resources for ocp2scp child\n"); | 67 | dev_err(&pdev->dev, |
| 68 | "failed to add resources for ocp2scp child\n"); | ||
| 44 | goto err0; | 69 | goto err0; |
| 45 | } | 70 | } |
| 71 | } else if (pdata) { | ||
| 72 | for (i = 0, dev = *pdata->devices; i < pdata->dev_cnt; i++, | ||
| 73 | dev++) { | ||
| 74 | res_cnt = _count_resources(dev->res); | ||
| 75 | |||
| 76 | pdev_child = platform_device_alloc(dev->drv_name, | ||
| 77 | PLATFORM_DEVID_AUTO); | ||
| 78 | if (!pdev_child) { | ||
| 79 | dev_err(&pdev->dev, | ||
| 80 | "failed to allocate mem for ocp2scp child\n"); | ||
| 81 | goto err0; | ||
| 82 | } | ||
| 83 | |||
| 84 | ret = platform_device_add_resources(pdev_child, | ||
| 85 | dev->res, res_cnt); | ||
| 86 | if (ret) { | ||
| 87 | dev_err(&pdev->dev, | ||
| 88 | "failed to add resources for ocp2scp child\n"); | ||
| 89 | goto err1; | ||
| 90 | } | ||
| 91 | |||
| 92 | pdev_child->dev.parent = &pdev->dev; | ||
| 93 | |||
| 94 | ret = platform_device_add(pdev_child); | ||
| 95 | if (ret) { | ||
| 96 | dev_err(&pdev->dev, | ||
| 97 | "failed to register ocp2scp child device\n"); | ||
| 98 | goto err1; | ||
| 99 | } | ||
| 100 | } | ||
| 101 | } else { | ||
| 102 | dev_err(&pdev->dev, "OCP2SCP initialized without plat data\n"); | ||
| 103 | return -EINVAL; | ||
| 46 | } | 104 | } |
| 105 | |||
| 47 | pm_runtime_enable(&pdev->dev); | 106 | pm_runtime_enable(&pdev->dev); |
| 48 | 107 | ||
| 49 | return 0; | 108 | return 0; |
| 50 | 109 | ||
| 110 | err1: | ||
| 111 | platform_device_put(pdev_child); | ||
| 112 | |||
| 51 | err0: | 113 | err0: |
| 52 | device_for_each_child(&pdev->dev, NULL, ocp2scp_remove_devices); | 114 | device_for_each_child(&pdev->dev, NULL, ocp2scp_remove_devices); |
| 53 | 115 | ||
diff --git a/drivers/char/Makefile b/drivers/char/Makefile index d0b27a39f1d4..7ff1d0d208a7 100644 --- a/drivers/char/Makefile +++ b/drivers/char/Makefile | |||
| @@ -52,7 +52,6 @@ obj-$(CONFIG_TELCLOCK) += tlclk.o | |||
| 52 | obj-$(CONFIG_MWAVE) += mwave/ | 52 | obj-$(CONFIG_MWAVE) += mwave/ |
| 53 | obj-$(CONFIG_AGP) += agp/ | 53 | obj-$(CONFIG_AGP) += agp/ |
| 54 | obj-$(CONFIG_PCMCIA) += pcmcia/ | 54 | obj-$(CONFIG_PCMCIA) += pcmcia/ |
| 55 | obj-$(CONFIG_IPMI_HANDLER) += ipmi/ | ||
| 56 | 55 | ||
| 57 | obj-$(CONFIG_HANGCHECK_TIMER) += hangcheck-timer.o | 56 | obj-$(CONFIG_HANGCHECK_TIMER) += hangcheck-timer.o |
| 58 | obj-$(CONFIG_TCG_TPM) += tpm/ | 57 | obj-$(CONFIG_TCG_TPM) += tpm/ |
diff --git a/drivers/char/agp/intel-gtt.c b/drivers/char/agp/intel-gtt.c index e01f5eaaec82..38390f7c6ab6 100644 --- a/drivers/char/agp/intel-gtt.c +++ b/drivers/char/agp/intel-gtt.c | |||
| @@ -667,7 +667,7 @@ static int intel_gtt_init(void) | |||
| 667 | gtt_map_size = intel_private.base.gtt_total_entries * 4; | 667 | gtt_map_size = intel_private.base.gtt_total_entries * 4; |
| 668 | 668 | ||
| 669 | intel_private.gtt = NULL; | 669 | intel_private.gtt = NULL; |
| 670 | if (INTEL_GTT_GEN < 6) | 670 | if (INTEL_GTT_GEN < 6 && INTEL_GTT_GEN > 2) |
| 671 | intel_private.gtt = ioremap_wc(intel_private.gtt_bus_addr, | 671 | intel_private.gtt = ioremap_wc(intel_private.gtt_bus_addr, |
| 672 | gtt_map_size); | 672 | gtt_map_size); |
| 673 | if (intel_private.gtt == NULL) | 673 | if (intel_private.gtt == NULL) |
diff --git a/drivers/char/hw_random/Kconfig b/drivers/char/hw_random/Kconfig index fbd9b2b850ef..c58ea9b80b1a 100644 --- a/drivers/char/hw_random/Kconfig +++ b/drivers/char/hw_random/Kconfig | |||
| @@ -127,12 +127,12 @@ config HW_RANDOM_VIA | |||
| 127 | If unsure, say Y. | 127 | If unsure, say Y. |
| 128 | 128 | ||
| 129 | config HW_RANDOM_IXP4XX | 129 | config HW_RANDOM_IXP4XX |
| 130 | tristate "Intel IXP4xx NPU HW Random Number Generator support" | 130 | tristate "Intel IXP4xx NPU HW Pseudo-Random Number Generator support" |
| 131 | depends on HW_RANDOM && ARCH_IXP4XX | 131 | depends on HW_RANDOM && ARCH_IXP4XX |
| 132 | default HW_RANDOM | 132 | default HW_RANDOM |
| 133 | ---help--- | 133 | ---help--- |
| 134 | This driver provides kernel-side support for the Random | 134 | This driver provides kernel-side support for the Pseudo-Random |
| 135 | Number Generator hardware found on the Intel IXP4xx NPU. | 135 | Number Generator hardware found on the Intel IXP45x/46x NPU. |
| 136 | 136 | ||
| 137 | To compile this driver as a module, choose M here: the | 137 | To compile this driver as a module, choose M here: the |
| 138 | module will be called ixp4xx-rng. | 138 | module will be called ixp4xx-rng. |
diff --git a/drivers/char/hw_random/ixp4xx-rng.c b/drivers/char/hw_random/ixp4xx-rng.c index 263567f5f392..beec1627db3c 100644 --- a/drivers/char/hw_random/ixp4xx-rng.c +++ b/drivers/char/hw_random/ixp4xx-rng.c | |||
| @@ -45,6 +45,9 @@ static int __init ixp4xx_rng_init(void) | |||
| 45 | void __iomem * rng_base; | 45 | void __iomem * rng_base; |
| 46 | int err; | 46 | int err; |
| 47 | 47 | ||
| 48 | if (!cpu_is_ixp46x()) /* includes IXP455 */ | ||
| 49 | return -ENOSYS; | ||
| 50 | |||
| 48 | rng_base = ioremap(0x70002100, 4); | 51 | rng_base = ioremap(0x70002100, 4); |
| 49 | if (!rng_base) | 52 | if (!rng_base) |
| 50 | return -ENOMEM; | 53 | return -ENOMEM; |
| @@ -68,5 +71,5 @@ module_init(ixp4xx_rng_init); | |||
| 68 | module_exit(ixp4xx_rng_exit); | 71 | module_exit(ixp4xx_rng_exit); |
| 69 | 72 | ||
| 70 | MODULE_AUTHOR("Deepak Saxena <dsaxena@plexity.net>"); | 73 | MODULE_AUTHOR("Deepak Saxena <dsaxena@plexity.net>"); |
| 71 | MODULE_DESCRIPTION("H/W Random Number Generator (RNG) driver for IXP4xx"); | 74 | MODULE_DESCRIPTION("H/W Pseudo-Random Number Generator (RNG) driver for IXP45x/46x"); |
| 72 | MODULE_LICENSE("GPL"); | 75 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/char/ipmi/ipmi_msghandler.c b/drivers/char/ipmi/ipmi_msghandler.c index 2c29942b1326..a0c84bb30856 100644 --- a/drivers/char/ipmi/ipmi_msghandler.c +++ b/drivers/char/ipmi/ipmi_msghandler.c | |||
| @@ -1880,7 +1880,7 @@ int ipmi_request_supply_msgs(ipmi_user_t user, | |||
| 1880 | struct ipmi_recv_msg *supplied_recv, | 1880 | struct ipmi_recv_msg *supplied_recv, |
| 1881 | int priority) | 1881 | int priority) |
| 1882 | { | 1882 | { |
| 1883 | unsigned char saddr, lun; | 1883 | unsigned char saddr = 0, lun = 0; |
| 1884 | int rv; | 1884 | int rv; |
| 1885 | 1885 | ||
| 1886 | if (!user) | 1886 | if (!user) |
diff --git a/drivers/char/ipmi/ipmi_si_intf.c b/drivers/char/ipmi/ipmi_si_intf.c index 83f85cf7fb1b..32a6c7e256bd 100644 --- a/drivers/char/ipmi/ipmi_si_intf.c +++ b/drivers/char/ipmi/ipmi_si_intf.c | |||
| @@ -2424,6 +2424,38 @@ static void ipmi_pci_cleanup(struct smi_info *info) | |||
| 2424 | pci_disable_device(pdev); | 2424 | pci_disable_device(pdev); |
| 2425 | } | 2425 | } |
| 2426 | 2426 | ||
| 2427 | static int __devinit ipmi_pci_probe_regspacing(struct smi_info *info) | ||
| 2428 | { | ||
| 2429 | if (info->si_type == SI_KCS) { | ||
| 2430 | unsigned char status; | ||
| 2431 | int regspacing; | ||
| 2432 | |||
| 2433 | info->io.regsize = DEFAULT_REGSIZE; | ||
| 2434 | info->io.regshift = 0; | ||
| 2435 | info->io_size = 2; | ||
| 2436 | info->handlers = &kcs_smi_handlers; | ||
| 2437 | |||
| 2438 | /* detect 1, 4, 16byte spacing */ | ||
| 2439 | for (regspacing = DEFAULT_REGSPACING; regspacing <= 16;) { | ||
| 2440 | info->io.regspacing = regspacing; | ||
| 2441 | if (info->io_setup(info)) { | ||
| 2442 | dev_err(info->dev, | ||
| 2443 | "Could not setup I/O space\n"); | ||
| 2444 | return DEFAULT_REGSPACING; | ||
| 2445 | } | ||
| 2446 | /* write invalid cmd */ | ||
| 2447 | info->io.outputb(&info->io, 1, 0x10); | ||
| 2448 | /* read status back */ | ||
| 2449 | status = info->io.inputb(&info->io, 1); | ||
| 2450 | info->io_cleanup(info); | ||
| 2451 | if (status) | ||
| 2452 | return regspacing; | ||
| 2453 | regspacing *= 4; | ||
| 2454 | } | ||
| 2455 | } | ||
| 2456 | return DEFAULT_REGSPACING; | ||
| 2457 | } | ||
| 2458 | |||
| 2427 | static int __devinit ipmi_pci_probe(struct pci_dev *pdev, | 2459 | static int __devinit ipmi_pci_probe(struct pci_dev *pdev, |
| 2428 | const struct pci_device_id *ent) | 2460 | const struct pci_device_id *ent) |
| 2429 | { | 2461 | { |
| @@ -2476,8 +2508,8 @@ static int __devinit ipmi_pci_probe(struct pci_dev *pdev, | |||
| 2476 | } | 2508 | } |
| 2477 | info->io.addr_data = pci_resource_start(pdev, 0); | 2509 | info->io.addr_data = pci_resource_start(pdev, 0); |
| 2478 | 2510 | ||
| 2479 | info->io.regspacing = DEFAULT_REGSPACING; | 2511 | info->io.regspacing = ipmi_pci_probe_regspacing(info); |
| 2480 | info->io.regsize = DEFAULT_REGSPACING; | 2512 | info->io.regsize = DEFAULT_REGSIZE; |
| 2481 | info->io.regshift = 0; | 2513 | info->io.regshift = 0; |
| 2482 | 2514 | ||
| 2483 | info->irq = pdev->irq; | 2515 | info->irq = pdev->irq; |
diff --git a/drivers/char/raw.c b/drivers/char/raw.c index 0bb207eaef2f..54a3a6d09819 100644 --- a/drivers/char/raw.c +++ b/drivers/char/raw.c | |||
| @@ -285,7 +285,7 @@ static long raw_ctl_compat_ioctl(struct file *file, unsigned int cmd, | |||
| 285 | 285 | ||
| 286 | static const struct file_operations raw_fops = { | 286 | static const struct file_operations raw_fops = { |
| 287 | .read = do_sync_read, | 287 | .read = do_sync_read, |
| 288 | .aio_read = blkdev_aio_read, | 288 | .aio_read = generic_file_aio_read, |
| 289 | .write = do_sync_write, | 289 | .write = do_sync_write, |
| 290 | .aio_write = blkdev_aio_write, | 290 | .aio_write = blkdev_aio_write, |
| 291 | .fsync = blkdev_fsync, | 291 | .fsync = blkdev_fsync, |
diff --git a/drivers/char/sonypi.c b/drivers/char/sonypi.c index 320debbe32fa..9b4f0116ff21 100644 --- a/drivers/char/sonypi.c +++ b/drivers/char/sonypi.c | |||
| @@ -1456,7 +1456,7 @@ static int __devexit sonypi_remove(struct platform_device *dev) | |||
| 1456 | return 0; | 1456 | return 0; |
| 1457 | } | 1457 | } |
| 1458 | 1458 | ||
| 1459 | #ifdef CONFIG_PM | 1459 | #ifdef CONFIG_PM_SLEEP |
| 1460 | static int old_camera_power; | 1460 | static int old_camera_power; |
| 1461 | 1461 | ||
| 1462 | static int sonypi_suspend(struct device *dev) | 1462 | static int sonypi_suspend(struct device *dev) |
diff --git a/drivers/clk/ux500/u8500_clk.c b/drivers/clk/ux500/u8500_clk.c index ca4a25ed844c..e2c17d187d98 100644 --- a/drivers/clk/ux500/u8500_clk.c +++ b/drivers/clk/ux500/u8500_clk.c | |||
| @@ -40,7 +40,7 @@ void u8500_clk_init(void) | |||
| 40 | CLK_IS_ROOT|CLK_IGNORE_UNUSED, | 40 | CLK_IS_ROOT|CLK_IGNORE_UNUSED, |
| 41 | 32768); | 41 | 32768); |
| 42 | clk_register_clkdev(clk, "clk32k", NULL); | 42 | clk_register_clkdev(clk, "clk32k", NULL); |
| 43 | clk_register_clkdev(clk, NULL, "rtc-pl031"); | 43 | clk_register_clkdev(clk, "apb_pclk", "rtc-pl031"); |
| 44 | 44 | ||
| 45 | /* PRCMU clocks */ | 45 | /* PRCMU clocks */ |
| 46 | fw_version = prcmu_get_fw_version(); | 46 | fw_version = prcmu_get_fw_version(); |
| @@ -228,10 +228,17 @@ void u8500_clk_init(void) | |||
| 228 | 228 | ||
| 229 | clk = clk_reg_prcc_pclk("p1_pclk2", "per1clk", U8500_CLKRST1_BASE, | 229 | clk = clk_reg_prcc_pclk("p1_pclk2", "per1clk", U8500_CLKRST1_BASE, |
| 230 | BIT(2), 0); | 230 | BIT(2), 0); |
| 231 | clk_register_clkdev(clk, "apb_pclk", "nmk-i2c.1"); | ||
| 232 | |||
| 231 | clk = clk_reg_prcc_pclk("p1_pclk3", "per1clk", U8500_CLKRST1_BASE, | 233 | clk = clk_reg_prcc_pclk("p1_pclk3", "per1clk", U8500_CLKRST1_BASE, |
| 232 | BIT(3), 0); | 234 | BIT(3), 0); |
| 235 | clk_register_clkdev(clk, "apb_pclk", "msp0"); | ||
| 236 | clk_register_clkdev(clk, "apb_pclk", "ux500-msp-i2s.0"); | ||
| 237 | |||
| 233 | clk = clk_reg_prcc_pclk("p1_pclk4", "per1clk", U8500_CLKRST1_BASE, | 238 | clk = clk_reg_prcc_pclk("p1_pclk4", "per1clk", U8500_CLKRST1_BASE, |
| 234 | BIT(4), 0); | 239 | BIT(4), 0); |
| 240 | clk_register_clkdev(clk, "apb_pclk", "msp1"); | ||
| 241 | clk_register_clkdev(clk, "apb_pclk", "ux500-msp-i2s.1"); | ||
| 235 | 242 | ||
| 236 | clk = clk_reg_prcc_pclk("p1_pclk5", "per1clk", U8500_CLKRST1_BASE, | 243 | clk = clk_reg_prcc_pclk("p1_pclk5", "per1clk", U8500_CLKRST1_BASE, |
| 237 | BIT(5), 0); | 244 | BIT(5), 0); |
| @@ -239,6 +246,7 @@ void u8500_clk_init(void) | |||
| 239 | 246 | ||
| 240 | clk = clk_reg_prcc_pclk("p1_pclk6", "per1clk", U8500_CLKRST1_BASE, | 247 | clk = clk_reg_prcc_pclk("p1_pclk6", "per1clk", U8500_CLKRST1_BASE, |
| 241 | BIT(6), 0); | 248 | BIT(6), 0); |
| 249 | clk_register_clkdev(clk, "apb_pclk", "nmk-i2c.2"); | ||
| 242 | 250 | ||
| 243 | clk = clk_reg_prcc_pclk("p1_pclk7", "per1clk", U8500_CLKRST1_BASE, | 251 | clk = clk_reg_prcc_pclk("p1_pclk7", "per1clk", U8500_CLKRST1_BASE, |
| 244 | BIT(7), 0); | 252 | BIT(7), 0); |
| @@ -246,6 +254,7 @@ void u8500_clk_init(void) | |||
| 246 | 254 | ||
| 247 | clk = clk_reg_prcc_pclk("p1_pclk8", "per1clk", U8500_CLKRST1_BASE, | 255 | clk = clk_reg_prcc_pclk("p1_pclk8", "per1clk", U8500_CLKRST1_BASE, |
| 248 | BIT(8), 0); | 256 | BIT(8), 0); |
| 257 | clk_register_clkdev(clk, "apb_pclk", "slimbus0"); | ||
| 249 | 258 | ||
| 250 | clk = clk_reg_prcc_pclk("p1_pclk9", "per1clk", U8500_CLKRST1_BASE, | 259 | clk = clk_reg_prcc_pclk("p1_pclk9", "per1clk", U8500_CLKRST1_BASE, |
| 251 | BIT(9), 0); | 260 | BIT(9), 0); |
| @@ -255,11 +264,16 @@ void u8500_clk_init(void) | |||
| 255 | 264 | ||
| 256 | clk = clk_reg_prcc_pclk("p1_pclk10", "per1clk", U8500_CLKRST1_BASE, | 265 | clk = clk_reg_prcc_pclk("p1_pclk10", "per1clk", U8500_CLKRST1_BASE, |
| 257 | BIT(10), 0); | 266 | BIT(10), 0); |
| 267 | clk_register_clkdev(clk, "apb_pclk", "nmk-i2c.4"); | ||
| 268 | |||
| 258 | clk = clk_reg_prcc_pclk("p1_pclk11", "per1clk", U8500_CLKRST1_BASE, | 269 | clk = clk_reg_prcc_pclk("p1_pclk11", "per1clk", U8500_CLKRST1_BASE, |
| 259 | BIT(11), 0); | 270 | BIT(11), 0); |
| 271 | clk_register_clkdev(clk, "apb_pclk", "msp3"); | ||
| 272 | clk_register_clkdev(clk, "apb_pclk", "ux500-msp-i2s.3"); | ||
| 260 | 273 | ||
| 261 | clk = clk_reg_prcc_pclk("p2_pclk0", "per2clk", U8500_CLKRST2_BASE, | 274 | clk = clk_reg_prcc_pclk("p2_pclk0", "per2clk", U8500_CLKRST2_BASE, |
| 262 | BIT(0), 0); | 275 | BIT(0), 0); |
| 276 | clk_register_clkdev(clk, "apb_pclk", "nmk-i2c.3"); | ||
| 263 | 277 | ||
| 264 | clk = clk_reg_prcc_pclk("p2_pclk1", "per2clk", U8500_CLKRST2_BASE, | 278 | clk = clk_reg_prcc_pclk("p2_pclk1", "per2clk", U8500_CLKRST2_BASE, |
| 265 | BIT(1), 0); | 279 | BIT(1), 0); |
| @@ -279,12 +293,13 @@ void u8500_clk_init(void) | |||
| 279 | 293 | ||
| 280 | clk = clk_reg_prcc_pclk("p2_pclk5", "per2clk", U8500_CLKRST2_BASE, | 294 | clk = clk_reg_prcc_pclk("p2_pclk5", "per2clk", U8500_CLKRST2_BASE, |
| 281 | BIT(5), 0); | 295 | BIT(5), 0); |
| 296 | clk_register_clkdev(clk, "apb_pclk", "msp2"); | ||
| 297 | clk_register_clkdev(clk, "apb_pclk", "ux500-msp-i2s.2"); | ||
| 282 | 298 | ||
| 283 | clk = clk_reg_prcc_pclk("p2_pclk6", "per2clk", U8500_CLKRST2_BASE, | 299 | clk = clk_reg_prcc_pclk("p2_pclk6", "per2clk", U8500_CLKRST2_BASE, |
| 284 | BIT(6), 0); | 300 | BIT(6), 0); |
| 285 | clk_register_clkdev(clk, "apb_pclk", "sdi1"); | 301 | clk_register_clkdev(clk, "apb_pclk", "sdi1"); |
| 286 | 302 | ||
| 287 | |||
| 288 | clk = clk_reg_prcc_pclk("p2_pclk7", "per2clk", U8500_CLKRST2_BASE, | 303 | clk = clk_reg_prcc_pclk("p2_pclk7", "per2clk", U8500_CLKRST2_BASE, |
| 289 | BIT(7), 0); | 304 | BIT(7), 0); |
| 290 | clk_register_clkdev(clk, "apb_pclk", "sdi3"); | 305 | clk_register_clkdev(clk, "apb_pclk", "sdi3"); |
| @@ -316,10 +331,15 @@ void u8500_clk_init(void) | |||
| 316 | 331 | ||
| 317 | clk = clk_reg_prcc_pclk("p3_pclk1", "per3clk", U8500_CLKRST3_BASE, | 332 | clk = clk_reg_prcc_pclk("p3_pclk1", "per3clk", U8500_CLKRST3_BASE, |
| 318 | BIT(1), 0); | 333 | BIT(1), 0); |
| 334 | clk_register_clkdev(clk, "apb_pclk", "ssp0"); | ||
| 335 | |||
| 319 | clk = clk_reg_prcc_pclk("p3_pclk2", "per3clk", U8500_CLKRST3_BASE, | 336 | clk = clk_reg_prcc_pclk("p3_pclk2", "per3clk", U8500_CLKRST3_BASE, |
| 320 | BIT(2), 0); | 337 | BIT(2), 0); |
| 338 | clk_register_clkdev(clk, "apb_pclk", "ssp1"); | ||
| 339 | |||
| 321 | clk = clk_reg_prcc_pclk("p3_pclk3", "per3clk", U8500_CLKRST3_BASE, | 340 | clk = clk_reg_prcc_pclk("p3_pclk3", "per3clk", U8500_CLKRST3_BASE, |
| 322 | BIT(3), 0); | 341 | BIT(3), 0); |
| 342 | clk_register_clkdev(clk, "apb_pclk", "nmk-i2c.0"); | ||
| 323 | 343 | ||
| 324 | clk = clk_reg_prcc_pclk("p3_pclk4", "per3clk", U8500_CLKRST3_BASE, | 344 | clk = clk_reg_prcc_pclk("p3_pclk4", "per3clk", U8500_CLKRST3_BASE, |
| 325 | BIT(4), 0); | 345 | BIT(4), 0); |
| @@ -401,10 +421,17 @@ void u8500_clk_init(void) | |||
| 401 | 421 | ||
| 402 | clk = clk_reg_prcc_kclk("p1_i2c1_kclk", "i2cclk", | 422 | clk = clk_reg_prcc_kclk("p1_i2c1_kclk", "i2cclk", |
| 403 | U8500_CLKRST1_BASE, BIT(2), CLK_SET_RATE_GATE); | 423 | U8500_CLKRST1_BASE, BIT(2), CLK_SET_RATE_GATE); |
| 424 | clk_register_clkdev(clk, NULL, "nmk-i2c.1"); | ||
| 425 | |||
| 404 | clk = clk_reg_prcc_kclk("p1_msp0_kclk", "msp02clk", | 426 | clk = clk_reg_prcc_kclk("p1_msp0_kclk", "msp02clk", |
| 405 | U8500_CLKRST1_BASE, BIT(3), CLK_SET_RATE_GATE); | 427 | U8500_CLKRST1_BASE, BIT(3), CLK_SET_RATE_GATE); |
| 428 | clk_register_clkdev(clk, NULL, "msp0"); | ||
| 429 | clk_register_clkdev(clk, NULL, "ux500-msp-i2s.0"); | ||
| 430 | |||
| 406 | clk = clk_reg_prcc_kclk("p1_msp1_kclk", "msp1clk", | 431 | clk = clk_reg_prcc_kclk("p1_msp1_kclk", "msp1clk", |
| 407 | U8500_CLKRST1_BASE, BIT(4), CLK_SET_RATE_GATE); | 432 | U8500_CLKRST1_BASE, BIT(4), CLK_SET_RATE_GATE); |
| 433 | clk_register_clkdev(clk, NULL, "msp1"); | ||
| 434 | clk_register_clkdev(clk, NULL, "ux500-msp-i2s.1"); | ||
| 408 | 435 | ||
| 409 | clk = clk_reg_prcc_kclk("p1_sdi0_kclk", "sdmmcclk", | 436 | clk = clk_reg_prcc_kclk("p1_sdi0_kclk", "sdmmcclk", |
| 410 | U8500_CLKRST1_BASE, BIT(5), CLK_SET_RATE_GATE); | 437 | U8500_CLKRST1_BASE, BIT(5), CLK_SET_RATE_GATE); |
| @@ -412,17 +439,25 @@ void u8500_clk_init(void) | |||
| 412 | 439 | ||
| 413 | clk = clk_reg_prcc_kclk("p1_i2c2_kclk", "i2cclk", | 440 | clk = clk_reg_prcc_kclk("p1_i2c2_kclk", "i2cclk", |
| 414 | U8500_CLKRST1_BASE, BIT(6), CLK_SET_RATE_GATE); | 441 | U8500_CLKRST1_BASE, BIT(6), CLK_SET_RATE_GATE); |
| 442 | clk_register_clkdev(clk, NULL, "nmk-i2c.2"); | ||
| 443 | |||
| 415 | clk = clk_reg_prcc_kclk("p1_slimbus0_kclk", "slimclk", | 444 | clk = clk_reg_prcc_kclk("p1_slimbus0_kclk", "slimclk", |
| 416 | U8500_CLKRST1_BASE, BIT(3), CLK_SET_RATE_GATE); | 445 | U8500_CLKRST1_BASE, BIT(8), CLK_SET_RATE_GATE); |
| 417 | /* FIXME: Redefinition of BIT(3). */ | 446 | clk_register_clkdev(clk, NULL, "slimbus0"); |
| 447 | |||
| 418 | clk = clk_reg_prcc_kclk("p1_i2c4_kclk", "i2cclk", | 448 | clk = clk_reg_prcc_kclk("p1_i2c4_kclk", "i2cclk", |
| 419 | U8500_CLKRST1_BASE, BIT(9), CLK_SET_RATE_GATE); | 449 | U8500_CLKRST1_BASE, BIT(9), CLK_SET_RATE_GATE); |
| 450 | clk_register_clkdev(clk, NULL, "nmk-i2c.4"); | ||
| 451 | |||
| 420 | clk = clk_reg_prcc_kclk("p1_msp3_kclk", "msp1clk", | 452 | clk = clk_reg_prcc_kclk("p1_msp3_kclk", "msp1clk", |
| 421 | U8500_CLKRST1_BASE, BIT(10), CLK_SET_RATE_GATE); | 453 | U8500_CLKRST1_BASE, BIT(10), CLK_SET_RATE_GATE); |
| 454 | clk_register_clkdev(clk, NULL, "msp3"); | ||
| 455 | clk_register_clkdev(clk, NULL, "ux500-msp-i2s.3"); | ||
| 422 | 456 | ||
| 423 | /* Periph2 */ | 457 | /* Periph2 */ |
| 424 | clk = clk_reg_prcc_kclk("p2_i2c3_kclk", "i2cclk", | 458 | clk = clk_reg_prcc_kclk("p2_i2c3_kclk", "i2cclk", |
| 425 | U8500_CLKRST2_BASE, BIT(0), CLK_SET_RATE_GATE); | 459 | U8500_CLKRST2_BASE, BIT(0), CLK_SET_RATE_GATE); |
| 460 | clk_register_clkdev(clk, NULL, "nmk-i2c.3"); | ||
| 426 | 461 | ||
| 427 | clk = clk_reg_prcc_kclk("p2_sdi4_kclk", "sdmmcclk", | 462 | clk = clk_reg_prcc_kclk("p2_sdi4_kclk", "sdmmcclk", |
| 428 | U8500_CLKRST2_BASE, BIT(2), CLK_SET_RATE_GATE); | 463 | U8500_CLKRST2_BASE, BIT(2), CLK_SET_RATE_GATE); |
| @@ -430,6 +465,8 @@ void u8500_clk_init(void) | |||
| 430 | 465 | ||
| 431 | clk = clk_reg_prcc_kclk("p2_msp2_kclk", "msp02clk", | 466 | clk = clk_reg_prcc_kclk("p2_msp2_kclk", "msp02clk", |
| 432 | U8500_CLKRST2_BASE, BIT(3), CLK_SET_RATE_GATE); | 467 | U8500_CLKRST2_BASE, BIT(3), CLK_SET_RATE_GATE); |
| 468 | clk_register_clkdev(clk, NULL, "msp2"); | ||
| 469 | clk_register_clkdev(clk, NULL, "ux500-msp-i2s.2"); | ||
| 433 | 470 | ||
| 434 | clk = clk_reg_prcc_kclk("p2_sdi1_kclk", "sdmmcclk", | 471 | clk = clk_reg_prcc_kclk("p2_sdi1_kclk", "sdmmcclk", |
| 435 | U8500_CLKRST2_BASE, BIT(4), CLK_SET_RATE_GATE); | 472 | U8500_CLKRST2_BASE, BIT(4), CLK_SET_RATE_GATE); |
| @@ -450,10 +487,15 @@ void u8500_clk_init(void) | |||
| 450 | /* Periph3 */ | 487 | /* Periph3 */ |
| 451 | clk = clk_reg_prcc_kclk("p3_ssp0_kclk", "sspclk", | 488 | clk = clk_reg_prcc_kclk("p3_ssp0_kclk", "sspclk", |
| 452 | U8500_CLKRST3_BASE, BIT(1), CLK_SET_RATE_GATE); | 489 | U8500_CLKRST3_BASE, BIT(1), CLK_SET_RATE_GATE); |
| 490 | clk_register_clkdev(clk, NULL, "ssp0"); | ||
| 491 | |||
| 453 | clk = clk_reg_prcc_kclk("p3_ssp1_kclk", "sspclk", | 492 | clk = clk_reg_prcc_kclk("p3_ssp1_kclk", "sspclk", |
| 454 | U8500_CLKRST3_BASE, BIT(2), CLK_SET_RATE_GATE); | 493 | U8500_CLKRST3_BASE, BIT(2), CLK_SET_RATE_GATE); |
| 494 | clk_register_clkdev(clk, NULL, "ssp1"); | ||
| 495 | |||
| 455 | clk = clk_reg_prcc_kclk("p3_i2c0_kclk", "i2cclk", | 496 | clk = clk_reg_prcc_kclk("p3_i2c0_kclk", "i2cclk", |
| 456 | U8500_CLKRST3_BASE, BIT(3), CLK_SET_RATE_GATE); | 497 | U8500_CLKRST3_BASE, BIT(3), CLK_SET_RATE_GATE); |
| 498 | clk_register_clkdev(clk, NULL, "nmk-i2c.0"); | ||
| 457 | 499 | ||
| 458 | clk = clk_reg_prcc_kclk("p3_sdi2_kclk", "sdmmcclk", | 500 | clk = clk_reg_prcc_kclk("p3_sdi2_kclk", "sdmmcclk", |
| 459 | U8500_CLKRST3_BASE, BIT(4), CLK_SET_RATE_GATE); | 501 | U8500_CLKRST3_BASE, BIT(4), CLK_SET_RATE_GATE); |
diff --git a/drivers/cpufreq/cpufreq_stats.c b/drivers/cpufreq/cpufreq_stats.c index b40ee1403be9..399831690fed 100644 --- a/drivers/cpufreq/cpufreq_stats.c +++ b/drivers/cpufreq/cpufreq_stats.c | |||
| @@ -328,6 +328,7 @@ static int __cpuinit cpufreq_stat_cpu_callback(struct notifier_block *nfb, | |||
| 328 | cpufreq_update_policy(cpu); | 328 | cpufreq_update_policy(cpu); |
| 329 | break; | 329 | break; |
| 330 | case CPU_DOWN_PREPARE: | 330 | case CPU_DOWN_PREPARE: |
| 331 | case CPU_DOWN_PREPARE_FROZEN: | ||
| 331 | cpufreq_stats_free_sysfs(cpu); | 332 | cpufreq_stats_free_sysfs(cpu); |
| 332 | break; | 333 | break; |
| 333 | case CPU_DEAD: | 334 | case CPU_DEAD: |
diff --git a/drivers/cpufreq/powernow-k8.c b/drivers/cpufreq/powernow-k8.c index 129e80bfff22..e3ebb4fa2c3e 100644 --- a/drivers/cpufreq/powernow-k8.c +++ b/drivers/cpufreq/powernow-k8.c | |||
| @@ -5,7 +5,7 @@ | |||
| 5 | * http://www.gnu.org/licenses/gpl.html | 5 | * http://www.gnu.org/licenses/gpl.html |
| 6 | * | 6 | * |
| 7 | * Maintainer: | 7 | * Maintainer: |
| 8 | * Andreas Herrmann <andreas.herrmann3@amd.com> | 8 | * Andreas Herrmann <herrmann.der.user@googlemail.com> |
| 9 | * | 9 | * |
| 10 | * Based on the powernow-k7.c module written by Dave Jones. | 10 | * Based on the powernow-k7.c module written by Dave Jones. |
| 11 | * (C) 2003 Dave Jones on behalf of SuSE Labs | 11 | * (C) 2003 Dave Jones on behalf of SuSE Labs |
| @@ -1052,14 +1052,7 @@ static int powernowk8_target(struct cpufreq_policy *pol, | |||
| 1052 | struct powernowk8_target_arg pta = { .pol = pol, .targfreq = targfreq, | 1052 | struct powernowk8_target_arg pta = { .pol = pol, .targfreq = targfreq, |
| 1053 | .relation = relation }; | 1053 | .relation = relation }; |
| 1054 | 1054 | ||
| 1055 | /* | 1055 | return work_on_cpu(pol->cpu, powernowk8_target_fn, &pta); |
| 1056 | * Must run on @pol->cpu. cpufreq core is responsible for ensuring | ||
| 1057 | * that we're bound to the current CPU and pol->cpu stays online. | ||
| 1058 | */ | ||
| 1059 | if (smp_processor_id() == pol->cpu) | ||
| 1060 | return powernowk8_target_fn(&pta); | ||
| 1061 | else | ||
| 1062 | return work_on_cpu(pol->cpu, powernowk8_target_fn, &pta); | ||
| 1063 | } | 1056 | } |
| 1064 | 1057 | ||
| 1065 | /* Driver entry point to verify the policy and range of frequencies */ | 1058 | /* Driver entry point to verify the policy and range of frequencies */ |
diff --git a/drivers/crypto/Kconfig b/drivers/crypto/Kconfig index 308c7fb92a60..f6644f59fd9d 100644 --- a/drivers/crypto/Kconfig +++ b/drivers/crypto/Kconfig | |||
| @@ -224,7 +224,7 @@ config CRYPTO_DEV_TALITOS | |||
| 224 | 224 | ||
| 225 | config CRYPTO_DEV_IXP4XX | 225 | config CRYPTO_DEV_IXP4XX |
| 226 | tristate "Driver for IXP4xx crypto hardware acceleration" | 226 | tristate "Driver for IXP4xx crypto hardware acceleration" |
| 227 | depends on ARCH_IXP4XX | 227 | depends on ARCH_IXP4XX && IXP4XX_QMGR && IXP4XX_NPE |
| 228 | select CRYPTO_DES | 228 | select CRYPTO_DES |
| 229 | select CRYPTO_ALGAPI | 229 | select CRYPTO_ALGAPI |
| 230 | select CRYPTO_AUTHENC | 230 | select CRYPTO_AUTHENC |
diff --git a/drivers/crypto/ixp4xx_crypto.c b/drivers/crypto/ixp4xx_crypto.c index 8f3f74ce8c7f..21180d6cad6e 100644 --- a/drivers/crypto/ixp4xx_crypto.c +++ b/drivers/crypto/ixp4xx_crypto.c | |||
| @@ -750,12 +750,12 @@ static int setup_cipher(struct crypto_tfm *tfm, int encrypt, | |||
| 750 | } | 750 | } |
| 751 | if (cipher_cfg & MOD_AES) { | 751 | if (cipher_cfg & MOD_AES) { |
| 752 | switch (key_len) { | 752 | switch (key_len) { |
| 753 | case 16: keylen_cfg = MOD_AES128 | KEYLEN_128; break; | 753 | case 16: keylen_cfg = MOD_AES128; break; |
| 754 | case 24: keylen_cfg = MOD_AES192 | KEYLEN_192; break; | 754 | case 24: keylen_cfg = MOD_AES192; break; |
| 755 | case 32: keylen_cfg = MOD_AES256 | KEYLEN_256; break; | 755 | case 32: keylen_cfg = MOD_AES256; break; |
| 756 | default: | 756 | default: |
| 757 | *flags |= CRYPTO_TFM_RES_BAD_KEY_LEN; | 757 | *flags |= CRYPTO_TFM_RES_BAD_KEY_LEN; |
| 758 | return -EINVAL; | 758 | return -EINVAL; |
| 759 | } | 759 | } |
| 760 | cipher_cfg |= keylen_cfg; | 760 | cipher_cfg |= keylen_cfg; |
| 761 | } else if (cipher_cfg & MOD_3DES) { | 761 | } else if (cipher_cfg & MOD_3DES) { |
diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig index 677cd6e4e1a1..d4c12180c654 100644 --- a/drivers/dma/Kconfig +++ b/drivers/dma/Kconfig | |||
| @@ -90,6 +90,17 @@ config DW_DMAC | |||
| 90 | Support the Synopsys DesignWare AHB DMA controller. This | 90 | Support the Synopsys DesignWare AHB DMA controller. This |
| 91 | can be integrated in chips such as the Atmel AT32ap7000. | 91 | can be integrated in chips such as the Atmel AT32ap7000. |
| 92 | 92 | ||
| 93 | config DW_DMAC_BIG_ENDIAN_IO | ||
| 94 | bool "Use big endian I/O register access" | ||
| 95 | default y if AVR32 | ||
| 96 | depends on DW_DMAC | ||
| 97 | help | ||
| 98 | Say yes here to use big endian I/O access when reading and writing | ||
| 99 | to the DMA controller registers. This is needed on some platforms, | ||
| 100 | like the Atmel AVR32 architecture. | ||
| 101 | |||
| 102 | If unsure, use the default setting. | ||
| 103 | |||
| 93 | config AT_HDMAC | 104 | config AT_HDMAC |
| 94 | tristate "Atmel AHB DMA support" | 105 | tristate "Atmel AHB DMA support" |
| 95 | depends on ARCH_AT91 | 106 | depends on ARCH_AT91 |
diff --git a/drivers/dma/dw_dmac_regs.h b/drivers/dma/dw_dmac_regs.h index ff39fa6cd2bc..88965597b7d0 100644 --- a/drivers/dma/dw_dmac_regs.h +++ b/drivers/dma/dw_dmac_regs.h | |||
| @@ -98,9 +98,17 @@ struct dw_dma_regs { | |||
| 98 | u32 DW_PARAMS; | 98 | u32 DW_PARAMS; |
| 99 | }; | 99 | }; |
| 100 | 100 | ||
| 101 | #ifdef CONFIG_DW_DMAC_BIG_ENDIAN_IO | ||
| 102 | #define dma_readl_native ioread32be | ||
| 103 | #define dma_writel_native iowrite32be | ||
| 104 | #else | ||
| 105 | #define dma_readl_native readl | ||
| 106 | #define dma_writel_native writel | ||
| 107 | #endif | ||
| 108 | |||
| 101 | /* To access the registers in early stage of probe */ | 109 | /* To access the registers in early stage of probe */ |
| 102 | #define dma_read_byaddr(addr, name) \ | 110 | #define dma_read_byaddr(addr, name) \ |
| 103 | readl((addr) + offsetof(struct dw_dma_regs, name)) | 111 | dma_readl_native((addr) + offsetof(struct dw_dma_regs, name)) |
| 104 | 112 | ||
| 105 | /* Bitfields in DW_PARAMS */ | 113 | /* Bitfields in DW_PARAMS */ |
| 106 | #define DW_PARAMS_NR_CHAN 8 /* number of channels */ | 114 | #define DW_PARAMS_NR_CHAN 8 /* number of channels */ |
| @@ -216,9 +224,9 @@ __dwc_regs(struct dw_dma_chan *dwc) | |||
| 216 | } | 224 | } |
| 217 | 225 | ||
| 218 | #define channel_readl(dwc, name) \ | 226 | #define channel_readl(dwc, name) \ |
| 219 | readl(&(__dwc_regs(dwc)->name)) | 227 | dma_readl_native(&(__dwc_regs(dwc)->name)) |
| 220 | #define channel_writel(dwc, name, val) \ | 228 | #define channel_writel(dwc, name, val) \ |
| 221 | writel((val), &(__dwc_regs(dwc)->name)) | 229 | dma_writel_native((val), &(__dwc_regs(dwc)->name)) |
| 222 | 230 | ||
| 223 | static inline struct dw_dma_chan *to_dw_dma_chan(struct dma_chan *chan) | 231 | static inline struct dw_dma_chan *to_dw_dma_chan(struct dma_chan *chan) |
| 224 | { | 232 | { |
| @@ -246,9 +254,9 @@ static inline struct dw_dma_regs __iomem *__dw_regs(struct dw_dma *dw) | |||
| 246 | } | 254 | } |
| 247 | 255 | ||
| 248 | #define dma_readl(dw, name) \ | 256 | #define dma_readl(dw, name) \ |
| 249 | readl(&(__dw_regs(dw)->name)) | 257 | dma_readl_native(&(__dw_regs(dw)->name)) |
| 250 | #define dma_writel(dw, name, val) \ | 258 | #define dma_writel(dw, name, val) \ |
| 251 | writel((val), &(__dw_regs(dw)->name)) | 259 | dma_writel_native((val), &(__dw_regs(dw)->name)) |
| 252 | 260 | ||
| 253 | #define channel_set_bit(dw, reg, mask) \ | 261 | #define channel_set_bit(dw, reg, mask) \ |
| 254 | dma_writel(dw, reg, ((mask) << 8) | (mask)) | 262 | dma_writel(dw, reg, ((mask) << 8) | (mask)) |
diff --git a/drivers/dma/imx-dma.c b/drivers/dma/imx-dma.c index f11b5b2b1a1c..7d9554cc4976 100644 --- a/drivers/dma/imx-dma.c +++ b/drivers/dma/imx-dma.c | |||
| @@ -474,8 +474,10 @@ static int imxdma_xfer_desc(struct imxdma_desc *d) | |||
| 474 | slot = i; | 474 | slot = i; |
| 475 | break; | 475 | break; |
| 476 | } | 476 | } |
| 477 | if (slot < 0) | 477 | if (slot < 0) { |
| 478 | spin_unlock_irqrestore(&imxdma->lock, flags); | ||
| 478 | return -EBUSY; | 479 | return -EBUSY; |
| 480 | } | ||
| 479 | 481 | ||
| 480 | imxdma->slots_2d[slot].xsr = d->x; | 482 | imxdma->slots_2d[slot].xsr = d->x; |
| 481 | imxdma->slots_2d[slot].ysr = d->y; | 483 | imxdma->slots_2d[slot].ysr = d->y; |
diff --git a/drivers/dma/sirf-dma.c b/drivers/dma/sirf-dma.c index 64385cde044b..d451caace806 100644 --- a/drivers/dma/sirf-dma.c +++ b/drivers/dma/sirf-dma.c | |||
| @@ -109,7 +109,7 @@ static void sirfsoc_dma_execute(struct sirfsoc_dma_chan *schan) | |||
| 109 | sdesc = list_first_entry(&schan->queued, struct sirfsoc_dma_desc, | 109 | sdesc = list_first_entry(&schan->queued, struct sirfsoc_dma_desc, |
| 110 | node); | 110 | node); |
| 111 | /* Move the first queued descriptor to active list */ | 111 | /* Move the first queued descriptor to active list */ |
| 112 | list_move_tail(&schan->queued, &schan->active); | 112 | list_move_tail(&sdesc->node, &schan->active); |
| 113 | 113 | ||
| 114 | /* Start the DMA transfer */ | 114 | /* Start the DMA transfer */ |
| 115 | writel_relaxed(sdesc->width, sdma->base + SIRFSOC_DMA_WIDTH_0 + | 115 | writel_relaxed(sdesc->width, sdma->base + SIRFSOC_DMA_WIDTH_0 + |
| @@ -428,7 +428,7 @@ static struct dma_async_tx_descriptor *sirfsoc_dma_prep_interleaved( | |||
| 428 | unsigned long iflags; | 428 | unsigned long iflags; |
| 429 | int ret; | 429 | int ret; |
| 430 | 430 | ||
| 431 | if ((xt->dir != DMA_MEM_TO_DEV) || (xt->dir != DMA_DEV_TO_MEM)) { | 431 | if ((xt->dir != DMA_MEM_TO_DEV) && (xt->dir != DMA_DEV_TO_MEM)) { |
| 432 | ret = -EINVAL; | 432 | ret = -EINVAL; |
| 433 | goto err_dir; | 433 | goto err_dir; |
| 434 | } | 434 | } |
diff --git a/drivers/edac/amd64_edac.c b/drivers/edac/amd64_edac.c index 5a297a26211d..cc8e7c78a23c 100644 --- a/drivers/edac/amd64_edac.c +++ b/drivers/edac/amd64_edac.c | |||
| @@ -170,8 +170,11 @@ static int __amd64_set_scrub_rate(struct pci_dev *ctl, u32 new_bw, u32 min_rate) | |||
| 170 | * memory controller and apply to register. Search for the first | 170 | * memory controller and apply to register. Search for the first |
| 171 | * bandwidth entry that is greater or equal than the setting requested | 171 | * bandwidth entry that is greater or equal than the setting requested |
| 172 | * and program that. If at last entry, turn off DRAM scrubbing. | 172 | * and program that. If at last entry, turn off DRAM scrubbing. |
| 173 | * | ||
| 174 | * If no suitable bandwidth is found, turn off DRAM scrubbing entirely | ||
| 175 | * by falling back to the last element in scrubrates[]. | ||
| 173 | */ | 176 | */ |
| 174 | for (i = 0; i < ARRAY_SIZE(scrubrates); i++) { | 177 | for (i = 0; i < ARRAY_SIZE(scrubrates) - 1; i++) { |
| 175 | /* | 178 | /* |
| 176 | * skip scrub rates which aren't recommended | 179 | * skip scrub rates which aren't recommended |
| 177 | * (see F10 BKDG, F3x58) | 180 | * (see F10 BKDG, F3x58) |
| @@ -181,12 +184,6 @@ static int __amd64_set_scrub_rate(struct pci_dev *ctl, u32 new_bw, u32 min_rate) | |||
| 181 | 184 | ||
| 182 | if (scrubrates[i].bandwidth <= new_bw) | 185 | if (scrubrates[i].bandwidth <= new_bw) |
| 183 | break; | 186 | break; |
| 184 | |||
| 185 | /* | ||
| 186 | * if no suitable bandwidth found, turn off DRAM scrubbing | ||
| 187 | * entirely by falling back to the last element in the | ||
| 188 | * scrubrates array. | ||
| 189 | */ | ||
| 190 | } | 187 | } |
| 191 | 188 | ||
| 192 | scrubval = scrubrates[i].scrubval; | 189 | scrubval = scrubrates[i].scrubval; |
diff --git a/drivers/edac/amd64_edac.h b/drivers/edac/amd64_edac.h index 8d4804732bac..8c4139647efc 100644 --- a/drivers/edac/amd64_edac.h +++ b/drivers/edac/amd64_edac.h | |||
| @@ -33,7 +33,7 @@ | |||
| 33 | * detection. The mods to Rev F required more family | 33 | * detection. The mods to Rev F required more family |
| 34 | * information detection. | 34 | * information detection. |
| 35 | * | 35 | * |
| 36 | * Changes/Fixes by Borislav Petkov <borislav.petkov@amd.com>: | 36 | * Changes/Fixes by Borislav Petkov <bp@alien8.de>: |
| 37 | * - misc fixes and code cleanups | 37 | * - misc fixes and code cleanups |
| 38 | * | 38 | * |
| 39 | * This module is based on the following documents | 39 | * This module is based on the following documents |
diff --git a/drivers/edac/edac_mc.c b/drivers/edac/edac_mc.c index 90f0b730e9bb..75c0a1a85fc3 100644 --- a/drivers/edac/edac_mc.c +++ b/drivers/edac/edac_mc.c | |||
| @@ -416,10 +416,18 @@ struct mem_ctl_info *edac_mc_alloc(unsigned mc_num, | |||
| 416 | dimm->cschannel = chn; | 416 | dimm->cschannel = chn; |
| 417 | 417 | ||
| 418 | /* Increment csrow location */ | 418 | /* Increment csrow location */ |
| 419 | row++; | 419 | if (layers[0].is_virt_csrow) { |
| 420 | if (row == tot_csrows) { | ||
| 421 | row = 0; | ||
| 422 | chn++; | 420 | chn++; |
| 421 | if (chn == tot_channels) { | ||
| 422 | chn = 0; | ||
| 423 | row++; | ||
| 424 | } | ||
| 425 | } else { | ||
| 426 | row++; | ||
| 427 | if (row == tot_csrows) { | ||
| 428 | row = 0; | ||
| 429 | chn++; | ||
| 430 | } | ||
| 423 | } | 431 | } |
| 424 | 432 | ||
| 425 | /* Increment dimm location */ | 433 | /* Increment dimm location */ |
diff --git a/drivers/edac/edac_stub.c b/drivers/edac/edac_stub.c index 6c86f6e54558..351945fa2ecd 100644 --- a/drivers/edac/edac_stub.c +++ b/drivers/edac/edac_stub.c | |||
| @@ -5,7 +5,7 @@ | |||
| 5 | * | 5 | * |
| 6 | * 2007 (c) MontaVista Software, Inc. | 6 | * 2007 (c) MontaVista Software, Inc. |
| 7 | * 2010 (c) Advanced Micro Devices Inc. | 7 | * 2010 (c) Advanced Micro Devices Inc. |
| 8 | * Borislav Petkov <borislav.petkov@amd.com> | 8 | * Borislav Petkov <bp@alien8.de> |
| 9 | * | 9 | * |
| 10 | * This file is licensed under the terms of the GNU General Public | 10 | * This file is licensed under the terms of the GNU General Public |
| 11 | * License version 2. This program is licensed "as is" without any | 11 | * License version 2. This program is licensed "as is" without any |
diff --git a/drivers/edac/i7300_edac.c b/drivers/edac/i7300_edac.c index a09d0667f72a..9d669cd43618 100644 --- a/drivers/edac/i7300_edac.c +++ b/drivers/edac/i7300_edac.c | |||
| @@ -197,8 +197,8 @@ static const char *ferr_fat_fbd_name[] = { | |||
| 197 | [0] = "Memory Write error on non-redundant retry or " | 197 | [0] = "Memory Write error on non-redundant retry or " |
| 198 | "FBD configuration Write error on retry", | 198 | "FBD configuration Write error on retry", |
| 199 | }; | 199 | }; |
| 200 | #define GET_FBD_FAT_IDX(fbderr) (fbderr & (3 << 28)) | 200 | #define GET_FBD_FAT_IDX(fbderr) (((fbderr) >> 28) & 3) |
| 201 | #define FERR_FAT_FBD_ERR_MASK ((1 << 0) | (1 << 1) | (1 << 2) | (1 << 3)) | 201 | #define FERR_FAT_FBD_ERR_MASK ((1 << 0) | (1 << 1) | (1 << 2) | (1 << 22)) |
| 202 | 202 | ||
| 203 | #define FERR_NF_FBD 0xa0 | 203 | #define FERR_NF_FBD 0xa0 |
| 204 | static const char *ferr_nf_fbd_name[] = { | 204 | static const char *ferr_nf_fbd_name[] = { |
| @@ -225,7 +225,7 @@ static const char *ferr_nf_fbd_name[] = { | |||
| 225 | [1] = "Aliased Uncorrectable Non-Mirrored Demand Data ECC", | 225 | [1] = "Aliased Uncorrectable Non-Mirrored Demand Data ECC", |
| 226 | [0] = "Uncorrectable Data ECC on Replay", | 226 | [0] = "Uncorrectable Data ECC on Replay", |
| 227 | }; | 227 | }; |
| 228 | #define GET_FBD_NF_IDX(fbderr) (fbderr & (3 << 28)) | 228 | #define GET_FBD_NF_IDX(fbderr) (((fbderr) >> 28) & 3) |
| 229 | #define FERR_NF_FBD_ERR_MASK ((1 << 24) | (1 << 23) | (1 << 22) | (1 << 21) |\ | 229 | #define FERR_NF_FBD_ERR_MASK ((1 << 24) | (1 << 23) | (1 << 22) | (1 << 21) |\ |
| 230 | (1 << 18) | (1 << 17) | (1 << 16) | (1 << 15) |\ | 230 | (1 << 18) | (1 << 17) | (1 << 16) | (1 << 15) |\ |
| 231 | (1 << 14) | (1 << 13) | (1 << 11) | (1 << 10) |\ | 231 | (1 << 14) | (1 << 13) | (1 << 11) | (1 << 10) |\ |
| @@ -464,7 +464,7 @@ static void i7300_process_fbd_error(struct mem_ctl_info *mci) | |||
| 464 | errnum = find_first_bit(&errors, | 464 | errnum = find_first_bit(&errors, |
| 465 | ARRAY_SIZE(ferr_nf_fbd_name)); | 465 | ARRAY_SIZE(ferr_nf_fbd_name)); |
| 466 | specific = GET_ERR_FROM_TABLE(ferr_nf_fbd_name, errnum); | 466 | specific = GET_ERR_FROM_TABLE(ferr_nf_fbd_name, errnum); |
| 467 | branch = (GET_FBD_FAT_IDX(error_reg) == 2) ? 1 : 0; | 467 | branch = (GET_FBD_NF_IDX(error_reg) == 2) ? 1 : 0; |
| 468 | 468 | ||
| 469 | pci_read_config_dword(pvt->pci_dev_16_1_fsb_addr_map, | 469 | pci_read_config_dword(pvt->pci_dev_16_1_fsb_addr_map, |
| 470 | REDMEMA, &syndrome); | 470 | REDMEMA, &syndrome); |
diff --git a/drivers/edac/i7core_edac.c b/drivers/edac/i7core_edac.c index 3672101023bd..10c8c00d6469 100644 --- a/drivers/edac/i7core_edac.c +++ b/drivers/edac/i7core_edac.c | |||
| @@ -816,7 +816,7 @@ static ssize_t i7core_inject_store_##param( \ | |||
| 816 | struct device_attribute *mattr, \ | 816 | struct device_attribute *mattr, \ |
| 817 | const char *data, size_t count) \ | 817 | const char *data, size_t count) \ |
| 818 | { \ | 818 | { \ |
| 819 | struct mem_ctl_info *mci = to_mci(dev); \ | 819 | struct mem_ctl_info *mci = dev_get_drvdata(dev); \ |
| 820 | struct i7core_pvt *pvt; \ | 820 | struct i7core_pvt *pvt; \ |
| 821 | long value; \ | 821 | long value; \ |
| 822 | int rc; \ | 822 | int rc; \ |
| @@ -845,7 +845,7 @@ static ssize_t i7core_inject_show_##param( \ | |||
| 845 | struct device_attribute *mattr, \ | 845 | struct device_attribute *mattr, \ |
| 846 | char *data) \ | 846 | char *data) \ |
| 847 | { \ | 847 | { \ |
| 848 | struct mem_ctl_info *mci = to_mci(dev); \ | 848 | struct mem_ctl_info *mci = dev_get_drvdata(dev); \ |
| 849 | struct i7core_pvt *pvt; \ | 849 | struct i7core_pvt *pvt; \ |
| 850 | \ | 850 | \ |
| 851 | pvt = mci->pvt_info; \ | 851 | pvt = mci->pvt_info; \ |
| @@ -1052,7 +1052,7 @@ static ssize_t i7core_show_counter_##param( \ | |||
| 1052 | struct device_attribute *mattr, \ | 1052 | struct device_attribute *mattr, \ |
| 1053 | char *data) \ | 1053 | char *data) \ |
| 1054 | { \ | 1054 | { \ |
| 1055 | struct mem_ctl_info *mci = to_mci(dev); \ | 1055 | struct mem_ctl_info *mci = dev_get_drvdata(dev); \ |
| 1056 | struct i7core_pvt *pvt = mci->pvt_info; \ | 1056 | struct i7core_pvt *pvt = mci->pvt_info; \ |
| 1057 | \ | 1057 | \ |
| 1058 | edac_dbg(1, "\n"); \ | 1058 | edac_dbg(1, "\n"); \ |
diff --git a/drivers/edac/i82975x_edac.c b/drivers/edac/i82975x_edac.c index 069e26c11c4f..a98020409fa9 100644 --- a/drivers/edac/i82975x_edac.c +++ b/drivers/edac/i82975x_edac.c | |||
| @@ -370,10 +370,6 @@ static enum dev_type i82975x_dram_type(void __iomem *mch_window, int rank) | |||
| 370 | static void i82975x_init_csrows(struct mem_ctl_info *mci, | 370 | static void i82975x_init_csrows(struct mem_ctl_info *mci, |
| 371 | struct pci_dev *pdev, void __iomem *mch_window) | 371 | struct pci_dev *pdev, void __iomem *mch_window) |
| 372 | { | 372 | { |
| 373 | static const char *labels[4] = { | ||
| 374 | "DIMM A1", "DIMM A2", | ||
| 375 | "DIMM B1", "DIMM B2" | ||
| 376 | }; | ||
| 377 | struct csrow_info *csrow; | 373 | struct csrow_info *csrow; |
| 378 | unsigned long last_cumul_size; | 374 | unsigned long last_cumul_size; |
| 379 | u8 value; | 375 | u8 value; |
| @@ -423,9 +419,10 @@ static void i82975x_init_csrows(struct mem_ctl_info *mci, | |||
| 423 | dimm = mci->csrows[index]->channels[chan]->dimm; | 419 | dimm = mci->csrows[index]->channels[chan]->dimm; |
| 424 | 420 | ||
| 425 | dimm->nr_pages = nr_pages / csrow->nr_channels; | 421 | dimm->nr_pages = nr_pages / csrow->nr_channels; |
| 426 | strncpy(csrow->channels[chan]->dimm->label, | 422 | |
| 427 | labels[(index >> 1) + (chan * 2)], | 423 | snprintf(csrow->channels[chan]->dimm->label, EDAC_MC_LABEL_LEN, "DIMM %c%d", |
| 428 | EDAC_MC_LABEL_LEN); | 424 | (chan == 0) ? 'A' : 'B', |
| 425 | index); | ||
| 429 | dimm->grain = 1 << 7; /* 128Byte cache-line resolution */ | 426 | dimm->grain = 1 << 7; /* 128Byte cache-line resolution */ |
| 430 | dimm->dtype = i82975x_dram_type(mch_window, index); | 427 | dimm->dtype = i82975x_dram_type(mch_window, index); |
| 431 | dimm->mtype = MEM_DDR2; /* I82975x supports only DDR2 */ | 428 | dimm->mtype = MEM_DDR2; /* I82975x supports only DDR2 */ |
diff --git a/drivers/edac/mce_amd_inj.c b/drivers/edac/mce_amd_inj.c index 66b5151c1080..2ae78f20cc28 100644 --- a/drivers/edac/mce_amd_inj.c +++ b/drivers/edac/mce_amd_inj.c | |||
| @@ -6,7 +6,7 @@ | |||
| 6 | * This file may be distributed under the terms of the GNU General Public | 6 | * This file may be distributed under the terms of the GNU General Public |
| 7 | * License version 2. | 7 | * License version 2. |
| 8 | * | 8 | * |
| 9 | * Copyright (c) 2010: Borislav Petkov <borislav.petkov@amd.com> | 9 | * Copyright (c) 2010: Borislav Petkov <bp@alien8.de> |
| 10 | * Advanced Micro Devices Inc. | 10 | * Advanced Micro Devices Inc. |
| 11 | */ | 11 | */ |
| 12 | 12 | ||
| @@ -168,6 +168,6 @@ module_init(edac_init_mce_inject); | |||
| 168 | module_exit(edac_exit_mce_inject); | 168 | module_exit(edac_exit_mce_inject); |
| 169 | 169 | ||
| 170 | MODULE_LICENSE("GPL"); | 170 | MODULE_LICENSE("GPL"); |
| 171 | MODULE_AUTHOR("Borislav Petkov <borislav.petkov@amd.com>"); | 171 | MODULE_AUTHOR("Borislav Petkov <bp@alien8.de>"); |
| 172 | MODULE_AUTHOR("AMD Inc."); | 172 | MODULE_AUTHOR("AMD Inc."); |
| 173 | MODULE_DESCRIPTION("MCE injection facility for testing MCE decoding"); | 173 | MODULE_DESCRIPTION("MCE injection facility for testing MCE decoding"); |
diff --git a/drivers/extcon/extcon-adc-jack.c b/drivers/extcon/extcon-adc-jack.c index 725eb5aa8d8c..e87196f6d2d2 100644 --- a/drivers/extcon/extcon-adc-jack.c +++ b/drivers/extcon/extcon-adc-jack.c | |||
| @@ -14,6 +14,7 @@ | |||
| 14 | * | 14 | * |
| 15 | */ | 15 | */ |
| 16 | 16 | ||
| 17 | #include <linux/module.h> | ||
| 17 | #include <linux/slab.h> | 18 | #include <linux/slab.h> |
| 18 | #include <linux/device.h> | 19 | #include <linux/device.h> |
| 19 | #include <linux/platform_device.h> | 20 | #include <linux/platform_device.h> |
| @@ -161,13 +162,12 @@ static int __devinit adc_jack_probe(struct platform_device *pdev) | |||
| 161 | err = request_any_context_irq(data->irq, adc_jack_irq_thread, | 162 | err = request_any_context_irq(data->irq, adc_jack_irq_thread, |
| 162 | pdata->irq_flags, pdata->name, data); | 163 | pdata->irq_flags, pdata->name, data); |
| 163 | 164 | ||
| 164 | if (err) { | 165 | if (err < 0) { |
| 165 | dev_err(&pdev->dev, "error: irq %d\n", data->irq); | 166 | dev_err(&pdev->dev, "error: irq %d\n", data->irq); |
| 166 | err = -EINVAL; | ||
| 167 | goto err_irq; | 167 | goto err_irq; |
| 168 | } | 168 | } |
| 169 | 169 | ||
| 170 | goto out; | 170 | return 0; |
| 171 | 171 | ||
| 172 | err_irq: | 172 | err_irq: |
| 173 | extcon_dev_unregister(&data->edev); | 173 | extcon_dev_unregister(&data->edev); |
| @@ -196,3 +196,7 @@ static struct platform_driver adc_jack_driver = { | |||
| 196 | }; | 196 | }; |
| 197 | 197 | ||
| 198 | module_platform_driver(adc_jack_driver); | 198 | module_platform_driver(adc_jack_driver); |
| 199 | |||
| 200 | MODULE_AUTHOR("MyungJoo Ham <myungjoo.ham@samsung.com>"); | ||
| 201 | MODULE_DESCRIPTION("ADC Jack extcon driver"); | ||
| 202 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/extcon/extcon-class.c b/drivers/extcon/extcon-class.c index 946a3188b2b7..d398821097f3 100644 --- a/drivers/extcon/extcon-class.c +++ b/drivers/extcon/extcon-class.c | |||
| @@ -41,7 +41,7 @@ | |||
| 41 | * every single port-type of the following cable names. Please choose cable | 41 | * every single port-type of the following cable names. Please choose cable |
| 42 | * names that are actually used in your extcon device. | 42 | * names that are actually used in your extcon device. |
| 43 | */ | 43 | */ |
| 44 | const char *extcon_cable_name[] = { | 44 | const char extcon_cable_name[][CABLE_NAME_MAX + 1] = { |
| 45 | [EXTCON_USB] = "USB", | 45 | [EXTCON_USB] = "USB", |
| 46 | [EXTCON_USB_HOST] = "USB-Host", | 46 | [EXTCON_USB_HOST] = "USB-Host", |
| 47 | [EXTCON_TA] = "TA", | 47 | [EXTCON_TA] = "TA", |
| @@ -62,8 +62,6 @@ const char *extcon_cable_name[] = { | |||
| 62 | [EXTCON_VIDEO_IN] = "Video-in", | 62 | [EXTCON_VIDEO_IN] = "Video-in", |
| 63 | [EXTCON_VIDEO_OUT] = "Video-out", | 63 | [EXTCON_VIDEO_OUT] = "Video-out", |
| 64 | [EXTCON_MECHANICAL] = "Mechanical", | 64 | [EXTCON_MECHANICAL] = "Mechanical", |
| 65 | |||
| 66 | NULL, | ||
| 67 | }; | 65 | }; |
| 68 | 66 | ||
| 69 | static struct class *extcon_class; | 67 | static struct class *extcon_class; |
| @@ -91,17 +89,13 @@ static int check_mutually_exclusive(struct extcon_dev *edev, u32 new_state) | |||
| 91 | return 0; | 89 | return 0; |
| 92 | 90 | ||
| 93 | for (i = 0; edev->mutually_exclusive[i]; i++) { | 91 | for (i = 0; edev->mutually_exclusive[i]; i++) { |
| 94 | int count = 0, j; | 92 | int weight; |
| 95 | u32 correspondants = new_state & edev->mutually_exclusive[i]; | 93 | u32 correspondants = new_state & edev->mutually_exclusive[i]; |
| 96 | u32 exp = 1; | 94 | |
| 97 | 95 | /* calculate the total number of bits set */ | |
| 98 | for (j = 0; j < 32; j++) { | 96 | weight = hweight32(correspondants); |
| 99 | if (exp & correspondants) | 97 | if (weight > 1) |
| 100 | count++; | 98 | return i + 1; |
| 101 | if (count > 1) | ||
| 102 | return i + 1; | ||
| 103 | exp <<= 1; | ||
| 104 | } | ||
| 105 | } | 99 | } |
| 106 | 100 | ||
| 107 | return 0; | 101 | return 0; |
| @@ -362,7 +356,7 @@ int extcon_get_cable_state(struct extcon_dev *edev, const char *cable_name) | |||
| 362 | EXPORT_SYMBOL_GPL(extcon_get_cable_state); | 356 | EXPORT_SYMBOL_GPL(extcon_get_cable_state); |
| 363 | 357 | ||
| 364 | /** | 358 | /** |
| 365 | * extcon_get_cable_state_() - Set the status of a specific cable. | 359 | * extcon_set_cable_state_() - Set the status of a specific cable. |
| 366 | * @edev: the extcon device that has the cable. | 360 | * @edev: the extcon device that has the cable. |
| 367 | * @index: cable index that can be retrieved by extcon_find_cable_index(). | 361 | * @index: cable index that can be retrieved by extcon_find_cable_index(). |
| 368 | * @cable_state: the new cable status. The default semantics is | 362 | * @cable_state: the new cable status. The default semantics is |
| @@ -382,7 +376,7 @@ int extcon_set_cable_state_(struct extcon_dev *edev, | |||
| 382 | EXPORT_SYMBOL_GPL(extcon_set_cable_state_); | 376 | EXPORT_SYMBOL_GPL(extcon_set_cable_state_); |
| 383 | 377 | ||
| 384 | /** | 378 | /** |
| 385 | * extcon_get_cable_state() - Set the status of a specific cable. | 379 | * extcon_set_cable_state() - Set the status of a specific cable. |
| 386 | * @edev: the extcon device that has the cable. | 380 | * @edev: the extcon device that has the cable. |
| 387 | * @cable_name: cable name. | 381 | * @cable_name: cable name. |
| 388 | * @cable_state: the new cable status. The default semantics is | 382 | * @cable_state: the new cable status. The default semantics is |
| @@ -447,6 +441,8 @@ static int _call_per_cable(struct notifier_block *nb, unsigned long val, | |||
| 447 | * extcon device. | 441 | * extcon device. |
| 448 | * @obj: an empty extcon_specific_cable_nb object to be returned. | 442 | * @obj: an empty extcon_specific_cable_nb object to be returned. |
| 449 | * @extcon_name: the name of extcon device. | 443 | * @extcon_name: the name of extcon device. |
| 444 | * if NULL, extcon_register_interest will register | ||
| 445 | * every cable with the target cable_name given. | ||
| 450 | * @cable_name: the target cable name. | 446 | * @cable_name: the target cable name. |
| 451 | * @nb: the notifier block to get notified. | 447 | * @nb: the notifier block to get notified. |
| 452 | * | 448 | * |
| @@ -466,22 +462,44 @@ int extcon_register_interest(struct extcon_specific_cable_nb *obj, | |||
| 466 | const char *extcon_name, const char *cable_name, | 462 | const char *extcon_name, const char *cable_name, |
| 467 | struct notifier_block *nb) | 463 | struct notifier_block *nb) |
| 468 | { | 464 | { |
| 469 | if (!obj || !extcon_name || !cable_name || !nb) | 465 | if (!obj || !cable_name || !nb) |
| 470 | return -EINVAL; | 466 | return -EINVAL; |
| 471 | 467 | ||
| 472 | obj->edev = extcon_get_extcon_dev(extcon_name); | 468 | if (extcon_name) { |
| 473 | if (!obj->edev) | 469 | obj->edev = extcon_get_extcon_dev(extcon_name); |
| 474 | return -ENODEV; | 470 | if (!obj->edev) |
| 471 | return -ENODEV; | ||
| 475 | 472 | ||
| 476 | obj->cable_index = extcon_find_cable_index(obj->edev, cable_name); | 473 | obj->cable_index = extcon_find_cable_index(obj->edev, cable_name); |
| 477 | if (obj->cable_index < 0) | 474 | if (obj->cable_index < 0) |
| 478 | return -ENODEV; | 475 | return -ENODEV; |
| 476 | |||
| 477 | obj->user_nb = nb; | ||
| 479 | 478 | ||
| 480 | obj->user_nb = nb; | 479 | obj->internal_nb.notifier_call = _call_per_cable; |
| 481 | 480 | ||
| 482 | obj->internal_nb.notifier_call = _call_per_cable; | 481 | return raw_notifier_chain_register(&obj->edev->nh, &obj->internal_nb); |
| 482 | } else { | ||
| 483 | struct class_dev_iter iter; | ||
| 484 | struct extcon_dev *extd; | ||
| 485 | struct device *dev; | ||
| 486 | |||
| 487 | if (!extcon_class) | ||
| 488 | return -ENODEV; | ||
| 489 | class_dev_iter_init(&iter, extcon_class, NULL, NULL); | ||
| 490 | while ((dev = class_dev_iter_next(&iter))) { | ||
| 491 | extd = (struct extcon_dev *)dev_get_drvdata(dev); | ||
| 492 | |||
| 493 | if (extcon_find_cable_index(extd, cable_name) < 0) | ||
| 494 | continue; | ||
| 495 | |||
| 496 | class_dev_iter_exit(&iter); | ||
| 497 | return extcon_register_interest(obj, extd->name, | ||
| 498 | cable_name, nb); | ||
| 499 | } | ||
| 483 | 500 | ||
| 484 | return raw_notifier_chain_register(&obj->edev->nh, &obj->internal_nb); | 501 | return -ENODEV; |
| 502 | } | ||
| 485 | } | 503 | } |
| 486 | 504 | ||
| 487 | /** | 505 | /** |
| @@ -551,43 +569,9 @@ static int create_extcon_class(void) | |||
| 551 | return 0; | 569 | return 0; |
| 552 | } | 570 | } |
| 553 | 571 | ||
| 554 | static void extcon_cleanup(struct extcon_dev *edev, bool skip) | ||
| 555 | { | ||
| 556 | mutex_lock(&extcon_dev_list_lock); | ||
| 557 | list_del(&edev->entry); | ||
| 558 | mutex_unlock(&extcon_dev_list_lock); | ||
| 559 | |||
| 560 | if (!skip && get_device(edev->dev)) { | ||
| 561 | int index; | ||
| 562 | |||
| 563 | if (edev->mutually_exclusive && edev->max_supported) { | ||
| 564 | for (index = 0; edev->mutually_exclusive[index]; | ||
| 565 | index++) | ||
| 566 | kfree(edev->d_attrs_muex[index].attr.name); | ||
| 567 | kfree(edev->d_attrs_muex); | ||
| 568 | kfree(edev->attrs_muex); | ||
| 569 | } | ||
| 570 | |||
| 571 | for (index = 0; index < edev->max_supported; index++) | ||
| 572 | kfree(edev->cables[index].attr_g.name); | ||
| 573 | |||
| 574 | if (edev->max_supported) { | ||
| 575 | kfree(edev->extcon_dev_type.groups); | ||
| 576 | kfree(edev->cables); | ||
| 577 | } | ||
| 578 | |||
| 579 | device_unregister(edev->dev); | ||
| 580 | put_device(edev->dev); | ||
| 581 | } | ||
| 582 | |||
| 583 | kfree(edev->dev); | ||
| 584 | } | ||
| 585 | |||
| 586 | static void extcon_dev_release(struct device *dev) | 572 | static void extcon_dev_release(struct device *dev) |
| 587 | { | 573 | { |
| 588 | struct extcon_dev *edev = (struct extcon_dev *) dev_get_drvdata(dev); | 574 | kfree(dev); |
| 589 | |||
| 590 | extcon_cleanup(edev, true); | ||
| 591 | } | 575 | } |
| 592 | 576 | ||
| 593 | static const char *muex_name = "mutually_exclusive"; | 577 | static const char *muex_name = "mutually_exclusive"; |
| @@ -813,7 +797,40 @@ EXPORT_SYMBOL_GPL(extcon_dev_register); | |||
| 813 | */ | 797 | */ |
| 814 | void extcon_dev_unregister(struct extcon_dev *edev) | 798 | void extcon_dev_unregister(struct extcon_dev *edev) |
| 815 | { | 799 | { |
| 816 | extcon_cleanup(edev, false); | 800 | int index; |
| 801 | |||
| 802 | mutex_lock(&extcon_dev_list_lock); | ||
| 803 | list_del(&edev->entry); | ||
| 804 | mutex_unlock(&extcon_dev_list_lock); | ||
| 805 | |||
| 806 | if (IS_ERR_OR_NULL(get_device(edev->dev))) { | ||
| 807 | dev_err(edev->dev, "Failed to unregister extcon_dev (%s)\n", | ||
| 808 | dev_name(edev->dev)); | ||
| 809 | return; | ||
| 810 | } | ||
| 811 | |||
| 812 | if (edev->mutually_exclusive && edev->max_supported) { | ||
| 813 | for (index = 0; edev->mutually_exclusive[index]; | ||
| 814 | index++) | ||
| 815 | kfree(edev->d_attrs_muex[index].attr.name); | ||
| 816 | kfree(edev->d_attrs_muex); | ||
| 817 | kfree(edev->attrs_muex); | ||
| 818 | } | ||
| 819 | |||
| 820 | for (index = 0; index < edev->max_supported; index++) | ||
| 821 | kfree(edev->cables[index].attr_g.name); | ||
| 822 | |||
| 823 | if (edev->max_supported) { | ||
| 824 | kfree(edev->extcon_dev_type.groups); | ||
| 825 | kfree(edev->cables); | ||
| 826 | } | ||
| 827 | |||
| 828 | #if defined(CONFIG_ANDROID) | ||
| 829 | if (switch_class) | ||
| 830 | class_compat_remove_link(switch_class, edev->dev, NULL); | ||
| 831 | #endif | ||
| 832 | device_unregister(edev->dev); | ||
| 833 | put_device(edev->dev); | ||
| 817 | } | 834 | } |
| 818 | EXPORT_SYMBOL_GPL(extcon_dev_unregister); | 835 | EXPORT_SYMBOL_GPL(extcon_dev_unregister); |
| 819 | 836 | ||
| @@ -825,6 +842,9 @@ module_init(extcon_class_init); | |||
| 825 | 842 | ||
| 826 | static void __exit extcon_class_exit(void) | 843 | static void __exit extcon_class_exit(void) |
| 827 | { | 844 | { |
| 845 | #if defined(CONFIG_ANDROID) | ||
| 846 | class_compat_unregister(switch_class); | ||
| 847 | #endif | ||
| 828 | class_destroy(extcon_class); | 848 | class_destroy(extcon_class); |
| 829 | } | 849 | } |
| 830 | module_exit(extcon_class_exit); | 850 | module_exit(extcon_class_exit); |
diff --git a/drivers/extcon/extcon-gpio.c b/drivers/extcon/extcon-gpio.c index 3cc152e690b0..71d3ab7b3d8d 100644 --- a/drivers/extcon/extcon-gpio.c +++ b/drivers/extcon/extcon-gpio.c | |||
| @@ -26,7 +26,6 @@ | |||
| 26 | #include <linux/interrupt.h> | 26 | #include <linux/interrupt.h> |
| 27 | #include <linux/platform_device.h> | 27 | #include <linux/platform_device.h> |
| 28 | #include <linux/slab.h> | 28 | #include <linux/slab.h> |
| 29 | #include <linux/extcon.h> | ||
| 30 | #include <linux/workqueue.h> | 29 | #include <linux/workqueue.h> |
| 31 | #include <linux/gpio.h> | 30 | #include <linux/gpio.h> |
| 32 | #include <linux/extcon.h> | 31 | #include <linux/extcon.h> |
diff --git a/drivers/extcon/extcon-max77693.c b/drivers/extcon/extcon-max77693.c index e21387e2da5c..a17d0d91ada2 100644 --- a/drivers/extcon/extcon-max77693.c +++ b/drivers/extcon/extcon-max77693.c | |||
| @@ -239,25 +239,19 @@ const char *max77693_extcon_cable[] = { | |||
| 239 | static int max77693_muic_set_debounce_time(struct max77693_muic_info *info, | 239 | static int max77693_muic_set_debounce_time(struct max77693_muic_info *info, |
| 240 | enum max77693_muic_adc_debounce_time time) | 240 | enum max77693_muic_adc_debounce_time time) |
| 241 | { | 241 | { |
| 242 | int ret = 0; | 242 | int ret; |
| 243 | u8 ctrl3; | ||
| 244 | 243 | ||
| 245 | switch (time) { | 244 | switch (time) { |
| 246 | case ADC_DEBOUNCE_TIME_5MS: | 245 | case ADC_DEBOUNCE_TIME_5MS: |
| 247 | case ADC_DEBOUNCE_TIME_10MS: | 246 | case ADC_DEBOUNCE_TIME_10MS: |
| 248 | case ADC_DEBOUNCE_TIME_25MS: | 247 | case ADC_DEBOUNCE_TIME_25MS: |
| 249 | case ADC_DEBOUNCE_TIME_38_62MS: | 248 | case ADC_DEBOUNCE_TIME_38_62MS: |
| 250 | ret = max77693_read_reg(info->max77693->regmap_muic, | 249 | ret = max77693_update_reg(info->max77693->regmap_muic, |
| 251 | MAX77693_MUIC_REG_CTRL3, &ctrl3); | 250 | MAX77693_MUIC_REG_CTRL3, |
| 252 | ctrl3 &= ~CONTROL3_ADCDBSET_MASK; | 251 | time << CONTROL3_ADCDBSET_SHIFT, |
| 253 | ctrl3 |= (time << CONTROL3_ADCDBSET_SHIFT); | 252 | CONTROL3_ADCDBSET_MASK); |
| 254 | 253 | if (ret) | |
| 255 | ret = max77693_write_reg(info->max77693->regmap_muic, | ||
| 256 | MAX77693_MUIC_REG_CTRL3, ctrl3); | ||
| 257 | if (ret) { | ||
| 258 | dev_err(info->dev, "failed to set ADC debounce time\n"); | 254 | dev_err(info->dev, "failed to set ADC debounce time\n"); |
| 259 | ret = -EINVAL; | ||
| 260 | } | ||
| 261 | break; | 255 | break; |
| 262 | default: | 256 | default: |
| 263 | dev_err(info->dev, "invalid ADC debounce time\n"); | 257 | dev_err(info->dev, "invalid ADC debounce time\n"); |
| @@ -657,6 +651,8 @@ out: | |||
| 657 | static int __devinit max77693_muic_probe(struct platform_device *pdev) | 651 | static int __devinit max77693_muic_probe(struct platform_device *pdev) |
| 658 | { | 652 | { |
| 659 | struct max77693_dev *max77693 = dev_get_drvdata(pdev->dev.parent); | 653 | struct max77693_dev *max77693 = dev_get_drvdata(pdev->dev.parent); |
| 654 | struct max77693_platform_data *pdata = dev_get_platdata(max77693->dev); | ||
| 655 | struct max77693_muic_platform_data *muic_pdata = pdata->muic_data; | ||
| 660 | struct max77693_muic_info *info; | 656 | struct max77693_muic_info *info; |
| 661 | int ret, i; | 657 | int ret, i; |
| 662 | u8 id; | 658 | u8 id; |
| @@ -727,6 +723,31 @@ static int __devinit max77693_muic_probe(struct platform_device *pdev) | |||
| 727 | goto err_extcon; | 723 | goto err_extcon; |
| 728 | } | 724 | } |
| 729 | 725 | ||
| 726 | /* Initialize MUIC register by using platform data */ | ||
| 727 | for (i = 0 ; i < muic_pdata->num_init_data ; i++) { | ||
| 728 | enum max77693_irq_source irq_src = MAX77693_IRQ_GROUP_NR; | ||
| 729 | |||
| 730 | max77693_write_reg(info->max77693->regmap_muic, | ||
| 731 | muic_pdata->init_data[i].addr, | ||
| 732 | muic_pdata->init_data[i].data); | ||
| 733 | |||
| 734 | switch (muic_pdata->init_data[i].addr) { | ||
| 735 | case MAX77693_MUIC_REG_INTMASK1: | ||
| 736 | irq_src = MUIC_INT1; | ||
| 737 | break; | ||
| 738 | case MAX77693_MUIC_REG_INTMASK2: | ||
| 739 | irq_src = MUIC_INT2; | ||
| 740 | break; | ||
| 741 | case MAX77693_MUIC_REG_INTMASK3: | ||
| 742 | irq_src = MUIC_INT3; | ||
| 743 | break; | ||
| 744 | } | ||
| 745 | |||
| 746 | if (irq_src < MAX77693_IRQ_GROUP_NR) | ||
| 747 | info->max77693->irq_masks_cur[irq_src] | ||
| 748 | = muic_pdata->init_data[i].data; | ||
| 749 | } | ||
| 750 | |||
| 730 | /* Check revision number of MUIC device*/ | 751 | /* Check revision number of MUIC device*/ |
| 731 | ret = max77693_read_reg(info->max77693->regmap_muic, | 752 | ret = max77693_read_reg(info->max77693->regmap_muic, |
| 732 | MAX77693_MUIC_REG_ID, &id); | 753 | MAX77693_MUIC_REG_ID, &id); |
| @@ -762,6 +783,7 @@ static int __devexit max77693_muic_remove(struct platform_device *pdev) | |||
| 762 | free_irq(muic_irqs[i].virq, info); | 783 | free_irq(muic_irqs[i].virq, info); |
| 763 | cancel_work_sync(&info->irq_work); | 784 | cancel_work_sync(&info->irq_work); |
| 764 | extcon_dev_unregister(info->edev); | 785 | extcon_dev_unregister(info->edev); |
| 786 | kfree(info->edev); | ||
| 765 | kfree(info); | 787 | kfree(info); |
| 766 | 788 | ||
| 767 | return 0; | 789 | return 0; |
diff --git a/drivers/extcon/extcon-max8997.c b/drivers/extcon/extcon-max8997.c index ef9090a4271d..77b66b0cc8f5 100644 --- a/drivers/extcon/extcon-max8997.c +++ b/drivers/extcon/extcon-max8997.c | |||
| @@ -271,8 +271,6 @@ out: | |||
| 271 | static int max8997_muic_handle_charger_type_detach( | 271 | static int max8997_muic_handle_charger_type_detach( |
| 272 | struct max8997_muic_info *info) | 272 | struct max8997_muic_info *info) |
| 273 | { | 273 | { |
| 274 | int ret = 0; | ||
| 275 | |||
| 276 | switch (info->pre_charger_type) { | 274 | switch (info->pre_charger_type) { |
| 277 | case MAX8997_CHARGER_TYPE_USB: | 275 | case MAX8997_CHARGER_TYPE_USB: |
| 278 | extcon_set_cable_state(info->edev, "USB", false); | 276 | extcon_set_cable_state(info->edev, "USB", false); |
| @@ -290,11 +288,11 @@ static int max8997_muic_handle_charger_type_detach( | |||
| 290 | extcon_set_cable_state(info->edev, "Fast-charger", false); | 288 | extcon_set_cable_state(info->edev, "Fast-charger", false); |
| 291 | break; | 289 | break; |
| 292 | default: | 290 | default: |
| 293 | ret = -EINVAL; | 291 | return -EINVAL; |
| 294 | break; | 292 | break; |
| 295 | } | 293 | } |
| 296 | 294 | ||
| 297 | return ret; | 295 | return 0; |
| 298 | } | 296 | } |
| 299 | 297 | ||
| 300 | static int max8997_muic_handle_charger_type(struct max8997_muic_info *info, | 298 | static int max8997_muic_handle_charger_type(struct max8997_muic_info *info, |
diff --git a/drivers/firewire/sbp2.c b/drivers/firewire/sbp2.c index 1162d6b3bf85..bb1b392f5cda 100644 --- a/drivers/firewire/sbp2.c +++ b/drivers/firewire/sbp2.c | |||
| @@ -1546,6 +1546,8 @@ static int sbp2_scsi_slave_configure(struct scsi_device *sdev) | |||
| 1546 | struct sbp2_logical_unit *lu = sdev->hostdata; | 1546 | struct sbp2_logical_unit *lu = sdev->hostdata; |
| 1547 | 1547 | ||
| 1548 | sdev->use_10_for_rw = 1; | 1548 | sdev->use_10_for_rw = 1; |
| 1549 | sdev->no_report_opcodes = 1; | ||
| 1550 | sdev->no_write_same = 1; | ||
| 1549 | 1551 | ||
| 1550 | if (sbp2_param_exclusive_login) | 1552 | if (sbp2_param_exclusive_login) |
| 1551 | sdev->manage_start_stop = 1; | 1553 | sdev->manage_start_stop = 1; |
diff --git a/drivers/firmware/memmap.c b/drivers/firmware/memmap.c index c1cdc9236666..90723e65b081 100644 --- a/drivers/firmware/memmap.c +++ b/drivers/firmware/memmap.c | |||
| @@ -237,7 +237,7 @@ static ssize_t memmap_attr_show(struct kobject *kobj, | |||
| 237 | * firmware_map_add() or firmware_map_add_early() afterwards, the entries | 237 | * firmware_map_add() or firmware_map_add_early() afterwards, the entries |
| 238 | * are not added to sysfs. | 238 | * are not added to sysfs. |
| 239 | */ | 239 | */ |
| 240 | static int __init memmap_init(void) | 240 | static int __init firmware_memmap_init(void) |
| 241 | { | 241 | { |
| 242 | struct firmware_map_entry *entry; | 242 | struct firmware_map_entry *entry; |
| 243 | 243 | ||
| @@ -246,5 +246,5 @@ static int __init memmap_init(void) | |||
| 246 | 246 | ||
| 247 | return 0; | 247 | return 0; |
| 248 | } | 248 | } |
| 249 | late_initcall(memmap_init); | 249 | late_initcall(firmware_memmap_init); |
| 250 | 250 | ||
diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig index d055cee36942..47150f5ded04 100644 --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig | |||
| @@ -47,7 +47,7 @@ if GPIOLIB | |||
| 47 | 47 | ||
| 48 | config OF_GPIO | 48 | config OF_GPIO |
| 49 | def_bool y | 49 | def_bool y |
| 50 | depends on OF && !SPARC | 50 | depends on OF |
| 51 | 51 | ||
| 52 | config DEBUG_GPIO | 52 | config DEBUG_GPIO |
| 53 | bool "Debug GPIO calls" | 53 | bool "Debug GPIO calls" |
| @@ -466,7 +466,7 @@ config GPIO_ADP5588_IRQ | |||
| 466 | 466 | ||
| 467 | config GPIO_ADNP | 467 | config GPIO_ADNP |
| 468 | tristate "Avionic Design N-bit GPIO expander" | 468 | tristate "Avionic Design N-bit GPIO expander" |
| 469 | depends on I2C && OF | 469 | depends on I2C && OF_GPIO |
| 470 | help | 470 | help |
| 471 | This option enables support for N GPIOs found on Avionic Design | 471 | This option enables support for N GPIOs found on Avionic Design |
| 472 | I2C GPIO expanders. The register space will be extended by powers | 472 | I2C GPIO expanders. The register space will be extended by powers |
diff --git a/drivers/gpio/gpio-74x164.c b/drivers/gpio/gpio-74x164.c index ed3e55161bdc..f05e54258ffb 100644 --- a/drivers/gpio/gpio-74x164.c +++ b/drivers/gpio/gpio-74x164.c | |||
| @@ -153,7 +153,7 @@ static int __devinit gen_74x164_probe(struct spi_device *spi) | |||
| 153 | } | 153 | } |
| 154 | 154 | ||
| 155 | chip->gpio_chip.ngpio = GEN_74X164_NUMBER_GPIOS * chip->registers; | 155 | chip->gpio_chip.ngpio = GEN_74X164_NUMBER_GPIOS * chip->registers; |
| 156 | chip->buffer = devm_kzalloc(&spi->dev, chip->gpio_chip.ngpio, GFP_KERNEL); | 156 | chip->buffer = devm_kzalloc(&spi->dev, chip->registers, GFP_KERNEL); |
| 157 | if (!chip->buffer) { | 157 | if (!chip->buffer) { |
| 158 | ret = -ENOMEM; | 158 | ret = -ENOMEM; |
| 159 | goto exit_destroy; | 159 | goto exit_destroy; |
diff --git a/drivers/gpio/gpio-mcp23s08.c b/drivers/gpio/gpio-mcp23s08.c index 0f425189de11..ce1c84760076 100644 --- a/drivers/gpio/gpio-mcp23s08.c +++ b/drivers/gpio/gpio-mcp23s08.c | |||
| @@ -77,7 +77,7 @@ struct mcp23s08_driver_data { | |||
| 77 | 77 | ||
| 78 | /*----------------------------------------------------------------------*/ | 78 | /*----------------------------------------------------------------------*/ |
| 79 | 79 | ||
| 80 | #ifdef CONFIG_I2C | 80 | #if IS_ENABLED(CONFIG_I2C) |
| 81 | 81 | ||
| 82 | static int mcp23008_read(struct mcp23s08 *mcp, unsigned reg) | 82 | static int mcp23008_read(struct mcp23s08 *mcp, unsigned reg) |
| 83 | { | 83 | { |
| @@ -399,7 +399,7 @@ static int mcp23s08_probe_one(struct mcp23s08 *mcp, struct device *dev, | |||
| 399 | break; | 399 | break; |
| 400 | #endif /* CONFIG_SPI_MASTER */ | 400 | #endif /* CONFIG_SPI_MASTER */ |
| 401 | 401 | ||
| 402 | #ifdef CONFIG_I2C | 402 | #if IS_ENABLED(CONFIG_I2C) |
| 403 | case MCP_TYPE_008: | 403 | case MCP_TYPE_008: |
| 404 | mcp->ops = &mcp23008_ops; | 404 | mcp->ops = &mcp23008_ops; |
| 405 | mcp->chip.ngpio = 8; | 405 | mcp->chip.ngpio = 8; |
| @@ -473,7 +473,7 @@ fail: | |||
| 473 | 473 | ||
| 474 | /*----------------------------------------------------------------------*/ | 474 | /*----------------------------------------------------------------------*/ |
| 475 | 475 | ||
| 476 | #ifdef CONFIG_I2C | 476 | #if IS_ENABLED(CONFIG_I2C) |
| 477 | 477 | ||
| 478 | static int __devinit mcp230xx_probe(struct i2c_client *client, | 478 | static int __devinit mcp230xx_probe(struct i2c_client *client, |
| 479 | const struct i2c_device_id *id) | 479 | const struct i2c_device_id *id) |
diff --git a/drivers/gpio/gpio-mvebu.c b/drivers/gpio/gpio-mvebu.c index 902af437eaf2..be65c0451ad5 100644 --- a/drivers/gpio/gpio-mvebu.c +++ b/drivers/gpio/gpio-mvebu.c | |||
| @@ -92,6 +92,11 @@ static inline void __iomem *mvebu_gpioreg_out(struct mvebu_gpio_chip *mvchip) | |||
| 92 | return mvchip->membase + GPIO_OUT_OFF; | 92 | return mvchip->membase + GPIO_OUT_OFF; |
| 93 | } | 93 | } |
| 94 | 94 | ||
| 95 | static inline void __iomem *mvebu_gpioreg_blink(struct mvebu_gpio_chip *mvchip) | ||
| 96 | { | ||
| 97 | return mvchip->membase + GPIO_BLINK_EN_OFF; | ||
| 98 | } | ||
| 99 | |||
| 95 | static inline void __iomem *mvebu_gpioreg_io_conf(struct mvebu_gpio_chip *mvchip) | 100 | static inline void __iomem *mvebu_gpioreg_io_conf(struct mvebu_gpio_chip *mvchip) |
| 96 | { | 101 | { |
| 97 | return mvchip->membase + GPIO_IO_CONF_OFF; | 102 | return mvchip->membase + GPIO_IO_CONF_OFF; |
| @@ -206,6 +211,23 @@ static int mvebu_gpio_get(struct gpio_chip *chip, unsigned pin) | |||
| 206 | return (u >> pin) & 1; | 211 | return (u >> pin) & 1; |
| 207 | } | 212 | } |
| 208 | 213 | ||
| 214 | static void mvebu_gpio_blink(struct gpio_chip *chip, unsigned pin, int value) | ||
| 215 | { | ||
| 216 | struct mvebu_gpio_chip *mvchip = | ||
| 217 | container_of(chip, struct mvebu_gpio_chip, chip); | ||
| 218 | unsigned long flags; | ||
| 219 | u32 u; | ||
| 220 | |||
| 221 | spin_lock_irqsave(&mvchip->lock, flags); | ||
| 222 | u = readl_relaxed(mvebu_gpioreg_blink(mvchip)); | ||
| 223 | if (value) | ||
| 224 | u |= 1 << pin; | ||
| 225 | else | ||
| 226 | u &= ~(1 << pin); | ||
| 227 | writel_relaxed(u, mvebu_gpioreg_blink(mvchip)); | ||
| 228 | spin_unlock_irqrestore(&mvchip->lock, flags); | ||
| 229 | } | ||
| 230 | |||
| 209 | static int mvebu_gpio_direction_input(struct gpio_chip *chip, unsigned pin) | 231 | static int mvebu_gpio_direction_input(struct gpio_chip *chip, unsigned pin) |
| 210 | { | 232 | { |
| 211 | struct mvebu_gpio_chip *mvchip = | 233 | struct mvebu_gpio_chip *mvchip = |
| @@ -244,6 +266,9 @@ static int mvebu_gpio_direction_output(struct gpio_chip *chip, unsigned pin, | |||
| 244 | if (ret) | 266 | if (ret) |
| 245 | return ret; | 267 | return ret; |
| 246 | 268 | ||
| 269 | mvebu_gpio_blink(chip, pin, 0); | ||
| 270 | mvebu_gpio_set(chip, pin, value); | ||
| 271 | |||
| 247 | spin_lock_irqsave(&mvchip->lock, flags); | 272 | spin_lock_irqsave(&mvchip->lock, flags); |
| 248 | u = readl_relaxed(mvebu_gpioreg_io_conf(mvchip)); | 273 | u = readl_relaxed(mvebu_gpioreg_io_conf(mvchip)); |
| 249 | u &= ~(1 << pin); | 274 | u &= ~(1 << pin); |
| @@ -381,11 +406,13 @@ static int mvebu_gpio_irq_set_type(struct irq_data *d, unsigned int type) | |||
| 381 | u = readl_relaxed(mvebu_gpioreg_in_pol(mvchip)); | 406 | u = readl_relaxed(mvebu_gpioreg_in_pol(mvchip)); |
| 382 | u &= ~(1 << pin); | 407 | u &= ~(1 << pin); |
| 383 | writel_relaxed(u, mvebu_gpioreg_in_pol(mvchip)); | 408 | writel_relaxed(u, mvebu_gpioreg_in_pol(mvchip)); |
| 409 | break; | ||
| 384 | case IRQ_TYPE_EDGE_FALLING: | 410 | case IRQ_TYPE_EDGE_FALLING: |
| 385 | case IRQ_TYPE_LEVEL_LOW: | 411 | case IRQ_TYPE_LEVEL_LOW: |
| 386 | u = readl_relaxed(mvebu_gpioreg_in_pol(mvchip)); | 412 | u = readl_relaxed(mvebu_gpioreg_in_pol(mvchip)); |
| 387 | u |= 1 << pin; | 413 | u |= 1 << pin; |
| 388 | writel_relaxed(u, mvebu_gpioreg_in_pol(mvchip)); | 414 | writel_relaxed(u, mvebu_gpioreg_in_pol(mvchip)); |
| 415 | break; | ||
| 389 | case IRQ_TYPE_EDGE_BOTH: { | 416 | case IRQ_TYPE_EDGE_BOTH: { |
| 390 | u32 v; | 417 | u32 v; |
| 391 | 418 | ||
| @@ -401,6 +428,7 @@ static int mvebu_gpio_irq_set_type(struct irq_data *d, unsigned int type) | |||
| 401 | else | 428 | else |
| 402 | u &= ~(1 << pin); /* rising */ | 429 | u &= ~(1 << pin); /* rising */ |
| 403 | writel_relaxed(u, mvebu_gpioreg_in_pol(mvchip)); | 430 | writel_relaxed(u, mvebu_gpioreg_in_pol(mvchip)); |
| 431 | break; | ||
| 404 | } | 432 | } |
| 405 | } | 433 | } |
| 406 | return 0; | 434 | return 0; |
| @@ -641,7 +669,7 @@ static int __devinit mvebu_gpio_probe(struct platform_device *pdev) | |||
| 641 | ct->handler = handle_edge_irq; | 669 | ct->handler = handle_edge_irq; |
| 642 | ct->chip.name = mvchip->chip.label; | 670 | ct->chip.name = mvchip->chip.label; |
| 643 | 671 | ||
| 644 | irq_setup_generic_chip(gc, IRQ_MSK(ngpios), IRQ_GC_INIT_MASK_CACHE, | 672 | irq_setup_generic_chip(gc, IRQ_MSK(ngpios), 0, |
| 645 | IRQ_NOREQUEST, IRQ_LEVEL | IRQ_NOPROBE); | 673 | IRQ_NOREQUEST, IRQ_LEVEL | IRQ_NOPROBE); |
| 646 | 674 | ||
| 647 | /* Setup irq domain on top of the generic chip. */ | 675 | /* Setup irq domain on top of the generic chip. */ |
diff --git a/drivers/gpio/gpio-omap.c b/drivers/gpio/gpio-omap.c index 94cbc842fbc3..d335af1d4d85 100644 --- a/drivers/gpio/gpio-omap.c +++ b/drivers/gpio/gpio-omap.c | |||
| @@ -251,6 +251,40 @@ static void _set_gpio_debounce(struct gpio_bank *bank, unsigned gpio, | |||
| 251 | } | 251 | } |
| 252 | } | 252 | } |
| 253 | 253 | ||
| 254 | /** | ||
| 255 | * _clear_gpio_debounce - clear debounce settings for a gpio | ||
| 256 | * @bank: the gpio bank we're acting upon | ||
| 257 | * @gpio: the gpio number on this @gpio | ||
| 258 | * | ||
| 259 | * If a gpio is using debounce, then clear the debounce enable bit and if | ||
| 260 | * this is the only gpio in this bank using debounce, then clear the debounce | ||
| 261 | * time too. The debounce clock will also be disabled when calling this function | ||
| 262 | * if this is the only gpio in the bank using debounce. | ||
| 263 | */ | ||
| 264 | static void _clear_gpio_debounce(struct gpio_bank *bank, unsigned gpio) | ||
| 265 | { | ||
| 266 | u32 gpio_bit = GPIO_BIT(bank, gpio); | ||
| 267 | |||
| 268 | if (!bank->dbck_flag) | ||
| 269 | return; | ||
| 270 | |||
| 271 | if (!(bank->dbck_enable_mask & gpio_bit)) | ||
| 272 | return; | ||
| 273 | |||
| 274 | bank->dbck_enable_mask &= ~gpio_bit; | ||
| 275 | bank->context.debounce_en &= ~gpio_bit; | ||
| 276 | __raw_writel(bank->context.debounce_en, | ||
| 277 | bank->base + bank->regs->debounce_en); | ||
| 278 | |||
| 279 | if (!bank->dbck_enable_mask) { | ||
| 280 | bank->context.debounce = 0; | ||
| 281 | __raw_writel(bank->context.debounce, bank->base + | ||
| 282 | bank->regs->debounce); | ||
| 283 | clk_disable(bank->dbck); | ||
| 284 | bank->dbck_enabled = false; | ||
| 285 | } | ||
| 286 | } | ||
| 287 | |||
| 254 | static inline void set_gpio_trigger(struct gpio_bank *bank, int gpio, | 288 | static inline void set_gpio_trigger(struct gpio_bank *bank, int gpio, |
| 255 | unsigned trigger) | 289 | unsigned trigger) |
| 256 | { | 290 | { |
| @@ -539,6 +573,7 @@ static void _reset_gpio(struct gpio_bank *bank, int gpio) | |||
| 539 | _set_gpio_irqenable(bank, gpio, 0); | 573 | _set_gpio_irqenable(bank, gpio, 0); |
| 540 | _clear_gpio_irqstatus(bank, gpio); | 574 | _clear_gpio_irqstatus(bank, gpio); |
| 541 | _set_gpio_triggering(bank, GPIO_INDEX(bank, gpio), IRQ_TYPE_NONE); | 575 | _set_gpio_triggering(bank, GPIO_INDEX(bank, gpio), IRQ_TYPE_NONE); |
| 576 | _clear_gpio_debounce(bank, gpio); | ||
| 542 | } | 577 | } |
| 543 | 578 | ||
| 544 | /* Use disable_irq_wake() and enable_irq_wake() functions from drivers */ | 579 | /* Use disable_irq_wake() and enable_irq_wake() functions from drivers */ |
diff --git a/drivers/gpio/gpio-timberdale.c b/drivers/gpio/gpio-timberdale.c index 031c6adf5b65..1a3e2b9b4772 100644 --- a/drivers/gpio/gpio-timberdale.c +++ b/drivers/gpio/gpio-timberdale.c | |||
| @@ -116,7 +116,7 @@ static void timbgpio_irq_disable(struct irq_data *d) | |||
| 116 | unsigned long flags; | 116 | unsigned long flags; |
| 117 | 117 | ||
| 118 | spin_lock_irqsave(&tgpio->lock, flags); | 118 | spin_lock_irqsave(&tgpio->lock, flags); |
| 119 | tgpio->last_ier &= ~(1 << offset); | 119 | tgpio->last_ier &= ~(1UL << offset); |
| 120 | iowrite32(tgpio->last_ier, tgpio->membase + TGPIO_IER); | 120 | iowrite32(tgpio->last_ier, tgpio->membase + TGPIO_IER); |
| 121 | spin_unlock_irqrestore(&tgpio->lock, flags); | 121 | spin_unlock_irqrestore(&tgpio->lock, flags); |
| 122 | } | 122 | } |
| @@ -128,7 +128,7 @@ static void timbgpio_irq_enable(struct irq_data *d) | |||
| 128 | unsigned long flags; | 128 | unsigned long flags; |
| 129 | 129 | ||
| 130 | spin_lock_irqsave(&tgpio->lock, flags); | 130 | spin_lock_irqsave(&tgpio->lock, flags); |
| 131 | tgpio->last_ier |= 1 << offset; | 131 | tgpio->last_ier |= 1UL << offset; |
| 132 | iowrite32(tgpio->last_ier, tgpio->membase + TGPIO_IER); | 132 | iowrite32(tgpio->last_ier, tgpio->membase + TGPIO_IER); |
| 133 | spin_unlock_irqrestore(&tgpio->lock, flags); | 133 | spin_unlock_irqrestore(&tgpio->lock, flags); |
| 134 | } | 134 | } |
diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index 5d6c71edc739..1c8d9e3380e1 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c | |||
| @@ -623,9 +623,11 @@ static ssize_t export_store(struct class *class, | |||
| 623 | */ | 623 | */ |
| 624 | 624 | ||
| 625 | status = gpio_request(gpio, "sysfs"); | 625 | status = gpio_request(gpio, "sysfs"); |
| 626 | if (status < 0) | 626 | if (status < 0) { |
| 627 | if (status == -EPROBE_DEFER) | ||
| 628 | status = -ENODEV; | ||
| 627 | goto done; | 629 | goto done; |
| 628 | 630 | } | |
| 629 | status = gpio_export(gpio, true); | 631 | status = gpio_export(gpio, true); |
| 630 | if (status < 0) | 632 | if (status < 0) |
| 631 | gpio_free(gpio); | 633 | gpio_free(gpio); |
| @@ -1191,8 +1193,10 @@ int gpio_request(unsigned gpio, const char *label) | |||
| 1191 | 1193 | ||
| 1192 | spin_lock_irqsave(&gpio_lock, flags); | 1194 | spin_lock_irqsave(&gpio_lock, flags); |
| 1193 | 1195 | ||
| 1194 | if (!gpio_is_valid(gpio)) | 1196 | if (!gpio_is_valid(gpio)) { |
| 1197 | status = -EINVAL; | ||
| 1195 | goto done; | 1198 | goto done; |
| 1199 | } | ||
| 1196 | desc = &gpio_desc[gpio]; | 1200 | desc = &gpio_desc[gpio]; |
| 1197 | chip = desc->chip; | 1201 | chip = desc->chip; |
| 1198 | if (chip == NULL) | 1202 | if (chip == NULL) |
diff --git a/drivers/gpu/drm/drm_fb_cma_helper.c b/drivers/gpu/drm/drm_fb_cma_helper.c index 09e11a5d921a..fd9d0af4d536 100644 --- a/drivers/gpu/drm/drm_fb_cma_helper.c +++ b/drivers/gpu/drm/drm_fb_cma_helper.c | |||
| @@ -206,7 +206,7 @@ static int drm_fbdev_cma_create(struct drm_fb_helper *helper, | |||
| 206 | size_t size; | 206 | size_t size; |
| 207 | int ret; | 207 | int ret; |
| 208 | 208 | ||
| 209 | DRM_DEBUG_KMS("surface width(%d), height(%d) and bpp(%d\n", | 209 | DRM_DEBUG_KMS("surface width(%d), height(%d) and bpp(%d)\n", |
| 210 | sizes->surface_width, sizes->surface_height, | 210 | sizes->surface_width, sizes->surface_height, |
| 211 | sizes->surface_bpp); | 211 | sizes->surface_bpp); |
| 212 | 212 | ||
| @@ -220,7 +220,7 @@ static int drm_fbdev_cma_create(struct drm_fb_helper *helper, | |||
| 220 | 220 | ||
| 221 | size = mode_cmd.pitches[0] * mode_cmd.height; | 221 | size = mode_cmd.pitches[0] * mode_cmd.height; |
| 222 | obj = drm_gem_cma_create(dev, size); | 222 | obj = drm_gem_cma_create(dev, size); |
| 223 | if (!obj) | 223 | if (IS_ERR(obj)) |
| 224 | return -ENOMEM; | 224 | return -ENOMEM; |
| 225 | 225 | ||
| 226 | fbi = framebuffer_alloc(0, dev->dev); | 226 | fbi = framebuffer_alloc(0, dev->dev); |
diff --git a/drivers/gpu/drm/drm_fops.c b/drivers/gpu/drm/drm_fops.c index 7ef1b673e1be..133b4132983e 100644 --- a/drivers/gpu/drm/drm_fops.c +++ b/drivers/gpu/drm/drm_fops.c | |||
| @@ -121,6 +121,8 @@ int drm_open(struct inode *inode, struct file *filp) | |||
| 121 | int minor_id = iminor(inode); | 121 | int minor_id = iminor(inode); |
| 122 | struct drm_minor *minor; | 122 | struct drm_minor *minor; |
| 123 | int retcode = 0; | 123 | int retcode = 0; |
| 124 | int need_setup = 0; | ||
| 125 | struct address_space *old_mapping; | ||
| 124 | 126 | ||
| 125 | minor = idr_find(&drm_minors_idr, minor_id); | 127 | minor = idr_find(&drm_minors_idr, minor_id); |
| 126 | if (!minor) | 128 | if (!minor) |
| @@ -132,23 +134,37 @@ int drm_open(struct inode *inode, struct file *filp) | |||
| 132 | if (drm_device_is_unplugged(dev)) | 134 | if (drm_device_is_unplugged(dev)) |
| 133 | return -ENODEV; | 135 | return -ENODEV; |
| 134 | 136 | ||
| 137 | if (!dev->open_count++) | ||
| 138 | need_setup = 1; | ||
| 139 | mutex_lock(&dev->struct_mutex); | ||
| 140 | old_mapping = dev->dev_mapping; | ||
| 141 | if (old_mapping == NULL) | ||
| 142 | dev->dev_mapping = &inode->i_data; | ||
| 143 | /* ihold ensures nobody can remove inode with our i_data */ | ||
| 144 | ihold(container_of(dev->dev_mapping, struct inode, i_data)); | ||
| 145 | inode->i_mapping = dev->dev_mapping; | ||
| 146 | filp->f_mapping = dev->dev_mapping; | ||
| 147 | mutex_unlock(&dev->struct_mutex); | ||
| 148 | |||
| 135 | retcode = drm_open_helper(inode, filp, dev); | 149 | retcode = drm_open_helper(inode, filp, dev); |
| 136 | if (!retcode) { | 150 | if (retcode) |
| 137 | atomic_inc(&dev->counts[_DRM_STAT_OPENS]); | 151 | goto err_undo; |
| 138 | if (!dev->open_count++) | 152 | atomic_inc(&dev->counts[_DRM_STAT_OPENS]); |
| 139 | retcode = drm_setup(dev); | 153 | if (need_setup) { |
| 140 | } | 154 | retcode = drm_setup(dev); |
| 141 | if (!retcode) { | 155 | if (retcode) |
| 142 | mutex_lock(&dev->struct_mutex); | 156 | goto err_undo; |
| 143 | if (dev->dev_mapping == NULL) | ||
| 144 | dev->dev_mapping = &inode->i_data; | ||
| 145 | /* ihold ensures nobody can remove inode with our i_data */ | ||
| 146 | ihold(container_of(dev->dev_mapping, struct inode, i_data)); | ||
| 147 | inode->i_mapping = dev->dev_mapping; | ||
| 148 | filp->f_mapping = dev->dev_mapping; | ||
| 149 | mutex_unlock(&dev->struct_mutex); | ||
| 150 | } | 157 | } |
| 158 | return 0; | ||
| 151 | 159 | ||
| 160 | err_undo: | ||
| 161 | mutex_lock(&dev->struct_mutex); | ||
| 162 | filp->f_mapping = old_mapping; | ||
| 163 | inode->i_mapping = old_mapping; | ||
| 164 | iput(container_of(dev->dev_mapping, struct inode, i_data)); | ||
| 165 | dev->dev_mapping = old_mapping; | ||
| 166 | mutex_unlock(&dev->struct_mutex); | ||
| 167 | dev->open_count--; | ||
| 152 | return retcode; | 168 | return retcode; |
| 153 | } | 169 | } |
| 154 | EXPORT_SYMBOL(drm_open); | 170 | EXPORT_SYMBOL(drm_open); |
diff --git a/drivers/gpu/drm/drm_info.c b/drivers/gpu/drm/drm_info.c index cdf8b1e7602d..d4b20ceda3fb 100644 --- a/drivers/gpu/drm/drm_info.c +++ b/drivers/gpu/drm/drm_info.c | |||
| @@ -205,8 +205,6 @@ static int drm_gem_one_name_info(int id, void *ptr, void *data) | |||
| 205 | struct drm_gem_object *obj = ptr; | 205 | struct drm_gem_object *obj = ptr; |
| 206 | struct seq_file *m = data; | 206 | struct seq_file *m = data; |
| 207 | 207 | ||
| 208 | seq_printf(m, "name %d size %zd\n", obj->name, obj->size); | ||
| 209 | |||
| 210 | seq_printf(m, "%6d %8zd %7d %8d\n", | 208 | seq_printf(m, "%6d %8zd %7d %8d\n", |
| 211 | obj->name, obj->size, | 209 | obj->name, obj->size, |
| 212 | atomic_read(&obj->handle_count), | 210 | atomic_read(&obj->handle_count), |
| @@ -239,7 +237,7 @@ int drm_vma_info(struct seq_file *m, void *data) | |||
| 239 | mutex_lock(&dev->struct_mutex); | 237 | mutex_lock(&dev->struct_mutex); |
| 240 | seq_printf(m, "vma use count: %d, high_memory = %pK, 0x%pK\n", | 238 | seq_printf(m, "vma use count: %d, high_memory = %pK, 0x%pK\n", |
| 241 | atomic_read(&dev->vma_count), | 239 | atomic_read(&dev->vma_count), |
| 242 | high_memory, (void *)virt_to_phys(high_memory)); | 240 | high_memory, (void *)(unsigned long)virt_to_phys(high_memory)); |
| 243 | 241 | ||
| 244 | list_for_each_entry(pt, &dev->vmalist, head) { | 242 | list_for_each_entry(pt, &dev->vmalist, head) { |
| 245 | vma = pt->vma; | 243 | vma = pt->vma; |
diff --git a/drivers/gpu/drm/drm_platform.c b/drivers/gpu/drm/drm_platform.c index aaeb6f8d69ce..b8a282ea8751 100644 --- a/drivers/gpu/drm/drm_platform.c +++ b/drivers/gpu/drm/drm_platform.c | |||
| @@ -64,7 +64,6 @@ int drm_get_platform_dev(struct platform_device *platdev, | |||
| 64 | } | 64 | } |
| 65 | 65 | ||
| 66 | if (drm_core_check_feature(dev, DRIVER_MODESET)) { | 66 | if (drm_core_check_feature(dev, DRIVER_MODESET)) { |
| 67 | dev_set_drvdata(&platdev->dev, dev); | ||
| 68 | ret = drm_get_minor(dev, &dev->control, DRM_MINOR_CONTROL); | 67 | ret = drm_get_minor(dev, &dev->control, DRM_MINOR_CONTROL); |
| 69 | if (ret) | 68 | if (ret) |
| 70 | goto err_g1; | 69 | goto err_g1; |
diff --git a/drivers/gpu/drm/exynos/Kconfig b/drivers/gpu/drm/exynos/Kconfig index 59a26e577b57..fc345d4ebb03 100644 --- a/drivers/gpu/drm/exynos/Kconfig +++ b/drivers/gpu/drm/exynos/Kconfig | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | config DRM_EXYNOS | 1 | config DRM_EXYNOS |
| 2 | tristate "DRM Support for Samsung SoC EXYNOS Series" | 2 | tristate "DRM Support for Samsung SoC EXYNOS Series" |
| 3 | depends on DRM && PLAT_SAMSUNG | 3 | depends on DRM && (PLAT_SAMSUNG || ARCH_MULTIPLATFORM) |
| 4 | select DRM_KMS_HELPER | 4 | select DRM_KMS_HELPER |
| 5 | select FB_CFB_FILLRECT | 5 | select FB_CFB_FILLRECT |
| 6 | select FB_CFB_COPYAREA | 6 | select FB_CFB_COPYAREA |
diff --git a/drivers/gpu/drm/exynos/exynos_drm_connector.c b/drivers/gpu/drm/exynos/exynos_drm_connector.c index 18c271862ca8..0f68a2872673 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_connector.c +++ b/drivers/gpu/drm/exynos/exynos_drm_connector.c | |||
| @@ -374,6 +374,7 @@ struct drm_connector *exynos_drm_connector_create(struct drm_device *dev, | |||
| 374 | exynos_connector->encoder_id = encoder->base.id; | 374 | exynos_connector->encoder_id = encoder->base.id; |
| 375 | exynos_connector->manager = manager; | 375 | exynos_connector->manager = manager; |
| 376 | exynos_connector->dpms = DRM_MODE_DPMS_OFF; | 376 | exynos_connector->dpms = DRM_MODE_DPMS_OFF; |
| 377 | connector->dpms = DRM_MODE_DPMS_OFF; | ||
| 377 | connector->encoder = encoder; | 378 | connector->encoder = encoder; |
| 378 | 379 | ||
| 379 | err = drm_mode_connector_attach_encoder(connector, encoder); | 380 | err = drm_mode_connector_attach_encoder(connector, encoder); |
diff --git a/drivers/gpu/drm/exynos/exynos_drm_encoder.c b/drivers/gpu/drm/exynos/exynos_drm_encoder.c index e51503fbaf2b..f2df06c603f7 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_encoder.c +++ b/drivers/gpu/drm/exynos/exynos_drm_encoder.c | |||
| @@ -43,12 +43,14 @@ | |||
| 43 | * @manager: specific encoder has its own manager to control a hardware | 43 | * @manager: specific encoder has its own manager to control a hardware |
| 44 | * appropriately and we can access a hardware drawing on this manager. | 44 | * appropriately and we can access a hardware drawing on this manager. |
| 45 | * @dpms: store the encoder dpms value. | 45 | * @dpms: store the encoder dpms value. |
| 46 | * @updated: indicate whether overlay data updating is needed or not. | ||
| 46 | */ | 47 | */ |
| 47 | struct exynos_drm_encoder { | 48 | struct exynos_drm_encoder { |
| 48 | struct drm_crtc *old_crtc; | 49 | struct drm_crtc *old_crtc; |
| 49 | struct drm_encoder drm_encoder; | 50 | struct drm_encoder drm_encoder; |
| 50 | struct exynos_drm_manager *manager; | 51 | struct exynos_drm_manager *manager; |
| 51 | int dpms; | 52 | int dpms; |
| 53 | bool updated; | ||
| 52 | }; | 54 | }; |
| 53 | 55 | ||
| 54 | static void exynos_drm_connector_power(struct drm_encoder *encoder, int mode) | 56 | static void exynos_drm_connector_power(struct drm_encoder *encoder, int mode) |
| @@ -85,7 +87,9 @@ static void exynos_drm_encoder_dpms(struct drm_encoder *encoder, int mode) | |||
| 85 | switch (mode) { | 87 | switch (mode) { |
| 86 | case DRM_MODE_DPMS_ON: | 88 | case DRM_MODE_DPMS_ON: |
| 87 | if (manager_ops && manager_ops->apply) | 89 | if (manager_ops && manager_ops->apply) |
| 88 | manager_ops->apply(manager->dev); | 90 | if (!exynos_encoder->updated) |
| 91 | manager_ops->apply(manager->dev); | ||
| 92 | |||
| 89 | exynos_drm_connector_power(encoder, mode); | 93 | exynos_drm_connector_power(encoder, mode); |
| 90 | exynos_encoder->dpms = mode; | 94 | exynos_encoder->dpms = mode; |
| 91 | break; | 95 | break; |
| @@ -94,6 +98,7 @@ static void exynos_drm_encoder_dpms(struct drm_encoder *encoder, int mode) | |||
| 94 | case DRM_MODE_DPMS_OFF: | 98 | case DRM_MODE_DPMS_OFF: |
| 95 | exynos_drm_connector_power(encoder, mode); | 99 | exynos_drm_connector_power(encoder, mode); |
| 96 | exynos_encoder->dpms = mode; | 100 | exynos_encoder->dpms = mode; |
| 101 | exynos_encoder->updated = false; | ||
| 97 | break; | 102 | break; |
| 98 | default: | 103 | default: |
| 99 | DRM_ERROR("unspecified mode %d\n", mode); | 104 | DRM_ERROR("unspecified mode %d\n", mode); |
| @@ -205,13 +210,28 @@ static void exynos_drm_encoder_prepare(struct drm_encoder *encoder) | |||
| 205 | 210 | ||
| 206 | static void exynos_drm_encoder_commit(struct drm_encoder *encoder) | 211 | static void exynos_drm_encoder_commit(struct drm_encoder *encoder) |
| 207 | { | 212 | { |
| 208 | struct exynos_drm_manager *manager = exynos_drm_get_manager(encoder); | 213 | struct exynos_drm_encoder *exynos_encoder = to_exynos_encoder(encoder); |
| 214 | struct exynos_drm_manager *manager = exynos_encoder->manager; | ||
| 209 | struct exynos_drm_manager_ops *manager_ops = manager->ops; | 215 | struct exynos_drm_manager_ops *manager_ops = manager->ops; |
| 210 | 216 | ||
| 211 | DRM_DEBUG_KMS("%s\n", __FILE__); | 217 | DRM_DEBUG_KMS("%s\n", __FILE__); |
| 212 | 218 | ||
| 213 | if (manager_ops && manager_ops->commit) | 219 | if (manager_ops && manager_ops->commit) |
| 214 | manager_ops->commit(manager->dev); | 220 | manager_ops->commit(manager->dev); |
| 221 | |||
| 222 | /* | ||
| 223 | * this will avoid one issue that overlay data is updated to | ||
| 224 | * real hardware two times. | ||
| 225 | * And this variable will be used to check if the data was | ||
| 226 | * already updated or not by exynos_drm_encoder_dpms function. | ||
| 227 | */ | ||
| 228 | exynos_encoder->updated = true; | ||
| 229 | |||
| 230 | /* | ||
| 231 | * In case of setcrtc, there is no way to update encoder's dpms | ||
| 232 | * so update it here. | ||
| 233 | */ | ||
| 234 | exynos_encoder->dpms = DRM_MODE_DPMS_ON; | ||
| 215 | } | 235 | } |
| 216 | 236 | ||
| 217 | static void exynos_drm_encoder_disable(struct drm_encoder *encoder) | 237 | static void exynos_drm_encoder_disable(struct drm_encoder *encoder) |
| @@ -401,19 +421,6 @@ void exynos_drm_encoder_crtc_dpms(struct drm_encoder *encoder, void *data) | |||
| 401 | manager_ops->dpms(manager->dev, mode); | 421 | manager_ops->dpms(manager->dev, mode); |
| 402 | 422 | ||
| 403 | /* | 423 | /* |
| 404 | * set current mode to new one so that data aren't updated into | ||
| 405 | * registers by drm_helper_connector_dpms two times. | ||
| 406 | * | ||
| 407 | * in case that drm_crtc_helper_set_mode() is called, | ||
| 408 | * overlay_ops->commit() and manager_ops->commit() callbacks | ||
| 409 | * can be called two times, first at drm_crtc_helper_set_mode() | ||
| 410 | * and second at drm_helper_connector_dpms(). | ||
| 411 | * so with this setting, when drm_helper_connector_dpms() is called | ||
| 412 | * encoder->funcs->dpms() will be ignored. | ||
| 413 | */ | ||
| 414 | exynos_encoder->dpms = mode; | ||
| 415 | |||
| 416 | /* | ||
| 417 | * if this condition is ok then it means that the crtc is already | 424 | * if this condition is ok then it means that the crtc is already |
| 418 | * detached from encoder and last function for detaching is properly | 425 | * detached from encoder and last function for detaching is properly |
| 419 | * done, so clear pipe from manager to prevent repeated call. | 426 | * done, so clear pipe from manager to prevent repeated call. |
| @@ -506,6 +513,6 @@ void exynos_drm_encoder_plane_disable(struct drm_encoder *encoder, void *data) | |||
| 506 | * because the setting for disabling the overlay will be updated | 513 | * because the setting for disabling the overlay will be updated |
| 507 | * at vsync. | 514 | * at vsync. |
| 508 | */ | 515 | */ |
| 509 | if (overlay_ops->wait_for_vblank) | 516 | if (overlay_ops && overlay_ops->wait_for_vblank) |
| 510 | overlay_ops->wait_for_vblank(manager->dev); | 517 | overlay_ops->wait_for_vblank(manager->dev); |
| 511 | } | 518 | } |
diff --git a/drivers/gpu/drm/exynos/exynos_drm_fbdev.c b/drivers/gpu/drm/exynos/exynos_drm_fbdev.c index 67eb6ba56edf..e7466c4414cb 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_fbdev.c +++ b/drivers/gpu/drm/exynos/exynos_drm_fbdev.c | |||
| @@ -87,7 +87,8 @@ static int exynos_drm_fbdev_update(struct drm_fb_helper *helper, | |||
| 87 | 87 | ||
| 88 | dev->mode_config.fb_base = (resource_size_t)buffer->dma_addr; | 88 | dev->mode_config.fb_base = (resource_size_t)buffer->dma_addr; |
| 89 | fbi->screen_base = buffer->kvaddr + offset; | 89 | fbi->screen_base = buffer->kvaddr + offset; |
| 90 | fbi->fix.smem_start = (unsigned long)(buffer->dma_addr + offset); | 90 | fbi->fix.smem_start = (unsigned long)(page_to_phys(buffer->pages[0]) + |
| 91 | offset); | ||
| 91 | fbi->screen_size = size; | 92 | fbi->screen_size = size; |
| 92 | fbi->fix.smem_len = size; | 93 | fbi->fix.smem_len = size; |
| 93 | 94 | ||
diff --git a/drivers/gpu/drm/exynos/exynos_drm_fimd.c b/drivers/gpu/drm/exynos/exynos_drm_fimd.c index 130a2b510d4a..e08478f19f1a 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_fimd.c +++ b/drivers/gpu/drm/exynos/exynos_drm_fimd.c | |||
| @@ -61,11 +61,11 @@ struct fimd_driver_data { | |||
| 61 | unsigned int timing_base; | 61 | unsigned int timing_base; |
| 62 | }; | 62 | }; |
| 63 | 63 | ||
| 64 | struct fimd_driver_data exynos4_fimd_driver_data = { | 64 | static struct fimd_driver_data exynos4_fimd_driver_data = { |
| 65 | .timing_base = 0x0, | 65 | .timing_base = 0x0, |
| 66 | }; | 66 | }; |
| 67 | 67 | ||
| 68 | struct fimd_driver_data exynos5_fimd_driver_data = { | 68 | static struct fimd_driver_data exynos5_fimd_driver_data = { |
| 69 | .timing_base = 0x20000, | 69 | .timing_base = 0x20000, |
| 70 | }; | 70 | }; |
| 71 | 71 | ||
diff --git a/drivers/gpu/drm/exynos/exynos_drm_plane.c b/drivers/gpu/drm/exynos/exynos_drm_plane.c index 60b877a388c2..862ca1eb2102 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_plane.c +++ b/drivers/gpu/drm/exynos/exynos_drm_plane.c | |||
| @@ -204,7 +204,6 @@ exynos_update_plane(struct drm_plane *plane, struct drm_crtc *crtc, | |||
| 204 | return ret; | 204 | return ret; |
| 205 | 205 | ||
| 206 | plane->crtc = crtc; | 206 | plane->crtc = crtc; |
| 207 | plane->fb = crtc->fb; | ||
| 208 | 207 | ||
| 209 | exynos_plane_commit(plane); | 208 | exynos_plane_commit(plane); |
| 210 | exynos_plane_dpms(plane, DRM_MODE_DPMS_ON); | 209 | exynos_plane_dpms(plane, DRM_MODE_DPMS_ON); |
diff --git a/drivers/gpu/drm/exynos/exynos_mixer.c b/drivers/gpu/drm/exynos/exynos_mixer.c index 614b2e9ac462..e7fbb823fd8e 100644 --- a/drivers/gpu/drm/exynos/exynos_mixer.c +++ b/drivers/gpu/drm/exynos/exynos_mixer.c | |||
| @@ -1142,7 +1142,7 @@ static int __devinit mixer_probe(struct platform_device *pdev) | |||
| 1142 | const struct of_device_id *match; | 1142 | const struct of_device_id *match; |
| 1143 | match = of_match_node(of_match_ptr(mixer_match_types), | 1143 | match = of_match_node(of_match_ptr(mixer_match_types), |
| 1144 | pdev->dev.of_node); | 1144 | pdev->dev.of_node); |
| 1145 | drv = match->data; | 1145 | drv = (struct mixer_drv_data *)match->data; |
| 1146 | } else { | 1146 | } else { |
| 1147 | drv = (struct mixer_drv_data *) | 1147 | drv = (struct mixer_drv_data *) |
| 1148 | platform_get_device_id(pdev)->driver_data; | 1148 | platform_get_device_id(pdev)->driver_data; |
diff --git a/drivers/gpu/drm/i915/dvo_ch7xxx.c b/drivers/gpu/drm/i915/dvo_ch7xxx.c index 38f3a6cb8c7d..3edd981e0770 100644 --- a/drivers/gpu/drm/i915/dvo_ch7xxx.c +++ b/drivers/gpu/drm/i915/dvo_ch7xxx.c | |||
| @@ -303,10 +303,10 @@ static bool ch7xxx_get_hw_state(struct intel_dvo_device *dvo) | |||
| 303 | 303 | ||
| 304 | ch7xxx_readb(dvo, CH7xxx_PM, &val); | 304 | ch7xxx_readb(dvo, CH7xxx_PM, &val); |
| 305 | 305 | ||
| 306 | if (val & CH7xxx_PM_FPD) | 306 | if (val & (CH7xxx_PM_DVIL | CH7xxx_PM_DVIP)) |
| 307 | return false; | ||
| 308 | else | ||
| 309 | return true; | 307 | return true; |
| 308 | else | ||
| 309 | return false; | ||
| 310 | } | 310 | } |
| 311 | 311 | ||
| 312 | static void ch7xxx_dump_regs(struct intel_dvo_device *dvo) | 312 | static void ch7xxx_dump_regs(struct intel_dvo_device *dvo) |
diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index c9bfd83dde64..61ae104dca8c 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c | |||
| @@ -1505,7 +1505,8 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) | |||
| 1505 | goto put_gmch; | 1505 | goto put_gmch; |
| 1506 | } | 1506 | } |
| 1507 | 1507 | ||
| 1508 | i915_kick_out_firmware_fb(dev_priv); | 1508 | if (drm_core_check_feature(dev, DRIVER_MODESET)) |
| 1509 | i915_kick_out_firmware_fb(dev_priv); | ||
| 1509 | 1510 | ||
| 1510 | pci_set_master(dev->pdev); | 1511 | pci_set_master(dev->pdev); |
| 1511 | 1512 | ||
diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index aac4e5e1a5b9..6770ee6084b4 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c | |||
| @@ -118,6 +118,13 @@ module_param_named(i915_enable_ppgtt, i915_enable_ppgtt, int, 0600); | |||
| 118 | MODULE_PARM_DESC(i915_enable_ppgtt, | 118 | MODULE_PARM_DESC(i915_enable_ppgtt, |
| 119 | "Enable PPGTT (default: true)"); | 119 | "Enable PPGTT (default: true)"); |
| 120 | 120 | ||
| 121 | unsigned int i915_preliminary_hw_support __read_mostly = 0; | ||
| 122 | module_param_named(preliminary_hw_support, i915_preliminary_hw_support, int, 0600); | ||
| 123 | MODULE_PARM_DESC(preliminary_hw_support, | ||
| 124 | "Enable preliminary hardware support. " | ||
| 125 | "Enable Haswell and ValleyView Support. " | ||
| 126 | "(default: false)"); | ||
| 127 | |||
| 121 | static struct drm_driver driver; | 128 | static struct drm_driver driver; |
| 122 | extern int intel_agp_enabled; | 129 | extern int intel_agp_enabled; |
| 123 | 130 | ||
| @@ -826,6 +833,12 @@ i915_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
| 826 | struct intel_device_info *intel_info = | 833 | struct intel_device_info *intel_info = |
| 827 | (struct intel_device_info *) ent->driver_data; | 834 | (struct intel_device_info *) ent->driver_data; |
| 828 | 835 | ||
| 836 | if (intel_info->is_haswell || intel_info->is_valleyview) | ||
| 837 | if(!i915_preliminary_hw_support) { | ||
| 838 | DRM_ERROR("Preliminary hardware support disabled\n"); | ||
| 839 | return -ENODEV; | ||
| 840 | } | ||
| 841 | |||
| 829 | /* Only bind to function 0 of the device. Early generations | 842 | /* Only bind to function 0 of the device. Early generations |
| 830 | * used function 1 as a placeholder for multi-head. This causes | 843 | * used function 1 as a placeholder for multi-head. This causes |
| 831 | * us confusion instead, especially on the systems where both | 844 | * us confusion instead, especially on the systems where both |
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 4f2831aa5fed..f511fa2f4168 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h | |||
| @@ -1217,6 +1217,7 @@ extern int i915_enable_rc6 __read_mostly; | |||
| 1217 | extern int i915_enable_fbc __read_mostly; | 1217 | extern int i915_enable_fbc __read_mostly; |
| 1218 | extern bool i915_enable_hangcheck __read_mostly; | 1218 | extern bool i915_enable_hangcheck __read_mostly; |
| 1219 | extern int i915_enable_ppgtt __read_mostly; | 1219 | extern int i915_enable_ppgtt __read_mostly; |
| 1220 | extern unsigned int i915_preliminary_hw_support __read_mostly; | ||
| 1220 | 1221 | ||
| 1221 | extern int i915_suspend(struct drm_device *dev, pm_message_t state); | 1222 | extern int i915_suspend(struct drm_device *dev, pm_message_t state); |
| 1222 | extern int i915_resume(struct drm_device *dev); | 1223 | extern int i915_resume(struct drm_device *dev); |
| @@ -1341,9 +1342,14 @@ int __must_check i915_gem_object_get_pages(struct drm_i915_gem_object *obj); | |||
| 1341 | static inline struct page *i915_gem_object_get_page(struct drm_i915_gem_object *obj, int n) | 1342 | static inline struct page *i915_gem_object_get_page(struct drm_i915_gem_object *obj, int n) |
| 1342 | { | 1343 | { |
| 1343 | struct scatterlist *sg = obj->pages->sgl; | 1344 | struct scatterlist *sg = obj->pages->sgl; |
| 1344 | while (n >= SG_MAX_SINGLE_ALLOC) { | 1345 | int nents = obj->pages->nents; |
| 1346 | while (nents > SG_MAX_SINGLE_ALLOC) { | ||
| 1347 | if (n < SG_MAX_SINGLE_ALLOC - 1) | ||
| 1348 | break; | ||
| 1349 | |||
| 1345 | sg = sg_chain_ptr(sg + SG_MAX_SINGLE_ALLOC - 1); | 1350 | sg = sg_chain_ptr(sg + SG_MAX_SINGLE_ALLOC - 1); |
| 1346 | n -= SG_MAX_SINGLE_ALLOC - 1; | 1351 | n -= SG_MAX_SINGLE_ALLOC - 1; |
| 1352 | nents -= SG_MAX_SINGLE_ALLOC - 1; | ||
| 1347 | } | 1353 | } |
| 1348 | return sg_page(sg+n); | 1354 | return sg_page(sg+n); |
| 1349 | } | 1355 | } |
| @@ -1427,7 +1433,7 @@ int __must_check i915_gpu_idle(struct drm_device *dev); | |||
| 1427 | int __must_check i915_gem_idle(struct drm_device *dev); | 1433 | int __must_check i915_gem_idle(struct drm_device *dev); |
| 1428 | int i915_add_request(struct intel_ring_buffer *ring, | 1434 | int i915_add_request(struct intel_ring_buffer *ring, |
| 1429 | struct drm_file *file, | 1435 | struct drm_file *file, |
| 1430 | struct drm_i915_gem_request *request); | 1436 | u32 *seqno); |
| 1431 | int __must_check i915_wait_seqno(struct intel_ring_buffer *ring, | 1437 | int __must_check i915_wait_seqno(struct intel_ring_buffer *ring, |
| 1432 | uint32_t seqno); | 1438 | uint32_t seqno); |
| 1433 | int i915_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf); | 1439 | int i915_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf); |
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 19dbdd7dd564..9b285da4449b 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c | |||
| @@ -1407,8 +1407,10 @@ out: | |||
| 1407 | return VM_FAULT_NOPAGE; | 1407 | return VM_FAULT_NOPAGE; |
| 1408 | case -ENOMEM: | 1408 | case -ENOMEM: |
| 1409 | return VM_FAULT_OOM; | 1409 | return VM_FAULT_OOM; |
| 1410 | case -ENOSPC: | ||
| 1411 | return VM_FAULT_SIGBUS; | ||
| 1410 | default: | 1412 | default: |
| 1411 | WARN_ON_ONCE(ret); | 1413 | WARN_ONCE(ret, "unhandled error in i915_gem_fault: %i\n", ret); |
| 1412 | return VM_FAULT_SIGBUS; | 1414 | return VM_FAULT_SIGBUS; |
| 1413 | } | 1415 | } |
| 1414 | } | 1416 | } |
| @@ -1794,7 +1796,7 @@ i915_gem_object_get_pages_gtt(struct drm_i915_gem_object *obj) | |||
| 1794 | */ | 1796 | */ |
| 1795 | mapping = obj->base.filp->f_path.dentry->d_inode->i_mapping; | 1797 | mapping = obj->base.filp->f_path.dentry->d_inode->i_mapping; |
| 1796 | gfp = mapping_gfp_mask(mapping); | 1798 | gfp = mapping_gfp_mask(mapping); |
| 1797 | gfp |= __GFP_NORETRY | __GFP_NOWARN; | 1799 | gfp |= __GFP_NORETRY | __GFP_NOWARN | __GFP_NO_KSWAPD; |
| 1798 | gfp &= ~(__GFP_IO | __GFP_WAIT); | 1800 | gfp &= ~(__GFP_IO | __GFP_WAIT); |
| 1799 | for_each_sg(st->sgl, sg, page_count, i) { | 1801 | for_each_sg(st->sgl, sg, page_count, i) { |
| 1800 | page = shmem_read_mapping_page_gfp(mapping, i, gfp); | 1802 | page = shmem_read_mapping_page_gfp(mapping, i, gfp); |
| @@ -1807,7 +1809,7 @@ i915_gem_object_get_pages_gtt(struct drm_i915_gem_object *obj) | |||
| 1807 | * our own buffer, now let the real VM do its job and | 1809 | * our own buffer, now let the real VM do its job and |
| 1808 | * go down in flames if truly OOM. | 1810 | * go down in flames if truly OOM. |
| 1809 | */ | 1811 | */ |
| 1810 | gfp &= ~(__GFP_NORETRY | __GFP_NOWARN); | 1812 | gfp &= ~(__GFP_NORETRY | __GFP_NOWARN | __GFP_NO_KSWAPD); |
| 1811 | gfp |= __GFP_IO | __GFP_WAIT; | 1813 | gfp |= __GFP_IO | __GFP_WAIT; |
| 1812 | 1814 | ||
| 1813 | i915_gem_shrink_all(dev_priv); | 1815 | i915_gem_shrink_all(dev_priv); |
| @@ -1815,17 +1817,18 @@ i915_gem_object_get_pages_gtt(struct drm_i915_gem_object *obj) | |||
| 1815 | if (IS_ERR(page)) | 1817 | if (IS_ERR(page)) |
| 1816 | goto err_pages; | 1818 | goto err_pages; |
| 1817 | 1819 | ||
| 1818 | gfp |= __GFP_NORETRY | __GFP_NOWARN; | 1820 | gfp |= __GFP_NORETRY | __GFP_NOWARN | __GFP_NO_KSWAPD; |
| 1819 | gfp &= ~(__GFP_IO | __GFP_WAIT); | 1821 | gfp &= ~(__GFP_IO | __GFP_WAIT); |
| 1820 | } | 1822 | } |
| 1821 | 1823 | ||
| 1822 | sg_set_page(sg, page, PAGE_SIZE, 0); | 1824 | sg_set_page(sg, page, PAGE_SIZE, 0); |
| 1823 | } | 1825 | } |
| 1824 | 1826 | ||
| 1827 | obj->pages = st; | ||
| 1828 | |||
| 1825 | if (i915_gem_object_needs_bit17_swizzle(obj)) | 1829 | if (i915_gem_object_needs_bit17_swizzle(obj)) |
| 1826 | i915_gem_object_do_bit_17_swizzle(obj); | 1830 | i915_gem_object_do_bit_17_swizzle(obj); |
| 1827 | 1831 | ||
| 1828 | obj->pages = st; | ||
| 1829 | return 0; | 1832 | return 0; |
| 1830 | 1833 | ||
| 1831 | err_pages: | 1834 | err_pages: |
| @@ -1955,11 +1958,12 @@ i915_gem_next_request_seqno(struct intel_ring_buffer *ring) | |||
| 1955 | int | 1958 | int |
| 1956 | i915_add_request(struct intel_ring_buffer *ring, | 1959 | i915_add_request(struct intel_ring_buffer *ring, |
| 1957 | struct drm_file *file, | 1960 | struct drm_file *file, |
| 1958 | struct drm_i915_gem_request *request) | 1961 | u32 *out_seqno) |
| 1959 | { | 1962 | { |
| 1960 | drm_i915_private_t *dev_priv = ring->dev->dev_private; | 1963 | drm_i915_private_t *dev_priv = ring->dev->dev_private; |
| 1961 | uint32_t seqno; | 1964 | struct drm_i915_gem_request *request; |
| 1962 | u32 request_ring_position; | 1965 | u32 request_ring_position; |
| 1966 | u32 seqno; | ||
| 1963 | int was_empty; | 1967 | int was_empty; |
| 1964 | int ret; | 1968 | int ret; |
| 1965 | 1969 | ||
| @@ -1974,11 +1978,9 @@ i915_add_request(struct intel_ring_buffer *ring, | |||
| 1974 | if (ret) | 1978 | if (ret) |
| 1975 | return ret; | 1979 | return ret; |
| 1976 | 1980 | ||
| 1977 | if (request == NULL) { | 1981 | request = kmalloc(sizeof(*request), GFP_KERNEL); |
| 1978 | request = kmalloc(sizeof(*request), GFP_KERNEL); | 1982 | if (request == NULL) |
| 1979 | if (request == NULL) | 1983 | return -ENOMEM; |
| 1980 | return -ENOMEM; | ||
| 1981 | } | ||
| 1982 | 1984 | ||
| 1983 | seqno = i915_gem_next_request_seqno(ring); | 1985 | seqno = i915_gem_next_request_seqno(ring); |
| 1984 | 1986 | ||
| @@ -2030,6 +2032,8 @@ i915_add_request(struct intel_ring_buffer *ring, | |||
| 2030 | } | 2032 | } |
| 2031 | } | 2033 | } |
| 2032 | 2034 | ||
| 2035 | if (out_seqno) | ||
| 2036 | *out_seqno = seqno; | ||
| 2033 | return 0; | 2037 | return 0; |
| 2034 | } | 2038 | } |
| 2035 | 2039 | ||
| @@ -3959,6 +3963,9 @@ i915_gem_init_hw(struct drm_device *dev) | |||
| 3959 | if (!intel_enable_gtt()) | 3963 | if (!intel_enable_gtt()) |
| 3960 | return -EIO; | 3964 | return -EIO; |
| 3961 | 3965 | ||
| 3966 | if (IS_HASWELL(dev) && (I915_READ(0x120010) == 1)) | ||
| 3967 | I915_WRITE(0x9008, I915_READ(0x9008) | 0xf0000); | ||
| 3968 | |||
| 3962 | i915_gem_l3_remap(dev); | 3969 | i915_gem_l3_remap(dev); |
| 3963 | 3970 | ||
| 3964 | i915_gem_init_swizzling(dev); | 3971 | i915_gem_init_swizzling(dev); |
| @@ -4098,7 +4105,6 @@ i915_gem_entervt_ioctl(struct drm_device *dev, void *data, | |||
| 4098 | } | 4105 | } |
| 4099 | 4106 | ||
| 4100 | BUG_ON(!list_empty(&dev_priv->mm.active_list)); | 4107 | BUG_ON(!list_empty(&dev_priv->mm.active_list)); |
| 4101 | BUG_ON(!list_empty(&dev_priv->mm.inactive_list)); | ||
| 4102 | mutex_unlock(&dev->struct_mutex); | 4108 | mutex_unlock(&dev->struct_mutex); |
| 4103 | 4109 | ||
| 4104 | ret = drm_irq_install(dev); | 4110 | ret = drm_irq_install(dev); |
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 64c1be0a9cfd..a4162ddff6c5 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h | |||
| @@ -521,7 +521,7 @@ | |||
| 521 | */ | 521 | */ |
| 522 | # define _3D_CHICKEN2_WM_READ_PIPELINED (1 << 14) | 522 | # define _3D_CHICKEN2_WM_READ_PIPELINED (1 << 14) |
| 523 | #define _3D_CHICKEN3 0x02090 | 523 | #define _3D_CHICKEN3 0x02090 |
| 524 | #define _3D_CHICKEN_SF_DISABLE_FASTCLIP_CULL (1 << 5) | 524 | #define _3D_CHICKEN3_SF_DISABLE_FASTCLIP_CULL (1 << 5) |
| 525 | 525 | ||
| 526 | #define MI_MODE 0x0209c | 526 | #define MI_MODE 0x0209c |
| 527 | # define VS_TIMER_DISPATCH (1 << 6) | 527 | # define VS_TIMER_DISPATCH (1 << 6) |
diff --git a/drivers/gpu/drm/i915/intel_bios.c b/drivers/gpu/drm/i915/intel_bios.c index 0ed6baff4b0c..56846ed5ee55 100644 --- a/drivers/gpu/drm/i915/intel_bios.c +++ b/drivers/gpu/drm/i915/intel_bios.c | |||
| @@ -499,12 +499,8 @@ parse_edp(struct drm_i915_private *dev_priv, struct bdb_header *bdb) | |||
| 499 | 499 | ||
| 500 | edp = find_section(bdb, BDB_EDP); | 500 | edp = find_section(bdb, BDB_EDP); |
| 501 | if (!edp) { | 501 | if (!edp) { |
| 502 | if (SUPPORTS_EDP(dev_priv->dev) && dev_priv->edp.support) { | 502 | if (SUPPORTS_EDP(dev_priv->dev) && dev_priv->edp.support) |
| 503 | DRM_DEBUG_KMS("No eDP BDB found but eDP panel " | 503 | DRM_DEBUG_KMS("No eDP BDB found but eDP panel supported.\n"); |
| 504 | "supported, assume %dbpp panel color " | ||
| 505 | "depth.\n", | ||
| 506 | dev_priv->edp.bpp); | ||
| 507 | } | ||
| 508 | return; | 504 | return; |
| 509 | } | 505 | } |
| 510 | 506 | ||
| @@ -657,9 +653,6 @@ init_vbt_defaults(struct drm_i915_private *dev_priv) | |||
| 657 | dev_priv->lvds_use_ssc = 1; | 653 | dev_priv->lvds_use_ssc = 1; |
| 658 | dev_priv->lvds_ssc_freq = intel_bios_ssc_frequency(dev, 1); | 654 | dev_priv->lvds_ssc_freq = intel_bios_ssc_frequency(dev, 1); |
| 659 | DRM_DEBUG_KMS("Set default to SSC at %dMHz\n", dev_priv->lvds_ssc_freq); | 655 | DRM_DEBUG_KMS("Set default to SSC at %dMHz\n", dev_priv->lvds_ssc_freq); |
| 660 | |||
| 661 | /* eDP data */ | ||
| 662 | dev_priv->edp.bpp = 18; | ||
| 663 | } | 656 | } |
| 664 | 657 | ||
| 665 | static int __init intel_no_opregion_vbt_callback(const struct dmi_system_id *id) | 658 | static int __init intel_no_opregion_vbt_callback(const struct dmi_system_id *id) |
diff --git a/drivers/gpu/drm/i915/intel_crt.c b/drivers/gpu/drm/i915/intel_crt.c index 893f30164b7e..6345878ae1e7 100644 --- a/drivers/gpu/drm/i915/intel_crt.c +++ b/drivers/gpu/drm/i915/intel_crt.c | |||
| @@ -143,7 +143,7 @@ static void intel_crt_dpms(struct drm_connector *connector, int mode) | |||
| 143 | int old_dpms; | 143 | int old_dpms; |
| 144 | 144 | ||
| 145 | /* PCH platforms and VLV only support on/off. */ | 145 | /* PCH platforms and VLV only support on/off. */ |
| 146 | if (INTEL_INFO(dev)->gen < 5 && mode != DRM_MODE_DPMS_ON) | 146 | if (INTEL_INFO(dev)->gen >= 5 && mode != DRM_MODE_DPMS_ON) |
| 147 | mode = DRM_MODE_DPMS_OFF; | 147 | mode = DRM_MODE_DPMS_OFF; |
| 148 | 148 | ||
| 149 | if (mode == connector->dpms) | 149 | if (mode == connector->dpms) |
| @@ -219,20 +219,7 @@ static void intel_crt_mode_set(struct drm_encoder *encoder, | |||
| 219 | intel_encoder_to_crt(to_intel_encoder(encoder)); | 219 | intel_encoder_to_crt(to_intel_encoder(encoder)); |
| 220 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); | 220 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
| 221 | struct drm_i915_private *dev_priv = dev->dev_private; | 221 | struct drm_i915_private *dev_priv = dev->dev_private; |
| 222 | int dpll_md_reg; | 222 | u32 adpa; |
| 223 | u32 adpa, dpll_md; | ||
| 224 | |||
| 225 | dpll_md_reg = DPLL_MD(intel_crtc->pipe); | ||
| 226 | |||
| 227 | /* | ||
| 228 | * Disable separate mode multiplier used when cloning SDVO to CRT | ||
| 229 | * XXX this needs to be adjusted when we really are cloning | ||
| 230 | */ | ||
| 231 | if (INTEL_INFO(dev)->gen >= 4 && !HAS_PCH_SPLIT(dev)) { | ||
| 232 | dpll_md = I915_READ(dpll_md_reg); | ||
| 233 | I915_WRITE(dpll_md_reg, | ||
| 234 | dpll_md & ~DPLL_MD_UDI_MULTIPLIER_MASK); | ||
| 235 | } | ||
| 236 | 223 | ||
| 237 | adpa = ADPA_HOTPLUG_BITS; | 224 | adpa = ADPA_HOTPLUG_BITS; |
| 238 | if (adjusted_mode->flags & DRM_MODE_FLAG_PHSYNC) | 225 | if (adjusted_mode->flags & DRM_MODE_FLAG_PHSYNC) |
| @@ -742,7 +729,7 @@ void intel_crt_init(struct drm_device *dev) | |||
| 742 | 729 | ||
| 743 | crt->base.type = INTEL_OUTPUT_ANALOG; | 730 | crt->base.type = INTEL_OUTPUT_ANALOG; |
| 744 | crt->base.cloneable = true; | 731 | crt->base.cloneable = true; |
| 745 | if (IS_HASWELL(dev)) | 732 | if (IS_HASWELL(dev) || IS_I830(dev)) |
| 746 | crt->base.crtc_mask = (1 << 0); | 733 | crt->base.crtc_mask = (1 << 0); |
| 747 | else | 734 | else |
| 748 | crt->base.crtc_mask = (1 << 0) | (1 << 1) | (1 << 2); | 735 | crt->base.crtc_mask = (1 << 0) | (1 << 1) | (1 << 2); |
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 2b6ce9b2674a..b426d44a2b05 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c | |||
| @@ -3253,6 +3253,16 @@ static void ironlake_crtc_enable(struct drm_crtc *crtc) | |||
| 3253 | 3253 | ||
| 3254 | if (HAS_PCH_CPT(dev)) | 3254 | if (HAS_PCH_CPT(dev)) |
| 3255 | intel_cpt_verify_modeset(dev, intel_crtc->pipe); | 3255 | intel_cpt_verify_modeset(dev, intel_crtc->pipe); |
| 3256 | |||
| 3257 | /* | ||
| 3258 | * There seems to be a race in PCH platform hw (at least on some | ||
| 3259 | * outputs) where an enabled pipe still completes any pageflip right | ||
| 3260 | * away (as if the pipe is off) instead of waiting for vblank. As soon | ||
| 3261 | * as the first vblank happend, everything works as expected. Hence just | ||
| 3262 | * wait for one vblank before returning to avoid strange things | ||
| 3263 | * happening. | ||
| 3264 | */ | ||
| 3265 | intel_wait_for_vblank(dev, intel_crtc->pipe); | ||
| 3256 | } | 3266 | } |
| 3257 | 3267 | ||
| 3258 | static void ironlake_crtc_disable(struct drm_crtc *crtc) | 3268 | static void ironlake_crtc_disable(struct drm_crtc *crtc) |
| @@ -3831,6 +3841,17 @@ static bool intel_choose_pipe_bpp_dither(struct drm_crtc *crtc, | |||
| 3831 | } | 3841 | } |
| 3832 | } | 3842 | } |
| 3833 | 3843 | ||
| 3844 | if (intel_encoder->type == INTEL_OUTPUT_EDP) { | ||
| 3845 | /* Use VBT settings if we have an eDP panel */ | ||
| 3846 | unsigned int edp_bpc = dev_priv->edp.bpp / 3; | ||
| 3847 | |||
| 3848 | if (edp_bpc && edp_bpc < display_bpc) { | ||
| 3849 | DRM_DEBUG_KMS("clamping display bpc (was %d) to eDP (%d)\n", display_bpc, edp_bpc); | ||
| 3850 | display_bpc = edp_bpc; | ||
| 3851 | } | ||
| 3852 | continue; | ||
| 3853 | } | ||
| 3854 | |||
| 3834 | /* | 3855 | /* |
| 3835 | * HDMI is either 12 or 8, so if the display lets 10bpc sneak | 3856 | * HDMI is either 12 or 8, so if the display lets 10bpc sneak |
| 3836 | * through, clamp it down. (Note: >12bpc will be caught below.) | 3857 | * through, clamp it down. (Note: >12bpc will be caught below.) |
| @@ -7882,6 +7903,34 @@ struct intel_quirk { | |||
| 7882 | void (*hook)(struct drm_device *dev); | 7903 | void (*hook)(struct drm_device *dev); |
| 7883 | }; | 7904 | }; |
| 7884 | 7905 | ||
| 7906 | /* For systems that don't have a meaningful PCI subdevice/subvendor ID */ | ||
| 7907 | struct intel_dmi_quirk { | ||
| 7908 | void (*hook)(struct drm_device *dev); | ||
| 7909 | const struct dmi_system_id (*dmi_id_list)[]; | ||
| 7910 | }; | ||
| 7911 | |||
| 7912 | static int intel_dmi_reverse_brightness(const struct dmi_system_id *id) | ||
| 7913 | { | ||
| 7914 | DRM_INFO("Backlight polarity reversed on %s\n", id->ident); | ||
| 7915 | return 1; | ||
| 7916 | } | ||
| 7917 | |||
| 7918 | static const struct intel_dmi_quirk intel_dmi_quirks[] = { | ||
| 7919 | { | ||
| 7920 | .dmi_id_list = &(const struct dmi_system_id[]) { | ||
| 7921 | { | ||
| 7922 | .callback = intel_dmi_reverse_brightness, | ||
| 7923 | .ident = "NCR Corporation", | ||
| 7924 | .matches = {DMI_MATCH(DMI_SYS_VENDOR, "NCR Corporation"), | ||
| 7925 | DMI_MATCH(DMI_PRODUCT_NAME, ""), | ||
| 7926 | }, | ||
| 7927 | }, | ||
| 7928 | { } /* terminating entry */ | ||
| 7929 | }, | ||
| 7930 | .hook = quirk_invert_brightness, | ||
| 7931 | }, | ||
| 7932 | }; | ||
| 7933 | |||
| 7885 | static struct intel_quirk intel_quirks[] = { | 7934 | static struct intel_quirk intel_quirks[] = { |
| 7886 | /* HP Mini needs pipe A force quirk (LP: #322104) */ | 7935 | /* HP Mini needs pipe A force quirk (LP: #322104) */ |
| 7887 | { 0x27ae, 0x103c, 0x361a, quirk_pipea_force }, | 7936 | { 0x27ae, 0x103c, 0x361a, quirk_pipea_force }, |
| @@ -7892,8 +7941,7 @@ static struct intel_quirk intel_quirks[] = { | |||
| 7892 | /* ThinkPad T60 needs pipe A force quirk (bug #16494) */ | 7941 | /* ThinkPad T60 needs pipe A force quirk (bug #16494) */ |
| 7893 | { 0x2782, 0x17aa, 0x201a, quirk_pipea_force }, | 7942 | { 0x2782, 0x17aa, 0x201a, quirk_pipea_force }, |
| 7894 | 7943 | ||
| 7895 | /* 855 & before need to leave pipe A & dpll A up */ | 7944 | /* 830/845 need to leave pipe A & dpll A up */ |
| 7896 | { 0x3582, PCI_ANY_ID, PCI_ANY_ID, quirk_pipea_force }, | ||
| 7897 | { 0x2562, PCI_ANY_ID, PCI_ANY_ID, quirk_pipea_force }, | 7945 | { 0x2562, PCI_ANY_ID, PCI_ANY_ID, quirk_pipea_force }, |
| 7898 | { 0x3577, PCI_ANY_ID, PCI_ANY_ID, quirk_pipea_force }, | 7946 | { 0x3577, PCI_ANY_ID, PCI_ANY_ID, quirk_pipea_force }, |
| 7899 | 7947 | ||
| @@ -7922,6 +7970,10 @@ static void intel_init_quirks(struct drm_device *dev) | |||
| 7922 | q->subsystem_device == PCI_ANY_ID)) | 7970 | q->subsystem_device == PCI_ANY_ID)) |
| 7923 | q->hook(dev); | 7971 | q->hook(dev); |
| 7924 | } | 7972 | } |
| 7973 | for (i = 0; i < ARRAY_SIZE(intel_dmi_quirks); i++) { | ||
| 7974 | if (dmi_check_system(*intel_dmi_quirks[i].dmi_id_list) != 0) | ||
| 7975 | intel_dmi_quirks[i].hook(dev); | ||
| 7976 | } | ||
| 7925 | } | 7977 | } |
| 7926 | 7978 | ||
| 7927 | /* Disable the VGA plane that we never use */ | 7979 | /* Disable the VGA plane that we never use */ |
| @@ -8049,29 +8101,42 @@ static void intel_enable_pipe_a(struct drm_device *dev) | |||
| 8049 | 8101 | ||
| 8050 | } | 8102 | } |
| 8051 | 8103 | ||
| 8104 | static bool | ||
| 8105 | intel_check_plane_mapping(struct intel_crtc *crtc) | ||
| 8106 | { | ||
| 8107 | struct drm_i915_private *dev_priv = crtc->base.dev->dev_private; | ||
| 8108 | u32 reg, val; | ||
| 8109 | |||
| 8110 | if (dev_priv->num_pipe == 1) | ||
| 8111 | return true; | ||
| 8112 | |||
| 8113 | reg = DSPCNTR(!crtc->plane); | ||
| 8114 | val = I915_READ(reg); | ||
| 8115 | |||
| 8116 | if ((val & DISPLAY_PLANE_ENABLE) && | ||
| 8117 | (!!(val & DISPPLANE_SEL_PIPE_MASK) == crtc->pipe)) | ||
| 8118 | return false; | ||
| 8119 | |||
| 8120 | return true; | ||
| 8121 | } | ||
| 8122 | |||
| 8052 | static void intel_sanitize_crtc(struct intel_crtc *crtc) | 8123 | static void intel_sanitize_crtc(struct intel_crtc *crtc) |
| 8053 | { | 8124 | { |
| 8054 | struct drm_device *dev = crtc->base.dev; | 8125 | struct drm_device *dev = crtc->base.dev; |
| 8055 | struct drm_i915_private *dev_priv = dev->dev_private; | 8126 | struct drm_i915_private *dev_priv = dev->dev_private; |
| 8056 | u32 reg, val; | 8127 | u32 reg; |
| 8057 | 8128 | ||
| 8058 | /* Clear any frame start delays used for debugging left by the BIOS */ | 8129 | /* Clear any frame start delays used for debugging left by the BIOS */ |
| 8059 | reg = PIPECONF(crtc->pipe); | 8130 | reg = PIPECONF(crtc->pipe); |
| 8060 | I915_WRITE(reg, I915_READ(reg) & ~PIPECONF_FRAME_START_DELAY_MASK); | 8131 | I915_WRITE(reg, I915_READ(reg) & ~PIPECONF_FRAME_START_DELAY_MASK); |
| 8061 | 8132 | ||
| 8062 | /* We need to sanitize the plane -> pipe mapping first because this will | 8133 | /* We need to sanitize the plane -> pipe mapping first because this will |
| 8063 | * disable the crtc (and hence change the state) if it is wrong. */ | 8134 | * disable the crtc (and hence change the state) if it is wrong. Note |
| 8064 | if (!HAS_PCH_SPLIT(dev)) { | 8135 | * that gen4+ has a fixed plane -> pipe mapping. */ |
| 8136 | if (INTEL_INFO(dev)->gen < 4 && !intel_check_plane_mapping(crtc)) { | ||
| 8065 | struct intel_connector *connector; | 8137 | struct intel_connector *connector; |
| 8066 | bool plane; | 8138 | bool plane; |
| 8067 | 8139 | ||
| 8068 | reg = DSPCNTR(crtc->plane); | ||
| 8069 | val = I915_READ(reg); | ||
| 8070 | |||
| 8071 | if ((val & DISPLAY_PLANE_ENABLE) == 0 && | ||
| 8072 | (!!(val & DISPPLANE_SEL_PIPE_MASK) == crtc->pipe)) | ||
| 8073 | goto ok; | ||
| 8074 | |||
| 8075 | DRM_DEBUG_KMS("[CRTC:%d] wrong plane connection detected!\n", | 8140 | DRM_DEBUG_KMS("[CRTC:%d] wrong plane connection detected!\n", |
| 8076 | crtc->base.base.id); | 8141 | crtc->base.base.id); |
| 8077 | 8142 | ||
| @@ -8095,7 +8160,6 @@ static void intel_sanitize_crtc(struct intel_crtc *crtc) | |||
| 8095 | WARN_ON(crtc->active); | 8160 | WARN_ON(crtc->active); |
| 8096 | crtc->base.enabled = false; | 8161 | crtc->base.enabled = false; |
| 8097 | } | 8162 | } |
| 8098 | ok: | ||
| 8099 | 8163 | ||
| 8100 | if (dev_priv->quirks & QUIRK_PIPEA_FORCE && | 8164 | if (dev_priv->quirks & QUIRK_PIPEA_FORCE && |
| 8101 | crtc->pipe == PIPE_A && !crtc->active) { | 8165 | crtc->pipe == PIPE_A && !crtc->active) { |
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index d1e8ddb2d6c0..368ed8ef1600 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c | |||
| @@ -1797,7 +1797,8 @@ intel_dp_start_link_train(struct intel_dp *intel_dp) | |||
| 1797 | if ((intel_dp->train_set[i] & DP_TRAIN_MAX_SWING_REACHED) == 0) | 1797 | if ((intel_dp->train_set[i] & DP_TRAIN_MAX_SWING_REACHED) == 0) |
| 1798 | break; | 1798 | break; |
| 1799 | if (i == intel_dp->lane_count && voltage_tries == 5) { | 1799 | if (i == intel_dp->lane_count && voltage_tries == 5) { |
| 1800 | if (++loop_tries == 5) { | 1800 | ++loop_tries; |
| 1801 | if (loop_tries == 5) { | ||
| 1801 | DRM_DEBUG_KMS("too many full retries, give up\n"); | 1802 | DRM_DEBUG_KMS("too many full retries, give up\n"); |
| 1802 | break; | 1803 | break; |
| 1803 | } | 1804 | } |
| @@ -1807,11 +1808,15 @@ intel_dp_start_link_train(struct intel_dp *intel_dp) | |||
| 1807 | } | 1808 | } |
| 1808 | 1809 | ||
| 1809 | /* Check to see if we've tried the same voltage 5 times */ | 1810 | /* Check to see if we've tried the same voltage 5 times */ |
| 1810 | if ((intel_dp->train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK) != voltage) { | 1811 | if ((intel_dp->train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK) == voltage) { |
| 1811 | voltage = intel_dp->train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK; | ||
| 1812 | voltage_tries = 0; | ||
| 1813 | } else | ||
| 1814 | ++voltage_tries; | 1812 | ++voltage_tries; |
| 1813 | if (voltage_tries == 5) { | ||
| 1814 | DRM_DEBUG_KMS("too many voltage retries, give up\n"); | ||
| 1815 | break; | ||
| 1816 | } | ||
| 1817 | } else | ||
| 1818 | voltage_tries = 0; | ||
| 1819 | voltage = intel_dp->train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK; | ||
| 1815 | 1820 | ||
| 1816 | /* Compute new intel_dp->train_set as requested by target */ | 1821 | /* Compute new intel_dp->train_set as requested by target */ |
| 1817 | intel_get_adjust_train(intel_dp, link_status); | 1822 | intel_get_adjust_train(intel_dp, link_status); |
| @@ -2369,8 +2374,9 @@ static void | |||
| 2369 | intel_dp_destroy(struct drm_connector *connector) | 2374 | intel_dp_destroy(struct drm_connector *connector) |
| 2370 | { | 2375 | { |
| 2371 | struct drm_device *dev = connector->dev; | 2376 | struct drm_device *dev = connector->dev; |
| 2377 | struct intel_dp *intel_dp = intel_attached_dp(connector); | ||
| 2372 | 2378 | ||
| 2373 | if (intel_dpd_is_edp(dev)) | 2379 | if (is_edp(intel_dp)) |
| 2374 | intel_panel_destroy_backlight(dev); | 2380 | intel_panel_destroy_backlight(dev); |
| 2375 | 2381 | ||
| 2376 | drm_sysfs_connector_remove(connector); | 2382 | drm_sysfs_connector_remove(connector); |
diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c index e3166df55daa..edba93b3474b 100644 --- a/drivers/gpu/drm/i915/intel_lvds.c +++ b/drivers/gpu/drm/i915/intel_lvds.c | |||
| @@ -777,6 +777,14 @@ static const struct dmi_system_id intel_no_lvds[] = { | |||
| 777 | DMI_MATCH(DMI_BOARD_NAME, "D525TUD"), | 777 | DMI_MATCH(DMI_BOARD_NAME, "D525TUD"), |
| 778 | }, | 778 | }, |
| 779 | }, | 779 | }, |
| 780 | { | ||
| 781 | .callback = intel_no_lvds_dmi_callback, | ||
| 782 | .ident = "Supermicro X7SPA-H", | ||
| 783 | .matches = { | ||
| 784 | DMI_MATCH(DMI_SYS_VENDOR, "Supermicro"), | ||
| 785 | DMI_MATCH(DMI_PRODUCT_NAME, "X7SPA-H"), | ||
| 786 | }, | ||
| 787 | }, | ||
| 780 | 788 | ||
| 781 | { } /* terminating entry */ | 789 | { } /* terminating entry */ |
| 782 | }; | 790 | }; |
diff --git a/drivers/gpu/drm/i915/intel_overlay.c b/drivers/gpu/drm/i915/intel_overlay.c index ebff850a9ab6..d7bc817f51a0 100644 --- a/drivers/gpu/drm/i915/intel_overlay.c +++ b/drivers/gpu/drm/i915/intel_overlay.c | |||
| @@ -209,7 +209,6 @@ static void intel_overlay_unmap_regs(struct intel_overlay *overlay, | |||
| 209 | } | 209 | } |
| 210 | 210 | ||
| 211 | static int intel_overlay_do_wait_request(struct intel_overlay *overlay, | 211 | static int intel_overlay_do_wait_request(struct intel_overlay *overlay, |
| 212 | struct drm_i915_gem_request *request, | ||
| 213 | void (*tail)(struct intel_overlay *)) | 212 | void (*tail)(struct intel_overlay *)) |
| 214 | { | 213 | { |
| 215 | struct drm_device *dev = overlay->dev; | 214 | struct drm_device *dev = overlay->dev; |
| @@ -218,12 +217,10 @@ static int intel_overlay_do_wait_request(struct intel_overlay *overlay, | |||
| 218 | int ret; | 217 | int ret; |
| 219 | 218 | ||
| 220 | BUG_ON(overlay->last_flip_req); | 219 | BUG_ON(overlay->last_flip_req); |
| 221 | ret = i915_add_request(ring, NULL, request); | 220 | ret = i915_add_request(ring, NULL, &overlay->last_flip_req); |
| 222 | if (ret) { | 221 | if (ret) |
| 223 | kfree(request); | 222 | return ret; |
| 224 | return ret; | 223 | |
| 225 | } | ||
| 226 | overlay->last_flip_req = request->seqno; | ||
| 227 | overlay->flip_tail = tail; | 224 | overlay->flip_tail = tail; |
| 228 | ret = i915_wait_seqno(ring, overlay->last_flip_req); | 225 | ret = i915_wait_seqno(ring, overlay->last_flip_req); |
| 229 | if (ret) | 226 | if (ret) |
| @@ -240,7 +237,6 @@ static int intel_overlay_on(struct intel_overlay *overlay) | |||
| 240 | struct drm_device *dev = overlay->dev; | 237 | struct drm_device *dev = overlay->dev; |
| 241 | struct drm_i915_private *dev_priv = dev->dev_private; | 238 | struct drm_i915_private *dev_priv = dev->dev_private; |
| 242 | struct intel_ring_buffer *ring = &dev_priv->ring[RCS]; | 239 | struct intel_ring_buffer *ring = &dev_priv->ring[RCS]; |
| 243 | struct drm_i915_gem_request *request; | ||
| 244 | int ret; | 240 | int ret; |
| 245 | 241 | ||
| 246 | BUG_ON(overlay->active); | 242 | BUG_ON(overlay->active); |
| @@ -248,17 +244,9 @@ static int intel_overlay_on(struct intel_overlay *overlay) | |||
| 248 | 244 | ||
| 249 | WARN_ON(IS_I830(dev) && !(dev_priv->quirks & QUIRK_PIPEA_FORCE)); | 245 | WARN_ON(IS_I830(dev) && !(dev_priv->quirks & QUIRK_PIPEA_FORCE)); |
| 250 | 246 | ||
| 251 | request = kzalloc(sizeof(*request), GFP_KERNEL); | ||
| 252 | if (request == NULL) { | ||
| 253 | ret = -ENOMEM; | ||
| 254 | goto out; | ||
| 255 | } | ||
| 256 | |||
| 257 | ret = intel_ring_begin(ring, 4); | 247 | ret = intel_ring_begin(ring, 4); |
| 258 | if (ret) { | 248 | if (ret) |
| 259 | kfree(request); | 249 | return ret; |
| 260 | goto out; | ||
| 261 | } | ||
| 262 | 250 | ||
| 263 | intel_ring_emit(ring, MI_OVERLAY_FLIP | MI_OVERLAY_ON); | 251 | intel_ring_emit(ring, MI_OVERLAY_FLIP | MI_OVERLAY_ON); |
| 264 | intel_ring_emit(ring, overlay->flip_addr | OFC_UPDATE); | 252 | intel_ring_emit(ring, overlay->flip_addr | OFC_UPDATE); |
| @@ -266,9 +254,7 @@ static int intel_overlay_on(struct intel_overlay *overlay) | |||
| 266 | intel_ring_emit(ring, MI_NOOP); | 254 | intel_ring_emit(ring, MI_NOOP); |
| 267 | intel_ring_advance(ring); | 255 | intel_ring_advance(ring); |
| 268 | 256 | ||
| 269 | ret = intel_overlay_do_wait_request(overlay, request, NULL); | 257 | return intel_overlay_do_wait_request(overlay, NULL); |
| 270 | out: | ||
| 271 | return ret; | ||
| 272 | } | 258 | } |
| 273 | 259 | ||
| 274 | /* overlay needs to be enabled in OCMD reg */ | 260 | /* overlay needs to be enabled in OCMD reg */ |
| @@ -278,17 +264,12 @@ static int intel_overlay_continue(struct intel_overlay *overlay, | |||
| 278 | struct drm_device *dev = overlay->dev; | 264 | struct drm_device *dev = overlay->dev; |
| 279 | drm_i915_private_t *dev_priv = dev->dev_private; | 265 | drm_i915_private_t *dev_priv = dev->dev_private; |
| 280 | struct intel_ring_buffer *ring = &dev_priv->ring[RCS]; | 266 | struct intel_ring_buffer *ring = &dev_priv->ring[RCS]; |
| 281 | struct drm_i915_gem_request *request; | ||
| 282 | u32 flip_addr = overlay->flip_addr; | 267 | u32 flip_addr = overlay->flip_addr; |
| 283 | u32 tmp; | 268 | u32 tmp; |
| 284 | int ret; | 269 | int ret; |
| 285 | 270 | ||
| 286 | BUG_ON(!overlay->active); | 271 | BUG_ON(!overlay->active); |
| 287 | 272 | ||
| 288 | request = kzalloc(sizeof(*request), GFP_KERNEL); | ||
| 289 | if (request == NULL) | ||
| 290 | return -ENOMEM; | ||
| 291 | |||
| 292 | if (load_polyphase_filter) | 273 | if (load_polyphase_filter) |
| 293 | flip_addr |= OFC_UPDATE; | 274 | flip_addr |= OFC_UPDATE; |
| 294 | 275 | ||
| @@ -298,22 +279,14 @@ static int intel_overlay_continue(struct intel_overlay *overlay, | |||
| 298 | DRM_DEBUG("overlay underrun, DOVSTA: %x\n", tmp); | 279 | DRM_DEBUG("overlay underrun, DOVSTA: %x\n", tmp); |
| 299 | 280 | ||
| 300 | ret = intel_ring_begin(ring, 2); | 281 | ret = intel_ring_begin(ring, 2); |
| 301 | if (ret) { | 282 | if (ret) |
| 302 | kfree(request); | ||
| 303 | return ret; | 283 | return ret; |
| 304 | } | 284 | |
| 305 | intel_ring_emit(ring, MI_OVERLAY_FLIP | MI_OVERLAY_CONTINUE); | 285 | intel_ring_emit(ring, MI_OVERLAY_FLIP | MI_OVERLAY_CONTINUE); |
| 306 | intel_ring_emit(ring, flip_addr); | 286 | intel_ring_emit(ring, flip_addr); |
| 307 | intel_ring_advance(ring); | 287 | intel_ring_advance(ring); |
| 308 | 288 | ||
| 309 | ret = i915_add_request(ring, NULL, request); | 289 | return i915_add_request(ring, NULL, &overlay->last_flip_req); |
| 310 | if (ret) { | ||
| 311 | kfree(request); | ||
| 312 | return ret; | ||
| 313 | } | ||
| 314 | |||
| 315 | overlay->last_flip_req = request->seqno; | ||
| 316 | return 0; | ||
| 317 | } | 290 | } |
| 318 | 291 | ||
| 319 | static void intel_overlay_release_old_vid_tail(struct intel_overlay *overlay) | 292 | static void intel_overlay_release_old_vid_tail(struct intel_overlay *overlay) |
| @@ -349,15 +322,10 @@ static int intel_overlay_off(struct intel_overlay *overlay) | |||
| 349 | struct drm_i915_private *dev_priv = dev->dev_private; | 322 | struct drm_i915_private *dev_priv = dev->dev_private; |
| 350 | struct intel_ring_buffer *ring = &dev_priv->ring[RCS]; | 323 | struct intel_ring_buffer *ring = &dev_priv->ring[RCS]; |
| 351 | u32 flip_addr = overlay->flip_addr; | 324 | u32 flip_addr = overlay->flip_addr; |
| 352 | struct drm_i915_gem_request *request; | ||
| 353 | int ret; | 325 | int ret; |
| 354 | 326 | ||
| 355 | BUG_ON(!overlay->active); | 327 | BUG_ON(!overlay->active); |
| 356 | 328 | ||
| 357 | request = kzalloc(sizeof(*request), GFP_KERNEL); | ||
| 358 | if (request == NULL) | ||
| 359 | return -ENOMEM; | ||
| 360 | |||
| 361 | /* According to intel docs the overlay hw may hang (when switching | 329 | /* According to intel docs the overlay hw may hang (when switching |
| 362 | * off) without loading the filter coeffs. It is however unclear whether | 330 | * off) without loading the filter coeffs. It is however unclear whether |
| 363 | * this applies to the disabling of the overlay or to the switching off | 331 | * this applies to the disabling of the overlay or to the switching off |
| @@ -365,22 +333,28 @@ static int intel_overlay_off(struct intel_overlay *overlay) | |||
| 365 | flip_addr |= OFC_UPDATE; | 333 | flip_addr |= OFC_UPDATE; |
| 366 | 334 | ||
| 367 | ret = intel_ring_begin(ring, 6); | 335 | ret = intel_ring_begin(ring, 6); |
| 368 | if (ret) { | 336 | if (ret) |
| 369 | kfree(request); | ||
| 370 | return ret; | 337 | return ret; |
| 371 | } | 338 | |
| 372 | /* wait for overlay to go idle */ | 339 | /* wait for overlay to go idle */ |
| 373 | intel_ring_emit(ring, MI_OVERLAY_FLIP | MI_OVERLAY_CONTINUE); | 340 | intel_ring_emit(ring, MI_OVERLAY_FLIP | MI_OVERLAY_CONTINUE); |
| 374 | intel_ring_emit(ring, flip_addr); | 341 | intel_ring_emit(ring, flip_addr); |
| 375 | intel_ring_emit(ring, MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP); | 342 | intel_ring_emit(ring, MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP); |
| 376 | /* turn overlay off */ | 343 | /* turn overlay off */ |
| 377 | intel_ring_emit(ring, MI_OVERLAY_FLIP | MI_OVERLAY_OFF); | 344 | if (IS_I830(dev)) { |
| 378 | intel_ring_emit(ring, flip_addr); | 345 | /* Workaround: Don't disable the overlay fully, since otherwise |
| 379 | intel_ring_emit(ring, MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP); | 346 | * it dies on the next OVERLAY_ON cmd. */ |
| 347 | intel_ring_emit(ring, MI_NOOP); | ||
| 348 | intel_ring_emit(ring, MI_NOOP); | ||
| 349 | intel_ring_emit(ring, MI_NOOP); | ||
| 350 | } else { | ||
| 351 | intel_ring_emit(ring, MI_OVERLAY_FLIP | MI_OVERLAY_OFF); | ||
| 352 | intel_ring_emit(ring, flip_addr); | ||
| 353 | intel_ring_emit(ring, MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP); | ||
| 354 | } | ||
| 380 | intel_ring_advance(ring); | 355 | intel_ring_advance(ring); |
| 381 | 356 | ||
| 382 | return intel_overlay_do_wait_request(overlay, request, | 357 | return intel_overlay_do_wait_request(overlay, intel_overlay_off_tail); |
| 383 | intel_overlay_off_tail); | ||
| 384 | } | 358 | } |
| 385 | 359 | ||
| 386 | /* recover from an interruption due to a signal | 360 | /* recover from an interruption due to a signal |
| @@ -425,24 +399,16 @@ static int intel_overlay_release_old_vid(struct intel_overlay *overlay) | |||
| 425 | return 0; | 399 | return 0; |
| 426 | 400 | ||
| 427 | if (I915_READ(ISR) & I915_OVERLAY_PLANE_FLIP_PENDING_INTERRUPT) { | 401 | if (I915_READ(ISR) & I915_OVERLAY_PLANE_FLIP_PENDING_INTERRUPT) { |
| 428 | struct drm_i915_gem_request *request; | ||
| 429 | |||
| 430 | /* synchronous slowpath */ | 402 | /* synchronous slowpath */ |
| 431 | request = kzalloc(sizeof(*request), GFP_KERNEL); | ||
| 432 | if (request == NULL) | ||
| 433 | return -ENOMEM; | ||
| 434 | |||
| 435 | ret = intel_ring_begin(ring, 2); | 403 | ret = intel_ring_begin(ring, 2); |
| 436 | if (ret) { | 404 | if (ret) |
| 437 | kfree(request); | ||
| 438 | return ret; | 405 | return ret; |
| 439 | } | ||
| 440 | 406 | ||
| 441 | intel_ring_emit(ring, MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP); | 407 | intel_ring_emit(ring, MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP); |
| 442 | intel_ring_emit(ring, MI_NOOP); | 408 | intel_ring_emit(ring, MI_NOOP); |
| 443 | intel_ring_advance(ring); | 409 | intel_ring_advance(ring); |
| 444 | 410 | ||
| 445 | ret = intel_overlay_do_wait_request(overlay, request, | 411 | ret = intel_overlay_do_wait_request(overlay, |
| 446 | intel_overlay_release_old_vid_tail); | 412 | intel_overlay_release_old_vid_tail); |
| 447 | if (ret) | 413 | if (ret) |
| 448 | return ret; | 414 | return ret; |
diff --git a/drivers/gpu/drm/i915/intel_panel.c b/drivers/gpu/drm/i915/intel_panel.c index e019b2369861..e2aacd329545 100644 --- a/drivers/gpu/drm/i915/intel_panel.c +++ b/drivers/gpu/drm/i915/intel_panel.c | |||
| @@ -435,7 +435,7 @@ int intel_panel_setup_backlight(struct drm_device *dev) | |||
| 435 | props.type = BACKLIGHT_RAW; | 435 | props.type = BACKLIGHT_RAW; |
| 436 | props.max_brightness = _intel_panel_get_max_backlight(dev); | 436 | props.max_brightness = _intel_panel_get_max_backlight(dev); |
| 437 | if (props.max_brightness == 0) { | 437 | if (props.max_brightness == 0) { |
| 438 | DRM_ERROR("Failed to get maximum backlight value\n"); | 438 | DRM_DEBUG_DRIVER("Failed to get maximum backlight value\n"); |
| 439 | return -ENODEV; | 439 | return -ENODEV; |
| 440 | } | 440 | } |
| 441 | dev_priv->backlight = | 441 | dev_priv->backlight = |
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index b3b4b6cea8b0..442968f8b201 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c | |||
| @@ -2373,15 +2373,9 @@ int intel_enable_rc6(const struct drm_device *dev) | |||
| 2373 | if (i915_enable_rc6 >= 0) | 2373 | if (i915_enable_rc6 >= 0) |
| 2374 | return i915_enable_rc6; | 2374 | return i915_enable_rc6; |
| 2375 | 2375 | ||
| 2376 | if (INTEL_INFO(dev)->gen == 5) { | 2376 | /* Disable RC6 on Ironlake */ |
| 2377 | #ifdef CONFIG_INTEL_IOMMU | 2377 | if (INTEL_INFO(dev)->gen == 5) |
| 2378 | /* Disable rc6 on ilk if VT-d is on. */ | 2378 | return 0; |
| 2379 | if (intel_iommu_gfx_mapped) | ||
| 2380 | return false; | ||
| 2381 | #endif | ||
| 2382 | DRM_DEBUG_DRIVER("Ironlake: only RC6 available\n"); | ||
| 2383 | return INTEL_RC6_ENABLE; | ||
| 2384 | } | ||
| 2385 | 2379 | ||
| 2386 | if (IS_HASWELL(dev)) { | 2380 | if (IS_HASWELL(dev)) { |
| 2387 | DRM_DEBUG_DRIVER("Haswell: only RC6 available\n"); | 2381 | DRM_DEBUG_DRIVER("Haswell: only RC6 available\n"); |
| @@ -3442,8 +3436,8 @@ static void gen6_init_clock_gating(struct drm_device *dev) | |||
| 3442 | GEN6_RCCUNIT_CLOCK_GATE_DISABLE); | 3436 | GEN6_RCCUNIT_CLOCK_GATE_DISABLE); |
| 3443 | 3437 | ||
| 3444 | /* Bspec says we need to always set all mask bits. */ | 3438 | /* Bspec says we need to always set all mask bits. */ |
| 3445 | I915_WRITE(_3D_CHICKEN, (0xFFFF << 16) | | 3439 | I915_WRITE(_3D_CHICKEN3, (0xFFFF << 16) | |
| 3446 | _3D_CHICKEN_SF_DISABLE_FASTCLIP_CULL); | 3440 | _3D_CHICKEN3_SF_DISABLE_FASTCLIP_CULL); |
| 3447 | 3441 | ||
| 3448 | /* | 3442 | /* |
| 3449 | * According to the spec the following bits should be | 3443 | * According to the spec the following bits should be |
diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c index 0007a4d9bf6e..a6ac0b416964 100644 --- a/drivers/gpu/drm/i915/intel_sdvo.c +++ b/drivers/gpu/drm/i915/intel_sdvo.c | |||
| @@ -139,6 +139,11 @@ struct intel_sdvo { | |||
| 139 | 139 | ||
| 140 | /* DDC bus used by this SDVO encoder */ | 140 | /* DDC bus used by this SDVO encoder */ |
| 141 | uint8_t ddc_bus; | 141 | uint8_t ddc_bus; |
| 142 | |||
| 143 | /* | ||
| 144 | * the sdvo flag gets lost in round trip: dtd->adjusted_mode->dtd | ||
| 145 | */ | ||
| 146 | uint8_t dtd_sdvo_flags; | ||
| 142 | }; | 147 | }; |
| 143 | 148 | ||
| 144 | struct intel_sdvo_connector { | 149 | struct intel_sdvo_connector { |
| @@ -889,6 +894,45 @@ static void intel_sdvo_dump_hdmi_buf(struct intel_sdvo *intel_sdvo) | |||
| 889 | } | 894 | } |
| 890 | #endif | 895 | #endif |
| 891 | 896 | ||
| 897 | static bool intel_sdvo_write_infoframe(struct intel_sdvo *intel_sdvo, | ||
| 898 | unsigned if_index, uint8_t tx_rate, | ||
| 899 | uint8_t *data, unsigned length) | ||
| 900 | { | ||
| 901 | uint8_t set_buf_index[2] = { if_index, 0 }; | ||
| 902 | uint8_t hbuf_size, tmp[8]; | ||
| 903 | int i; | ||
| 904 | |||
| 905 | if (!intel_sdvo_set_value(intel_sdvo, | ||
| 906 | SDVO_CMD_SET_HBUF_INDEX, | ||
| 907 | set_buf_index, 2)) | ||
| 908 | return false; | ||
| 909 | |||
| 910 | if (!intel_sdvo_get_value(intel_sdvo, SDVO_CMD_GET_HBUF_INFO, | ||
| 911 | &hbuf_size, 1)) | ||
| 912 | return false; | ||
| 913 | |||
| 914 | /* Buffer size is 0 based, hooray! */ | ||
| 915 | hbuf_size++; | ||
| 916 | |||
| 917 | DRM_DEBUG_KMS("writing sdvo hbuf: %i, hbuf_size %i, hbuf_size: %i\n", | ||
| 918 | if_index, length, hbuf_size); | ||
| 919 | |||
| 920 | for (i = 0; i < hbuf_size; i += 8) { | ||
| 921 | memset(tmp, 0, 8); | ||
| 922 | if (i < length) | ||
| 923 | memcpy(tmp, data + i, min_t(unsigned, 8, length - i)); | ||
| 924 | |||
| 925 | if (!intel_sdvo_set_value(intel_sdvo, | ||
| 926 | SDVO_CMD_SET_HBUF_DATA, | ||
| 927 | tmp, 8)) | ||
| 928 | return false; | ||
| 929 | } | ||
| 930 | |||
| 931 | return intel_sdvo_set_value(intel_sdvo, | ||
| 932 | SDVO_CMD_SET_HBUF_TXRATE, | ||
| 933 | &tx_rate, 1); | ||
| 934 | } | ||
| 935 | |||
| 892 | static bool intel_sdvo_set_avi_infoframe(struct intel_sdvo *intel_sdvo) | 936 | static bool intel_sdvo_set_avi_infoframe(struct intel_sdvo *intel_sdvo) |
| 893 | { | 937 | { |
| 894 | struct dip_infoframe avi_if = { | 938 | struct dip_infoframe avi_if = { |
| @@ -896,11 +940,7 @@ static bool intel_sdvo_set_avi_infoframe(struct intel_sdvo *intel_sdvo) | |||
| 896 | .ver = DIP_VERSION_AVI, | 940 | .ver = DIP_VERSION_AVI, |
| 897 | .len = DIP_LEN_AVI, | 941 | .len = DIP_LEN_AVI, |
| 898 | }; | 942 | }; |
| 899 | uint8_t tx_rate = SDVO_HBUF_TX_VSYNC; | ||
| 900 | uint8_t set_buf_index[2] = { 1, 0 }; | ||
| 901 | uint8_t sdvo_data[4 + sizeof(avi_if.body.avi)]; | 943 | uint8_t sdvo_data[4 + sizeof(avi_if.body.avi)]; |
| 902 | uint64_t *data = (uint64_t *)sdvo_data; | ||
| 903 | unsigned i; | ||
| 904 | 944 | ||
| 905 | intel_dip_infoframe_csum(&avi_if); | 945 | intel_dip_infoframe_csum(&avi_if); |
| 906 | 946 | ||
| @@ -910,22 +950,9 @@ static bool intel_sdvo_set_avi_infoframe(struct intel_sdvo *intel_sdvo) | |||
| 910 | sdvo_data[3] = avi_if.checksum; | 950 | sdvo_data[3] = avi_if.checksum; |
| 911 | memcpy(&sdvo_data[4], &avi_if.body, sizeof(avi_if.body.avi)); | 951 | memcpy(&sdvo_data[4], &avi_if.body, sizeof(avi_if.body.avi)); |
| 912 | 952 | ||
| 913 | if (!intel_sdvo_set_value(intel_sdvo, | 953 | return intel_sdvo_write_infoframe(intel_sdvo, SDVO_HBUF_INDEX_AVI_IF, |
| 914 | SDVO_CMD_SET_HBUF_INDEX, | 954 | SDVO_HBUF_TX_VSYNC, |
| 915 | set_buf_index, 2)) | 955 | sdvo_data, sizeof(sdvo_data)); |
| 916 | return false; | ||
| 917 | |||
| 918 | for (i = 0; i < sizeof(sdvo_data); i += 8) { | ||
| 919 | if (!intel_sdvo_set_value(intel_sdvo, | ||
| 920 | SDVO_CMD_SET_HBUF_DATA, | ||
| 921 | data, 8)) | ||
| 922 | return false; | ||
| 923 | data++; | ||
| 924 | } | ||
| 925 | |||
| 926 | return intel_sdvo_set_value(intel_sdvo, | ||
| 927 | SDVO_CMD_SET_HBUF_TXRATE, | ||
| 928 | &tx_rate, 1); | ||
| 929 | } | 956 | } |
| 930 | 957 | ||
| 931 | static bool intel_sdvo_set_tv_format(struct intel_sdvo *intel_sdvo) | 958 | static bool intel_sdvo_set_tv_format(struct intel_sdvo *intel_sdvo) |
| @@ -984,6 +1011,7 @@ intel_sdvo_get_preferred_input_mode(struct intel_sdvo *intel_sdvo, | |||
| 984 | return false; | 1011 | return false; |
| 985 | 1012 | ||
| 986 | intel_sdvo_get_mode_from_dtd(adjusted_mode, &input_dtd); | 1013 | intel_sdvo_get_mode_from_dtd(adjusted_mode, &input_dtd); |
| 1014 | intel_sdvo->dtd_sdvo_flags = input_dtd.part2.sdvo_flags; | ||
| 987 | 1015 | ||
| 988 | return true; | 1016 | return true; |
| 989 | } | 1017 | } |
| @@ -1092,6 +1120,8 @@ static void intel_sdvo_mode_set(struct drm_encoder *encoder, | |||
| 1092 | * adjusted_mode. | 1120 | * adjusted_mode. |
| 1093 | */ | 1121 | */ |
| 1094 | intel_sdvo_get_dtd_from_mode(&input_dtd, adjusted_mode); | 1122 | intel_sdvo_get_dtd_from_mode(&input_dtd, adjusted_mode); |
| 1123 | if (intel_sdvo->is_tv || intel_sdvo->is_lvds) | ||
| 1124 | input_dtd.part2.sdvo_flags = intel_sdvo->dtd_sdvo_flags; | ||
| 1095 | if (!intel_sdvo_set_input_timing(intel_sdvo, &input_dtd)) | 1125 | if (!intel_sdvo_set_input_timing(intel_sdvo, &input_dtd)) |
| 1096 | DRM_INFO("Setting input timings on %s failed\n", | 1126 | DRM_INFO("Setting input timings on %s failed\n", |
| 1097 | SDVO_NAME(intel_sdvo)); | 1127 | SDVO_NAME(intel_sdvo)); |
| @@ -2171,7 +2201,6 @@ intel_sdvo_dvi_init(struct intel_sdvo *intel_sdvo, int device) | |||
| 2171 | connector->connector_type = DRM_MODE_CONNECTOR_HDMIA; | 2201 | connector->connector_type = DRM_MODE_CONNECTOR_HDMIA; |
| 2172 | intel_sdvo->is_hdmi = true; | 2202 | intel_sdvo->is_hdmi = true; |
| 2173 | } | 2203 | } |
| 2174 | intel_sdvo->base.cloneable = true; | ||
| 2175 | 2204 | ||
| 2176 | intel_sdvo_connector_init(intel_sdvo_connector, intel_sdvo); | 2205 | intel_sdvo_connector_init(intel_sdvo_connector, intel_sdvo); |
| 2177 | if (intel_sdvo->is_hdmi) | 2206 | if (intel_sdvo->is_hdmi) |
| @@ -2202,7 +2231,6 @@ intel_sdvo_tv_init(struct intel_sdvo *intel_sdvo, int type) | |||
| 2202 | 2231 | ||
| 2203 | intel_sdvo->is_tv = true; | 2232 | intel_sdvo->is_tv = true; |
| 2204 | intel_sdvo->base.needs_tv_clock = true; | 2233 | intel_sdvo->base.needs_tv_clock = true; |
| 2205 | intel_sdvo->base.cloneable = false; | ||
| 2206 | 2234 | ||
| 2207 | intel_sdvo_connector_init(intel_sdvo_connector, intel_sdvo); | 2235 | intel_sdvo_connector_init(intel_sdvo_connector, intel_sdvo); |
| 2208 | 2236 | ||
| @@ -2245,8 +2273,6 @@ intel_sdvo_analog_init(struct intel_sdvo *intel_sdvo, int device) | |||
| 2245 | intel_sdvo_connector->output_flag = SDVO_OUTPUT_RGB1; | 2273 | intel_sdvo_connector->output_flag = SDVO_OUTPUT_RGB1; |
| 2246 | } | 2274 | } |
| 2247 | 2275 | ||
| 2248 | intel_sdvo->base.cloneable = true; | ||
| 2249 | |||
| 2250 | intel_sdvo_connector_init(intel_sdvo_connector, | 2276 | intel_sdvo_connector_init(intel_sdvo_connector, |
| 2251 | intel_sdvo); | 2277 | intel_sdvo); |
| 2252 | return true; | 2278 | return true; |
| @@ -2277,11 +2303,6 @@ intel_sdvo_lvds_init(struct intel_sdvo *intel_sdvo, int device) | |||
| 2277 | intel_sdvo_connector->output_flag = SDVO_OUTPUT_LVDS1; | 2303 | intel_sdvo_connector->output_flag = SDVO_OUTPUT_LVDS1; |
| 2278 | } | 2304 | } |
| 2279 | 2305 | ||
| 2280 | /* SDVO LVDS is cloneable because the SDVO encoder does the upscaling, | ||
| 2281 | * as opposed to native LVDS, where we upscale with the panel-fitter | ||
| 2282 | * (and hence only the native LVDS resolution could be cloned). */ | ||
| 2283 | intel_sdvo->base.cloneable = true; | ||
| 2284 | |||
| 2285 | intel_sdvo_connector_init(intel_sdvo_connector, intel_sdvo); | 2306 | intel_sdvo_connector_init(intel_sdvo_connector, intel_sdvo); |
| 2286 | if (!intel_sdvo_create_enhance_property(intel_sdvo, intel_sdvo_connector)) | 2307 | if (!intel_sdvo_create_enhance_property(intel_sdvo, intel_sdvo_connector)) |
| 2287 | goto err; | 2308 | goto err; |
| @@ -2354,6 +2375,18 @@ intel_sdvo_output_setup(struct intel_sdvo *intel_sdvo, uint16_t flags) | |||
| 2354 | return true; | 2375 | return true; |
| 2355 | } | 2376 | } |
| 2356 | 2377 | ||
| 2378 | static void intel_sdvo_output_cleanup(struct intel_sdvo *intel_sdvo) | ||
| 2379 | { | ||
| 2380 | struct drm_device *dev = intel_sdvo->base.base.dev; | ||
| 2381 | struct drm_connector *connector, *tmp; | ||
| 2382 | |||
| 2383 | list_for_each_entry_safe(connector, tmp, | ||
| 2384 | &dev->mode_config.connector_list, head) { | ||
| 2385 | if (intel_attached_encoder(connector) == &intel_sdvo->base) | ||
| 2386 | intel_sdvo_destroy(connector); | ||
| 2387 | } | ||
| 2388 | } | ||
| 2389 | |||
| 2357 | static bool intel_sdvo_tv_create_property(struct intel_sdvo *intel_sdvo, | 2390 | static bool intel_sdvo_tv_create_property(struct intel_sdvo *intel_sdvo, |
| 2358 | struct intel_sdvo_connector *intel_sdvo_connector, | 2391 | struct intel_sdvo_connector *intel_sdvo_connector, |
| 2359 | int type) | 2392 | int type) |
| @@ -2677,9 +2710,20 @@ bool intel_sdvo_init(struct drm_device *dev, uint32_t sdvo_reg, bool is_sdvob) | |||
| 2677 | intel_sdvo->caps.output_flags) != true) { | 2710 | intel_sdvo->caps.output_flags) != true) { |
| 2678 | DRM_DEBUG_KMS("SDVO output failed to setup on %s\n", | 2711 | DRM_DEBUG_KMS("SDVO output failed to setup on %s\n", |
| 2679 | SDVO_NAME(intel_sdvo)); | 2712 | SDVO_NAME(intel_sdvo)); |
| 2680 | goto err; | 2713 | /* Output_setup can leave behind connectors! */ |
| 2714 | goto err_output; | ||
| 2681 | } | 2715 | } |
| 2682 | 2716 | ||
| 2717 | /* | ||
| 2718 | * Cloning SDVO with anything is often impossible, since the SDVO | ||
| 2719 | * encoder can request a special input timing mode. And even if that's | ||
| 2720 | * not the case we have evidence that cloning a plain unscaled mode with | ||
| 2721 | * VGA doesn't really work. Furthermore the cloning flags are way too | ||
| 2722 | * simplistic anyway to express such constraints, so just give up on | ||
| 2723 | * cloning for SDVO encoders. | ||
| 2724 | */ | ||
| 2725 | intel_sdvo->base.cloneable = false; | ||
| 2726 | |||
| 2683 | /* Only enable the hotplug irq if we need it, to work around noisy | 2727 | /* Only enable the hotplug irq if we need it, to work around noisy |
| 2684 | * hotplug lines. | 2728 | * hotplug lines. |
| 2685 | */ | 2729 | */ |
| @@ -2690,12 +2734,12 @@ bool intel_sdvo_init(struct drm_device *dev, uint32_t sdvo_reg, bool is_sdvob) | |||
| 2690 | 2734 | ||
| 2691 | /* Set the input timing to the screen. Assume always input 0. */ | 2735 | /* Set the input timing to the screen. Assume always input 0. */ |
| 2692 | if (!intel_sdvo_set_target_input(intel_sdvo)) | 2736 | if (!intel_sdvo_set_target_input(intel_sdvo)) |
| 2693 | goto err; | 2737 | goto err_output; |
| 2694 | 2738 | ||
| 2695 | if (!intel_sdvo_get_input_pixel_clock_range(intel_sdvo, | 2739 | if (!intel_sdvo_get_input_pixel_clock_range(intel_sdvo, |
| 2696 | &intel_sdvo->pixel_clock_min, | 2740 | &intel_sdvo->pixel_clock_min, |
| 2697 | &intel_sdvo->pixel_clock_max)) | 2741 | &intel_sdvo->pixel_clock_max)) |
| 2698 | goto err; | 2742 | goto err_output; |
| 2699 | 2743 | ||
| 2700 | DRM_DEBUG_KMS("%s device VID/DID: %02X:%02X.%02X, " | 2744 | DRM_DEBUG_KMS("%s device VID/DID: %02X:%02X.%02X, " |
| 2701 | "clock range %dMHz - %dMHz, " | 2745 | "clock range %dMHz - %dMHz, " |
| @@ -2715,6 +2759,9 @@ bool intel_sdvo_init(struct drm_device *dev, uint32_t sdvo_reg, bool is_sdvob) | |||
| 2715 | (SDVO_OUTPUT_TMDS1 | SDVO_OUTPUT_RGB1) ? 'Y' : 'N'); | 2759 | (SDVO_OUTPUT_TMDS1 | SDVO_OUTPUT_RGB1) ? 'Y' : 'N'); |
| 2716 | return true; | 2760 | return true; |
| 2717 | 2761 | ||
| 2762 | err_output: | ||
| 2763 | intel_sdvo_output_cleanup(intel_sdvo); | ||
| 2764 | |||
| 2718 | err: | 2765 | err: |
| 2719 | drm_encoder_cleanup(&intel_encoder->base); | 2766 | drm_encoder_cleanup(&intel_encoder->base); |
| 2720 | i2c_del_adapter(&intel_sdvo->ddc); | 2767 | i2c_del_adapter(&intel_sdvo->ddc); |
diff --git a/drivers/gpu/drm/i915/intel_sdvo_regs.h b/drivers/gpu/drm/i915/intel_sdvo_regs.h index 9d030142ee43..770bdd6ecd9f 100644 --- a/drivers/gpu/drm/i915/intel_sdvo_regs.h +++ b/drivers/gpu/drm/i915/intel_sdvo_regs.h | |||
| @@ -708,6 +708,8 @@ struct intel_sdvo_enhancements_arg { | |||
| 708 | #define SDVO_CMD_SET_AUDIO_STAT 0x91 | 708 | #define SDVO_CMD_SET_AUDIO_STAT 0x91 |
| 709 | #define SDVO_CMD_GET_AUDIO_STAT 0x92 | 709 | #define SDVO_CMD_GET_AUDIO_STAT 0x92 |
| 710 | #define SDVO_CMD_SET_HBUF_INDEX 0x93 | 710 | #define SDVO_CMD_SET_HBUF_INDEX 0x93 |
| 711 | #define SDVO_HBUF_INDEX_ELD 0 | ||
| 712 | #define SDVO_HBUF_INDEX_AVI_IF 1 | ||
| 711 | #define SDVO_CMD_GET_HBUF_INDEX 0x94 | 713 | #define SDVO_CMD_GET_HBUF_INDEX 0x94 |
| 712 | #define SDVO_CMD_GET_HBUF_INFO 0x95 | 714 | #define SDVO_CMD_GET_HBUF_INFO 0x95 |
| 713 | #define SDVO_CMD_SET_HBUF_AV_SPLIT 0x96 | 715 | #define SDVO_CMD_SET_HBUF_AV_SPLIT 0x96 |
diff --git a/drivers/gpu/drm/nouveau/core/core/gpuobj.c b/drivers/gpu/drm/nouveau/core/core/gpuobj.c index 1f34549aff18..70586fde69cf 100644 --- a/drivers/gpu/drm/nouveau/core/core/gpuobj.c +++ b/drivers/gpu/drm/nouveau/core/core/gpuobj.c | |||
| @@ -39,6 +39,11 @@ nouveau_gpuobj_destroy(struct nouveau_gpuobj *gpuobj) | |||
| 39 | nv_wo32(gpuobj, i, 0x00000000); | 39 | nv_wo32(gpuobj, i, 0x00000000); |
| 40 | } | 40 | } |
| 41 | 41 | ||
| 42 | if (gpuobj->node) { | ||
| 43 | nouveau_mm_free(&nv_gpuobj(gpuobj->parent)->heap, | ||
| 44 | &gpuobj->node); | ||
| 45 | } | ||
| 46 | |||
| 42 | if (gpuobj->heap.block_size) | 47 | if (gpuobj->heap.block_size) |
| 43 | nouveau_mm_fini(&gpuobj->heap); | 48 | nouveau_mm_fini(&gpuobj->heap); |
| 44 | 49 | ||
diff --git a/drivers/gpu/drm/nouveau/core/core/mm.c b/drivers/gpu/drm/nouveau/core/core/mm.c index bfddf87926dd..a6d3cd6490f7 100644 --- a/drivers/gpu/drm/nouveau/core/core/mm.c +++ b/drivers/gpu/drm/nouveau/core/core/mm.c | |||
| @@ -218,13 +218,16 @@ nouveau_mm_init(struct nouveau_mm *mm, u32 offset, u32 length, u32 block) | |||
| 218 | node = kzalloc(sizeof(*node), GFP_KERNEL); | 218 | node = kzalloc(sizeof(*node), GFP_KERNEL); |
| 219 | if (!node) | 219 | if (!node) |
| 220 | return -ENOMEM; | 220 | return -ENOMEM; |
| 221 | node->offset = roundup(offset, mm->block_size); | 221 | |
| 222 | node->length = rounddown(offset + length, mm->block_size) - node->offset; | 222 | if (length) { |
| 223 | node->offset = roundup(offset, mm->block_size); | ||
| 224 | node->length = rounddown(offset + length, mm->block_size); | ||
| 225 | node->length -= node->offset; | ||
| 226 | } | ||
| 223 | 227 | ||
| 224 | list_add_tail(&node->nl_entry, &mm->nodes); | 228 | list_add_tail(&node->nl_entry, &mm->nodes); |
| 225 | list_add_tail(&node->fl_entry, &mm->free); | 229 | list_add_tail(&node->fl_entry, &mm->free); |
| 226 | mm->heap_nodes++; | 230 | mm->heap_nodes++; |
| 227 | mm->heap_size += length; | ||
| 228 | return 0; | 231 | return 0; |
| 229 | } | 232 | } |
| 230 | 233 | ||
| @@ -236,7 +239,7 @@ nouveau_mm_fini(struct nouveau_mm *mm) | |||
| 236 | int nodes = 0; | 239 | int nodes = 0; |
| 237 | 240 | ||
| 238 | list_for_each_entry(node, &mm->nodes, nl_entry) { | 241 | list_for_each_entry(node, &mm->nodes, nl_entry) { |
| 239 | if (nodes++ == mm->heap_nodes) | 242 | if (WARN_ON(nodes++ == mm->heap_nodes)) |
| 240 | return -EBUSY; | 243 | return -EBUSY; |
| 241 | } | 244 | } |
| 242 | 245 | ||
diff --git a/drivers/gpu/drm/nouveau/core/engine/disp/nv50.c b/drivers/gpu/drm/nouveau/core/engine/disp/nv50.c index 16a9afb1060b..15b182c84ce8 100644 --- a/drivers/gpu/drm/nouveau/core/engine/disp/nv50.c +++ b/drivers/gpu/drm/nouveau/core/engine/disp/nv50.c | |||
| @@ -22,6 +22,8 @@ | |||
| 22 | * Authors: Ben Skeggs | 22 | * Authors: Ben Skeggs |
| 23 | */ | 23 | */ |
| 24 | 24 | ||
| 25 | #include <subdev/bar.h> | ||
| 26 | |||
| 25 | #include <engine/software.h> | 27 | #include <engine/software.h> |
| 26 | #include <engine/disp.h> | 28 | #include <engine/disp.h> |
| 27 | 29 | ||
| @@ -37,6 +39,7 @@ nv50_disp_sclass[] = { | |||
| 37 | static void | 39 | static void |
| 38 | nv50_disp_intr_vblank(struct nv50_disp_priv *priv, int crtc) | 40 | nv50_disp_intr_vblank(struct nv50_disp_priv *priv, int crtc) |
| 39 | { | 41 | { |
| 42 | struct nouveau_bar *bar = nouveau_bar(priv); | ||
| 40 | struct nouveau_disp *disp = &priv->base; | 43 | struct nouveau_disp *disp = &priv->base; |
| 41 | struct nouveau_software_chan *chan, *temp; | 44 | struct nouveau_software_chan *chan, *temp; |
| 42 | unsigned long flags; | 45 | unsigned long flags; |
| @@ -46,19 +49,25 @@ nv50_disp_intr_vblank(struct nv50_disp_priv *priv, int crtc) | |||
| 46 | if (chan->vblank.crtc != crtc) | 49 | if (chan->vblank.crtc != crtc) |
| 47 | continue; | 50 | continue; |
| 48 | 51 | ||
| 49 | nv_wr32(priv, 0x001704, chan->vblank.channel); | 52 | if (nv_device(priv)->chipset >= 0xc0) { |
| 50 | nv_wr32(priv, 0x001710, 0x80000000 | chan->vblank.ctxdma); | 53 | nv_wr32(priv, 0x001718, 0x80000000 | chan->vblank.channel); |
| 51 | 54 | bar->flush(bar); | |
| 52 | if (nv_device(priv)->chipset == 0x50) { | 55 | nv_wr32(priv, 0x06000c, |
| 53 | nv_wr32(priv, 0x001570, chan->vblank.offset); | 56 | upper_32_bits(chan->vblank.offset)); |
| 54 | nv_wr32(priv, 0x001574, chan->vblank.value); | 57 | nv_wr32(priv, 0x060010, |
| 58 | lower_32_bits(chan->vblank.offset)); | ||
| 59 | nv_wr32(priv, 0x060014, chan->vblank.value); | ||
| 55 | } else { | 60 | } else { |
| 56 | if (nv_device(priv)->chipset >= 0xc0) { | 61 | nv_wr32(priv, 0x001704, chan->vblank.channel); |
| 57 | nv_wr32(priv, 0x06000c, | 62 | nv_wr32(priv, 0x001710, 0x80000000 | chan->vblank.ctxdma); |
| 58 | upper_32_bits(chan->vblank.offset)); | 63 | bar->flush(bar); |
| 64 | if (nv_device(priv)->chipset == 0x50) { | ||
| 65 | nv_wr32(priv, 0x001570, chan->vblank.offset); | ||
| 66 | nv_wr32(priv, 0x001574, chan->vblank.value); | ||
| 67 | } else { | ||
| 68 | nv_wr32(priv, 0x060010, chan->vblank.offset); | ||
| 69 | nv_wr32(priv, 0x060014, chan->vblank.value); | ||
| 59 | } | 70 | } |
| 60 | nv_wr32(priv, 0x060010, chan->vblank.offset); | ||
| 61 | nv_wr32(priv, 0x060014, chan->vblank.value); | ||
| 62 | } | 71 | } |
| 63 | 72 | ||
| 64 | list_del(&chan->vblank.head); | 73 | list_del(&chan->vblank.head); |
diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/ctxnv40.c b/drivers/gpu/drm/nouveau/core/engine/graph/ctxnv40.c index e45035efb8ca..7bbb1e1b7a8d 100644 --- a/drivers/gpu/drm/nouveau/core/engine/graph/ctxnv40.c +++ b/drivers/gpu/drm/nouveau/core/engine/graph/ctxnv40.c | |||
| @@ -669,21 +669,27 @@ nv40_grctx_fill(struct nouveau_device *device, struct nouveau_gpuobj *mem) | |||
| 669 | }); | 669 | }); |
| 670 | } | 670 | } |
| 671 | 671 | ||
| 672 | void | 672 | int |
| 673 | nv40_grctx_init(struct nouveau_device *device, u32 *size) | 673 | nv40_grctx_init(struct nouveau_device *device, u32 *size) |
| 674 | { | 674 | { |
| 675 | u32 ctxprog[256], i; | 675 | u32 *ctxprog = kmalloc(256 * 4, GFP_KERNEL), i; |
| 676 | struct nouveau_grctx ctx = { | 676 | struct nouveau_grctx ctx = { |
| 677 | .device = device, | 677 | .device = device, |
| 678 | .mode = NOUVEAU_GRCTX_PROG, | 678 | .mode = NOUVEAU_GRCTX_PROG, |
| 679 | .data = ctxprog, | 679 | .data = ctxprog, |
| 680 | .ctxprog_max = ARRAY_SIZE(ctxprog) | 680 | .ctxprog_max = 256, |
| 681 | }; | 681 | }; |
| 682 | 682 | ||
| 683 | if (!ctxprog) | ||
| 684 | return -ENOMEM; | ||
| 685 | |||
| 683 | nv40_grctx_generate(&ctx); | 686 | nv40_grctx_generate(&ctx); |
| 684 | 687 | ||
| 685 | nv_wr32(device, 0x400324, 0); | 688 | nv_wr32(device, 0x400324, 0); |
| 686 | for (i = 0; i < ctx.ctxprog_len; i++) | 689 | for (i = 0; i < ctx.ctxprog_len; i++) |
| 687 | nv_wr32(device, 0x400328, ctxprog[i]); | 690 | nv_wr32(device, 0x400328, ctxprog[i]); |
| 688 | *size = ctx.ctxvals_pos * 4; | 691 | *size = ctx.ctxvals_pos * 4; |
| 692 | |||
| 693 | kfree(ctxprog); | ||
| 694 | return 0; | ||
| 689 | } | 695 | } |
diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/nv40.c b/drivers/gpu/drm/nouveau/core/engine/graph/nv40.c index 8d0021049ec0..cc6574eeb80e 100644 --- a/drivers/gpu/drm/nouveau/core/engine/graph/nv40.c +++ b/drivers/gpu/drm/nouveau/core/engine/graph/nv40.c | |||
| @@ -156,8 +156,8 @@ nv40_graph_context_ctor(struct nouveau_object *parent, | |||
| 156 | static int | 156 | static int |
| 157 | nv40_graph_context_fini(struct nouveau_object *object, bool suspend) | 157 | nv40_graph_context_fini(struct nouveau_object *object, bool suspend) |
| 158 | { | 158 | { |
| 159 | struct nv04_graph_priv *priv = (void *)object->engine; | 159 | struct nv40_graph_priv *priv = (void *)object->engine; |
| 160 | struct nv04_graph_chan *chan = (void *)object; | 160 | struct nv40_graph_chan *chan = (void *)object; |
| 161 | u32 inst = 0x01000000 | nv_gpuobj(chan)->addr >> 4; | 161 | u32 inst = 0x01000000 | nv_gpuobj(chan)->addr >> 4; |
| 162 | int ret = 0; | 162 | int ret = 0; |
| 163 | 163 | ||
| @@ -346,7 +346,9 @@ nv40_graph_init(struct nouveau_object *object) | |||
| 346 | return ret; | 346 | return ret; |
| 347 | 347 | ||
| 348 | /* generate and upload context program */ | 348 | /* generate and upload context program */ |
| 349 | nv40_grctx_init(nv_device(priv), &priv->size); | 349 | ret = nv40_grctx_init(nv_device(priv), &priv->size); |
| 350 | if (ret) | ||
| 351 | return ret; | ||
| 350 | 352 | ||
| 351 | /* No context present currently */ | 353 | /* No context present currently */ |
| 352 | nv_wr32(priv, NV40_PGRAPH_CTXCTL_CUR, 0x00000000); | 354 | nv_wr32(priv, NV40_PGRAPH_CTXCTL_CUR, 0x00000000); |
diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/nv40.h b/drivers/gpu/drm/nouveau/core/engine/graph/nv40.h index d2ac975afc2e..7da35a4e7970 100644 --- a/drivers/gpu/drm/nouveau/core/engine/graph/nv40.h +++ b/drivers/gpu/drm/nouveau/core/engine/graph/nv40.h | |||
| @@ -15,7 +15,7 @@ nv44_graph_class(void *priv) | |||
| 15 | return !(0x0baf & (1 << (device->chipset & 0x0f))); | 15 | return !(0x0baf & (1 << (device->chipset & 0x0f))); |
| 16 | } | 16 | } |
| 17 | 17 | ||
| 18 | void nv40_grctx_init(struct nouveau_device *, u32 *size); | 18 | int nv40_grctx_init(struct nouveau_device *, u32 *size); |
| 19 | void nv40_grctx_fill(struct nouveau_device *, struct nouveau_gpuobj *); | 19 | void nv40_grctx_fill(struct nouveau_device *, struct nouveau_gpuobj *); |
| 20 | 20 | ||
| 21 | #endif | 21 | #endif |
diff --git a/drivers/gpu/drm/nouveau/core/engine/mpeg/nv40.c b/drivers/gpu/drm/nouveau/core/engine/mpeg/nv40.c index 12418574efea..f7c581ad1991 100644 --- a/drivers/gpu/drm/nouveau/core/engine/mpeg/nv40.c +++ b/drivers/gpu/drm/nouveau/core/engine/mpeg/nv40.c | |||
| @@ -38,7 +38,7 @@ struct nv40_mpeg_priv { | |||
| 38 | }; | 38 | }; |
| 39 | 39 | ||
| 40 | struct nv40_mpeg_chan { | 40 | struct nv40_mpeg_chan { |
| 41 | struct nouveau_mpeg base; | 41 | struct nouveau_mpeg_chan base; |
| 42 | }; | 42 | }; |
| 43 | 43 | ||
| 44 | /******************************************************************************* | 44 | /******************************************************************************* |
diff --git a/drivers/gpu/drm/nouveau/core/include/core/mm.h b/drivers/gpu/drm/nouveau/core/include/core/mm.h index 9ee9bf4028ca..975137ba34a6 100644 --- a/drivers/gpu/drm/nouveau/core/include/core/mm.h +++ b/drivers/gpu/drm/nouveau/core/include/core/mm.h | |||
| @@ -19,7 +19,6 @@ struct nouveau_mm { | |||
| 19 | 19 | ||
| 20 | u32 block_size; | 20 | u32 block_size; |
| 21 | int heap_nodes; | 21 | int heap_nodes; |
| 22 | u32 heap_size; | ||
| 23 | }; | 22 | }; |
| 24 | 23 | ||
| 25 | int nouveau_mm_init(struct nouveau_mm *, u32 offset, u32 length, u32 block); | 24 | int nouveau_mm_init(struct nouveau_mm *, u32 offset, u32 length, u32 block); |
diff --git a/drivers/gpu/drm/nouveau/core/include/core/object.h b/drivers/gpu/drm/nouveau/core/include/core/object.h index 818feabbf4a0..486f1a9217fd 100644 --- a/drivers/gpu/drm/nouveau/core/include/core/object.h +++ b/drivers/gpu/drm/nouveau/core/include/core/object.h | |||
| @@ -175,14 +175,18 @@ nv_mo32(void *obj, u32 addr, u32 mask, u32 data) | |||
| 175 | return temp; | 175 | return temp; |
| 176 | } | 176 | } |
| 177 | 177 | ||
| 178 | static inline bool | 178 | static inline int |
| 179 | nv_strncmp(void *obj, u32 addr, u32 len, const char *str) | 179 | nv_memcmp(void *obj, u32 addr, const char *str, u32 len) |
| 180 | { | 180 | { |
| 181 | unsigned char c1, c2; | ||
| 182 | |||
| 181 | while (len--) { | 183 | while (len--) { |
| 182 | if (nv_ro08(obj, addr++) != *(str++)) | 184 | c1 = nv_ro08(obj, addr++); |
| 183 | return false; | 185 | c2 = *(str++); |
| 186 | if (c1 != c2) | ||
| 187 | return c1 - c2; | ||
| 184 | } | 188 | } |
| 185 | return true; | 189 | return 0; |
| 186 | } | 190 | } |
| 187 | 191 | ||
| 188 | #endif | 192 | #endif |
diff --git a/drivers/gpu/drm/nouveau/core/include/subdev/clock.h b/drivers/gpu/drm/nouveau/core/include/subdev/clock.h index 39e73b91d360..41b7a6a76f19 100644 --- a/drivers/gpu/drm/nouveau/core/include/subdev/clock.h +++ b/drivers/gpu/drm/nouveau/core/include/subdev/clock.h | |||
| @@ -54,6 +54,7 @@ int nv04_clock_pll_calc(struct nouveau_clock *, struct nvbios_pll *, | |||
| 54 | int clk, struct nouveau_pll_vals *); | 54 | int clk, struct nouveau_pll_vals *); |
| 55 | int nv04_clock_pll_prog(struct nouveau_clock *, u32 reg1, | 55 | int nv04_clock_pll_prog(struct nouveau_clock *, u32 reg1, |
| 56 | struct nouveau_pll_vals *); | 56 | struct nouveau_pll_vals *); |
| 57 | 57 | int nva3_clock_pll_calc(struct nouveau_clock *, struct nvbios_pll *, | |
| 58 | int clk, struct nouveau_pll_vals *); | ||
| 58 | 59 | ||
| 59 | #endif | 60 | #endif |
diff --git a/drivers/gpu/drm/nouveau/core/subdev/bios/base.c b/drivers/gpu/drm/nouveau/core/subdev/bios/base.c index dcb5c2befc92..70ca7d5a1aa1 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/bios/base.c +++ b/drivers/gpu/drm/nouveau/core/subdev/bios/base.c | |||
| @@ -72,7 +72,7 @@ nouveau_bios_shadow_of(struct nouveau_bios *bios) | |||
| 72 | } | 72 | } |
| 73 | 73 | ||
| 74 | data = of_get_property(dn, "NVDA,BMP", &size); | 74 | data = of_get_property(dn, "NVDA,BMP", &size); |
| 75 | if (data) { | 75 | if (data && size) { |
| 76 | bios->size = size; | 76 | bios->size = size; |
| 77 | bios->data = kmalloc(bios->size, GFP_KERNEL); | 77 | bios->data = kmalloc(bios->size, GFP_KERNEL); |
| 78 | if (bios->data) | 78 | if (bios->data) |
| @@ -104,6 +104,9 @@ nouveau_bios_shadow_pramin(struct nouveau_bios *bios) | |||
| 104 | goto out; | 104 | goto out; |
| 105 | 105 | ||
| 106 | bios->size = nv_rd08(bios, 0x700002) * 512; | 106 | bios->size = nv_rd08(bios, 0x700002) * 512; |
| 107 | if (!bios->size) | ||
| 108 | goto out; | ||
| 109 | |||
| 107 | bios->data = kmalloc(bios->size, GFP_KERNEL); | 110 | bios->data = kmalloc(bios->size, GFP_KERNEL); |
| 108 | if (bios->data) { | 111 | if (bios->data) { |
| 109 | for (i = 0; i < bios->size; i++) | 112 | for (i = 0; i < bios->size; i++) |
| @@ -155,6 +158,9 @@ nouveau_bios_shadow_prom(struct nouveau_bios *bios) | |||
| 155 | 158 | ||
| 156 | /* read entire bios image to system memory */ | 159 | /* read entire bios image to system memory */ |
| 157 | bios->size = nv_rd08(bios, 0x300002) * 512; | 160 | bios->size = nv_rd08(bios, 0x300002) * 512; |
| 161 | if (!bios->size) | ||
| 162 | goto out; | ||
| 163 | |||
| 158 | bios->data = kmalloc(bios->size, GFP_KERNEL); | 164 | bios->data = kmalloc(bios->size, GFP_KERNEL); |
| 159 | if (bios->data) { | 165 | if (bios->data) { |
| 160 | for (i = 0; i < bios->size; i++) | 166 | for (i = 0; i < bios->size; i++) |
| @@ -186,14 +192,22 @@ nouveau_bios_shadow_acpi(struct nouveau_bios *bios) | |||
| 186 | { | 192 | { |
| 187 | struct pci_dev *pdev = nv_device(bios)->pdev; | 193 | struct pci_dev *pdev = nv_device(bios)->pdev; |
| 188 | int ret, cnt, i; | 194 | int ret, cnt, i; |
| 189 | u8 data[3]; | ||
| 190 | 195 | ||
| 191 | if (!nouveau_acpi_rom_supported(pdev)) | 196 | if (!nouveau_acpi_rom_supported(pdev)) { |
| 197 | bios->data = NULL; | ||
| 192 | return; | 198 | return; |
| 199 | } | ||
| 193 | 200 | ||
| 194 | bios->size = 0; | 201 | bios->size = 0; |
| 195 | if (nouveau_acpi_get_bios_chunk(data, 0, 3) == 3) | 202 | bios->data = kmalloc(4096, GFP_KERNEL); |
| 196 | bios->size = data[2] * 512; | 203 | if (bios->data) { |
| 204 | if (nouveau_acpi_get_bios_chunk(bios->data, 0, 4096) == 4096) | ||
| 205 | bios->size = bios->data[2] * 512; | ||
| 206 | kfree(bios->data); | ||
| 207 | } | ||
| 208 | |||
| 209 | if (!bios->size) | ||
| 210 | return; | ||
| 197 | 211 | ||
| 198 | bios->data = kmalloc(bios->size, GFP_KERNEL); | 212 | bios->data = kmalloc(bios->size, GFP_KERNEL); |
| 199 | for (i = 0; bios->data && i < bios->size; i += cnt) { | 213 | for (i = 0; bios->data && i < bios->size; i += cnt) { |
| @@ -229,12 +243,14 @@ nouveau_bios_shadow_pci(struct nouveau_bios *bios) | |||
| 229 | static int | 243 | static int |
| 230 | nouveau_bios_score(struct nouveau_bios *bios, const bool writeable) | 244 | nouveau_bios_score(struct nouveau_bios *bios, const bool writeable) |
| 231 | { | 245 | { |
| 232 | if (!bios->data || bios->data[0] != 0x55 || bios->data[1] != 0xAA) { | 246 | if (bios->size < 3 || !bios->data || bios->data[0] != 0x55 || |
| 247 | bios->data[1] != 0xAA) { | ||
| 233 | nv_info(bios, "... signature not found\n"); | 248 | nv_info(bios, "... signature not found\n"); |
| 234 | return 0; | 249 | return 0; |
| 235 | } | 250 | } |
| 236 | 251 | ||
| 237 | if (nvbios_checksum(bios->data, bios->data[2] * 512)) { | 252 | if (nvbios_checksum(bios->data, |
| 253 | min_t(u32, bios->data[2] * 512, bios->size))) { | ||
| 238 | nv_info(bios, "... checksum invalid\n"); | 254 | nv_info(bios, "... checksum invalid\n"); |
| 239 | /* if a ro image is somewhat bad, it's probably all rubbish */ | 255 | /* if a ro image is somewhat bad, it's probably all rubbish */ |
| 240 | return writeable ? 2 : 1; | 256 | return writeable ? 2 : 1; |
diff --git a/drivers/gpu/drm/nouveau/core/subdev/bios/dcb.c b/drivers/gpu/drm/nouveau/core/subdev/bios/dcb.c index 9ed6e728a94c..c51197157749 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/bios/dcb.c +++ b/drivers/gpu/drm/nouveau/core/subdev/bios/dcb.c | |||
| @@ -43,7 +43,7 @@ dcb_table(struct nouveau_bios *bios, u8 *ver, u8 *hdr, u8 *cnt, u8 *len) | |||
| 43 | *ver = nv_ro08(bios, dcb); | 43 | *ver = nv_ro08(bios, dcb); |
| 44 | 44 | ||
| 45 | if (*ver >= 0x41) { | 45 | if (*ver >= 0x41) { |
| 46 | nv_warn(bios, "DCB *ver 0x%02x unknown\n", *ver); | 46 | nv_warn(bios, "DCB version 0x%02x unknown\n", *ver); |
| 47 | return 0x0000; | 47 | return 0x0000; |
| 48 | } else | 48 | } else |
| 49 | if (*ver >= 0x30) { | 49 | if (*ver >= 0x30) { |
| @@ -64,7 +64,7 @@ dcb_table(struct nouveau_bios *bios, u8 *ver, u8 *hdr, u8 *cnt, u8 *len) | |||
| 64 | } | 64 | } |
| 65 | } else | 65 | } else |
| 66 | if (*ver >= 0x15) { | 66 | if (*ver >= 0x15) { |
| 67 | if (!nv_strncmp(bios, dcb - 7, 7, "DEV_REC")) { | 67 | if (!nv_memcmp(bios, dcb - 7, "DEV_REC", 7)) { |
| 68 | u16 i2c = nv_ro16(bios, dcb + 2); | 68 | u16 i2c = nv_ro16(bios, dcb + 2); |
| 69 | *hdr = 4; | 69 | *hdr = 4; |
| 70 | *cnt = (i2c - dcb) / 10; | 70 | *cnt = (i2c - dcb) / 10; |
diff --git a/drivers/gpu/drm/nouveau/core/subdev/bios/pll.c b/drivers/gpu/drm/nouveau/core/subdev/bios/pll.c index 5e5f4cddae3c..f835501203e5 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/bios/pll.c +++ b/drivers/gpu/drm/nouveau/core/subdev/bios/pll.c | |||
| @@ -157,11 +157,10 @@ pll_map_reg(struct nouveau_bios *bios, u32 reg, u32 *type, u8 *ver, u8 *len) | |||
| 157 | while (map->reg) { | 157 | while (map->reg) { |
| 158 | if (map->reg == reg && *ver >= 0x20) { | 158 | if (map->reg == reg && *ver >= 0x20) { |
| 159 | u16 addr = (data += hdr); | 159 | u16 addr = (data += hdr); |
| 160 | *type = map->type; | ||
| 160 | while (cnt--) { | 161 | while (cnt--) { |
| 161 | if (nv_ro32(bios, data) == map->reg) { | 162 | if (nv_ro32(bios, data) == map->reg) |
| 162 | *type = map->type; | ||
| 163 | return data; | 163 | return data; |
| 164 | } | ||
| 165 | data += *len; | 164 | data += *len; |
| 166 | } | 165 | } |
| 167 | return addr; | 166 | return addr; |
| @@ -200,11 +199,10 @@ pll_map_type(struct nouveau_bios *bios, u8 type, u32 *reg, u8 *ver, u8 *len) | |||
| 200 | while (map->reg) { | 199 | while (map->reg) { |
| 201 | if (map->type == type && *ver >= 0x20) { | 200 | if (map->type == type && *ver >= 0x20) { |
| 202 | u16 addr = (data += hdr); | 201 | u16 addr = (data += hdr); |
| 202 | *reg = map->reg; | ||
| 203 | while (cnt--) { | 203 | while (cnt--) { |
| 204 | if (nv_ro32(bios, data) == map->reg) { | 204 | if (nv_ro32(bios, data) == map->reg) |
| 205 | *reg = map->reg; | ||
| 206 | return data; | 205 | return data; |
| 207 | } | ||
| 208 | data += *len; | 206 | data += *len; |
| 209 | } | 207 | } |
| 210 | return addr; | 208 | return addr; |
diff --git a/drivers/gpu/drm/nouveau/core/subdev/clock/nva3.c b/drivers/gpu/drm/nouveau/core/subdev/clock/nva3.c index cc8d7d162d7c..9068c98b96f6 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/clock/nva3.c +++ b/drivers/gpu/drm/nouveau/core/subdev/clock/nva3.c | |||
| @@ -66,6 +66,24 @@ nva3_clock_pll_set(struct nouveau_clock *clk, u32 type, u32 freq) | |||
| 66 | return ret; | 66 | return ret; |
| 67 | } | 67 | } |
| 68 | 68 | ||
| 69 | int | ||
| 70 | nva3_clock_pll_calc(struct nouveau_clock *clock, struct nvbios_pll *info, | ||
| 71 | int clk, struct nouveau_pll_vals *pv) | ||
| 72 | { | ||
| 73 | int ret, N, M, P; | ||
| 74 | |||
| 75 | ret = nva3_pll_calc(clock, info, clk, &N, NULL, &M, &P); | ||
| 76 | |||
| 77 | if (ret > 0) { | ||
| 78 | pv->refclk = info->refclk; | ||
| 79 | pv->N1 = N; | ||
| 80 | pv->M1 = M; | ||
| 81 | pv->log2P = P; | ||
| 82 | } | ||
| 83 | return ret; | ||
| 84 | } | ||
| 85 | |||
| 86 | |||
| 69 | static int | 87 | static int |
| 70 | nva3_clock_ctor(struct nouveau_object *parent, struct nouveau_object *engine, | 88 | nva3_clock_ctor(struct nouveau_object *parent, struct nouveau_object *engine, |
| 71 | struct nouveau_oclass *oclass, void *data, u32 size, | 89 | struct nouveau_oclass *oclass, void *data, u32 size, |
| @@ -80,6 +98,7 @@ nva3_clock_ctor(struct nouveau_object *parent, struct nouveau_object *engine, | |||
| 80 | return ret; | 98 | return ret; |
| 81 | 99 | ||
| 82 | priv->base.pll_set = nva3_clock_pll_set; | 100 | priv->base.pll_set = nva3_clock_pll_set; |
| 101 | priv->base.pll_calc = nva3_clock_pll_calc; | ||
| 83 | return 0; | 102 | return 0; |
| 84 | } | 103 | } |
| 85 | 104 | ||
diff --git a/drivers/gpu/drm/nouveau/core/subdev/clock/nvc0.c b/drivers/gpu/drm/nouveau/core/subdev/clock/nvc0.c index 5ccce0b17bf3..f6962c9b6c36 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/clock/nvc0.c +++ b/drivers/gpu/drm/nouveau/core/subdev/clock/nvc0.c | |||
| @@ -79,6 +79,7 @@ nvc0_clock_ctor(struct nouveau_object *parent, struct nouveau_object *engine, | |||
| 79 | return ret; | 79 | return ret; |
| 80 | 80 | ||
| 81 | priv->base.pll_set = nvc0_clock_pll_set; | 81 | priv->base.pll_set = nvc0_clock_pll_set; |
| 82 | priv->base.pll_calc = nva3_clock_pll_calc; | ||
| 82 | return 0; | 83 | return 0; |
| 83 | } | 84 | } |
| 84 | 85 | ||
diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/nv50.c b/drivers/gpu/drm/nouveau/core/subdev/fb/nv50.c index 436e9efe7ef5..5f570806143a 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/fb/nv50.c +++ b/drivers/gpu/drm/nouveau/core/subdev/fb/nv50.c | |||
| @@ -219,13 +219,11 @@ nv50_fb_ctor(struct nouveau_object *parent, struct nouveau_object *engine, | |||
| 219 | ((priv->base.ram.size & 0x000000ff) << 32); | 219 | ((priv->base.ram.size & 0x000000ff) << 32); |
| 220 | 220 | ||
| 221 | tags = nv_rd32(priv, 0x100320); | 221 | tags = nv_rd32(priv, 0x100320); |
| 222 | if (tags) { | 222 | ret = nouveau_mm_init(&priv->base.tags, 0, tags, 1); |
| 223 | ret = nouveau_mm_init(&priv->base.tags, 0, tags, 1); | 223 | if (ret) |
| 224 | if (ret) | 224 | return ret; |
| 225 | return ret; | ||
| 226 | 225 | ||
| 227 | nv_debug(priv, "%d compression tags\n", tags); | 226 | nv_debug(priv, "%d compression tags\n", tags); |
| 228 | } | ||
| 229 | 227 | ||
| 230 | size = (priv->base.ram.size >> 12) - rsvd_head - rsvd_tail; | 228 | size = (priv->base.ram.size >> 12) - rsvd_head - rsvd_tail; |
| 231 | switch (device->chipset) { | 229 | switch (device->chipset) { |
| @@ -237,6 +235,7 @@ nv50_fb_ctor(struct nouveau_object *parent, struct nouveau_object *engine, | |||
| 237 | return ret; | 235 | return ret; |
| 238 | 236 | ||
| 239 | priv->base.ram.stolen = (u64)nv_rd32(priv, 0x100e10) << 12; | 237 | priv->base.ram.stolen = (u64)nv_rd32(priv, 0x100e10) << 12; |
| 238 | priv->base.ram.type = NV_MEM_TYPE_STOLEN; | ||
| 240 | break; | 239 | break; |
| 241 | default: | 240 | default: |
| 242 | ret = nouveau_mm_init(&priv->base.vram, rsvd_head, size, | 241 | ret = nouveau_mm_init(&priv->base.vram, rsvd_head, size, |
| @@ -277,7 +276,6 @@ nv50_fb_dtor(struct nouveau_object *object) | |||
| 277 | __free_page(priv->r100c08_page); | 276 | __free_page(priv->r100c08_page); |
| 278 | } | 277 | } |
| 279 | 278 | ||
| 280 | nouveau_mm_fini(&priv->base.vram); | ||
| 281 | nouveau_fb_destroy(&priv->base); | 279 | nouveau_fb_destroy(&priv->base); |
| 282 | } | 280 | } |
| 283 | 281 | ||
diff --git a/drivers/gpu/drm/nouveau/core/subdev/i2c/base.c b/drivers/gpu/drm/nouveau/core/subdev/i2c/base.c index 3d2c88310f98..dbfc2abf0cfe 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/i2c/base.c +++ b/drivers/gpu/drm/nouveau/core/subdev/i2c/base.c | |||
| @@ -292,7 +292,7 @@ nouveau_i2c_ctor(struct nouveau_object *parent, struct nouveau_object *engine, | |||
| 292 | case DCB_I2C_NVIO_BIT: | 292 | case DCB_I2C_NVIO_BIT: |
| 293 | port->drive = info.drive & 0x0f; | 293 | port->drive = info.drive & 0x0f; |
| 294 | if (device->card_type < NV_D0) { | 294 | if (device->card_type < NV_D0) { |
| 295 | if (info.drive >= ARRAY_SIZE(nv50_i2c_port)) | 295 | if (port->drive >= ARRAY_SIZE(nv50_i2c_port)) |
| 296 | break; | 296 | break; |
| 297 | port->drive = nv50_i2c_port[port->drive]; | 297 | port->drive = nv50_i2c_port[port->drive]; |
| 298 | port->sense = port->drive; | 298 | port->sense = port->drive; |
diff --git a/drivers/gpu/drm/nouveau/core/subdev/therm/fan.c b/drivers/gpu/drm/nouveau/core/subdev/therm/fan.c index b29237970fa0..523178685180 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/therm/fan.c +++ b/drivers/gpu/drm/nouveau/core/subdev/therm/fan.c | |||
| @@ -134,7 +134,7 @@ nouveau_therm_fan_sense(struct nouveau_therm *therm) | |||
| 134 | end = ptimer->read(ptimer); | 134 | end = ptimer->read(ptimer); |
| 135 | 135 | ||
| 136 | if (cycles == 5) { | 136 | if (cycles == 5) { |
| 137 | tach = (u64)60000000000; | 137 | tach = (u64)60000000000ULL; |
| 138 | do_div(tach, (end - start)); | 138 | do_div(tach, (end - start)); |
| 139 | return tach; | 139 | return tach; |
| 140 | } else | 140 | } else |
diff --git a/drivers/gpu/drm/nouveau/core/subdev/vm/nv41.c b/drivers/gpu/drm/nouveau/core/subdev/vm/nv41.c index 0203e1e12caa..9474cfca6e4c 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/vm/nv41.c +++ b/drivers/gpu/drm/nouveau/core/subdev/vm/nv41.c | |||
| @@ -67,7 +67,7 @@ nv41_vm_unmap(struct nouveau_gpuobj *pgt, u32 pte, u32 cnt) | |||
| 67 | static void | 67 | static void |
| 68 | nv41_vm_flush(struct nouveau_vm *vm) | 68 | nv41_vm_flush(struct nouveau_vm *vm) |
| 69 | { | 69 | { |
| 70 | struct nv04_vm_priv *priv = (void *)vm->vmm; | 70 | struct nv04_vmmgr_priv *priv = (void *)vm->vmm; |
| 71 | 71 | ||
| 72 | mutex_lock(&nv_subdev(priv)->mutex); | 72 | mutex_lock(&nv_subdev(priv)->mutex); |
| 73 | nv_wr32(priv, 0x100810, 0x00000022); | 73 | nv_wr32(priv, 0x100810, 0x00000022); |
| @@ -92,7 +92,8 @@ nv41_vmmgr_ctor(struct nouveau_object *parent, struct nouveau_object *engine, | |||
| 92 | struct nv04_vmmgr_priv *priv; | 92 | struct nv04_vmmgr_priv *priv; |
| 93 | int ret; | 93 | int ret; |
| 94 | 94 | ||
| 95 | if (!nouveau_boolopt(device->cfgopt, "NvPCIE", true)) { | 95 | if (pci_find_capability(device->pdev, PCI_CAP_ID_AGP) || |
| 96 | !nouveau_boolopt(device->cfgopt, "NvPCIE", true)) { | ||
| 96 | return nouveau_object_ctor(parent, engine, &nv04_vmmgr_oclass, | 97 | return nouveau_object_ctor(parent, engine, &nv04_vmmgr_oclass, |
| 97 | data, size, pobject); | 98 | data, size, pobject); |
| 98 | } | 99 | } |
diff --git a/drivers/gpu/drm/nouveau/core/subdev/vm/nv44.c b/drivers/gpu/drm/nouveau/core/subdev/vm/nv44.c index 0ac18d05a146..aa8131436e3d 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/vm/nv44.c +++ b/drivers/gpu/drm/nouveau/core/subdev/vm/nv44.c | |||
| @@ -163,7 +163,8 @@ nv44_vmmgr_ctor(struct nouveau_object *parent, struct nouveau_object *engine, | |||
| 163 | struct nv04_vmmgr_priv *priv; | 163 | struct nv04_vmmgr_priv *priv; |
| 164 | int ret; | 164 | int ret; |
| 165 | 165 | ||
| 166 | if (!nouveau_boolopt(device->cfgopt, "NvPCIE", true)) { | 166 | if (pci_find_capability(device->pdev, PCI_CAP_ID_AGP) || |
| 167 | !nouveau_boolopt(device->cfgopt, "NvPCIE", true)) { | ||
| 167 | return nouveau_object_ctor(parent, engine, &nv04_vmmgr_oclass, | 168 | return nouveau_object_ctor(parent, engine, &nv04_vmmgr_oclass, |
| 168 | data, size, pobject); | 169 | data, size, pobject); |
| 169 | } | 170 | } |
diff --git a/drivers/gpu/drm/nouveau/nouveau_abi16.c b/drivers/gpu/drm/nouveau/nouveau_abi16.c index cc79c796afee..cbf1fc60a386 100644 --- a/drivers/gpu/drm/nouveau/nouveau_abi16.c +++ b/drivers/gpu/drm/nouveau/nouveau_abi16.c | |||
| @@ -241,6 +241,10 @@ nouveau_abi16_ioctl_channel_alloc(ABI16_IOCTL_ARGS) | |||
| 241 | 241 | ||
| 242 | if (unlikely(!abi16)) | 242 | if (unlikely(!abi16)) |
| 243 | return -ENOMEM; | 243 | return -ENOMEM; |
| 244 | |||
| 245 | if (!drm->channel) | ||
| 246 | return nouveau_abi16_put(abi16, -ENODEV); | ||
| 247 | |||
| 244 | client = nv_client(abi16->client); | 248 | client = nv_client(abi16->client); |
| 245 | 249 | ||
| 246 | if (init->fb_ctxdma_handle == ~0 || init->tt_ctxdma_handle == ~0) | 250 | if (init->fb_ctxdma_handle == ~0 || init->tt_ctxdma_handle == ~0) |
diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.c b/drivers/gpu/drm/nouveau/nouveau_bo.c index 259e5f1adf47..35ac57f0aab6 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bo.c +++ b/drivers/gpu/drm/nouveau/nouveau_bo.c | |||
| @@ -456,6 +456,7 @@ static struct ttm_tt * | |||
| 456 | nouveau_ttm_tt_create(struct ttm_bo_device *bdev, unsigned long size, | 456 | nouveau_ttm_tt_create(struct ttm_bo_device *bdev, unsigned long size, |
| 457 | uint32_t page_flags, struct page *dummy_read) | 457 | uint32_t page_flags, struct page *dummy_read) |
| 458 | { | 458 | { |
| 459 | #if __OS_HAS_AGP | ||
| 459 | struct nouveau_drm *drm = nouveau_bdev(bdev); | 460 | struct nouveau_drm *drm = nouveau_bdev(bdev); |
| 460 | struct drm_device *dev = drm->dev; | 461 | struct drm_device *dev = drm->dev; |
| 461 | 462 | ||
| @@ -463,6 +464,7 @@ nouveau_ttm_tt_create(struct ttm_bo_device *bdev, unsigned long size, | |||
| 463 | return ttm_agp_tt_create(bdev, dev->agp->bridge, size, | 464 | return ttm_agp_tt_create(bdev, dev->agp->bridge, size, |
| 464 | page_flags, dummy_read); | 465 | page_flags, dummy_read); |
| 465 | } | 466 | } |
| 467 | #endif | ||
| 466 | 468 | ||
| 467 | return nouveau_sgdma_create_ttm(bdev, size, page_flags, dummy_read); | 469 | return nouveau_sgdma_create_ttm(bdev, size, page_flags, dummy_read); |
| 468 | } | 470 | } |
diff --git a/drivers/gpu/drm/nouveau/nouveau_connector.c b/drivers/gpu/drm/nouveau/nouveau_connector.c index 9a6e2cb282dc..d3595b23434a 100644 --- a/drivers/gpu/drm/nouveau/nouveau_connector.c +++ b/drivers/gpu/drm/nouveau/nouveau_connector.c | |||
| @@ -355,7 +355,7 @@ nouveau_connector_detect_lvds(struct drm_connector *connector, bool force) | |||
| 355 | * valid - it's not (rh#613284) | 355 | * valid - it's not (rh#613284) |
| 356 | */ | 356 | */ |
| 357 | if (nv_encoder->dcb->lvdsconf.use_acpi_for_edid) { | 357 | if (nv_encoder->dcb->lvdsconf.use_acpi_for_edid) { |
| 358 | if (!(nv_connector->edid = nouveau_acpi_edid(dev, connector))) { | 358 | if ((nv_connector->edid = nouveau_acpi_edid(dev, connector))) { |
| 359 | status = connector_status_connected; | 359 | status = connector_status_connected; |
| 360 | goto out; | 360 | goto out; |
| 361 | } | 361 | } |
diff --git a/drivers/gpu/drm/nouveau/nouveau_display.c b/drivers/gpu/drm/nouveau/nouveau_display.c index 8f98e5a8c488..86124b131f4f 100644 --- a/drivers/gpu/drm/nouveau/nouveau_display.c +++ b/drivers/gpu/drm/nouveau/nouveau_display.c | |||
| @@ -290,6 +290,7 @@ nouveau_display_create(struct drm_device *dev) | |||
| 290 | struct nouveau_drm *drm = nouveau_drm(dev); | 290 | struct nouveau_drm *drm = nouveau_drm(dev); |
| 291 | struct nouveau_disp *pdisp = nouveau_disp(drm->device); | 291 | struct nouveau_disp *pdisp = nouveau_disp(drm->device); |
| 292 | struct nouveau_display *disp; | 292 | struct nouveau_display *disp; |
| 293 | u32 pclass = dev->pdev->class >> 8; | ||
| 293 | int ret, gen; | 294 | int ret, gen; |
| 294 | 295 | ||
| 295 | disp = drm->display = kzalloc(sizeof(*disp), GFP_KERNEL); | 296 | disp = drm->display = kzalloc(sizeof(*disp), GFP_KERNEL); |
| @@ -360,23 +361,27 @@ nouveau_display_create(struct drm_device *dev) | |||
| 360 | drm_kms_helper_poll_init(dev); | 361 | drm_kms_helper_poll_init(dev); |
| 361 | drm_kms_helper_poll_disable(dev); | 362 | drm_kms_helper_poll_disable(dev); |
| 362 | 363 | ||
| 363 | if (nv_device(drm->device)->card_type < NV_50) | 364 | if (nouveau_modeset == 1 || |
| 364 | ret = nv04_display_create(dev); | 365 | (nouveau_modeset < 0 && pclass == PCI_CLASS_DISPLAY_VGA)) { |
| 365 | else | 366 | if (nv_device(drm->device)->card_type < NV_50) |
| 366 | if (nv_device(drm->device)->card_type < NV_D0) | 367 | ret = nv04_display_create(dev); |
| 367 | ret = nv50_display_create(dev); | 368 | else |
| 368 | else | 369 | if (nv_device(drm->device)->card_type < NV_D0) |
| 369 | ret = nvd0_display_create(dev); | 370 | ret = nv50_display_create(dev); |
| 370 | if (ret) | 371 | else |
| 371 | goto disp_create_err; | 372 | ret = nvd0_display_create(dev); |
| 372 | |||
| 373 | if (dev->mode_config.num_crtc) { | ||
| 374 | ret = drm_vblank_init(dev, dev->mode_config.num_crtc); | ||
| 375 | if (ret) | 373 | if (ret) |
| 376 | goto vblank_err; | 374 | goto disp_create_err; |
| 375 | |||
| 376 | if (dev->mode_config.num_crtc) { | ||
| 377 | ret = drm_vblank_init(dev, dev->mode_config.num_crtc); | ||
| 378 | if (ret) | ||
| 379 | goto vblank_err; | ||
| 380 | } | ||
| 381 | |||
| 382 | nouveau_backlight_init(dev); | ||
| 377 | } | 383 | } |
| 378 | 384 | ||
| 379 | nouveau_backlight_init(dev); | ||
| 380 | return 0; | 385 | return 0; |
| 381 | 386 | ||
| 382 | vblank_err: | 387 | vblank_err: |
| @@ -395,7 +400,8 @@ nouveau_display_destroy(struct drm_device *dev) | |||
| 395 | nouveau_backlight_exit(dev); | 400 | nouveau_backlight_exit(dev); |
| 396 | drm_vblank_cleanup(dev); | 401 | drm_vblank_cleanup(dev); |
| 397 | 402 | ||
| 398 | disp->dtor(dev); | 403 | if (disp->dtor) |
| 404 | disp->dtor(dev); | ||
| 399 | 405 | ||
| 400 | drm_kms_helper_poll_fini(dev); | 406 | drm_kms_helper_poll_fini(dev); |
| 401 | drm_mode_config_cleanup(dev); | 407 | drm_mode_config_cleanup(dev); |
| @@ -530,9 +536,11 @@ nouveau_page_flip_reserve(struct nouveau_bo *old_bo, | |||
| 530 | if (ret) | 536 | if (ret) |
| 531 | goto fail; | 537 | goto fail; |
| 532 | 538 | ||
| 533 | ret = ttm_bo_reserve(&old_bo->bo, false, false, false, 0); | 539 | if (likely(old_bo != new_bo)) { |
| 534 | if (ret) | 540 | ret = ttm_bo_reserve(&old_bo->bo, false, false, false, 0); |
| 535 | goto fail_unreserve; | 541 | if (ret) |
| 542 | goto fail_unreserve; | ||
| 543 | } | ||
| 536 | 544 | ||
| 537 | return 0; | 545 | return 0; |
| 538 | 546 | ||
| @@ -551,8 +559,10 @@ nouveau_page_flip_unreserve(struct nouveau_bo *old_bo, | |||
| 551 | nouveau_bo_fence(new_bo, fence); | 559 | nouveau_bo_fence(new_bo, fence); |
| 552 | ttm_bo_unreserve(&new_bo->bo); | 560 | ttm_bo_unreserve(&new_bo->bo); |
| 553 | 561 | ||
| 554 | nouveau_bo_fence(old_bo, fence); | 562 | if (likely(old_bo != new_bo)) { |
| 555 | ttm_bo_unreserve(&old_bo->bo); | 563 | nouveau_bo_fence(old_bo, fence); |
| 564 | ttm_bo_unreserve(&old_bo->bo); | ||
| 565 | } | ||
| 556 | 566 | ||
| 557 | nouveau_bo_unpin(old_bo); | 567 | nouveau_bo_unpin(old_bo); |
| 558 | } | 568 | } |
diff --git a/drivers/gpu/drm/nouveau/nouveau_drm.c b/drivers/gpu/drm/nouveau/nouveau_drm.c index ccae8c26ae2b..8503b2ea570a 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drm.c +++ b/drivers/gpu/drm/nouveau/nouveau_drm.c | |||
| @@ -63,8 +63,9 @@ MODULE_PARM_DESC(noaccel, "disable kernel/abi16 acceleration"); | |||
| 63 | static int nouveau_noaccel = 0; | 63 | static int nouveau_noaccel = 0; |
| 64 | module_param_named(noaccel, nouveau_noaccel, int, 0400); | 64 | module_param_named(noaccel, nouveau_noaccel, int, 0400); |
| 65 | 65 | ||
| 66 | MODULE_PARM_DESC(modeset, "enable driver"); | 66 | MODULE_PARM_DESC(modeset, "enable driver (default: auto, " |
| 67 | static int nouveau_modeset = -1; | 67 | "0 = disabled, 1 = enabled, 2 = headless)"); |
| 68 | int nouveau_modeset = -1; | ||
| 68 | module_param_named(modeset, nouveau_modeset, int, 0400); | 69 | module_param_named(modeset, nouveau_modeset, int, 0400); |
| 69 | 70 | ||
| 70 | static struct drm_driver driver; | 71 | static struct drm_driver driver; |
| @@ -128,7 +129,8 @@ nouveau_accel_init(struct nouveau_drm *drm) | |||
| 128 | 129 | ||
| 129 | /* initialise synchronisation routines */ | 130 | /* initialise synchronisation routines */ |
| 130 | if (device->card_type < NV_10) ret = nv04_fence_create(drm); | 131 | if (device->card_type < NV_10) ret = nv04_fence_create(drm); |
| 131 | else if (device->chipset < 0x84) ret = nv10_fence_create(drm); | 132 | else if (device->card_type < NV_50) ret = nv10_fence_create(drm); |
| 133 | else if (device->chipset < 0x84) ret = nv50_fence_create(drm); | ||
| 132 | else if (device->card_type < NV_C0) ret = nv84_fence_create(drm); | 134 | else if (device->card_type < NV_C0) ret = nv84_fence_create(drm); |
| 133 | else ret = nvc0_fence_create(drm); | 135 | else ret = nvc0_fence_create(drm); |
| 134 | if (ret) { | 136 | if (ret) { |
| @@ -363,7 +365,8 @@ nouveau_drm_unload(struct drm_device *dev) | |||
| 363 | 365 | ||
| 364 | nouveau_pm_fini(dev); | 366 | nouveau_pm_fini(dev); |
| 365 | 367 | ||
| 366 | nouveau_display_fini(dev); | 368 | if (dev->mode_config.num_crtc) |
| 369 | nouveau_display_fini(dev); | ||
| 367 | nouveau_display_destroy(dev); | 370 | nouveau_display_destroy(dev); |
| 368 | 371 | ||
| 369 | nouveau_irq_fini(dev); | 372 | nouveau_irq_fini(dev); |
| @@ -403,13 +406,15 @@ nouveau_drm_suspend(struct pci_dev *pdev, pm_message_t pm_state) | |||
| 403 | pm_state.event == PM_EVENT_PRETHAW) | 406 | pm_state.event == PM_EVENT_PRETHAW) |
| 404 | return 0; | 407 | return 0; |
| 405 | 408 | ||
| 406 | NV_INFO(drm, "suspending fbcon...\n"); | 409 | if (dev->mode_config.num_crtc) { |
| 407 | nouveau_fbcon_set_suspend(dev, 1); | 410 | NV_INFO(drm, "suspending fbcon...\n"); |
| 411 | nouveau_fbcon_set_suspend(dev, 1); | ||
| 408 | 412 | ||
| 409 | NV_INFO(drm, "suspending display...\n"); | 413 | NV_INFO(drm, "suspending display...\n"); |
| 410 | ret = nouveau_display_suspend(dev); | 414 | ret = nouveau_display_suspend(dev); |
| 411 | if (ret) | 415 | if (ret) |
| 412 | return ret; | 416 | return ret; |
| 417 | } | ||
| 413 | 418 | ||
| 414 | NV_INFO(drm, "evicting buffers...\n"); | 419 | NV_INFO(drm, "evicting buffers...\n"); |
| 415 | ttm_bo_evict_mm(&drm->ttm.bdev, TTM_PL_VRAM); | 420 | ttm_bo_evict_mm(&drm->ttm.bdev, TTM_PL_VRAM); |
| @@ -445,8 +450,10 @@ fail_client: | |||
| 445 | nouveau_client_init(&cli->base); | 450 | nouveau_client_init(&cli->base); |
| 446 | } | 451 | } |
| 447 | 452 | ||
| 448 | NV_INFO(drm, "resuming display...\n"); | 453 | if (dev->mode_config.num_crtc) { |
| 449 | nouveau_display_resume(dev); | 454 | NV_INFO(drm, "resuming display...\n"); |
| 455 | nouveau_display_resume(dev); | ||
| 456 | } | ||
| 450 | return ret; | 457 | return ret; |
| 451 | } | 458 | } |
| 452 | 459 | ||
| @@ -486,8 +493,10 @@ nouveau_drm_resume(struct pci_dev *pdev) | |||
| 486 | nouveau_irq_postinstall(dev); | 493 | nouveau_irq_postinstall(dev); |
| 487 | nouveau_pm_resume(dev); | 494 | nouveau_pm_resume(dev); |
| 488 | 495 | ||
| 489 | NV_INFO(drm, "resuming display...\n"); | 496 | if (dev->mode_config.num_crtc) { |
| 490 | nouveau_display_resume(dev); | 497 | NV_INFO(drm, "resuming display...\n"); |
| 498 | nouveau_display_resume(dev); | ||
| 499 | } | ||
| 491 | return 0; | 500 | return 0; |
| 492 | } | 501 | } |
| 493 | 502 | ||
| @@ -662,9 +671,7 @@ nouveau_drm_init(void) | |||
| 662 | #ifdef CONFIG_VGA_CONSOLE | 671 | #ifdef CONFIG_VGA_CONSOLE |
| 663 | if (vgacon_text_force()) | 672 | if (vgacon_text_force()) |
| 664 | nouveau_modeset = 0; | 673 | nouveau_modeset = 0; |
| 665 | else | ||
| 666 | #endif | 674 | #endif |
| 667 | nouveau_modeset = 1; | ||
| 668 | } | 675 | } |
| 669 | 676 | ||
| 670 | if (!nouveau_modeset) | 677 | if (!nouveau_modeset) |
diff --git a/drivers/gpu/drm/nouveau/nouveau_drm.h b/drivers/gpu/drm/nouveau/nouveau_drm.h index 819471217546..a10169927086 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drm.h +++ b/drivers/gpu/drm/nouveau/nouveau_drm.h | |||
| @@ -141,4 +141,6 @@ int nouveau_drm_resume(struct pci_dev *); | |||
| 141 | nv_info((cli), fmt, ##args); \ | 141 | nv_info((cli), fmt, ##args); \ |
| 142 | } while (0) | 142 | } while (0) |
| 143 | 143 | ||
| 144 | extern int nouveau_modeset; | ||
| 145 | |||
| 144 | #endif | 146 | #endif |
diff --git a/drivers/gpu/drm/nouveau/nouveau_irq.c b/drivers/gpu/drm/nouveau/nouveau_irq.c index 9ca8afdb5549..1d8cb506a28a 100644 --- a/drivers/gpu/drm/nouveau/nouveau_irq.c +++ b/drivers/gpu/drm/nouveau/nouveau_irq.c | |||
| @@ -61,13 +61,15 @@ nouveau_irq_handler(DRM_IRQ_ARGS) | |||
| 61 | 61 | ||
| 62 | nv_subdev(pmc)->intr(nv_subdev(pmc)); | 62 | nv_subdev(pmc)->intr(nv_subdev(pmc)); |
| 63 | 63 | ||
| 64 | if (device->card_type >= NV_D0) { | 64 | if (dev->mode_config.num_crtc) { |
| 65 | if (nv_rd32(device, 0x000100) & 0x04000000) | 65 | if (device->card_type >= NV_D0) { |
| 66 | nvd0_display_intr(dev); | 66 | if (nv_rd32(device, 0x000100) & 0x04000000) |
| 67 | } else | 67 | nvd0_display_intr(dev); |
| 68 | if (device->card_type >= NV_50) { | 68 | } else |
| 69 | if (nv_rd32(device, 0x000100) & 0x04000000) | 69 | if (device->card_type >= NV_50) { |
| 70 | nv50_display_intr(dev); | 70 | if (nv_rd32(device, 0x000100) & 0x04000000) |
| 71 | nv50_display_intr(dev); | ||
| 72 | } | ||
| 71 | } | 73 | } |
| 72 | 74 | ||
| 73 | return IRQ_HANDLED; | 75 | return IRQ_HANDLED; |
diff --git a/drivers/gpu/drm/nouveau/nouveau_pm.c b/drivers/gpu/drm/nouveau/nouveau_pm.c index 0bf64c90aa20..5566172774df 100644 --- a/drivers/gpu/drm/nouveau/nouveau_pm.c +++ b/drivers/gpu/drm/nouveau/nouveau_pm.c | |||
| @@ -52,7 +52,7 @@ nouveau_pm_perflvl_aux(struct drm_device *dev, struct nouveau_pm_level *perflvl, | |||
| 52 | { | 52 | { |
| 53 | struct nouveau_drm *drm = nouveau_drm(dev); | 53 | struct nouveau_drm *drm = nouveau_drm(dev); |
| 54 | struct nouveau_pm *pm = nouveau_pm(dev); | 54 | struct nouveau_pm *pm = nouveau_pm(dev); |
| 55 | struct nouveau_therm *therm = nouveau_therm(drm); | 55 | struct nouveau_therm *therm = nouveau_therm(drm->device); |
| 56 | int ret; | 56 | int ret; |
| 57 | 57 | ||
| 58 | /*XXX: not on all boards, we should control based on temperature | 58 | /*XXX: not on all boards, we should control based on temperature |
| @@ -64,7 +64,6 @@ nouveau_pm_perflvl_aux(struct drm_device *dev, struct nouveau_pm_level *perflvl, | |||
| 64 | ret = therm->fan_set(therm, perflvl->fanspeed); | 64 | ret = therm->fan_set(therm, perflvl->fanspeed); |
| 65 | if (ret && ret != -ENODEV) { | 65 | if (ret && ret != -ENODEV) { |
| 66 | NV_ERROR(drm, "fanspeed set failed: %d\n", ret); | 66 | NV_ERROR(drm, "fanspeed set failed: %d\n", ret); |
| 67 | return ret; | ||
| 68 | } | 67 | } |
| 69 | } | 68 | } |
| 70 | 69 | ||
| @@ -706,8 +705,7 @@ nouveau_hwmon_init(struct drm_device *dev) | |||
| 706 | struct device *hwmon_dev; | 705 | struct device *hwmon_dev; |
| 707 | int ret = 0; | 706 | int ret = 0; |
| 708 | 707 | ||
| 709 | if (!therm || !therm->temp_get || !therm->attr_get || | 708 | if (!therm || !therm->temp_get || !therm->attr_get || !therm->attr_set) |
| 710 | !therm->attr_set || therm->temp_get(therm) < 0) | ||
| 711 | return -ENODEV; | 709 | return -ENODEV; |
| 712 | 710 | ||
| 713 | hwmon_dev = hwmon_device_register(&dev->pdev->dev); | 711 | hwmon_dev = hwmon_device_register(&dev->pdev->dev); |
diff --git a/drivers/gpu/drm/nouveau/nv04_dac.c b/drivers/gpu/drm/nouveau/nv04_dac.c index 347a3bd78d04..64f7020fb605 100644 --- a/drivers/gpu/drm/nouveau/nv04_dac.c +++ b/drivers/gpu/drm/nouveau/nv04_dac.c | |||
| @@ -220,7 +220,7 @@ out: | |||
| 220 | NVWriteVgaCrtc(dev, 0, NV_CIO_CR_MODE_INDEX, saved_cr_mode); | 220 | NVWriteVgaCrtc(dev, 0, NV_CIO_CR_MODE_INDEX, saved_cr_mode); |
| 221 | 221 | ||
| 222 | if (blue == 0x18) { | 222 | if (blue == 0x18) { |
| 223 | NV_INFO(drm, "Load detected on head A\n"); | 223 | NV_DEBUG(drm, "Load detected on head A\n"); |
| 224 | return connector_status_connected; | 224 | return connector_status_connected; |
| 225 | } | 225 | } |
| 226 | 226 | ||
| @@ -338,8 +338,8 @@ nv17_dac_detect(struct drm_encoder *encoder, struct drm_connector *connector) | |||
| 338 | 338 | ||
| 339 | if (nv17_dac_sample_load(encoder) & | 339 | if (nv17_dac_sample_load(encoder) & |
| 340 | NV_PRAMDAC_TEST_CONTROL_SENSEB_ALLHI) { | 340 | NV_PRAMDAC_TEST_CONTROL_SENSEB_ALLHI) { |
| 341 | NV_INFO(drm, "Load detected on output %c\n", | 341 | NV_DEBUG(drm, "Load detected on output %c\n", |
| 342 | '@' + ffs(dcb->or)); | 342 | '@' + ffs(dcb->or)); |
| 343 | return connector_status_connected; | 343 | return connector_status_connected; |
| 344 | } else { | 344 | } else { |
| 345 | return connector_status_disconnected; | 345 | return connector_status_disconnected; |
| @@ -413,9 +413,9 @@ static void nv04_dac_commit(struct drm_encoder *encoder) | |||
| 413 | 413 | ||
| 414 | helper->dpms(encoder, DRM_MODE_DPMS_ON); | 414 | helper->dpms(encoder, DRM_MODE_DPMS_ON); |
| 415 | 415 | ||
| 416 | NV_INFO(drm, "Output %s is running on CRTC %d using output %c\n", | 416 | NV_DEBUG(drm, "Output %s is running on CRTC %d using output %c\n", |
| 417 | drm_get_connector_name(&nouveau_encoder_connector_get(nv_encoder)->base), | 417 | drm_get_connector_name(&nouveau_encoder_connector_get(nv_encoder)->base), |
| 418 | nv_crtc->index, '@' + ffs(nv_encoder->dcb->or)); | 418 | nv_crtc->index, '@' + ffs(nv_encoder->dcb->or)); |
| 419 | } | 419 | } |
| 420 | 420 | ||
| 421 | void nv04_dac_update_dacclk(struct drm_encoder *encoder, bool enable) | 421 | void nv04_dac_update_dacclk(struct drm_encoder *encoder, bool enable) |
| @@ -461,8 +461,8 @@ static void nv04_dac_dpms(struct drm_encoder *encoder, int mode) | |||
| 461 | return; | 461 | return; |
| 462 | nv_encoder->last_dpms = mode; | 462 | nv_encoder->last_dpms = mode; |
| 463 | 463 | ||
| 464 | NV_INFO(drm, "Setting dpms mode %d on vga encoder (output %d)\n", | 464 | NV_DEBUG(drm, "Setting dpms mode %d on vga encoder (output %d)\n", |
| 465 | mode, nv_encoder->dcb->index); | 465 | mode, nv_encoder->dcb->index); |
| 466 | 466 | ||
| 467 | nv04_dac_update_dacclk(encoder, mode == DRM_MODE_DPMS_ON); | 467 | nv04_dac_update_dacclk(encoder, mode == DRM_MODE_DPMS_ON); |
| 468 | } | 468 | } |
diff --git a/drivers/gpu/drm/nouveau/nv04_dfp.c b/drivers/gpu/drm/nouveau/nv04_dfp.c index da55d7642c8c..184cdf806761 100644 --- a/drivers/gpu/drm/nouveau/nv04_dfp.c +++ b/drivers/gpu/drm/nouveau/nv04_dfp.c | |||
| @@ -476,9 +476,9 @@ static void nv04_dfp_commit(struct drm_encoder *encoder) | |||
| 476 | 476 | ||
| 477 | helper->dpms(encoder, DRM_MODE_DPMS_ON); | 477 | helper->dpms(encoder, DRM_MODE_DPMS_ON); |
| 478 | 478 | ||
| 479 | NV_INFO(drm, "Output %s is running on CRTC %d using output %c\n", | 479 | NV_DEBUG(drm, "Output %s is running on CRTC %d using output %c\n", |
| 480 | drm_get_connector_name(&nouveau_encoder_connector_get(nv_encoder)->base), | 480 | drm_get_connector_name(&nouveau_encoder_connector_get(nv_encoder)->base), |
| 481 | nv_crtc->index, '@' + ffs(nv_encoder->dcb->or)); | 481 | nv_crtc->index, '@' + ffs(nv_encoder->dcb->or)); |
| 482 | } | 482 | } |
| 483 | 483 | ||
| 484 | static void nv04_dfp_update_backlight(struct drm_encoder *encoder, int mode) | 484 | static void nv04_dfp_update_backlight(struct drm_encoder *encoder, int mode) |
| @@ -520,8 +520,8 @@ static void nv04_lvds_dpms(struct drm_encoder *encoder, int mode) | |||
| 520 | return; | 520 | return; |
| 521 | nv_encoder->last_dpms = mode; | 521 | nv_encoder->last_dpms = mode; |
| 522 | 522 | ||
| 523 | NV_INFO(drm, "Setting dpms mode %d on lvds encoder (output %d)\n", | 523 | NV_DEBUG(drm, "Setting dpms mode %d on lvds encoder (output %d)\n", |
| 524 | mode, nv_encoder->dcb->index); | 524 | mode, nv_encoder->dcb->index); |
| 525 | 525 | ||
| 526 | if (was_powersaving && is_powersaving_dpms(mode)) | 526 | if (was_powersaving && is_powersaving_dpms(mode)) |
| 527 | return; | 527 | return; |
| @@ -565,8 +565,8 @@ static void nv04_tmds_dpms(struct drm_encoder *encoder, int mode) | |||
| 565 | return; | 565 | return; |
| 566 | nv_encoder->last_dpms = mode; | 566 | nv_encoder->last_dpms = mode; |
| 567 | 567 | ||
| 568 | NV_INFO(drm, "Setting dpms mode %d on tmds encoder (output %d)\n", | 568 | NV_DEBUG(drm, "Setting dpms mode %d on tmds encoder (output %d)\n", |
| 569 | mode, nv_encoder->dcb->index); | 569 | mode, nv_encoder->dcb->index); |
| 570 | 570 | ||
| 571 | nv04_dfp_update_backlight(encoder, mode); | 571 | nv04_dfp_update_backlight(encoder, mode); |
| 572 | nv04_dfp_update_fp_control(encoder, mode); | 572 | nv04_dfp_update_fp_control(encoder, mode); |
diff --git a/drivers/gpu/drm/nouveau/nv04_tv.c b/drivers/gpu/drm/nouveau/nv04_tv.c index 099fbeda6e2e..62e826a139b3 100644 --- a/drivers/gpu/drm/nouveau/nv04_tv.c +++ b/drivers/gpu/drm/nouveau/nv04_tv.c | |||
| @@ -75,8 +75,8 @@ static void nv04_tv_dpms(struct drm_encoder *encoder, int mode) | |||
| 75 | struct nv04_mode_state *state = &nv04_display(dev)->mode_reg; | 75 | struct nv04_mode_state *state = &nv04_display(dev)->mode_reg; |
| 76 | uint8_t crtc1A; | 76 | uint8_t crtc1A; |
| 77 | 77 | ||
| 78 | NV_INFO(drm, "Setting dpms mode %d on TV encoder (output %d)\n", | 78 | NV_DEBUG(drm, "Setting dpms mode %d on TV encoder (output %d)\n", |
| 79 | mode, nv_encoder->dcb->index); | 79 | mode, nv_encoder->dcb->index); |
| 80 | 80 | ||
| 81 | state->pllsel &= ~(PLLSEL_TV_CRTC1_MASK | PLLSEL_TV_CRTC2_MASK); | 81 | state->pllsel &= ~(PLLSEL_TV_CRTC1_MASK | PLLSEL_TV_CRTC2_MASK); |
| 82 | 82 | ||
| @@ -167,9 +167,8 @@ static void nv04_tv_commit(struct drm_encoder *encoder) | |||
| 167 | 167 | ||
| 168 | helper->dpms(encoder, DRM_MODE_DPMS_ON); | 168 | helper->dpms(encoder, DRM_MODE_DPMS_ON); |
| 169 | 169 | ||
| 170 | NV_INFO(drm, "Output %s is running on CRTC %d using output %c\n", | 170 | NV_DEBUG(drm, "Output %s is running on CRTC %d using output %c\n", |
| 171 | drm_get_connector_name(&nouveau_encoder_connector_get(nv_encoder)->base), nv_crtc->index, | 171 | drm_get_connector_name(&nouveau_encoder_connector_get(nv_encoder)->base), nv_crtc->index, '@' + ffs(nv_encoder->dcb->or)); |
| 172 | '@' + ffs(nv_encoder->dcb->or)); | ||
| 173 | } | 172 | } |
| 174 | 173 | ||
| 175 | static void nv04_tv_destroy(struct drm_encoder *encoder) | 174 | static void nv04_tv_destroy(struct drm_encoder *encoder) |
diff --git a/drivers/gpu/drm/radeon/atombios_crtc.c b/drivers/gpu/drm/radeon/atombios_crtc.c index 96184d02c8d9..24d932f53203 100644 --- a/drivers/gpu/drm/radeon/atombios_crtc.c +++ b/drivers/gpu/drm/radeon/atombios_crtc.c | |||
| @@ -1690,41 +1690,29 @@ static int radeon_atom_pick_pll(struct drm_crtc *crtc) | |||
| 1690 | } | 1690 | } |
| 1691 | /* all other cases */ | 1691 | /* all other cases */ |
| 1692 | pll_in_use = radeon_get_pll_use_mask(crtc); | 1692 | pll_in_use = radeon_get_pll_use_mask(crtc); |
| 1693 | if (!(pll_in_use & (1 << ATOM_PPLL2))) | ||
| 1694 | return ATOM_PPLL2; | ||
| 1695 | if (!(pll_in_use & (1 << ATOM_PPLL1))) | 1693 | if (!(pll_in_use & (1 << ATOM_PPLL1))) |
| 1696 | return ATOM_PPLL1; | 1694 | return ATOM_PPLL1; |
| 1695 | if (!(pll_in_use & (1 << ATOM_PPLL2))) | ||
| 1696 | return ATOM_PPLL2; | ||
| 1697 | DRM_ERROR("unable to allocate a PPLL\n"); | 1697 | DRM_ERROR("unable to allocate a PPLL\n"); |
| 1698 | return ATOM_PPLL_INVALID; | 1698 | return ATOM_PPLL_INVALID; |
| 1699 | } else { | 1699 | } else { |
| 1700 | if (ASIC_IS_AVIVO(rdev)) { | 1700 | /* on pre-R5xx asics, the crtc to pll mapping is hardcoded */ |
| 1701 | /* in DP mode, the DP ref clock can come from either PPLL | 1701 | /* some atombios (observed in some DCE2/DCE3) code have a bug, |
| 1702 | * depending on the asic: | 1702 | * the matching btw pll and crtc is done through |
| 1703 | * DCE3: PPLL1 or PPLL2 | 1703 | * PCLK_CRTC[1|2]_CNTL (0x480/0x484) but atombios code use the |
| 1704 | */ | 1704 | * pll (1 or 2) to select which register to write. ie if using |
| 1705 | if (ENCODER_MODE_IS_DP(atombios_get_encoder_mode(radeon_crtc->encoder))) { | 1705 | * pll1 it will use PCLK_CRTC1_CNTL (0x480) and if using pll2 |
| 1706 | /* use the same PPLL for all DP monitors */ | 1706 | * it will use PCLK_CRTC2_CNTL (0x484), it then use crtc id to |
| 1707 | pll = radeon_get_shared_dp_ppll(crtc); | 1707 | * choose which value to write. Which is reverse order from |
| 1708 | if (pll != ATOM_PPLL_INVALID) | 1708 | * register logic. So only case that works is when pllid is |
| 1709 | return pll; | 1709 | * same as crtcid or when both pll and crtc are enabled and |
| 1710 | } else { | 1710 | * both use same clock. |
| 1711 | /* use the same PPLL for all monitors with the same clock */ | 1711 | * |
| 1712 | pll = radeon_get_shared_nondp_ppll(crtc); | 1712 | * So just return crtc id as if crtc and pll were hard linked |
| 1713 | if (pll != ATOM_PPLL_INVALID) | 1713 | * together even if they aren't |
| 1714 | return pll; | 1714 | */ |
| 1715 | } | 1715 | return radeon_crtc->crtc_id; |
| 1716 | /* all other cases */ | ||
| 1717 | pll_in_use = radeon_get_pll_use_mask(crtc); | ||
| 1718 | if (!(pll_in_use & (1 << ATOM_PPLL2))) | ||
| 1719 | return ATOM_PPLL2; | ||
| 1720 | if (!(pll_in_use & (1 << ATOM_PPLL1))) | ||
| 1721 | return ATOM_PPLL1; | ||
| 1722 | DRM_ERROR("unable to allocate a PPLL\n"); | ||
| 1723 | return ATOM_PPLL_INVALID; | ||
| 1724 | } else { | ||
| 1725 | /* on pre-R5xx asics, the crtc to pll mapping is hardcoded */ | ||
| 1726 | return radeon_crtc->crtc_id; | ||
| 1727 | } | ||
| 1728 | } | 1716 | } |
| 1729 | } | 1717 | } |
| 1730 | 1718 | ||
diff --git a/drivers/gpu/drm/radeon/atombios_encoders.c b/drivers/gpu/drm/radeon/atombios_encoders.c index 49cbb3795a10..010bae19554a 100644 --- a/drivers/gpu/drm/radeon/atombios_encoders.c +++ b/drivers/gpu/drm/radeon/atombios_encoders.c | |||
| @@ -184,6 +184,7 @@ void radeon_atom_backlight_init(struct radeon_encoder *radeon_encoder, | |||
| 184 | struct radeon_backlight_privdata *pdata; | 184 | struct radeon_backlight_privdata *pdata; |
| 185 | struct radeon_encoder_atom_dig *dig; | 185 | struct radeon_encoder_atom_dig *dig; |
| 186 | u8 backlight_level; | 186 | u8 backlight_level; |
| 187 | char bl_name[16]; | ||
| 187 | 188 | ||
| 188 | if (!radeon_encoder->enc_priv) | 189 | if (!radeon_encoder->enc_priv) |
| 189 | return; | 190 | return; |
| @@ -203,7 +204,9 @@ void radeon_atom_backlight_init(struct radeon_encoder *radeon_encoder, | |||
| 203 | memset(&props, 0, sizeof(props)); | 204 | memset(&props, 0, sizeof(props)); |
| 204 | props.max_brightness = RADEON_MAX_BL_LEVEL; | 205 | props.max_brightness = RADEON_MAX_BL_LEVEL; |
| 205 | props.type = BACKLIGHT_RAW; | 206 | props.type = BACKLIGHT_RAW; |
| 206 | bd = backlight_device_register("radeon_bl", &drm_connector->kdev, | 207 | snprintf(bl_name, sizeof(bl_name), |
| 208 | "radeon_bl%d", dev->primary->index); | ||
| 209 | bd = backlight_device_register(bl_name, &drm_connector->kdev, | ||
| 207 | pdata, &radeon_atom_backlight_ops, &props); | 210 | pdata, &radeon_atom_backlight_ops, &props); |
| 208 | if (IS_ERR(bd)) { | 211 | if (IS_ERR(bd)) { |
| 209 | DRM_ERROR("Backlight registration failed\n"); | 212 | DRM_ERROR("Backlight registration failed\n"); |
| @@ -1622,7 +1625,7 @@ radeon_atom_encoder_dpms_dig(struct drm_encoder *encoder, int mode) | |||
| 1622 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_SETUP, 0, 0); | 1625 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_SETUP, 0, 0); |
| 1623 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE, 0, 0); | 1626 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE, 0, 0); |
| 1624 | /* some early dce3.2 boards have a bug in their transmitter control table */ | 1627 | /* some early dce3.2 boards have a bug in their transmitter control table */ |
| 1625 | if ((rdev->family != CHIP_RV710) || (rdev->family != CHIP_RV730)) | 1628 | if ((rdev->family != CHIP_RV710) && (rdev->family != CHIP_RV730)) |
| 1626 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE_OUTPUT, 0, 0); | 1629 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE_OUTPUT, 0, 0); |
| 1627 | } | 1630 | } |
| 1628 | if (ENCODER_MODE_IS_DP(atombios_get_encoder_mode(encoder)) && connector) { | 1631 | if (ENCODER_MODE_IS_DP(atombios_get_encoder_mode(encoder)) && connector) { |
diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c index a1f49c5fd74b..219942c660d7 100644 --- a/drivers/gpu/drm/radeon/evergreen.c +++ b/drivers/gpu/drm/radeon/evergreen.c | |||
| @@ -1330,6 +1330,8 @@ void evergreen_mc_stop(struct radeon_device *rdev, struct evergreen_mc_save *sav | |||
| 1330 | break; | 1330 | break; |
| 1331 | udelay(1); | 1331 | udelay(1); |
| 1332 | } | 1332 | } |
| 1333 | } else { | ||
| 1334 | save->crtc_enabled[i] = false; | ||
| 1333 | } | 1335 | } |
| 1334 | } | 1336 | } |
| 1335 | 1337 | ||
| @@ -1372,7 +1374,7 @@ void evergreen_mc_resume(struct radeon_device *rdev, struct evergreen_mc_save *s | |||
| 1372 | WREG32(BIF_FB_EN, FB_READ_EN | FB_WRITE_EN); | 1374 | WREG32(BIF_FB_EN, FB_READ_EN | FB_WRITE_EN); |
| 1373 | 1375 | ||
| 1374 | for (i = 0; i < rdev->num_crtc; i++) { | 1376 | for (i = 0; i < rdev->num_crtc; i++) { |
| 1375 | if (save->crtc_enabled) { | 1377 | if (save->crtc_enabled[i]) { |
| 1376 | if (ASIC_IS_DCE6(rdev)) { | 1378 | if (ASIC_IS_DCE6(rdev)) { |
| 1377 | tmp = RREG32(EVERGREEN_CRTC_BLANK_CONTROL + crtc_offsets[i]); | 1379 | tmp = RREG32(EVERGREEN_CRTC_BLANK_CONTROL + crtc_offsets[i]); |
| 1378 | tmp |= EVERGREEN_CRTC_BLANK_DATA_EN; | 1380 | tmp |= EVERGREEN_CRTC_BLANK_DATA_EN; |
| @@ -3431,9 +3433,14 @@ void evergreen_pcie_gen2_enable(struct radeon_device *rdev) | |||
| 3431 | if (!(mask & DRM_PCIE_SPEED_50)) | 3433 | if (!(mask & DRM_PCIE_SPEED_50)) |
| 3432 | return; | 3434 | return; |
| 3433 | 3435 | ||
| 3436 | speed_cntl = RREG32_PCIE_P(PCIE_LC_SPEED_CNTL); | ||
| 3437 | if (speed_cntl & LC_CURRENT_DATA_RATE) { | ||
| 3438 | DRM_INFO("PCIE gen 2 link speeds already enabled\n"); | ||
| 3439 | return; | ||
| 3440 | } | ||
| 3441 | |||
| 3434 | DRM_INFO("enabling PCIE gen 2 link speeds, disable with radeon.pcie_gen2=0\n"); | 3442 | DRM_INFO("enabling PCIE gen 2 link speeds, disable with radeon.pcie_gen2=0\n"); |
| 3435 | 3443 | ||
| 3436 | speed_cntl = RREG32_PCIE_P(PCIE_LC_SPEED_CNTL); | ||
| 3437 | if ((speed_cntl & LC_OTHER_SIDE_EVER_SENT_GEN2) || | 3444 | if ((speed_cntl & LC_OTHER_SIDE_EVER_SENT_GEN2) || |
| 3438 | (speed_cntl & LC_OTHER_SIDE_SUPPORTS_GEN2)) { | 3445 | (speed_cntl & LC_OTHER_SIDE_SUPPORTS_GEN2)) { |
| 3439 | 3446 | ||
diff --git a/drivers/gpu/drm/radeon/evergreen_cs.c b/drivers/gpu/drm/radeon/evergreen_cs.c index 573ed1bc6cf7..c042e497e450 100644 --- a/drivers/gpu/drm/radeon/evergreen_cs.c +++ b/drivers/gpu/drm/radeon/evergreen_cs.c | |||
| @@ -264,7 +264,7 @@ static int evergreen_surface_check_2d(struct radeon_cs_parser *p, | |||
| 264 | /* macro tile width & height */ | 264 | /* macro tile width & height */ |
| 265 | palign = (8 * surf->bankw * track->npipes) * surf->mtilea; | 265 | palign = (8 * surf->bankw * track->npipes) * surf->mtilea; |
| 266 | halign = (8 * surf->bankh * surf->nbanks) / surf->mtilea; | 266 | halign = (8 * surf->bankh * surf->nbanks) / surf->mtilea; |
| 267 | mtileb = (palign / 8) * (halign / 8) * tileb;; | 267 | mtileb = (palign / 8) * (halign / 8) * tileb; |
| 268 | mtile_pr = surf->nbx / palign; | 268 | mtile_pr = surf->nbx / palign; |
| 269 | mtile_ps = (mtile_pr * surf->nby) / halign; | 269 | mtile_ps = (mtile_pr * surf->nby) / halign; |
| 270 | surf->layer_size = mtile_ps * mtileb * slice_pt; | 270 | surf->layer_size = mtile_ps * mtileb * slice_pt; |
| @@ -2725,6 +2725,9 @@ static bool evergreen_vm_reg_valid(u32 reg) | |||
| 2725 | /* check config regs */ | 2725 | /* check config regs */ |
| 2726 | switch (reg) { | 2726 | switch (reg) { |
| 2727 | case GRBM_GFX_INDEX: | 2727 | case GRBM_GFX_INDEX: |
| 2728 | case CP_STRMOUT_CNTL: | ||
| 2729 | case CP_COHER_CNTL: | ||
| 2730 | case CP_COHER_SIZE: | ||
| 2728 | case VGT_VTX_VECT_EJECT_REG: | 2731 | case VGT_VTX_VECT_EJECT_REG: |
| 2729 | case VGT_CACHE_INVALIDATION: | 2732 | case VGT_CACHE_INVALIDATION: |
| 2730 | case VGT_GS_VERTEX_REUSE: | 2733 | case VGT_GS_VERTEX_REUSE: |
| @@ -2829,6 +2832,7 @@ static bool evergreen_vm_reg_valid(u32 reg) | |||
| 2829 | case CAYMAN_SQ_EX_ALLOC_TABLE_SLOTS: | 2832 | case CAYMAN_SQ_EX_ALLOC_TABLE_SLOTS: |
| 2830 | return true; | 2833 | return true; |
| 2831 | default: | 2834 | default: |
| 2835 | DRM_ERROR("Invalid register 0x%x in CS\n", reg); | ||
| 2832 | return false; | 2836 | return false; |
| 2833 | } | 2837 | } |
| 2834 | } | 2838 | } |
diff --git a/drivers/gpu/drm/radeon/evergreend.h b/drivers/gpu/drm/radeon/evergreend.h index df542f1a5dfb..2bc0f6a1b428 100644 --- a/drivers/gpu/drm/radeon/evergreend.h +++ b/drivers/gpu/drm/radeon/evergreend.h | |||
| @@ -91,6 +91,10 @@ | |||
| 91 | #define FB_READ_EN (1 << 0) | 91 | #define FB_READ_EN (1 << 0) |
| 92 | #define FB_WRITE_EN (1 << 1) | 92 | #define FB_WRITE_EN (1 << 1) |
| 93 | 93 | ||
| 94 | #define CP_STRMOUT_CNTL 0x84FC | ||
| 95 | |||
| 96 | #define CP_COHER_CNTL 0x85F0 | ||
| 97 | #define CP_COHER_SIZE 0x85F4 | ||
| 94 | #define CP_COHER_BASE 0x85F8 | 98 | #define CP_COHER_BASE 0x85F8 |
| 95 | #define CP_STALLED_STAT1 0x8674 | 99 | #define CP_STALLED_STAT1 0x8674 |
| 96 | #define CP_STALLED_STAT2 0x8678 | 100 | #define CP_STALLED_STAT2 0x8678 |
diff --git a/drivers/gpu/drm/radeon/ni.c b/drivers/gpu/drm/radeon/ni.c index 8bcb554ea0c5..81e6a568c29d 100644 --- a/drivers/gpu/drm/radeon/ni.c +++ b/drivers/gpu/drm/radeon/ni.c | |||
| @@ -770,9 +770,13 @@ static int cayman_pcie_gart_enable(struct radeon_device *rdev) | |||
| 770 | WREG32(0x15DC, 0); | 770 | WREG32(0x15DC, 0); |
| 771 | 771 | ||
| 772 | /* empty context1-7 */ | 772 | /* empty context1-7 */ |
| 773 | /* Assign the pt base to something valid for now; the pts used for | ||
| 774 | * the VMs are determined by the application and setup and assigned | ||
| 775 | * on the fly in the vm part of radeon_gart.c | ||
| 776 | */ | ||
| 773 | for (i = 1; i < 8; i++) { | 777 | for (i = 1; i < 8; i++) { |
| 774 | WREG32(VM_CONTEXT0_PAGE_TABLE_START_ADDR + (i << 2), 0); | 778 | WREG32(VM_CONTEXT0_PAGE_TABLE_START_ADDR + (i << 2), 0); |
| 775 | WREG32(VM_CONTEXT0_PAGE_TABLE_END_ADDR + (i << 2), 0); | 779 | WREG32(VM_CONTEXT0_PAGE_TABLE_END_ADDR + (i << 2), rdev->vm_manager.max_pfn); |
| 776 | WREG32(VM_CONTEXT0_PAGE_TABLE_BASE_ADDR + (i << 2), | 780 | WREG32(VM_CONTEXT0_PAGE_TABLE_BASE_ADDR + (i << 2), |
| 777 | rdev->gart.table_addr >> 12); | 781 | rdev->gart.table_addr >> 12); |
| 778 | } | 782 | } |
| @@ -1534,26 +1538,31 @@ void cayman_vm_set_page(struct radeon_device *rdev, uint64_t pe, | |||
| 1534 | { | 1538 | { |
| 1535 | struct radeon_ring *ring = &rdev->ring[rdev->asic->vm.pt_ring_index]; | 1539 | struct radeon_ring *ring = &rdev->ring[rdev->asic->vm.pt_ring_index]; |
| 1536 | uint32_t r600_flags = cayman_vm_page_flags(rdev, flags); | 1540 | uint32_t r600_flags = cayman_vm_page_flags(rdev, flags); |
| 1537 | int i; | ||
| 1538 | 1541 | ||
| 1539 | radeon_ring_write(ring, PACKET3(PACKET3_ME_WRITE, 1 + count * 2)); | 1542 | while (count) { |
| 1540 | radeon_ring_write(ring, pe); | 1543 | unsigned ndw = 1 + count * 2; |
| 1541 | radeon_ring_write(ring, upper_32_bits(pe) & 0xff); | 1544 | if (ndw > 0x3FFF) |
| 1542 | for (i = 0; i < count; ++i) { | 1545 | ndw = 0x3FFF; |
| 1543 | uint64_t value = 0; | 1546 | |
| 1544 | if (flags & RADEON_VM_PAGE_SYSTEM) { | 1547 | radeon_ring_write(ring, PACKET3(PACKET3_ME_WRITE, ndw)); |
| 1545 | value = radeon_vm_map_gart(rdev, addr); | 1548 | radeon_ring_write(ring, pe); |
| 1546 | value &= 0xFFFFFFFFFFFFF000ULL; | 1549 | radeon_ring_write(ring, upper_32_bits(pe) & 0xff); |
| 1547 | addr += incr; | 1550 | for (; ndw > 1; ndw -= 2, --count, pe += 8) { |
| 1548 | 1551 | uint64_t value = 0; | |
| 1549 | } else if (flags & RADEON_VM_PAGE_VALID) { | 1552 | if (flags & RADEON_VM_PAGE_SYSTEM) { |
| 1550 | value = addr; | 1553 | value = radeon_vm_map_gart(rdev, addr); |
| 1551 | addr += incr; | 1554 | value &= 0xFFFFFFFFFFFFF000ULL; |
| 1552 | } | 1555 | addr += incr; |
| 1556 | |||
| 1557 | } else if (flags & RADEON_VM_PAGE_VALID) { | ||
| 1558 | value = addr; | ||
| 1559 | addr += incr; | ||
| 1560 | } | ||
| 1553 | 1561 | ||
| 1554 | value |= r600_flags; | 1562 | value |= r600_flags; |
| 1555 | radeon_ring_write(ring, value); | 1563 | radeon_ring_write(ring, value); |
| 1556 | radeon_ring_write(ring, upper_32_bits(value)); | 1564 | radeon_ring_write(ring, upper_32_bits(value)); |
| 1565 | } | ||
| 1557 | } | 1566 | } |
| 1558 | } | 1567 | } |
| 1559 | 1568 | ||
| @@ -1572,12 +1581,6 @@ void cayman_vm_flush(struct radeon_device *rdev, int ridx, struct radeon_vm *vm) | |||
| 1572 | if (vm == NULL) | 1581 | if (vm == NULL) |
| 1573 | return; | 1582 | return; |
| 1574 | 1583 | ||
| 1575 | radeon_ring_write(ring, PACKET0(VM_CONTEXT0_PAGE_TABLE_START_ADDR + (vm->id << 2), 0)); | ||
| 1576 | radeon_ring_write(ring, 0); | ||
| 1577 | |||
| 1578 | radeon_ring_write(ring, PACKET0(VM_CONTEXT0_PAGE_TABLE_END_ADDR + (vm->id << 2), 0)); | ||
| 1579 | radeon_ring_write(ring, vm->last_pfn); | ||
| 1580 | |||
| 1581 | radeon_ring_write(ring, PACKET0(VM_CONTEXT0_PAGE_TABLE_BASE_ADDR + (vm->id << 2), 0)); | 1584 | radeon_ring_write(ring, PACKET0(VM_CONTEXT0_PAGE_TABLE_BASE_ADDR + (vm->id << 2), 0)); |
| 1582 | radeon_ring_write(ring, vm->pd_gpu_addr >> 12); | 1585 | radeon_ring_write(ring, vm->pd_gpu_addr >> 12); |
| 1583 | 1586 | ||
| @@ -1588,4 +1591,8 @@ void cayman_vm_flush(struct radeon_device *rdev, int ridx, struct radeon_vm *vm) | |||
| 1588 | /* bits 0-7 are the VM contexts0-7 */ | 1591 | /* bits 0-7 are the VM contexts0-7 */ |
| 1589 | radeon_ring_write(ring, PACKET0(VM_INVALIDATE_REQUEST, 0)); | 1592 | radeon_ring_write(ring, PACKET0(VM_INVALIDATE_REQUEST, 0)); |
| 1590 | radeon_ring_write(ring, 1 << vm->id); | 1593 | radeon_ring_write(ring, 1 << vm->id); |
| 1594 | |||
| 1595 | /* sync PFP to ME, otherwise we might get invalid PFP reads */ | ||
| 1596 | radeon_ring_write(ring, PACKET3(PACKET3_PFP_SYNC_ME, 0)); | ||
| 1597 | radeon_ring_write(ring, 0x0); | ||
| 1591 | } | 1598 | } |
diff --git a/drivers/gpu/drm/radeon/nid.h b/drivers/gpu/drm/radeon/nid.h index 2423d1b5d385..cbef6815907a 100644 --- a/drivers/gpu/drm/radeon/nid.h +++ b/drivers/gpu/drm/radeon/nid.h | |||
| @@ -502,6 +502,7 @@ | |||
| 502 | #define PACKET3_MPEG_INDEX 0x3A | 502 | #define PACKET3_MPEG_INDEX 0x3A |
| 503 | #define PACKET3_WAIT_REG_MEM 0x3C | 503 | #define PACKET3_WAIT_REG_MEM 0x3C |
| 504 | #define PACKET3_MEM_WRITE 0x3D | 504 | #define PACKET3_MEM_WRITE 0x3D |
| 505 | #define PACKET3_PFP_SYNC_ME 0x42 | ||
| 505 | #define PACKET3_SURFACE_SYNC 0x43 | 506 | #define PACKET3_SURFACE_SYNC 0x43 |
| 506 | # define PACKET3_CB0_DEST_BASE_ENA (1 << 6) | 507 | # define PACKET3_CB0_DEST_BASE_ENA (1 << 6) |
| 507 | # define PACKET3_CB1_DEST_BASE_ENA (1 << 7) | 508 | # define PACKET3_CB1_DEST_BASE_ENA (1 << 7) |
diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c index 70c800ff6190..cda280d157da 100644 --- a/drivers/gpu/drm/radeon/r600.c +++ b/drivers/gpu/drm/radeon/r600.c | |||
| @@ -3703,6 +3703,12 @@ static void r600_pcie_gen2_enable(struct radeon_device *rdev) | |||
| 3703 | if (!(mask & DRM_PCIE_SPEED_50)) | 3703 | if (!(mask & DRM_PCIE_SPEED_50)) |
| 3704 | return; | 3704 | return; |
| 3705 | 3705 | ||
| 3706 | speed_cntl = RREG32_PCIE_P(PCIE_LC_SPEED_CNTL); | ||
| 3707 | if (speed_cntl & LC_CURRENT_DATA_RATE) { | ||
| 3708 | DRM_INFO("PCIE gen 2 link speeds already enabled\n"); | ||
| 3709 | return; | ||
| 3710 | } | ||
| 3711 | |||
| 3706 | DRM_INFO("enabling PCIE gen 2 link speeds, disable with radeon.pcie_gen2=0\n"); | 3712 | DRM_INFO("enabling PCIE gen 2 link speeds, disable with radeon.pcie_gen2=0\n"); |
| 3707 | 3713 | ||
| 3708 | /* 55 nm r6xx asics */ | 3714 | /* 55 nm r6xx asics */ |
diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h index b04c06444d8b..8c42d54c2e26 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h | |||
| @@ -663,9 +663,14 @@ struct radeon_vm { | |||
| 663 | struct list_head list; | 663 | struct list_head list; |
| 664 | struct list_head va; | 664 | struct list_head va; |
| 665 | unsigned id; | 665 | unsigned id; |
| 666 | unsigned last_pfn; | 666 | |
| 667 | u64 pd_gpu_addr; | 667 | /* contains the page directory */ |
| 668 | struct radeon_sa_bo *sa_bo; | 668 | struct radeon_sa_bo *page_directory; |
| 669 | uint64_t pd_gpu_addr; | ||
| 670 | |||
| 671 | /* array of page tables, one for each page directory entry */ | ||
| 672 | struct radeon_sa_bo **page_tables; | ||
| 673 | |||
| 669 | struct mutex mutex; | 674 | struct mutex mutex; |
| 670 | /* last fence for cs using this vm */ | 675 | /* last fence for cs using this vm */ |
| 671 | struct radeon_fence *fence; | 676 | struct radeon_fence *fence; |
| @@ -1843,9 +1848,10 @@ extern void radeon_ttm_set_active_vram_size(struct radeon_device *rdev, u64 size | |||
| 1843 | */ | 1848 | */ |
| 1844 | int radeon_vm_manager_init(struct radeon_device *rdev); | 1849 | int radeon_vm_manager_init(struct radeon_device *rdev); |
| 1845 | void radeon_vm_manager_fini(struct radeon_device *rdev); | 1850 | void radeon_vm_manager_fini(struct radeon_device *rdev); |
| 1846 | int radeon_vm_init(struct radeon_device *rdev, struct radeon_vm *vm); | 1851 | void radeon_vm_init(struct radeon_device *rdev, struct radeon_vm *vm); |
| 1847 | void radeon_vm_fini(struct radeon_device *rdev, struct radeon_vm *vm); | 1852 | void radeon_vm_fini(struct radeon_device *rdev, struct radeon_vm *vm); |
| 1848 | int radeon_vm_alloc_pt(struct radeon_device *rdev, struct radeon_vm *vm); | 1853 | int radeon_vm_alloc_pt(struct radeon_device *rdev, struct radeon_vm *vm); |
| 1854 | void radeon_vm_add_to_lru(struct radeon_device *rdev, struct radeon_vm *vm); | ||
| 1849 | struct radeon_fence *radeon_vm_grab_id(struct radeon_device *rdev, | 1855 | struct radeon_fence *radeon_vm_grab_id(struct radeon_device *rdev, |
| 1850 | struct radeon_vm *vm, int ring); | 1856 | struct radeon_vm *vm, int ring); |
| 1851 | void radeon_vm_fence(struct radeon_device *rdev, | 1857 | void radeon_vm_fence(struct radeon_device *rdev, |
diff --git a/drivers/gpu/drm/radeon/radeon_acpi.c b/drivers/gpu/drm/radeon/radeon_acpi.c index b0a5688c67f8..196d28d99570 100644 --- a/drivers/gpu/drm/radeon/radeon_acpi.c +++ b/drivers/gpu/drm/radeon/radeon_acpi.c | |||
| @@ -201,7 +201,7 @@ static int radeon_atif_verify_interface(acpi_handle handle, | |||
| 201 | 201 | ||
| 202 | size = *(u16 *) info->buffer.pointer; | 202 | size = *(u16 *) info->buffer.pointer; |
| 203 | if (size < 12) { | 203 | if (size < 12) { |
| 204 | DRM_INFO("ATIF buffer is too small: %lu\n", size); | 204 | DRM_INFO("ATIF buffer is too small: %zu\n", size); |
| 205 | err = -EINVAL; | 205 | err = -EINVAL; |
| 206 | goto out; | 206 | goto out; |
| 207 | } | 207 | } |
| @@ -370,6 +370,7 @@ int radeon_atif_handler(struct radeon_device *rdev, | |||
| 370 | 370 | ||
| 371 | radeon_set_backlight_level(rdev, enc, req.backlight_level); | 371 | radeon_set_backlight_level(rdev, enc, req.backlight_level); |
| 372 | 372 | ||
| 373 | #if defined(CONFIG_BACKLIGHT_CLASS_DEVICE) || defined(CONFIG_BACKLIGHT_CLASS_DEVICE_MODULE) | ||
| 373 | if (rdev->is_atom_bios) { | 374 | if (rdev->is_atom_bios) { |
| 374 | struct radeon_encoder_atom_dig *dig = enc->enc_priv; | 375 | struct radeon_encoder_atom_dig *dig = enc->enc_priv; |
| 375 | backlight_force_update(dig->bl_dev, | 376 | backlight_force_update(dig->bl_dev, |
| @@ -379,6 +380,7 @@ int radeon_atif_handler(struct radeon_device *rdev, | |||
| 379 | backlight_force_update(dig->bl_dev, | 380 | backlight_force_update(dig->bl_dev, |
| 380 | BACKLIGHT_UPDATE_HOTKEY); | 381 | BACKLIGHT_UPDATE_HOTKEY); |
| 381 | } | 382 | } |
| 383 | #endif | ||
| 382 | } | 384 | } |
| 383 | } | 385 | } |
| 384 | /* TODO: check other events */ | 386 | /* TODO: check other events */ |
| @@ -485,7 +487,7 @@ static int radeon_atcs_verify_interface(acpi_handle handle, | |||
| 485 | 487 | ||
| 486 | size = *(u16 *) info->buffer.pointer; | 488 | size = *(u16 *) info->buffer.pointer; |
| 487 | if (size < 8) { | 489 | if (size < 8) { |
| 488 | DRM_INFO("ATCS buffer is too small: %lu\n", size); | 490 | DRM_INFO("ATCS buffer is too small: %zu\n", size); |
| 489 | err = -EINVAL; | 491 | err = -EINVAL; |
| 490 | goto out; | 492 | goto out; |
| 491 | } | 493 | } |
diff --git a/drivers/gpu/drm/radeon/radeon_agp.c b/drivers/gpu/drm/radeon/radeon_agp.c index 10ea17a6b2a6..42433344cb1b 100644 --- a/drivers/gpu/drm/radeon/radeon_agp.c +++ b/drivers/gpu/drm/radeon/radeon_agp.c | |||
| @@ -69,9 +69,12 @@ static struct radeon_agpmode_quirk radeon_agpmode_quirk_list[] = { | |||
| 69 | /* Intel 82830 830 Chipset Host Bridge / Mobility M6 LY Needs AGPMode 2 (fdo #17360)*/ | 69 | /* Intel 82830 830 Chipset Host Bridge / Mobility M6 LY Needs AGPMode 2 (fdo #17360)*/ |
| 70 | { PCI_VENDOR_ID_INTEL, 0x3575, PCI_VENDOR_ID_ATI, 0x4c59, | 70 | { PCI_VENDOR_ID_INTEL, 0x3575, PCI_VENDOR_ID_ATI, 0x4c59, |
| 71 | PCI_VENDOR_ID_DELL, 0x00e3, 2}, | 71 | PCI_VENDOR_ID_DELL, 0x00e3, 2}, |
| 72 | /* Intel 82852/82855 host bridge / Mobility FireGL 9000 R250 Needs AGPMode 1 (lp #296617) */ | 72 | /* Intel 82852/82855 host bridge / Mobility FireGL 9000 RV250 Needs AGPMode 1 (lp #296617) */ |
| 73 | { PCI_VENDOR_ID_INTEL, 0x3580, PCI_VENDOR_ID_ATI, 0x4c66, | 73 | { PCI_VENDOR_ID_INTEL, 0x3580, PCI_VENDOR_ID_ATI, 0x4c66, |
| 74 | PCI_VENDOR_ID_DELL, 0x0149, 1}, | 74 | PCI_VENDOR_ID_DELL, 0x0149, 1}, |
| 75 | /* Intel 82855PM host bridge / Mobility FireGL 9000 RV250 Needs AGPMode 1 for suspend/resume */ | ||
| 76 | { PCI_VENDOR_ID_INTEL, 0x3340, PCI_VENDOR_ID_ATI, 0x4c66, | ||
| 77 | PCI_VENDOR_ID_IBM, 0x0531, 1}, | ||
| 75 | /* Intel 82852/82855 host bridge / Mobility 9600 M10 RV350 Needs AGPMode 1 (deb #467460) */ | 78 | /* Intel 82852/82855 host bridge / Mobility 9600 M10 RV350 Needs AGPMode 1 (deb #467460) */ |
| 76 | { PCI_VENDOR_ID_INTEL, 0x3580, PCI_VENDOR_ID_ATI, 0x4e50, | 79 | { PCI_VENDOR_ID_INTEL, 0x3580, PCI_VENDOR_ID_ATI, 0x4e50, |
| 77 | 0x1025, 0x0061, 1}, | 80 | 0x1025, 0x0061, 1}, |
diff --git a/drivers/gpu/drm/radeon/radeon_atpx_handler.c b/drivers/gpu/drm/radeon/radeon_atpx_handler.c index 582e99449c12..15f5ded65e0c 100644 --- a/drivers/gpu/drm/radeon/radeon_atpx_handler.c +++ b/drivers/gpu/drm/radeon/radeon_atpx_handler.c | |||
| @@ -87,7 +87,7 @@ static union acpi_object *radeon_atpx_call(acpi_handle handle, int function, | |||
| 87 | atpx_arg_elements[1].integer.value = 0; | 87 | atpx_arg_elements[1].integer.value = 0; |
| 88 | } | 88 | } |
| 89 | 89 | ||
| 90 | status = acpi_evaluate_object(handle, "ATPX", &atpx_arg, &buffer); | 90 | status = acpi_evaluate_object(handle, NULL, &atpx_arg, &buffer); |
| 91 | 91 | ||
| 92 | /* Fail only if calling the method fails and ATPX is supported */ | 92 | /* Fail only if calling the method fails and ATPX is supported */ |
| 93 | if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) { | 93 | if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) { |
| @@ -148,7 +148,7 @@ static int radeon_atpx_verify_interface(struct radeon_atpx *atpx) | |||
| 148 | 148 | ||
| 149 | size = *(u16 *) info->buffer.pointer; | 149 | size = *(u16 *) info->buffer.pointer; |
| 150 | if (size < 8) { | 150 | if (size < 8) { |
| 151 | printk("ATPX buffer is too small: %lu\n", size); | 151 | printk("ATPX buffer is too small: %zu\n", size); |
| 152 | err = -EINVAL; | 152 | err = -EINVAL; |
| 153 | goto out; | 153 | goto out; |
| 154 | } | 154 | } |
| @@ -352,9 +352,9 @@ static int radeon_atpx_switchto(enum vga_switcheroo_client_id id) | |||
| 352 | } | 352 | } |
| 353 | 353 | ||
| 354 | /** | 354 | /** |
| 355 | * radeon_atpx_switchto - switch to the requested GPU | 355 | * radeon_atpx_power_state - power down/up the requested GPU |
| 356 | * | 356 | * |
| 357 | * @id: GPU to switch to | 357 | * @id: GPU to power down/up |
| 358 | * @state: requested power state (0 = off, 1 = on) | 358 | * @state: requested power state (0 = off, 1 = on) |
| 359 | * | 359 | * |
| 360 | * Execute the necessary ATPX function to power down/up the discrete GPU | 360 | * Execute the necessary ATPX function to power down/up the discrete GPU |
| @@ -373,11 +373,11 @@ static int radeon_atpx_power_state(enum vga_switcheroo_client_id id, | |||
| 373 | } | 373 | } |
| 374 | 374 | ||
| 375 | /** | 375 | /** |
| 376 | * radeon_atpx_pci_probe_handle - look up the ATRM and ATPX handles | 376 | * radeon_atpx_pci_probe_handle - look up the ATPX handle |
| 377 | * | 377 | * |
| 378 | * @pdev: pci device | 378 | * @pdev: pci device |
| 379 | * | 379 | * |
| 380 | * Look up the ATPX and ATRM handles (all asics). | 380 | * Look up the ATPX handles (all asics). |
| 381 | * Returns true if the handles are found, false if not. | 381 | * Returns true if the handles are found, false if not. |
| 382 | */ | 382 | */ |
| 383 | static bool radeon_atpx_pci_probe_handle(struct pci_dev *pdev) | 383 | static bool radeon_atpx_pci_probe_handle(struct pci_dev *pdev) |
diff --git a/drivers/gpu/drm/radeon/radeon_connectors.c b/drivers/gpu/drm/radeon/radeon_connectors.c index 67cfc1795ecd..b884c362a8c2 100644 --- a/drivers/gpu/drm/radeon/radeon_connectors.c +++ b/drivers/gpu/drm/radeon/radeon_connectors.c | |||
| @@ -941,7 +941,7 @@ radeon_dvi_detect(struct drm_connector *connector, bool force) | |||
| 941 | struct drm_mode_object *obj; | 941 | struct drm_mode_object *obj; |
| 942 | int i; | 942 | int i; |
| 943 | enum drm_connector_status ret = connector_status_disconnected; | 943 | enum drm_connector_status ret = connector_status_disconnected; |
| 944 | bool dret = false; | 944 | bool dret = false, broken_edid = false; |
| 945 | 945 | ||
| 946 | if (!force && radeon_check_hpd_status_unchanged(connector)) | 946 | if (!force && radeon_check_hpd_status_unchanged(connector)) |
| 947 | return connector->status; | 947 | return connector->status; |
| @@ -965,6 +965,9 @@ radeon_dvi_detect(struct drm_connector *connector, bool force) | |||
| 965 | ret = connector_status_disconnected; | 965 | ret = connector_status_disconnected; |
| 966 | DRM_ERROR("%s: detected RS690 floating bus bug, stopping ddc detect\n", drm_get_connector_name(connector)); | 966 | DRM_ERROR("%s: detected RS690 floating bus bug, stopping ddc detect\n", drm_get_connector_name(connector)); |
| 967 | radeon_connector->ddc_bus = NULL; | 967 | radeon_connector->ddc_bus = NULL; |
| 968 | } else { | ||
| 969 | ret = connector_status_connected; | ||
| 970 | broken_edid = true; /* defer use_digital to later */ | ||
| 968 | } | 971 | } |
| 969 | } else { | 972 | } else { |
| 970 | radeon_connector->use_digital = !!(radeon_connector->edid->input & DRM_EDID_INPUT_DIGITAL); | 973 | radeon_connector->use_digital = !!(radeon_connector->edid->input & DRM_EDID_INPUT_DIGITAL); |
| @@ -1047,13 +1050,24 @@ radeon_dvi_detect(struct drm_connector *connector, bool force) | |||
| 1047 | 1050 | ||
| 1048 | encoder_funcs = encoder->helper_private; | 1051 | encoder_funcs = encoder->helper_private; |
| 1049 | if (encoder_funcs->detect) { | 1052 | if (encoder_funcs->detect) { |
| 1050 | if (ret != connector_status_connected) { | 1053 | if (!broken_edid) { |
| 1051 | ret = encoder_funcs->detect(encoder, connector); | 1054 | if (ret != connector_status_connected) { |
| 1052 | if (ret == connector_status_connected) { | 1055 | /* deal with analog monitors without DDC */ |
| 1053 | radeon_connector->use_digital = false; | 1056 | ret = encoder_funcs->detect(encoder, connector); |
| 1057 | if (ret == connector_status_connected) { | ||
| 1058 | radeon_connector->use_digital = false; | ||
| 1059 | } | ||
| 1060 | if (ret != connector_status_disconnected) | ||
| 1061 | radeon_connector->detected_by_load = true; | ||
| 1054 | } | 1062 | } |
| 1055 | if (ret != connector_status_disconnected) | 1063 | } else { |
| 1056 | radeon_connector->detected_by_load = true; | 1064 | enum drm_connector_status lret; |
| 1065 | /* assume digital unless load detected otherwise */ | ||
| 1066 | radeon_connector->use_digital = true; | ||
| 1067 | lret = encoder_funcs->detect(encoder, connector); | ||
| 1068 | DRM_DEBUG_KMS("load_detect %x returned: %x\n",encoder->encoder_type,lret); | ||
| 1069 | if (lret == connector_status_connected) | ||
| 1070 | radeon_connector->use_digital = false; | ||
| 1057 | } | 1071 | } |
| 1058 | break; | 1072 | break; |
| 1059 | } | 1073 | } |
diff --git a/drivers/gpu/drm/radeon/radeon_cs.c b/drivers/gpu/drm/radeon/radeon_cs.c index cb7b7c062fef..41672cc563fb 100644 --- a/drivers/gpu/drm/radeon/radeon_cs.c +++ b/drivers/gpu/drm/radeon/radeon_cs.c | |||
| @@ -478,6 +478,7 @@ static int radeon_cs_ib_vm_chunk(struct radeon_device *rdev, | |||
| 478 | } | 478 | } |
| 479 | 479 | ||
| 480 | out: | 480 | out: |
| 481 | radeon_vm_add_to_lru(rdev, vm); | ||
| 481 | mutex_unlock(&vm->mutex); | 482 | mutex_unlock(&vm->mutex); |
| 482 | mutex_unlock(&rdev->vm_manager.lock); | 483 | mutex_unlock(&rdev->vm_manager.lock); |
| 483 | return r; | 484 | return r; |
diff --git a/drivers/gpu/drm/radeon/radeon_device.c b/drivers/gpu/drm/radeon/radeon_device.c index 64a42647f08a..e2f5f888c374 100644 --- a/drivers/gpu/drm/radeon/radeon_device.c +++ b/drivers/gpu/drm/radeon/radeon_device.c | |||
| @@ -355,6 +355,8 @@ int radeon_wb_init(struct radeon_device *rdev) | |||
| 355 | */ | 355 | */ |
| 356 | void radeon_vram_location(struct radeon_device *rdev, struct radeon_mc *mc, u64 base) | 356 | void radeon_vram_location(struct radeon_device *rdev, struct radeon_mc *mc, u64 base) |
| 357 | { | 357 | { |
| 358 | uint64_t limit = (uint64_t)radeon_vram_limit << 20; | ||
| 359 | |||
| 358 | mc->vram_start = base; | 360 | mc->vram_start = base; |
| 359 | if (mc->mc_vram_size > (0xFFFFFFFF - base + 1)) { | 361 | if (mc->mc_vram_size > (0xFFFFFFFF - base + 1)) { |
| 360 | dev_warn(rdev->dev, "limiting VRAM to PCI aperture size\n"); | 362 | dev_warn(rdev->dev, "limiting VRAM to PCI aperture size\n"); |
| @@ -368,8 +370,8 @@ void radeon_vram_location(struct radeon_device *rdev, struct radeon_mc *mc, u64 | |||
| 368 | mc->mc_vram_size = mc->aper_size; | 370 | mc->mc_vram_size = mc->aper_size; |
| 369 | } | 371 | } |
| 370 | mc->vram_end = mc->vram_start + mc->mc_vram_size - 1; | 372 | mc->vram_end = mc->vram_start + mc->mc_vram_size - 1; |
| 371 | if (radeon_vram_limit && radeon_vram_limit < mc->real_vram_size) | 373 | if (limit && limit < mc->real_vram_size) |
| 372 | mc->real_vram_size = radeon_vram_limit; | 374 | mc->real_vram_size = limit; |
| 373 | dev_info(rdev->dev, "VRAM: %lluM 0x%016llX - 0x%016llX (%lluM used)\n", | 375 | dev_info(rdev->dev, "VRAM: %lluM 0x%016llX - 0x%016llX (%lluM used)\n", |
| 374 | mc->mc_vram_size >> 20, mc->vram_start, | 376 | mc->mc_vram_size >> 20, mc->vram_start, |
| 375 | mc->vram_end, mc->real_vram_size >> 20); | 377 | mc->vram_end, mc->real_vram_size >> 20); |
| @@ -835,6 +837,19 @@ static unsigned int radeon_vga_set_decode(void *cookie, bool state) | |||
| 835 | } | 837 | } |
| 836 | 838 | ||
| 837 | /** | 839 | /** |
| 840 | * radeon_check_pot_argument - check that argument is a power of two | ||
| 841 | * | ||
| 842 | * @arg: value to check | ||
| 843 | * | ||
| 844 | * Validates that a certain argument is a power of two (all asics). | ||
| 845 | * Returns true if argument is valid. | ||
| 846 | */ | ||
| 847 | static bool radeon_check_pot_argument(int arg) | ||
| 848 | { | ||
| 849 | return (arg & (arg - 1)) == 0; | ||
| 850 | } | ||
| 851 | |||
| 852 | /** | ||
| 838 | * radeon_check_arguments - validate module params | 853 | * radeon_check_arguments - validate module params |
| 839 | * | 854 | * |
| 840 | * @rdev: radeon_device pointer | 855 | * @rdev: radeon_device pointer |
| @@ -845,52 +860,25 @@ static unsigned int radeon_vga_set_decode(void *cookie, bool state) | |||
| 845 | static void radeon_check_arguments(struct radeon_device *rdev) | 860 | static void radeon_check_arguments(struct radeon_device *rdev) |
| 846 | { | 861 | { |
| 847 | /* vramlimit must be a power of two */ | 862 | /* vramlimit must be a power of two */ |
| 848 | switch (radeon_vram_limit) { | 863 | if (!radeon_check_pot_argument(radeon_vram_limit)) { |
| 849 | case 0: | ||
| 850 | case 4: | ||
| 851 | case 8: | ||
| 852 | case 16: | ||
| 853 | case 32: | ||
| 854 | case 64: | ||
| 855 | case 128: | ||
| 856 | case 256: | ||
| 857 | case 512: | ||
| 858 | case 1024: | ||
| 859 | case 2048: | ||
| 860 | case 4096: | ||
| 861 | break; | ||
| 862 | default: | ||
| 863 | dev_warn(rdev->dev, "vram limit (%d) must be a power of 2\n", | 864 | dev_warn(rdev->dev, "vram limit (%d) must be a power of 2\n", |
| 864 | radeon_vram_limit); | 865 | radeon_vram_limit); |
| 865 | radeon_vram_limit = 0; | 866 | radeon_vram_limit = 0; |
| 866 | break; | ||
| 867 | } | 867 | } |
| 868 | radeon_vram_limit = radeon_vram_limit << 20; | 868 | |
| 869 | /* gtt size must be power of two and greater or equal to 32M */ | 869 | /* gtt size must be power of two and greater or equal to 32M */ |
| 870 | switch (radeon_gart_size) { | 870 | if (radeon_gart_size < 32) { |
| 871 | case 4: | ||
| 872 | case 8: | ||
| 873 | case 16: | ||
| 874 | dev_warn(rdev->dev, "gart size (%d) too small forcing to 512M\n", | 871 | dev_warn(rdev->dev, "gart size (%d) too small forcing to 512M\n", |
| 875 | radeon_gart_size); | 872 | radeon_gart_size); |
| 876 | radeon_gart_size = 512; | 873 | radeon_gart_size = 512; |
| 877 | break; | 874 | |
| 878 | case 32: | 875 | } else if (!radeon_check_pot_argument(radeon_gart_size)) { |
| 879 | case 64: | ||
| 880 | case 128: | ||
| 881 | case 256: | ||
| 882 | case 512: | ||
| 883 | case 1024: | ||
| 884 | case 2048: | ||
| 885 | case 4096: | ||
| 886 | break; | ||
| 887 | default: | ||
| 888 | dev_warn(rdev->dev, "gart size (%d) must be a power of 2\n", | 876 | dev_warn(rdev->dev, "gart size (%d) must be a power of 2\n", |
| 889 | radeon_gart_size); | 877 | radeon_gart_size); |
| 890 | radeon_gart_size = 512; | 878 | radeon_gart_size = 512; |
| 891 | break; | ||
| 892 | } | 879 | } |
| 893 | rdev->mc.gtt_size = radeon_gart_size * 1024 * 1024; | 880 | rdev->mc.gtt_size = (uint64_t)radeon_gart_size << 20; |
| 881 | |||
| 894 | /* AGP mode can only be -1, 1, 2, 4, 8 */ | 882 | /* AGP mode can only be -1, 1, 2, 4, 8 */ |
| 895 | switch (radeon_agpmode) { | 883 | switch (radeon_agpmode) { |
| 896 | case -1: | 884 | case -1: |
| @@ -1018,6 +1006,10 @@ int radeon_device_init(struct radeon_device *rdev, | |||
| 1018 | return r; | 1006 | return r; |
| 1019 | /* initialize vm here */ | 1007 | /* initialize vm here */ |
| 1020 | mutex_init(&rdev->vm_manager.lock); | 1008 | mutex_init(&rdev->vm_manager.lock); |
| 1009 | /* Adjust VM size here. | ||
| 1010 | * Currently set to 4GB ((1 << 20) 4k pages). | ||
| 1011 | * Max GPUVM size for cayman and SI is 40 bits. | ||
| 1012 | */ | ||
| 1021 | rdev->vm_manager.max_pfn = 1 << 20; | 1013 | rdev->vm_manager.max_pfn = 1 << 20; |
| 1022 | INIT_LIST_HEAD(&rdev->vm_manager.lru_vm); | 1014 | INIT_LIST_HEAD(&rdev->vm_manager.lru_vm); |
| 1023 | 1015 | ||
diff --git a/drivers/gpu/drm/radeon/radeon_gart.c b/drivers/gpu/drm/radeon/radeon_gart.c index f0c06d196b75..4debd60e5aa6 100644 --- a/drivers/gpu/drm/radeon/radeon_gart.c +++ b/drivers/gpu/drm/radeon/radeon_gart.c | |||
| @@ -355,14 +355,13 @@ int radeon_gart_init(struct radeon_device *rdev) | |||
| 355 | DRM_INFO("GART: num cpu pages %u, num gpu pages %u\n", | 355 | DRM_INFO("GART: num cpu pages %u, num gpu pages %u\n", |
| 356 | rdev->gart.num_cpu_pages, rdev->gart.num_gpu_pages); | 356 | rdev->gart.num_cpu_pages, rdev->gart.num_gpu_pages); |
| 357 | /* Allocate pages table */ | 357 | /* Allocate pages table */ |
| 358 | rdev->gart.pages = kzalloc(sizeof(void *) * rdev->gart.num_cpu_pages, | 358 | rdev->gart.pages = vzalloc(sizeof(void *) * rdev->gart.num_cpu_pages); |
| 359 | GFP_KERNEL); | ||
| 360 | if (rdev->gart.pages == NULL) { | 359 | if (rdev->gart.pages == NULL) { |
| 361 | radeon_gart_fini(rdev); | 360 | radeon_gart_fini(rdev); |
| 362 | return -ENOMEM; | 361 | return -ENOMEM; |
| 363 | } | 362 | } |
| 364 | rdev->gart.pages_addr = kzalloc(sizeof(dma_addr_t) * | 363 | rdev->gart.pages_addr = vzalloc(sizeof(dma_addr_t) * |
| 365 | rdev->gart.num_cpu_pages, GFP_KERNEL); | 364 | rdev->gart.num_cpu_pages); |
| 366 | if (rdev->gart.pages_addr == NULL) { | 365 | if (rdev->gart.pages_addr == NULL) { |
| 367 | radeon_gart_fini(rdev); | 366 | radeon_gart_fini(rdev); |
| 368 | return -ENOMEM; | 367 | return -ENOMEM; |
| @@ -388,8 +387,8 @@ void radeon_gart_fini(struct radeon_device *rdev) | |||
| 388 | radeon_gart_unbind(rdev, 0, rdev->gart.num_cpu_pages); | 387 | radeon_gart_unbind(rdev, 0, rdev->gart.num_cpu_pages); |
| 389 | } | 388 | } |
| 390 | rdev->gart.ready = false; | 389 | rdev->gart.ready = false; |
| 391 | kfree(rdev->gart.pages); | 390 | vfree(rdev->gart.pages); |
| 392 | kfree(rdev->gart.pages_addr); | 391 | vfree(rdev->gart.pages_addr); |
| 393 | rdev->gart.pages = NULL; | 392 | rdev->gart.pages = NULL; |
| 394 | rdev->gart.pages_addr = NULL; | 393 | rdev->gart.pages_addr = NULL; |
| 395 | 394 | ||
| @@ -423,6 +422,18 @@ void radeon_gart_fini(struct radeon_device *rdev) | |||
| 423 | */ | 422 | */ |
| 424 | 423 | ||
| 425 | /** | 424 | /** |
| 425 | * radeon_vm_num_pde - return the number of page directory entries | ||
| 426 | * | ||
| 427 | * @rdev: radeon_device pointer | ||
| 428 | * | ||
| 429 | * Calculate the number of page directory entries (cayman+). | ||
| 430 | */ | ||
| 431 | static unsigned radeon_vm_num_pdes(struct radeon_device *rdev) | ||
| 432 | { | ||
| 433 | return rdev->vm_manager.max_pfn >> RADEON_VM_BLOCK_SIZE; | ||
| 434 | } | ||
| 435 | |||
| 436 | /** | ||
| 426 | * radeon_vm_directory_size - returns the size of the page directory in bytes | 437 | * radeon_vm_directory_size - returns the size of the page directory in bytes |
| 427 | * | 438 | * |
| 428 | * @rdev: radeon_device pointer | 439 | * @rdev: radeon_device pointer |
| @@ -431,7 +442,7 @@ void radeon_gart_fini(struct radeon_device *rdev) | |||
| 431 | */ | 442 | */ |
| 432 | static unsigned radeon_vm_directory_size(struct radeon_device *rdev) | 443 | static unsigned radeon_vm_directory_size(struct radeon_device *rdev) |
| 433 | { | 444 | { |
| 434 | return (rdev->vm_manager.max_pfn >> RADEON_VM_BLOCK_SIZE) * 8; | 445 | return RADEON_GPU_PAGE_ALIGN(radeon_vm_num_pdes(rdev) * 8); |
| 435 | } | 446 | } |
| 436 | 447 | ||
| 437 | /** | 448 | /** |
| @@ -451,11 +462,11 @@ int radeon_vm_manager_init(struct radeon_device *rdev) | |||
| 451 | 462 | ||
| 452 | if (!rdev->vm_manager.enabled) { | 463 | if (!rdev->vm_manager.enabled) { |
| 453 | /* allocate enough for 2 full VM pts */ | 464 | /* allocate enough for 2 full VM pts */ |
| 454 | size = RADEON_GPU_PAGE_ALIGN(radeon_vm_directory_size(rdev)); | 465 | size = radeon_vm_directory_size(rdev); |
| 455 | size += RADEON_GPU_PAGE_ALIGN(rdev->vm_manager.max_pfn * 8); | 466 | size += rdev->vm_manager.max_pfn * 8; |
| 456 | size *= 2; | 467 | size *= 2; |
| 457 | r = radeon_sa_bo_manager_init(rdev, &rdev->vm_manager.sa_manager, | 468 | r = radeon_sa_bo_manager_init(rdev, &rdev->vm_manager.sa_manager, |
| 458 | size, | 469 | RADEON_GPU_PAGE_ALIGN(size), |
| 459 | RADEON_GEM_DOMAIN_VRAM); | 470 | RADEON_GEM_DOMAIN_VRAM); |
| 460 | if (r) { | 471 | if (r) { |
| 461 | dev_err(rdev->dev, "failed to allocate vm bo (%dKB)\n", | 472 | dev_err(rdev->dev, "failed to allocate vm bo (%dKB)\n", |
| @@ -476,7 +487,7 @@ int radeon_vm_manager_init(struct radeon_device *rdev) | |||
| 476 | 487 | ||
| 477 | /* restore page table */ | 488 | /* restore page table */ |
| 478 | list_for_each_entry(vm, &rdev->vm_manager.lru_vm, list) { | 489 | list_for_each_entry(vm, &rdev->vm_manager.lru_vm, list) { |
| 479 | if (vm->sa_bo == NULL) | 490 | if (vm->page_directory == NULL) |
| 480 | continue; | 491 | continue; |
| 481 | 492 | ||
| 482 | list_for_each_entry(bo_va, &vm->va, vm_list) { | 493 | list_for_each_entry(bo_va, &vm->va, vm_list) { |
| @@ -500,16 +511,25 @@ static void radeon_vm_free_pt(struct radeon_device *rdev, | |||
| 500 | struct radeon_vm *vm) | 511 | struct radeon_vm *vm) |
| 501 | { | 512 | { |
| 502 | struct radeon_bo_va *bo_va; | 513 | struct radeon_bo_va *bo_va; |
| 514 | int i; | ||
| 503 | 515 | ||
| 504 | if (!vm->sa_bo) | 516 | if (!vm->page_directory) |
| 505 | return; | 517 | return; |
| 506 | 518 | ||
| 507 | list_del_init(&vm->list); | 519 | list_del_init(&vm->list); |
| 508 | radeon_sa_bo_free(rdev, &vm->sa_bo, vm->fence); | 520 | radeon_sa_bo_free(rdev, &vm->page_directory, vm->fence); |
| 509 | 521 | ||
| 510 | list_for_each_entry(bo_va, &vm->va, vm_list) { | 522 | list_for_each_entry(bo_va, &vm->va, vm_list) { |
| 511 | bo_va->valid = false; | 523 | bo_va->valid = false; |
| 512 | } | 524 | } |
| 525 | |||
| 526 | if (vm->page_tables == NULL) | ||
| 527 | return; | ||
| 528 | |||
| 529 | for (i = 0; i < radeon_vm_num_pdes(rdev); i++) | ||
| 530 | radeon_sa_bo_free(rdev, &vm->page_tables[i], vm->fence); | ||
| 531 | |||
| 532 | kfree(vm->page_tables); | ||
| 513 | } | 533 | } |
| 514 | 534 | ||
| 515 | /** | 535 | /** |
| @@ -546,63 +566,106 @@ void radeon_vm_manager_fini(struct radeon_device *rdev) | |||
| 546 | } | 566 | } |
| 547 | 567 | ||
| 548 | /** | 568 | /** |
| 569 | * radeon_vm_evict - evict page table to make room for new one | ||
| 570 | * | ||
| 571 | * @rdev: radeon_device pointer | ||
| 572 | * @vm: VM we want to allocate something for | ||
| 573 | * | ||
| 574 | * Evict a VM from the lru, making sure that it isn't @vm. (cayman+). | ||
| 575 | * Returns 0 for success, -ENOMEM for failure. | ||
| 576 | * | ||
| 577 | * Global and local mutex must be locked! | ||
| 578 | */ | ||
| 579 | static int radeon_vm_evict(struct radeon_device *rdev, struct radeon_vm *vm) | ||
| 580 | { | ||
| 581 | struct radeon_vm *vm_evict; | ||
| 582 | |||
| 583 | if (list_empty(&rdev->vm_manager.lru_vm)) | ||
| 584 | return -ENOMEM; | ||
| 585 | |||
| 586 | vm_evict = list_first_entry(&rdev->vm_manager.lru_vm, | ||
| 587 | struct radeon_vm, list); | ||
| 588 | if (vm_evict == vm) | ||
| 589 | return -ENOMEM; | ||
| 590 | |||
| 591 | mutex_lock(&vm_evict->mutex); | ||
| 592 | radeon_vm_free_pt(rdev, vm_evict); | ||
| 593 | mutex_unlock(&vm_evict->mutex); | ||
| 594 | return 0; | ||
| 595 | } | ||
| 596 | |||
| 597 | /** | ||
| 549 | * radeon_vm_alloc_pt - allocates a page table for a VM | 598 | * radeon_vm_alloc_pt - allocates a page table for a VM |
| 550 | * | 599 | * |
| 551 | * @rdev: radeon_device pointer | 600 | * @rdev: radeon_device pointer |
| 552 | * @vm: vm to bind | 601 | * @vm: vm to bind |
| 553 | * | 602 | * |
| 554 | * Allocate a page table for the requested vm (cayman+). | 603 | * Allocate a page table for the requested vm (cayman+). |
| 555 | * Also starts to populate the page table. | ||
| 556 | * Returns 0 for success, error for failure. | 604 | * Returns 0 for success, error for failure. |
| 557 | * | 605 | * |
| 558 | * Global and local mutex must be locked! | 606 | * Global and local mutex must be locked! |
| 559 | */ | 607 | */ |
| 560 | int radeon_vm_alloc_pt(struct radeon_device *rdev, struct radeon_vm *vm) | 608 | int radeon_vm_alloc_pt(struct radeon_device *rdev, struct radeon_vm *vm) |
| 561 | { | 609 | { |
| 562 | struct radeon_vm *vm_evict; | 610 | unsigned pd_size, pts_size; |
| 563 | int r; | ||
| 564 | u64 *pd_addr; | 611 | u64 *pd_addr; |
| 565 | int tables_size; | 612 | int r; |
| 566 | 613 | ||
| 567 | if (vm == NULL) { | 614 | if (vm == NULL) { |
| 568 | return -EINVAL; | 615 | return -EINVAL; |
| 569 | } | 616 | } |
| 570 | 617 | ||
| 571 | /* allocate enough to cover the current VM size */ | 618 | if (vm->page_directory != NULL) { |
| 572 | tables_size = RADEON_GPU_PAGE_ALIGN(radeon_vm_directory_size(rdev)); | ||
| 573 | tables_size += RADEON_GPU_PAGE_ALIGN(vm->last_pfn * 8); | ||
| 574 | |||
| 575 | if (vm->sa_bo != NULL) { | ||
| 576 | /* update lru */ | ||
| 577 | list_del_init(&vm->list); | ||
| 578 | list_add_tail(&vm->list, &rdev->vm_manager.lru_vm); | ||
| 579 | return 0; | 619 | return 0; |
| 580 | } | 620 | } |
| 581 | 621 | ||
| 582 | retry: | 622 | retry: |
| 583 | r = radeon_sa_bo_new(rdev, &rdev->vm_manager.sa_manager, &vm->sa_bo, | 623 | pd_size = RADEON_GPU_PAGE_ALIGN(radeon_vm_directory_size(rdev)); |
| 584 | tables_size, RADEON_GPU_PAGE_SIZE, false); | 624 | r = radeon_sa_bo_new(rdev, &rdev->vm_manager.sa_manager, |
| 625 | &vm->page_directory, pd_size, | ||
| 626 | RADEON_GPU_PAGE_SIZE, false); | ||
| 585 | if (r == -ENOMEM) { | 627 | if (r == -ENOMEM) { |
| 586 | if (list_empty(&rdev->vm_manager.lru_vm)) { | 628 | r = radeon_vm_evict(rdev, vm); |
| 629 | if (r) | ||
| 587 | return r; | 630 | return r; |
| 588 | } | ||
| 589 | vm_evict = list_first_entry(&rdev->vm_manager.lru_vm, struct radeon_vm, list); | ||
| 590 | mutex_lock(&vm_evict->mutex); | ||
| 591 | radeon_vm_free_pt(rdev, vm_evict); | ||
| 592 | mutex_unlock(&vm_evict->mutex); | ||
| 593 | goto retry; | 631 | goto retry; |
| 594 | 632 | ||
| 595 | } else if (r) { | 633 | } else if (r) { |
| 596 | return r; | 634 | return r; |
| 597 | } | 635 | } |
| 598 | 636 | ||
| 599 | pd_addr = radeon_sa_bo_cpu_addr(vm->sa_bo); | 637 | vm->pd_gpu_addr = radeon_sa_bo_gpu_addr(vm->page_directory); |
| 600 | vm->pd_gpu_addr = radeon_sa_bo_gpu_addr(vm->sa_bo); | 638 | |
| 601 | memset(pd_addr, 0, tables_size); | 639 | /* Initially clear the page directory */ |
| 640 | pd_addr = radeon_sa_bo_cpu_addr(vm->page_directory); | ||
| 641 | memset(pd_addr, 0, pd_size); | ||
| 642 | |||
| 643 | pts_size = radeon_vm_num_pdes(rdev) * sizeof(struct radeon_sa_bo *); | ||
| 644 | vm->page_tables = kzalloc(pts_size, GFP_KERNEL); | ||
| 645 | |||
| 646 | if (vm->page_tables == NULL) { | ||
| 647 | DRM_ERROR("Cannot allocate memory for page table array\n"); | ||
| 648 | radeon_sa_bo_free(rdev, &vm->page_directory, vm->fence); | ||
| 649 | return -ENOMEM; | ||
| 650 | } | ||
| 651 | |||
| 652 | return 0; | ||
| 653 | } | ||
| 602 | 654 | ||
| 655 | /** | ||
| 656 | * radeon_vm_add_to_lru - add VMs page table to LRU list | ||
| 657 | * | ||
| 658 | * @rdev: radeon_device pointer | ||
| 659 | * @vm: vm to add to LRU | ||
| 660 | * | ||
| 661 | * Add the allocated page table to the LRU list (cayman+). | ||
| 662 | * | ||
| 663 | * Global mutex must be locked! | ||
| 664 | */ | ||
| 665 | void radeon_vm_add_to_lru(struct radeon_device *rdev, struct radeon_vm *vm) | ||
| 666 | { | ||
| 667 | list_del_init(&vm->list); | ||
| 603 | list_add_tail(&vm->list, &rdev->vm_manager.lru_vm); | 668 | list_add_tail(&vm->list, &rdev->vm_manager.lru_vm); |
| 604 | return radeon_vm_bo_update_pte(rdev, vm, rdev->ring_tmp_bo.bo, | ||
| 605 | &rdev->ring_tmp_bo.bo->tbo.mem); | ||
| 606 | } | 669 | } |
| 607 | 670 | ||
| 608 | /** | 671 | /** |
| @@ -793,20 +856,6 @@ int radeon_vm_bo_set_addr(struct radeon_device *rdev, | |||
| 793 | } | 856 | } |
| 794 | 857 | ||
| 795 | mutex_lock(&vm->mutex); | 858 | mutex_lock(&vm->mutex); |
| 796 | if (last_pfn > vm->last_pfn) { | ||
| 797 | /* release mutex and lock in right order */ | ||
| 798 | mutex_unlock(&vm->mutex); | ||
| 799 | mutex_lock(&rdev->vm_manager.lock); | ||
| 800 | mutex_lock(&vm->mutex); | ||
| 801 | /* and check again */ | ||
| 802 | if (last_pfn > vm->last_pfn) { | ||
| 803 | /* grow va space 32M by 32M */ | ||
| 804 | unsigned align = ((32 << 20) >> 12) - 1; | ||
| 805 | radeon_vm_free_pt(rdev, vm); | ||
| 806 | vm->last_pfn = (last_pfn + align) & ~align; | ||
| 807 | } | ||
| 808 | mutex_unlock(&rdev->vm_manager.lock); | ||
| 809 | } | ||
| 810 | head = &vm->va; | 859 | head = &vm->va; |
| 811 | last_offset = 0; | 860 | last_offset = 0; |
| 812 | list_for_each_entry(tmp, &vm->va, vm_list) { | 861 | list_for_each_entry(tmp, &vm->va, vm_list) { |
| @@ -865,6 +914,154 @@ uint64_t radeon_vm_map_gart(struct radeon_device *rdev, uint64_t addr) | |||
| 865 | } | 914 | } |
| 866 | 915 | ||
| 867 | /** | 916 | /** |
| 917 | * radeon_vm_update_pdes - make sure that page directory is valid | ||
| 918 | * | ||
| 919 | * @rdev: radeon_device pointer | ||
| 920 | * @vm: requested vm | ||
| 921 | * @start: start of GPU address range | ||
| 922 | * @end: end of GPU address range | ||
| 923 | * | ||
| 924 | * Allocates new page tables if necessary | ||
| 925 | * and updates the page directory (cayman+). | ||
| 926 | * Returns 0 for success, error for failure. | ||
| 927 | * | ||
| 928 | * Global and local mutex must be locked! | ||
| 929 | */ | ||
| 930 | static int radeon_vm_update_pdes(struct radeon_device *rdev, | ||
| 931 | struct radeon_vm *vm, | ||
| 932 | uint64_t start, uint64_t end) | ||
| 933 | { | ||
| 934 | static const uint32_t incr = RADEON_VM_PTE_COUNT * 8; | ||
| 935 | |||
| 936 | uint64_t last_pde = ~0, last_pt = ~0; | ||
| 937 | unsigned count = 0; | ||
| 938 | uint64_t pt_idx; | ||
| 939 | int r; | ||
| 940 | |||
| 941 | start = (start / RADEON_GPU_PAGE_SIZE) >> RADEON_VM_BLOCK_SIZE; | ||
| 942 | end = (end / RADEON_GPU_PAGE_SIZE) >> RADEON_VM_BLOCK_SIZE; | ||
| 943 | |||
| 944 | /* walk over the address space and update the page directory */ | ||
| 945 | for (pt_idx = start; pt_idx <= end; ++pt_idx) { | ||
| 946 | uint64_t pde, pt; | ||
| 947 | |||
| 948 | if (vm->page_tables[pt_idx]) | ||
| 949 | continue; | ||
| 950 | |||
| 951 | retry: | ||
| 952 | r = radeon_sa_bo_new(rdev, &rdev->vm_manager.sa_manager, | ||
| 953 | &vm->page_tables[pt_idx], | ||
| 954 | RADEON_VM_PTE_COUNT * 8, | ||
| 955 | RADEON_GPU_PAGE_SIZE, false); | ||
| 956 | |||
| 957 | if (r == -ENOMEM) { | ||
| 958 | r = radeon_vm_evict(rdev, vm); | ||
| 959 | if (r) | ||
| 960 | return r; | ||
| 961 | goto retry; | ||
| 962 | } else if (r) { | ||
| 963 | return r; | ||
| 964 | } | ||
| 965 | |||
| 966 | pde = vm->pd_gpu_addr + pt_idx * 8; | ||
| 967 | |||
| 968 | pt = radeon_sa_bo_gpu_addr(vm->page_tables[pt_idx]); | ||
| 969 | |||
| 970 | if (((last_pde + 8 * count) != pde) || | ||
| 971 | ((last_pt + incr * count) != pt)) { | ||
| 972 | |||
| 973 | if (count) { | ||
| 974 | radeon_asic_vm_set_page(rdev, last_pde, | ||
| 975 | last_pt, count, incr, | ||
| 976 | RADEON_VM_PAGE_VALID); | ||
| 977 | } | ||
| 978 | |||
| 979 | count = 1; | ||
| 980 | last_pde = pde; | ||
| 981 | last_pt = pt; | ||
| 982 | } else { | ||
| 983 | ++count; | ||
| 984 | } | ||
| 985 | } | ||
| 986 | |||
| 987 | if (count) { | ||
| 988 | radeon_asic_vm_set_page(rdev, last_pde, last_pt, count, | ||
| 989 | incr, RADEON_VM_PAGE_VALID); | ||
| 990 | |||
| 991 | } | ||
| 992 | |||
| 993 | return 0; | ||
| 994 | } | ||
| 995 | |||
| 996 | /** | ||
| 997 | * radeon_vm_update_ptes - make sure that page tables are valid | ||
| 998 | * | ||
| 999 | * @rdev: radeon_device pointer | ||
| 1000 | * @vm: requested vm | ||
| 1001 | * @start: start of GPU address range | ||
| 1002 | * @end: end of GPU address range | ||
| 1003 | * @dst: destination address to map to | ||
| 1004 | * @flags: mapping flags | ||
| 1005 | * | ||
| 1006 | * Update the page tables in the range @start - @end (cayman+). | ||
| 1007 | * | ||
| 1008 | * Global and local mutex must be locked! | ||
| 1009 | */ | ||
| 1010 | static void radeon_vm_update_ptes(struct radeon_device *rdev, | ||
| 1011 | struct radeon_vm *vm, | ||
| 1012 | uint64_t start, uint64_t end, | ||
| 1013 | uint64_t dst, uint32_t flags) | ||
| 1014 | { | ||
| 1015 | static const uint64_t mask = RADEON_VM_PTE_COUNT - 1; | ||
| 1016 | |||
| 1017 | uint64_t last_pte = ~0, last_dst = ~0; | ||
| 1018 | unsigned count = 0; | ||
| 1019 | uint64_t addr; | ||
| 1020 | |||
| 1021 | start = start / RADEON_GPU_PAGE_SIZE; | ||
| 1022 | end = end / RADEON_GPU_PAGE_SIZE; | ||
| 1023 | |||
| 1024 | /* walk over the address space and update the page tables */ | ||
| 1025 | for (addr = start; addr < end; ) { | ||
| 1026 | uint64_t pt_idx = addr >> RADEON_VM_BLOCK_SIZE; | ||
| 1027 | unsigned nptes; | ||
| 1028 | uint64_t pte; | ||
| 1029 | |||
| 1030 | if ((addr & ~mask) == (end & ~mask)) | ||
| 1031 | nptes = end - addr; | ||
| 1032 | else | ||
| 1033 | nptes = RADEON_VM_PTE_COUNT - (addr & mask); | ||
| 1034 | |||
| 1035 | pte = radeon_sa_bo_gpu_addr(vm->page_tables[pt_idx]); | ||
| 1036 | pte += (addr & mask) * 8; | ||
| 1037 | |||
| 1038 | if ((last_pte + 8 * count) != pte) { | ||
| 1039 | |||
| 1040 | if (count) { | ||
| 1041 | radeon_asic_vm_set_page(rdev, last_pte, | ||
| 1042 | last_dst, count, | ||
| 1043 | RADEON_GPU_PAGE_SIZE, | ||
| 1044 | flags); | ||
| 1045 | } | ||
| 1046 | |||
| 1047 | count = nptes; | ||
| 1048 | last_pte = pte; | ||
| 1049 | last_dst = dst; | ||
| 1050 | } else { | ||
| 1051 | count += nptes; | ||
| 1052 | } | ||
| 1053 | |||
| 1054 | addr += nptes; | ||
| 1055 | dst += nptes * RADEON_GPU_PAGE_SIZE; | ||
| 1056 | } | ||
| 1057 | |||
| 1058 | if (count) { | ||
| 1059 | radeon_asic_vm_set_page(rdev, last_pte, last_dst, count, | ||
| 1060 | RADEON_GPU_PAGE_SIZE, flags); | ||
| 1061 | } | ||
| 1062 | } | ||
| 1063 | |||
| 1064 | /** | ||
| 868 | * radeon_vm_bo_update_pte - map a bo into the vm page table | 1065 | * radeon_vm_bo_update_pte - map a bo into the vm page table |
| 869 | * | 1066 | * |
| 870 | * @rdev: radeon_device pointer | 1067 | * @rdev: radeon_device pointer |
| @@ -887,12 +1084,11 @@ int radeon_vm_bo_update_pte(struct radeon_device *rdev, | |||
| 887 | struct radeon_semaphore *sem = NULL; | 1084 | struct radeon_semaphore *sem = NULL; |
| 888 | struct radeon_bo_va *bo_va; | 1085 | struct radeon_bo_va *bo_va; |
| 889 | unsigned nptes, npdes, ndw; | 1086 | unsigned nptes, npdes, ndw; |
| 890 | uint64_t pe, addr; | 1087 | uint64_t addr; |
| 891 | uint64_t pfn; | ||
| 892 | int r; | 1088 | int r; |
| 893 | 1089 | ||
| 894 | /* nothing to do if vm isn't bound */ | 1090 | /* nothing to do if vm isn't bound */ |
| 895 | if (vm->sa_bo == NULL) | 1091 | if (vm->page_directory == NULL) |
| 896 | return 0; | 1092 | return 0; |
| 897 | 1093 | ||
| 898 | bo_va = radeon_vm_bo_find(vm, bo); | 1094 | bo_va = radeon_vm_bo_find(vm, bo); |
| @@ -939,25 +1135,29 @@ int radeon_vm_bo_update_pte(struct radeon_device *rdev, | |||
| 939 | } | 1135 | } |
| 940 | } | 1136 | } |
| 941 | 1137 | ||
| 942 | /* estimate number of dw needed */ | ||
| 943 | /* reserve space for 32-bit padding */ | ||
| 944 | ndw = 32; | ||
| 945 | |||
| 946 | nptes = radeon_bo_ngpu_pages(bo); | 1138 | nptes = radeon_bo_ngpu_pages(bo); |
| 947 | 1139 | ||
| 948 | pfn = (bo_va->soffset / RADEON_GPU_PAGE_SIZE); | 1140 | /* assume two extra pdes in case the mapping overlaps the borders */ |
| 1141 | npdes = (nptes >> RADEON_VM_BLOCK_SIZE) + 2; | ||
| 949 | 1142 | ||
| 950 | /* handle cases where a bo spans several pdes */ | 1143 | /* estimate number of dw needed */ |
| 951 | npdes = (ALIGN(pfn + nptes, RADEON_VM_PTE_COUNT) - | 1144 | /* semaphore, fence and padding */ |
| 952 | (pfn & ~(RADEON_VM_PTE_COUNT - 1))) >> RADEON_VM_BLOCK_SIZE; | 1145 | ndw = 32; |
| 1146 | |||
| 1147 | if (RADEON_VM_BLOCK_SIZE > 11) | ||
| 1148 | /* reserve space for one header for every 2k dwords */ | ||
| 1149 | ndw += (nptes >> 11) * 4; | ||
| 1150 | else | ||
| 1151 | /* reserve space for one header for | ||
| 1152 | every (1 << BLOCK_SIZE) entries */ | ||
| 1153 | ndw += (nptes >> RADEON_VM_BLOCK_SIZE) * 4; | ||
| 953 | 1154 | ||
| 954 | /* reserve space for one header for every 2k dwords */ | ||
| 955 | ndw += (nptes >> 11) * 3; | ||
| 956 | /* reserve space for pte addresses */ | 1155 | /* reserve space for pte addresses */ |
| 957 | ndw += nptes * 2; | 1156 | ndw += nptes * 2; |
| 958 | 1157 | ||
| 959 | /* reserve space for one header for every 2k dwords */ | 1158 | /* reserve space for one header for every 2k dwords */ |
| 960 | ndw += (npdes >> 11) * 3; | 1159 | ndw += (npdes >> 11) * 4; |
| 1160 | |||
| 961 | /* reserve space for pde addresses */ | 1161 | /* reserve space for pde addresses */ |
| 962 | ndw += npdes * 2; | 1162 | ndw += npdes * 2; |
| 963 | 1163 | ||
| @@ -971,22 +1171,14 @@ int radeon_vm_bo_update_pte(struct radeon_device *rdev, | |||
| 971 | radeon_fence_note_sync(vm->fence, ridx); | 1171 | radeon_fence_note_sync(vm->fence, ridx); |
| 972 | } | 1172 | } |
| 973 | 1173 | ||
| 974 | /* update page table entries */ | 1174 | r = radeon_vm_update_pdes(rdev, vm, bo_va->soffset, bo_va->eoffset); |
| 975 | pe = vm->pd_gpu_addr; | 1175 | if (r) { |
| 976 | pe += radeon_vm_directory_size(rdev); | 1176 | radeon_ring_unlock_undo(rdev, ring); |
| 977 | pe += (bo_va->soffset / RADEON_GPU_PAGE_SIZE) * 8; | 1177 | return r; |
| 978 | 1178 | } | |
| 979 | radeon_asic_vm_set_page(rdev, pe, addr, nptes, | ||
| 980 | RADEON_GPU_PAGE_SIZE, bo_va->flags); | ||
| 981 | |||
| 982 | /* update page directory entries */ | ||
| 983 | addr = pe; | ||
| 984 | |||
| 985 | pe = vm->pd_gpu_addr; | ||
| 986 | pe += ((bo_va->soffset / RADEON_GPU_PAGE_SIZE) >> RADEON_VM_BLOCK_SIZE) * 8; | ||
| 987 | 1179 | ||
| 988 | radeon_asic_vm_set_page(rdev, pe, addr, npdes, | 1180 | radeon_vm_update_ptes(rdev, vm, bo_va->soffset, bo_va->eoffset, |
| 989 | RADEON_VM_PTE_COUNT * 8, RADEON_VM_PAGE_VALID); | 1181 | addr, bo_va->flags); |
| 990 | 1182 | ||
| 991 | radeon_fence_unref(&vm->fence); | 1183 | radeon_fence_unref(&vm->fence); |
| 992 | r = radeon_fence_emit(rdev, &vm->fence, ridx); | 1184 | r = radeon_fence_emit(rdev, &vm->fence, ridx); |
| @@ -997,6 +1189,7 @@ int radeon_vm_bo_update_pte(struct radeon_device *rdev, | |||
| 997 | radeon_ring_unlock_commit(rdev, ring); | 1189 | radeon_ring_unlock_commit(rdev, ring); |
| 998 | radeon_semaphore_free(rdev, &sem, vm->fence); | 1190 | radeon_semaphore_free(rdev, &sem, vm->fence); |
| 999 | radeon_fence_unref(&vm->last_flush); | 1191 | radeon_fence_unref(&vm->last_flush); |
| 1192 | |||
| 1000 | return 0; | 1193 | return 0; |
| 1001 | } | 1194 | } |
| 1002 | 1195 | ||
| @@ -1056,31 +1249,15 @@ void radeon_vm_bo_invalidate(struct radeon_device *rdev, | |||
| 1056 | * @rdev: radeon_device pointer | 1249 | * @rdev: radeon_device pointer |
| 1057 | * @vm: requested vm | 1250 | * @vm: requested vm |
| 1058 | * | 1251 | * |
| 1059 | * Init @vm (cayman+). | 1252 | * Init @vm fields (cayman+). |
| 1060 | * Map the IB pool and any other shared objects into the VM | ||
| 1061 | * by default as it's used by all VMs. | ||
| 1062 | * Returns 0 for success, error for failure. | ||
| 1063 | */ | 1253 | */ |
| 1064 | int radeon_vm_init(struct radeon_device *rdev, struct radeon_vm *vm) | 1254 | void radeon_vm_init(struct radeon_device *rdev, struct radeon_vm *vm) |
| 1065 | { | 1255 | { |
| 1066 | struct radeon_bo_va *bo_va; | ||
| 1067 | int r; | ||
| 1068 | |||
| 1069 | vm->id = 0; | 1256 | vm->id = 0; |
| 1070 | vm->fence = NULL; | 1257 | vm->fence = NULL; |
| 1071 | vm->last_pfn = 0; | ||
| 1072 | mutex_init(&vm->mutex); | 1258 | mutex_init(&vm->mutex); |
| 1073 | INIT_LIST_HEAD(&vm->list); | 1259 | INIT_LIST_HEAD(&vm->list); |
| 1074 | INIT_LIST_HEAD(&vm->va); | 1260 | INIT_LIST_HEAD(&vm->va); |
| 1075 | |||
| 1076 | /* map the ib pool buffer at 0 in virtual address space, set | ||
| 1077 | * read only | ||
| 1078 | */ | ||
| 1079 | bo_va = radeon_vm_bo_add(rdev, vm, rdev->ring_tmp_bo.bo); | ||
| 1080 | r = radeon_vm_bo_set_addr(rdev, bo_va, RADEON_VA_IB_OFFSET, | ||
| 1081 | RADEON_VM_PAGE_READABLE | | ||
| 1082 | RADEON_VM_PAGE_SNOOPED); | ||
| 1083 | return r; | ||
| 1084 | } | 1261 | } |
| 1085 | 1262 | ||
| 1086 | /** | 1263 | /** |
| @@ -1102,17 +1279,6 @@ void radeon_vm_fini(struct radeon_device *rdev, struct radeon_vm *vm) | |||
| 1102 | radeon_vm_free_pt(rdev, vm); | 1279 | radeon_vm_free_pt(rdev, vm); |
| 1103 | mutex_unlock(&rdev->vm_manager.lock); | 1280 | mutex_unlock(&rdev->vm_manager.lock); |
| 1104 | 1281 | ||
| 1105 | /* remove all bo at this point non are busy any more because unbind | ||
| 1106 | * waited for the last vm fence to signal | ||
| 1107 | */ | ||
| 1108 | r = radeon_bo_reserve(rdev->ring_tmp_bo.bo, false); | ||
| 1109 | if (!r) { | ||
| 1110 | bo_va = radeon_vm_bo_find(vm, rdev->ring_tmp_bo.bo); | ||
| 1111 | list_del_init(&bo_va->bo_list); | ||
| 1112 | list_del_init(&bo_va->vm_list); | ||
| 1113 | radeon_bo_unreserve(rdev->ring_tmp_bo.bo); | ||
| 1114 | kfree(bo_va); | ||
| 1115 | } | ||
| 1116 | if (!list_empty(&vm->va)) { | 1282 | if (!list_empty(&vm->va)) { |
| 1117 | dev_err(rdev->dev, "still active bo inside vm\n"); | 1283 | dev_err(rdev->dev, "still active bo inside vm\n"); |
| 1118 | } | 1284 | } |
diff --git a/drivers/gpu/drm/radeon/radeon_gem.c b/drivers/gpu/drm/radeon/radeon_gem.c index f38fbcc46935..fe5c1f6b7957 100644 --- a/drivers/gpu/drm/radeon/radeon_gem.c +++ b/drivers/gpu/drm/radeon/radeon_gem.c | |||
| @@ -53,6 +53,7 @@ int radeon_gem_object_create(struct radeon_device *rdev, int size, | |||
| 53 | struct drm_gem_object **obj) | 53 | struct drm_gem_object **obj) |
| 54 | { | 54 | { |
| 55 | struct radeon_bo *robj; | 55 | struct radeon_bo *robj; |
| 56 | unsigned long max_size; | ||
| 56 | int r; | 57 | int r; |
| 57 | 58 | ||
| 58 | *obj = NULL; | 59 | *obj = NULL; |
| @@ -60,11 +61,26 @@ int radeon_gem_object_create(struct radeon_device *rdev, int size, | |||
| 60 | if (alignment < PAGE_SIZE) { | 61 | if (alignment < PAGE_SIZE) { |
| 61 | alignment = PAGE_SIZE; | 62 | alignment = PAGE_SIZE; |
| 62 | } | 63 | } |
| 64 | |||
| 65 | /* maximun bo size is the minimun btw visible vram and gtt size */ | ||
| 66 | max_size = min(rdev->mc.visible_vram_size, rdev->mc.gtt_size); | ||
| 67 | if (size > max_size) { | ||
| 68 | printk(KERN_WARNING "%s:%d alloc size %dMb bigger than %ldMb limit\n", | ||
| 69 | __func__, __LINE__, size >> 20, max_size >> 20); | ||
| 70 | return -ENOMEM; | ||
| 71 | } | ||
| 72 | |||
| 73 | retry: | ||
| 63 | r = radeon_bo_create(rdev, size, alignment, kernel, initial_domain, NULL, &robj); | 74 | r = radeon_bo_create(rdev, size, alignment, kernel, initial_domain, NULL, &robj); |
| 64 | if (r) { | 75 | if (r) { |
| 65 | if (r != -ERESTARTSYS) | 76 | if (r != -ERESTARTSYS) { |
| 77 | if (initial_domain == RADEON_GEM_DOMAIN_VRAM) { | ||
| 78 | initial_domain |= RADEON_GEM_DOMAIN_GTT; | ||
| 79 | goto retry; | ||
| 80 | } | ||
| 66 | DRM_ERROR("Failed to allocate GEM object (%d, %d, %u, %d)\n", | 81 | DRM_ERROR("Failed to allocate GEM object (%d, %d, %u, %d)\n", |
| 67 | size, initial_domain, alignment, r); | 82 | size, initial_domain, alignment, r); |
| 83 | } | ||
| 68 | return r; | 84 | return r; |
| 69 | } | 85 | } |
| 70 | *obj = &robj->gem_base; | 86 | *obj = &robj->gem_base; |
diff --git a/drivers/gpu/drm/radeon/radeon_kms.c b/drivers/gpu/drm/radeon/radeon_kms.c index 83b8d8aa71c0..dc781c49b96b 100644 --- a/drivers/gpu/drm/radeon/radeon_kms.c +++ b/drivers/gpu/drm/radeon/radeon_kms.c | |||
| @@ -419,6 +419,7 @@ int radeon_driver_open_kms(struct drm_device *dev, struct drm_file *file_priv) | |||
| 419 | /* new gpu have virtual address space support */ | 419 | /* new gpu have virtual address space support */ |
| 420 | if (rdev->family >= CHIP_CAYMAN) { | 420 | if (rdev->family >= CHIP_CAYMAN) { |
| 421 | struct radeon_fpriv *fpriv; | 421 | struct radeon_fpriv *fpriv; |
| 422 | struct radeon_bo_va *bo_va; | ||
| 422 | int r; | 423 | int r; |
| 423 | 424 | ||
| 424 | fpriv = kzalloc(sizeof(*fpriv), GFP_KERNEL); | 425 | fpriv = kzalloc(sizeof(*fpriv), GFP_KERNEL); |
| @@ -426,7 +427,15 @@ int radeon_driver_open_kms(struct drm_device *dev, struct drm_file *file_priv) | |||
| 426 | return -ENOMEM; | 427 | return -ENOMEM; |
| 427 | } | 428 | } |
| 428 | 429 | ||
| 429 | r = radeon_vm_init(rdev, &fpriv->vm); | 430 | radeon_vm_init(rdev, &fpriv->vm); |
| 431 | |||
| 432 | /* map the ib pool buffer read only into | ||
| 433 | * virtual address space */ | ||
| 434 | bo_va = radeon_vm_bo_add(rdev, &fpriv->vm, | ||
| 435 | rdev->ring_tmp_bo.bo); | ||
| 436 | r = radeon_vm_bo_set_addr(rdev, bo_va, RADEON_VA_IB_OFFSET, | ||
| 437 | RADEON_VM_PAGE_READABLE | | ||
| 438 | RADEON_VM_PAGE_SNOOPED); | ||
| 430 | if (r) { | 439 | if (r) { |
| 431 | radeon_vm_fini(rdev, &fpriv->vm); | 440 | radeon_vm_fini(rdev, &fpriv->vm); |
| 432 | kfree(fpriv); | 441 | kfree(fpriv); |
| @@ -454,6 +463,17 @@ void radeon_driver_postclose_kms(struct drm_device *dev, | |||
| 454 | /* new gpu have virtual address space support */ | 463 | /* new gpu have virtual address space support */ |
| 455 | if (rdev->family >= CHIP_CAYMAN && file_priv->driver_priv) { | 464 | if (rdev->family >= CHIP_CAYMAN && file_priv->driver_priv) { |
| 456 | struct radeon_fpriv *fpriv = file_priv->driver_priv; | 465 | struct radeon_fpriv *fpriv = file_priv->driver_priv; |
| 466 | struct radeon_bo_va *bo_va; | ||
| 467 | int r; | ||
| 468 | |||
| 469 | r = radeon_bo_reserve(rdev->ring_tmp_bo.bo, false); | ||
| 470 | if (!r) { | ||
| 471 | bo_va = radeon_vm_bo_find(&fpriv->vm, | ||
| 472 | rdev->ring_tmp_bo.bo); | ||
| 473 | if (bo_va) | ||
| 474 | radeon_vm_bo_rmv(rdev, bo_va); | ||
| 475 | radeon_bo_unreserve(rdev->ring_tmp_bo.bo); | ||
| 476 | } | ||
| 457 | 477 | ||
| 458 | radeon_vm_fini(rdev, &fpriv->vm); | 478 | radeon_vm_fini(rdev, &fpriv->vm); |
| 459 | kfree(fpriv); | 479 | kfree(fpriv); |
diff --git a/drivers/gpu/drm/radeon/radeon_legacy_crtc.c b/drivers/gpu/drm/radeon/radeon_legacy_crtc.c index 5677a424b585..6857cb4efb76 100644 --- a/drivers/gpu/drm/radeon/radeon_legacy_crtc.c +++ b/drivers/gpu/drm/radeon/radeon_legacy_crtc.c | |||
| @@ -295,6 +295,7 @@ static void radeon_crtc_dpms(struct drm_crtc *crtc, int mode) | |||
| 295 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); | 295 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); |
| 296 | struct drm_device *dev = crtc->dev; | 296 | struct drm_device *dev = crtc->dev; |
| 297 | struct radeon_device *rdev = dev->dev_private; | 297 | struct radeon_device *rdev = dev->dev_private; |
| 298 | uint32_t crtc_ext_cntl = 0; | ||
| 298 | uint32_t mask; | 299 | uint32_t mask; |
| 299 | 300 | ||
| 300 | if (radeon_crtc->crtc_id) | 301 | if (radeon_crtc->crtc_id) |
| @@ -307,6 +308,16 @@ static void radeon_crtc_dpms(struct drm_crtc *crtc, int mode) | |||
| 307 | RADEON_CRTC_VSYNC_DIS | | 308 | RADEON_CRTC_VSYNC_DIS | |
| 308 | RADEON_CRTC_HSYNC_DIS); | 309 | RADEON_CRTC_HSYNC_DIS); |
| 309 | 310 | ||
| 311 | /* | ||
| 312 | * On all dual CRTC GPUs this bit controls the CRTC of the primary DAC. | ||
| 313 | * Therefore it is set in the DAC DMPS function. | ||
| 314 | * This is different for GPU's with a single CRTC but a primary and a | ||
| 315 | * TV DAC: here it controls the single CRTC no matter where it is | ||
| 316 | * routed. Therefore we set it here. | ||
| 317 | */ | ||
| 318 | if (rdev->flags & RADEON_SINGLE_CRTC) | ||
| 319 | crtc_ext_cntl = RADEON_CRTC_CRT_ON; | ||
| 320 | |||
| 310 | switch (mode) { | 321 | switch (mode) { |
| 311 | case DRM_MODE_DPMS_ON: | 322 | case DRM_MODE_DPMS_ON: |
| 312 | radeon_crtc->enabled = true; | 323 | radeon_crtc->enabled = true; |
| @@ -317,7 +328,7 @@ static void radeon_crtc_dpms(struct drm_crtc *crtc, int mode) | |||
| 317 | else { | 328 | else { |
| 318 | WREG32_P(RADEON_CRTC_GEN_CNTL, RADEON_CRTC_EN, ~(RADEON_CRTC_EN | | 329 | WREG32_P(RADEON_CRTC_GEN_CNTL, RADEON_CRTC_EN, ~(RADEON_CRTC_EN | |
| 319 | RADEON_CRTC_DISP_REQ_EN_B)); | 330 | RADEON_CRTC_DISP_REQ_EN_B)); |
| 320 | WREG32_P(RADEON_CRTC_EXT_CNTL, 0, ~mask); | 331 | WREG32_P(RADEON_CRTC_EXT_CNTL, crtc_ext_cntl, ~(mask | crtc_ext_cntl)); |
| 321 | } | 332 | } |
| 322 | drm_vblank_post_modeset(dev, radeon_crtc->crtc_id); | 333 | drm_vblank_post_modeset(dev, radeon_crtc->crtc_id); |
| 323 | radeon_crtc_load_lut(crtc); | 334 | radeon_crtc_load_lut(crtc); |
| @@ -331,7 +342,7 @@ static void radeon_crtc_dpms(struct drm_crtc *crtc, int mode) | |||
| 331 | else { | 342 | else { |
| 332 | WREG32_P(RADEON_CRTC_GEN_CNTL, RADEON_CRTC_DISP_REQ_EN_B, ~(RADEON_CRTC_EN | | 343 | WREG32_P(RADEON_CRTC_GEN_CNTL, RADEON_CRTC_DISP_REQ_EN_B, ~(RADEON_CRTC_EN | |
| 333 | RADEON_CRTC_DISP_REQ_EN_B)); | 344 | RADEON_CRTC_DISP_REQ_EN_B)); |
| 334 | WREG32_P(RADEON_CRTC_EXT_CNTL, mask, ~mask); | 345 | WREG32_P(RADEON_CRTC_EXT_CNTL, mask, ~(mask | crtc_ext_cntl)); |
| 335 | } | 346 | } |
| 336 | radeon_crtc->enabled = false; | 347 | radeon_crtc->enabled = false; |
| 337 | /* adjust pm to dpms changes AFTER disabling crtcs */ | 348 | /* adjust pm to dpms changes AFTER disabling crtcs */ |
diff --git a/drivers/gpu/drm/radeon/radeon_legacy_encoders.c b/drivers/gpu/drm/radeon/radeon_legacy_encoders.c index 92487e614778..f5ba2241dacc 100644 --- a/drivers/gpu/drm/radeon/radeon_legacy_encoders.c +++ b/drivers/gpu/drm/radeon/radeon_legacy_encoders.c | |||
| @@ -269,27 +269,6 @@ static const struct drm_encoder_helper_funcs radeon_legacy_lvds_helper_funcs = { | |||
| 269 | .disable = radeon_legacy_encoder_disable, | 269 | .disable = radeon_legacy_encoder_disable, |
| 270 | }; | 270 | }; |
| 271 | 271 | ||
| 272 | #if defined(CONFIG_BACKLIGHT_CLASS_DEVICE) || defined(CONFIG_BACKLIGHT_CLASS_DEVICE_MODULE) | ||
| 273 | |||
| 274 | static uint8_t radeon_legacy_lvds_level(struct backlight_device *bd) | ||
| 275 | { | ||
| 276 | struct radeon_backlight_privdata *pdata = bl_get_data(bd); | ||
| 277 | uint8_t level; | ||
| 278 | |||
| 279 | /* Convert brightness to hardware level */ | ||
| 280 | if (bd->props.brightness < 0) | ||
| 281 | level = 0; | ||
| 282 | else if (bd->props.brightness > RADEON_MAX_BL_LEVEL) | ||
| 283 | level = RADEON_MAX_BL_LEVEL; | ||
| 284 | else | ||
| 285 | level = bd->props.brightness; | ||
| 286 | |||
| 287 | if (pdata->negative) | ||
| 288 | level = RADEON_MAX_BL_LEVEL - level; | ||
| 289 | |||
| 290 | return level; | ||
| 291 | } | ||
| 292 | |||
| 293 | u8 | 272 | u8 |
| 294 | radeon_legacy_get_backlight_level(struct radeon_encoder *radeon_encoder) | 273 | radeon_legacy_get_backlight_level(struct radeon_encoder *radeon_encoder) |
| 295 | { | 274 | { |
| @@ -331,6 +310,27 @@ radeon_legacy_set_backlight_level(struct radeon_encoder *radeon_encoder, u8 leve | |||
| 331 | radeon_legacy_lvds_update(&radeon_encoder->base, dpms_mode); | 310 | radeon_legacy_lvds_update(&radeon_encoder->base, dpms_mode); |
| 332 | } | 311 | } |
| 333 | 312 | ||
| 313 | #if defined(CONFIG_BACKLIGHT_CLASS_DEVICE) || defined(CONFIG_BACKLIGHT_CLASS_DEVICE_MODULE) | ||
| 314 | |||
| 315 | static uint8_t radeon_legacy_lvds_level(struct backlight_device *bd) | ||
| 316 | { | ||
| 317 | struct radeon_backlight_privdata *pdata = bl_get_data(bd); | ||
| 318 | uint8_t level; | ||
| 319 | |||
| 320 | /* Convert brightness to hardware level */ | ||
| 321 | if (bd->props.brightness < 0) | ||
| 322 | level = 0; | ||
| 323 | else if (bd->props.brightness > RADEON_MAX_BL_LEVEL) | ||
| 324 | level = RADEON_MAX_BL_LEVEL; | ||
| 325 | else | ||
| 326 | level = bd->props.brightness; | ||
| 327 | |||
| 328 | if (pdata->negative) | ||
| 329 | level = RADEON_MAX_BL_LEVEL - level; | ||
| 330 | |||
| 331 | return level; | ||
| 332 | } | ||
| 333 | |||
| 334 | static int radeon_legacy_backlight_update_status(struct backlight_device *bd) | 334 | static int radeon_legacy_backlight_update_status(struct backlight_device *bd) |
| 335 | { | 335 | { |
| 336 | struct radeon_backlight_privdata *pdata = bl_get_data(bd); | 336 | struct radeon_backlight_privdata *pdata = bl_get_data(bd); |
| @@ -370,6 +370,7 @@ void radeon_legacy_backlight_init(struct radeon_encoder *radeon_encoder, | |||
| 370 | struct backlight_properties props; | 370 | struct backlight_properties props; |
| 371 | struct radeon_backlight_privdata *pdata; | 371 | struct radeon_backlight_privdata *pdata; |
| 372 | uint8_t backlight_level; | 372 | uint8_t backlight_level; |
| 373 | char bl_name[16]; | ||
| 373 | 374 | ||
| 374 | if (!radeon_encoder->enc_priv) | 375 | if (!radeon_encoder->enc_priv) |
| 375 | return; | 376 | return; |
| @@ -389,7 +390,9 @@ void radeon_legacy_backlight_init(struct radeon_encoder *radeon_encoder, | |||
| 389 | memset(&props, 0, sizeof(props)); | 390 | memset(&props, 0, sizeof(props)); |
| 390 | props.max_brightness = RADEON_MAX_BL_LEVEL; | 391 | props.max_brightness = RADEON_MAX_BL_LEVEL; |
| 391 | props.type = BACKLIGHT_RAW; | 392 | props.type = BACKLIGHT_RAW; |
| 392 | bd = backlight_device_register("radeon_bl", &drm_connector->kdev, | 393 | snprintf(bl_name, sizeof(bl_name), |
| 394 | "radeon_bl%d", dev->primary->index); | ||
| 395 | bd = backlight_device_register(bl_name, &drm_connector->kdev, | ||
| 393 | pdata, &radeon_backlight_ops, &props); | 396 | pdata, &radeon_backlight_ops, &props); |
| 394 | if (IS_ERR(bd)) { | 397 | if (IS_ERR(bd)) { |
| 395 | DRM_ERROR("Backlight registration failed\n"); | 398 | DRM_ERROR("Backlight registration failed\n"); |
| @@ -534,7 +537,9 @@ static void radeon_legacy_primary_dac_dpms(struct drm_encoder *encoder, int mode | |||
| 534 | break; | 537 | break; |
| 535 | } | 538 | } |
| 536 | 539 | ||
| 537 | WREG32(RADEON_CRTC_EXT_CNTL, crtc_ext_cntl); | 540 | /* handled in radeon_crtc_dpms() */ |
| 541 | if (!(rdev->flags & RADEON_SINGLE_CRTC)) | ||
| 542 | WREG32(RADEON_CRTC_EXT_CNTL, crtc_ext_cntl); | ||
| 538 | WREG32(RADEON_DAC_CNTL, dac_cntl); | 543 | WREG32(RADEON_DAC_CNTL, dac_cntl); |
| 539 | WREG32(RADEON_DAC_MACRO_CNTL, dac_macro_cntl); | 544 | WREG32(RADEON_DAC_MACRO_CNTL, dac_macro_cntl); |
| 540 | 545 | ||
| @@ -659,6 +664,8 @@ static enum drm_connector_status radeon_legacy_primary_dac_detect(struct drm_enc | |||
| 659 | 664 | ||
| 660 | if (ASIC_IS_R300(rdev)) | 665 | if (ASIC_IS_R300(rdev)) |
| 661 | tmp |= (0x1b6 << RADEON_DAC_FORCE_DATA_SHIFT); | 666 | tmp |= (0x1b6 << RADEON_DAC_FORCE_DATA_SHIFT); |
| 667 | else if (ASIC_IS_RV100(rdev)) | ||
| 668 | tmp |= (0x1ac << RADEON_DAC_FORCE_DATA_SHIFT); | ||
| 662 | else | 669 | else |
| 663 | tmp |= (0x180 << RADEON_DAC_FORCE_DATA_SHIFT); | 670 | tmp |= (0x180 << RADEON_DAC_FORCE_DATA_SHIFT); |
| 664 | 671 | ||
| @@ -668,6 +675,7 @@ static enum drm_connector_status radeon_legacy_primary_dac_detect(struct drm_enc | |||
| 668 | tmp |= RADEON_DAC_RANGE_CNTL_PS2 | RADEON_DAC_CMP_EN; | 675 | tmp |= RADEON_DAC_RANGE_CNTL_PS2 | RADEON_DAC_CMP_EN; |
| 669 | WREG32(RADEON_DAC_CNTL, tmp); | 676 | WREG32(RADEON_DAC_CNTL, tmp); |
| 670 | 677 | ||
| 678 | tmp = dac_macro_cntl; | ||
| 671 | tmp &= ~(RADEON_DAC_PDWN_R | | 679 | tmp &= ~(RADEON_DAC_PDWN_R | |
| 672 | RADEON_DAC_PDWN_G | | 680 | RADEON_DAC_PDWN_G | |
| 673 | RADEON_DAC_PDWN_B); | 681 | RADEON_DAC_PDWN_B); |
| @@ -991,11 +999,7 @@ static void radeon_legacy_tmds_ext_mode_set(struct drm_encoder *encoder, | |||
| 991 | static void radeon_ext_tmds_enc_destroy(struct drm_encoder *encoder) | 999 | static void radeon_ext_tmds_enc_destroy(struct drm_encoder *encoder) |
| 992 | { | 1000 | { |
| 993 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | 1001 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); |
| 994 | struct radeon_encoder_ext_tmds *tmds = radeon_encoder->enc_priv; | 1002 | /* don't destroy the i2c bus record here, this will be done in radeon_i2c_fini */ |
| 995 | if (tmds) { | ||
| 996 | if (tmds->i2c_bus) | ||
| 997 | radeon_i2c_destroy(tmds->i2c_bus); | ||
| 998 | } | ||
| 999 | kfree(radeon_encoder->enc_priv); | 1003 | kfree(radeon_encoder->enc_priv); |
| 1000 | drm_encoder_cleanup(encoder); | 1004 | drm_encoder_cleanup(encoder); |
| 1001 | kfree(radeon_encoder); | 1005 | kfree(radeon_encoder); |
| @@ -1093,7 +1097,8 @@ static void radeon_legacy_tv_dac_dpms(struct drm_encoder *encoder, int mode) | |||
| 1093 | } else { | 1097 | } else { |
| 1094 | if (is_tv) | 1098 | if (is_tv) |
| 1095 | WREG32(RADEON_TV_MASTER_CNTL, tv_master_cntl); | 1099 | WREG32(RADEON_TV_MASTER_CNTL, tv_master_cntl); |
| 1096 | else | 1100 | /* handled in radeon_crtc_dpms() */ |
| 1101 | else if (!(rdev->flags & RADEON_SINGLE_CRTC)) | ||
| 1097 | WREG32(RADEON_CRTC2_GEN_CNTL, crtc2_gen_cntl); | 1102 | WREG32(RADEON_CRTC2_GEN_CNTL, crtc2_gen_cntl); |
| 1098 | WREG32(RADEON_TV_DAC_CNTL, tv_dac_cntl); | 1103 | WREG32(RADEON_TV_DAC_CNTL, tv_dac_cntl); |
| 1099 | } | 1104 | } |
| @@ -1417,13 +1422,104 @@ static bool radeon_legacy_tv_detect(struct drm_encoder *encoder, | |||
| 1417 | return found; | 1422 | return found; |
| 1418 | } | 1423 | } |
| 1419 | 1424 | ||
| 1425 | static bool radeon_legacy_ext_dac_detect(struct drm_encoder *encoder, | ||
| 1426 | struct drm_connector *connector) | ||
| 1427 | { | ||
| 1428 | struct drm_device *dev = encoder->dev; | ||
| 1429 | struct radeon_device *rdev = dev->dev_private; | ||
| 1430 | uint32_t gpio_monid, fp2_gen_cntl, disp_output_cntl, crtc2_gen_cntl; | ||
| 1431 | uint32_t disp_lin_trans_grph_a, disp_lin_trans_grph_b, disp_lin_trans_grph_c; | ||
| 1432 | uint32_t disp_lin_trans_grph_d, disp_lin_trans_grph_e, disp_lin_trans_grph_f; | ||
| 1433 | uint32_t tmp, crtc2_h_total_disp, crtc2_v_total_disp; | ||
| 1434 | uint32_t crtc2_h_sync_strt_wid, crtc2_v_sync_strt_wid; | ||
| 1435 | bool found = false; | ||
| 1436 | int i; | ||
| 1437 | |||
| 1438 | /* save the regs we need */ | ||
| 1439 | gpio_monid = RREG32(RADEON_GPIO_MONID); | ||
| 1440 | fp2_gen_cntl = RREG32(RADEON_FP2_GEN_CNTL); | ||
| 1441 | disp_output_cntl = RREG32(RADEON_DISP_OUTPUT_CNTL); | ||
| 1442 | crtc2_gen_cntl = RREG32(RADEON_CRTC2_GEN_CNTL); | ||
| 1443 | disp_lin_trans_grph_a = RREG32(RADEON_DISP_LIN_TRANS_GRPH_A); | ||
| 1444 | disp_lin_trans_grph_b = RREG32(RADEON_DISP_LIN_TRANS_GRPH_B); | ||
| 1445 | disp_lin_trans_grph_c = RREG32(RADEON_DISP_LIN_TRANS_GRPH_C); | ||
| 1446 | disp_lin_trans_grph_d = RREG32(RADEON_DISP_LIN_TRANS_GRPH_D); | ||
| 1447 | disp_lin_trans_grph_e = RREG32(RADEON_DISP_LIN_TRANS_GRPH_E); | ||
| 1448 | disp_lin_trans_grph_f = RREG32(RADEON_DISP_LIN_TRANS_GRPH_F); | ||
| 1449 | crtc2_h_total_disp = RREG32(RADEON_CRTC2_H_TOTAL_DISP); | ||
| 1450 | crtc2_v_total_disp = RREG32(RADEON_CRTC2_V_TOTAL_DISP); | ||
| 1451 | crtc2_h_sync_strt_wid = RREG32(RADEON_CRTC2_H_SYNC_STRT_WID); | ||
| 1452 | crtc2_v_sync_strt_wid = RREG32(RADEON_CRTC2_V_SYNC_STRT_WID); | ||
| 1453 | |||
| 1454 | tmp = RREG32(RADEON_GPIO_MONID); | ||
| 1455 | tmp &= ~RADEON_GPIO_A_0; | ||
| 1456 | WREG32(RADEON_GPIO_MONID, tmp); | ||
| 1457 | |||
| 1458 | WREG32(RADEON_FP2_GEN_CNTL, (RADEON_FP2_ON | | ||
| 1459 | RADEON_FP2_PANEL_FORMAT | | ||
| 1460 | R200_FP2_SOURCE_SEL_TRANS_UNIT | | ||
| 1461 | RADEON_FP2_DVO_EN | | ||
| 1462 | R200_FP2_DVO_RATE_SEL_SDR)); | ||
| 1463 | |||
| 1464 | WREG32(RADEON_DISP_OUTPUT_CNTL, (RADEON_DISP_DAC_SOURCE_RMX | | ||
| 1465 | RADEON_DISP_TRANS_MATRIX_GRAPHICS)); | ||
| 1466 | |||
| 1467 | WREG32(RADEON_CRTC2_GEN_CNTL, (RADEON_CRTC2_EN | | ||
| 1468 | RADEON_CRTC2_DISP_REQ_EN_B)); | ||
| 1469 | |||
| 1470 | WREG32(RADEON_DISP_LIN_TRANS_GRPH_A, 0x00000000); | ||
| 1471 | WREG32(RADEON_DISP_LIN_TRANS_GRPH_B, 0x000003f0); | ||
| 1472 | WREG32(RADEON_DISP_LIN_TRANS_GRPH_C, 0x00000000); | ||
| 1473 | WREG32(RADEON_DISP_LIN_TRANS_GRPH_D, 0x000003f0); | ||
| 1474 | WREG32(RADEON_DISP_LIN_TRANS_GRPH_E, 0x00000000); | ||
| 1475 | WREG32(RADEON_DISP_LIN_TRANS_GRPH_F, 0x000003f0); | ||
| 1476 | |||
| 1477 | WREG32(RADEON_CRTC2_H_TOTAL_DISP, 0x01000008); | ||
| 1478 | WREG32(RADEON_CRTC2_H_SYNC_STRT_WID, 0x00000800); | ||
| 1479 | WREG32(RADEON_CRTC2_V_TOTAL_DISP, 0x00080001); | ||
| 1480 | WREG32(RADEON_CRTC2_V_SYNC_STRT_WID, 0x00000080); | ||
| 1481 | |||
| 1482 | for (i = 0; i < 200; i++) { | ||
| 1483 | tmp = RREG32(RADEON_GPIO_MONID); | ||
| 1484 | if (tmp & RADEON_GPIO_Y_0) | ||
| 1485 | found = true; | ||
| 1486 | |||
| 1487 | if (found) | ||
| 1488 | break; | ||
| 1489 | |||
| 1490 | if (!drm_can_sleep()) | ||
| 1491 | mdelay(1); | ||
| 1492 | else | ||
| 1493 | msleep(1); | ||
| 1494 | } | ||
| 1495 | |||
| 1496 | /* restore the regs we used */ | ||
| 1497 | WREG32(RADEON_DISP_LIN_TRANS_GRPH_A, disp_lin_trans_grph_a); | ||
| 1498 | WREG32(RADEON_DISP_LIN_TRANS_GRPH_B, disp_lin_trans_grph_b); | ||
| 1499 | WREG32(RADEON_DISP_LIN_TRANS_GRPH_C, disp_lin_trans_grph_c); | ||
| 1500 | WREG32(RADEON_DISP_LIN_TRANS_GRPH_D, disp_lin_trans_grph_d); | ||
| 1501 | WREG32(RADEON_DISP_LIN_TRANS_GRPH_E, disp_lin_trans_grph_e); | ||
| 1502 | WREG32(RADEON_DISP_LIN_TRANS_GRPH_F, disp_lin_trans_grph_f); | ||
| 1503 | WREG32(RADEON_CRTC2_H_TOTAL_DISP, crtc2_h_total_disp); | ||
| 1504 | WREG32(RADEON_CRTC2_V_TOTAL_DISP, crtc2_v_total_disp); | ||
| 1505 | WREG32(RADEON_CRTC2_H_SYNC_STRT_WID, crtc2_h_sync_strt_wid); | ||
| 1506 | WREG32(RADEON_CRTC2_V_SYNC_STRT_WID, crtc2_v_sync_strt_wid); | ||
| 1507 | WREG32(RADEON_CRTC2_GEN_CNTL, crtc2_gen_cntl); | ||
| 1508 | WREG32(RADEON_DISP_OUTPUT_CNTL, disp_output_cntl); | ||
| 1509 | WREG32(RADEON_FP2_GEN_CNTL, fp2_gen_cntl); | ||
| 1510 | WREG32(RADEON_GPIO_MONID, gpio_monid); | ||
| 1511 | |||
| 1512 | return found; | ||
| 1513 | } | ||
| 1514 | |||
| 1420 | static enum drm_connector_status radeon_legacy_tv_dac_detect(struct drm_encoder *encoder, | 1515 | static enum drm_connector_status radeon_legacy_tv_dac_detect(struct drm_encoder *encoder, |
| 1421 | struct drm_connector *connector) | 1516 | struct drm_connector *connector) |
| 1422 | { | 1517 | { |
| 1423 | struct drm_device *dev = encoder->dev; | 1518 | struct drm_device *dev = encoder->dev; |
| 1424 | struct radeon_device *rdev = dev->dev_private; | 1519 | struct radeon_device *rdev = dev->dev_private; |
| 1425 | uint32_t crtc2_gen_cntl, tv_dac_cntl, dac_cntl2, dac_ext_cntl; | 1520 | uint32_t crtc2_gen_cntl = 0, tv_dac_cntl, dac_cntl2, dac_ext_cntl; |
| 1426 | uint32_t disp_hw_debug, disp_output_cntl, gpiopad_a, pixclks_cntl, tmp; | 1521 | uint32_t gpiopad_a = 0, pixclks_cntl, tmp; |
| 1522 | uint32_t disp_output_cntl = 0, disp_hw_debug = 0, crtc_ext_cntl = 0; | ||
| 1427 | enum drm_connector_status found = connector_status_disconnected; | 1523 | enum drm_connector_status found = connector_status_disconnected; |
| 1428 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | 1524 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); |
| 1429 | struct radeon_encoder_tv_dac *tv_dac = radeon_encoder->enc_priv; | 1525 | struct radeon_encoder_tv_dac *tv_dac = radeon_encoder->enc_priv; |
| @@ -1460,12 +1556,27 @@ static enum drm_connector_status radeon_legacy_tv_dac_detect(struct drm_encoder | |||
| 1460 | return connector_status_disconnected; | 1556 | return connector_status_disconnected; |
| 1461 | } | 1557 | } |
| 1462 | 1558 | ||
| 1559 | /* R200 uses an external DAC for secondary DAC */ | ||
| 1560 | if (rdev->family == CHIP_R200) { | ||
| 1561 | if (radeon_legacy_ext_dac_detect(encoder, connector)) | ||
| 1562 | found = connector_status_connected; | ||
| 1563 | return found; | ||
| 1564 | } | ||
| 1565 | |||
| 1463 | /* save the regs we need */ | 1566 | /* save the regs we need */ |
| 1464 | pixclks_cntl = RREG32_PLL(RADEON_PIXCLKS_CNTL); | 1567 | pixclks_cntl = RREG32_PLL(RADEON_PIXCLKS_CNTL); |
| 1465 | gpiopad_a = ASIC_IS_R300(rdev) ? RREG32(RADEON_GPIOPAD_A) : 0; | 1568 | |
| 1466 | disp_output_cntl = ASIC_IS_R300(rdev) ? RREG32(RADEON_DISP_OUTPUT_CNTL) : 0; | 1569 | if (rdev->flags & RADEON_SINGLE_CRTC) { |
| 1467 | disp_hw_debug = ASIC_IS_R300(rdev) ? 0 : RREG32(RADEON_DISP_HW_DEBUG); | 1570 | crtc_ext_cntl = RREG32(RADEON_CRTC_EXT_CNTL); |
| 1468 | crtc2_gen_cntl = RREG32(RADEON_CRTC2_GEN_CNTL); | 1571 | } else { |
| 1572 | if (ASIC_IS_R300(rdev)) { | ||
| 1573 | gpiopad_a = RREG32(RADEON_GPIOPAD_A); | ||
| 1574 | disp_output_cntl = RREG32(RADEON_DISP_OUTPUT_CNTL); | ||
| 1575 | } else { | ||
| 1576 | disp_hw_debug = RREG32(RADEON_DISP_HW_DEBUG); | ||
| 1577 | } | ||
| 1578 | crtc2_gen_cntl = RREG32(RADEON_CRTC2_GEN_CNTL); | ||
| 1579 | } | ||
| 1469 | tv_dac_cntl = RREG32(RADEON_TV_DAC_CNTL); | 1580 | tv_dac_cntl = RREG32(RADEON_TV_DAC_CNTL); |
| 1470 | dac_ext_cntl = RREG32(RADEON_DAC_EXT_CNTL); | 1581 | dac_ext_cntl = RREG32(RADEON_DAC_EXT_CNTL); |
| 1471 | dac_cntl2 = RREG32(RADEON_DAC_CNTL2); | 1582 | dac_cntl2 = RREG32(RADEON_DAC_CNTL2); |
| @@ -1474,22 +1585,24 @@ static enum drm_connector_status radeon_legacy_tv_dac_detect(struct drm_encoder | |||
| 1474 | | RADEON_PIX2CLK_DAC_ALWAYS_ONb); | 1585 | | RADEON_PIX2CLK_DAC_ALWAYS_ONb); |
| 1475 | WREG32_PLL(RADEON_PIXCLKS_CNTL, tmp); | 1586 | WREG32_PLL(RADEON_PIXCLKS_CNTL, tmp); |
| 1476 | 1587 | ||
| 1477 | if (ASIC_IS_R300(rdev)) | 1588 | if (rdev->flags & RADEON_SINGLE_CRTC) { |
| 1478 | WREG32_P(RADEON_GPIOPAD_A, 1, ~1); | 1589 | tmp = crtc_ext_cntl | RADEON_CRTC_CRT_ON; |
| 1479 | 1590 | WREG32(RADEON_CRTC_EXT_CNTL, tmp); | |
| 1480 | tmp = crtc2_gen_cntl & ~RADEON_CRTC2_PIX_WIDTH_MASK; | ||
| 1481 | tmp |= RADEON_CRTC2_CRT2_ON | | ||
| 1482 | (2 << RADEON_CRTC2_PIX_WIDTH_SHIFT); | ||
| 1483 | |||
| 1484 | WREG32(RADEON_CRTC2_GEN_CNTL, tmp); | ||
| 1485 | |||
| 1486 | if (ASIC_IS_R300(rdev)) { | ||
| 1487 | tmp = disp_output_cntl & ~RADEON_DISP_TVDAC_SOURCE_MASK; | ||
| 1488 | tmp |= RADEON_DISP_TVDAC_SOURCE_CRTC2; | ||
| 1489 | WREG32(RADEON_DISP_OUTPUT_CNTL, tmp); | ||
| 1490 | } else { | 1591 | } else { |
| 1491 | tmp = disp_hw_debug & ~RADEON_CRT2_DISP1_SEL; | 1592 | tmp = crtc2_gen_cntl & ~RADEON_CRTC2_PIX_WIDTH_MASK; |
| 1492 | WREG32(RADEON_DISP_HW_DEBUG, tmp); | 1593 | tmp |= RADEON_CRTC2_CRT2_ON | |
| 1594 | (2 << RADEON_CRTC2_PIX_WIDTH_SHIFT); | ||
| 1595 | WREG32(RADEON_CRTC2_GEN_CNTL, tmp); | ||
| 1596 | |||
| 1597 | if (ASIC_IS_R300(rdev)) { | ||
| 1598 | WREG32_P(RADEON_GPIOPAD_A, 1, ~1); | ||
| 1599 | tmp = disp_output_cntl & ~RADEON_DISP_TVDAC_SOURCE_MASK; | ||
| 1600 | tmp |= RADEON_DISP_TVDAC_SOURCE_CRTC2; | ||
| 1601 | WREG32(RADEON_DISP_OUTPUT_CNTL, tmp); | ||
| 1602 | } else { | ||
| 1603 | tmp = disp_hw_debug & ~RADEON_CRT2_DISP1_SEL; | ||
| 1604 | WREG32(RADEON_DISP_HW_DEBUG, tmp); | ||
| 1605 | } | ||
| 1493 | } | 1606 | } |
| 1494 | 1607 | ||
| 1495 | tmp = RADEON_TV_DAC_NBLANK | | 1608 | tmp = RADEON_TV_DAC_NBLANK | |
| @@ -1531,14 +1644,19 @@ static enum drm_connector_status radeon_legacy_tv_dac_detect(struct drm_encoder | |||
| 1531 | WREG32(RADEON_DAC_CNTL2, dac_cntl2); | 1644 | WREG32(RADEON_DAC_CNTL2, dac_cntl2); |
| 1532 | WREG32(RADEON_DAC_EXT_CNTL, dac_ext_cntl); | 1645 | WREG32(RADEON_DAC_EXT_CNTL, dac_ext_cntl); |
| 1533 | WREG32(RADEON_TV_DAC_CNTL, tv_dac_cntl); | 1646 | WREG32(RADEON_TV_DAC_CNTL, tv_dac_cntl); |
| 1534 | WREG32(RADEON_CRTC2_GEN_CNTL, crtc2_gen_cntl); | ||
| 1535 | 1647 | ||
| 1536 | if (ASIC_IS_R300(rdev)) { | 1648 | if (rdev->flags & RADEON_SINGLE_CRTC) { |
| 1537 | WREG32(RADEON_DISP_OUTPUT_CNTL, disp_output_cntl); | 1649 | WREG32(RADEON_CRTC_EXT_CNTL, crtc_ext_cntl); |
| 1538 | WREG32_P(RADEON_GPIOPAD_A, gpiopad_a, ~1); | ||
| 1539 | } else { | 1650 | } else { |
| 1540 | WREG32(RADEON_DISP_HW_DEBUG, disp_hw_debug); | 1651 | WREG32(RADEON_CRTC2_GEN_CNTL, crtc2_gen_cntl); |
| 1652 | if (ASIC_IS_R300(rdev)) { | ||
| 1653 | WREG32(RADEON_DISP_OUTPUT_CNTL, disp_output_cntl); | ||
| 1654 | WREG32_P(RADEON_GPIOPAD_A, gpiopad_a, ~1); | ||
| 1655 | } else { | ||
| 1656 | WREG32(RADEON_DISP_HW_DEBUG, disp_hw_debug); | ||
| 1657 | } | ||
| 1541 | } | 1658 | } |
| 1659 | |||
| 1542 | WREG32_PLL(RADEON_PIXCLKS_CNTL, pixclks_cntl); | 1660 | WREG32_PLL(RADEON_PIXCLKS_CNTL, pixclks_cntl); |
| 1543 | 1661 | ||
| 1544 | return found; | 1662 | return found; |
diff --git a/drivers/gpu/drm/radeon/radeon_object.c b/drivers/gpu/drm/radeon/radeon_object.c index 8b27dd6e3144..b91118ccef86 100644 --- a/drivers/gpu/drm/radeon/radeon_object.c +++ b/drivers/gpu/drm/radeon/radeon_object.c | |||
| @@ -105,7 +105,6 @@ int radeon_bo_create(struct radeon_device *rdev, | |||
| 105 | struct radeon_bo *bo; | 105 | struct radeon_bo *bo; |
| 106 | enum ttm_bo_type type; | 106 | enum ttm_bo_type type; |
| 107 | unsigned long page_align = roundup(byte_align, PAGE_SIZE) >> PAGE_SHIFT; | 107 | unsigned long page_align = roundup(byte_align, PAGE_SIZE) >> PAGE_SHIFT; |
| 108 | unsigned long max_size = 0; | ||
| 109 | size_t acc_size; | 108 | size_t acc_size; |
| 110 | int r; | 109 | int r; |
| 111 | 110 | ||
| @@ -121,18 +120,9 @@ int radeon_bo_create(struct radeon_device *rdev, | |||
| 121 | } | 120 | } |
| 122 | *bo_ptr = NULL; | 121 | *bo_ptr = NULL; |
| 123 | 122 | ||
| 124 | /* maximun bo size is the minimun btw visible vram and gtt size */ | ||
| 125 | max_size = min(rdev->mc.visible_vram_size, rdev->mc.gtt_size); | ||
| 126 | if ((page_align << PAGE_SHIFT) >= max_size) { | ||
| 127 | printk(KERN_WARNING "%s:%d alloc size %ldM bigger than %ldMb limit\n", | ||
| 128 | __func__, __LINE__, page_align >> (20 - PAGE_SHIFT), max_size >> 20); | ||
| 129 | return -ENOMEM; | ||
| 130 | } | ||
| 131 | |||
| 132 | acc_size = ttm_bo_dma_acc_size(&rdev->mman.bdev, size, | 123 | acc_size = ttm_bo_dma_acc_size(&rdev->mman.bdev, size, |
| 133 | sizeof(struct radeon_bo)); | 124 | sizeof(struct radeon_bo)); |
| 134 | 125 | ||
| 135 | retry: | ||
| 136 | bo = kzalloc(sizeof(struct radeon_bo), GFP_KERNEL); | 126 | bo = kzalloc(sizeof(struct radeon_bo), GFP_KERNEL); |
| 137 | if (bo == NULL) | 127 | if (bo == NULL) |
| 138 | return -ENOMEM; | 128 | return -ENOMEM; |
| @@ -154,15 +144,6 @@ retry: | |||
| 154 | acc_size, sg, &radeon_ttm_bo_destroy); | 144 | acc_size, sg, &radeon_ttm_bo_destroy); |
| 155 | up_read(&rdev->pm.mclk_lock); | 145 | up_read(&rdev->pm.mclk_lock); |
| 156 | if (unlikely(r != 0)) { | 146 | if (unlikely(r != 0)) { |
| 157 | if (r != -ERESTARTSYS) { | ||
| 158 | if (domain == RADEON_GEM_DOMAIN_VRAM) { | ||
| 159 | domain |= RADEON_GEM_DOMAIN_GTT; | ||
| 160 | goto retry; | ||
| 161 | } | ||
| 162 | dev_err(rdev->dev, | ||
| 163 | "object_init failed for (%lu, 0x%08X)\n", | ||
| 164 | size, domain); | ||
| 165 | } | ||
| 166 | return r; | 147 | return r; |
| 167 | } | 148 | } |
| 168 | *bo_ptr = bo; | 149 | *bo_ptr = bo; |
diff --git a/drivers/gpu/drm/radeon/radeon_ring.c b/drivers/gpu/drm/radeon/radeon_ring.c index bba66902c83b..47634f27f2e5 100644 --- a/drivers/gpu/drm/radeon/radeon_ring.c +++ b/drivers/gpu/drm/radeon/radeon_ring.c | |||
| @@ -305,7 +305,7 @@ void radeon_ring_write(struct radeon_ring *ring, uint32_t v) | |||
| 305 | { | 305 | { |
| 306 | #if DRM_DEBUG_CODE | 306 | #if DRM_DEBUG_CODE |
| 307 | if (ring->count_dw <= 0) { | 307 | if (ring->count_dw <= 0) { |
| 308 | DRM_ERROR("radeon: writting more dword to ring than expected !\n"); | 308 | DRM_ERROR("radeon: writing more dwords to the ring than expected!\n"); |
| 309 | } | 309 | } |
| 310 | #endif | 310 | #endif |
| 311 | ring->ring[ring->wptr++] = v; | 311 | ring->ring[ring->wptr++] = v; |
diff --git a/drivers/gpu/drm/radeon/si.c b/drivers/gpu/drm/radeon/si.c index f79633a036c3..4422d630b33b 100644 --- a/drivers/gpu/drm/radeon/si.c +++ b/drivers/gpu/drm/radeon/si.c | |||
| @@ -2407,12 +2407,13 @@ static int si_pcie_gart_enable(struct radeon_device *rdev) | |||
| 2407 | WREG32(0x15DC, 0); | 2407 | WREG32(0x15DC, 0); |
| 2408 | 2408 | ||
| 2409 | /* empty context1-15 */ | 2409 | /* empty context1-15 */ |
| 2410 | /* FIXME start with 4G, once using 2 level pt switch to full | ||
| 2411 | * vm size space | ||
| 2412 | */ | ||
| 2413 | /* set vm size, must be a multiple of 4 */ | 2410 | /* set vm size, must be a multiple of 4 */ |
| 2414 | WREG32(VM_CONTEXT1_PAGE_TABLE_START_ADDR, 0); | 2411 | WREG32(VM_CONTEXT1_PAGE_TABLE_START_ADDR, 0); |
| 2415 | WREG32(VM_CONTEXT1_PAGE_TABLE_END_ADDR, rdev->vm_manager.max_pfn); | 2412 | WREG32(VM_CONTEXT1_PAGE_TABLE_END_ADDR, rdev->vm_manager.max_pfn); |
| 2413 | /* Assign the pt base to something valid for now; the pts used for | ||
| 2414 | * the VMs are determined by the application and setup and assigned | ||
| 2415 | * on the fly in the vm part of radeon_gart.c | ||
| 2416 | */ | ||
| 2416 | for (i = 1; i < 16; i++) { | 2417 | for (i = 1; i < 16; i++) { |
| 2417 | if (i < 8) | 2418 | if (i < 8) |
| 2418 | WREG32(VM_CONTEXT0_PAGE_TABLE_BASE_ADDR + (i << 2), | 2419 | WREG32(VM_CONTEXT0_PAGE_TABLE_BASE_ADDR + (i << 2), |
| @@ -2473,6 +2474,7 @@ static bool si_vm_reg_valid(u32 reg) | |||
| 2473 | /* check config regs */ | 2474 | /* check config regs */ |
| 2474 | switch (reg) { | 2475 | switch (reg) { |
| 2475 | case GRBM_GFX_INDEX: | 2476 | case GRBM_GFX_INDEX: |
| 2477 | case CP_STRMOUT_CNTL: | ||
| 2476 | case VGT_VTX_VECT_EJECT_REG: | 2478 | case VGT_VTX_VECT_EJECT_REG: |
| 2477 | case VGT_CACHE_INVALIDATION: | 2479 | case VGT_CACHE_INVALIDATION: |
| 2478 | case VGT_ESGS_RING_SIZE: | 2480 | case VGT_ESGS_RING_SIZE: |
| @@ -2807,26 +2809,31 @@ void si_vm_set_page(struct radeon_device *rdev, uint64_t pe, | |||
| 2807 | { | 2809 | { |
| 2808 | struct radeon_ring *ring = &rdev->ring[rdev->asic->vm.pt_ring_index]; | 2810 | struct radeon_ring *ring = &rdev->ring[rdev->asic->vm.pt_ring_index]; |
| 2809 | uint32_t r600_flags = cayman_vm_page_flags(rdev, flags); | 2811 | uint32_t r600_flags = cayman_vm_page_flags(rdev, flags); |
| 2810 | int i; | ||
| 2811 | uint64_t value; | ||
| 2812 | 2812 | ||
| 2813 | radeon_ring_write(ring, PACKET3(PACKET3_WRITE_DATA, 2 + count * 2)); | 2813 | while (count) { |
| 2814 | radeon_ring_write(ring, (WRITE_DATA_ENGINE_SEL(0) | | 2814 | unsigned ndw = 2 + count * 2; |
| 2815 | WRITE_DATA_DST_SEL(1))); | 2815 | if (ndw > 0x3FFE) |
| 2816 | radeon_ring_write(ring, pe); | 2816 | ndw = 0x3FFE; |
| 2817 | radeon_ring_write(ring, upper_32_bits(pe)); | 2817 | |
| 2818 | for (i = 0; i < count; ++i) { | 2818 | radeon_ring_write(ring, PACKET3(PACKET3_WRITE_DATA, ndw)); |
| 2819 | if (flags & RADEON_VM_PAGE_SYSTEM) { | 2819 | radeon_ring_write(ring, (WRITE_DATA_ENGINE_SEL(0) | |
| 2820 | value = radeon_vm_map_gart(rdev, addr); | 2820 | WRITE_DATA_DST_SEL(1))); |
| 2821 | value &= 0xFFFFFFFFFFFFF000ULL; | 2821 | radeon_ring_write(ring, pe); |
| 2822 | } else if (flags & RADEON_VM_PAGE_VALID) | 2822 | radeon_ring_write(ring, upper_32_bits(pe)); |
| 2823 | value = addr; | 2823 | for (; ndw > 2; ndw -= 2, --count, pe += 8) { |
| 2824 | else | 2824 | uint64_t value; |
| 2825 | value = 0; | 2825 | if (flags & RADEON_VM_PAGE_SYSTEM) { |
| 2826 | addr += incr; | 2826 | value = radeon_vm_map_gart(rdev, addr); |
| 2827 | value |= r600_flags; | 2827 | value &= 0xFFFFFFFFFFFFF000ULL; |
| 2828 | radeon_ring_write(ring, value); | 2828 | } else if (flags & RADEON_VM_PAGE_VALID) |
| 2829 | radeon_ring_write(ring, upper_32_bits(value)); | 2829 | value = addr; |
| 2830 | else | ||
| 2831 | value = 0; | ||
| 2832 | addr += incr; | ||
| 2833 | value |= r600_flags; | ||
| 2834 | radeon_ring_write(ring, value); | ||
| 2835 | radeon_ring_write(ring, upper_32_bits(value)); | ||
| 2836 | } | ||
| 2830 | } | 2837 | } |
| 2831 | } | 2838 | } |
| 2832 | 2839 | ||
| @@ -2867,6 +2874,10 @@ void si_vm_flush(struct radeon_device *rdev, int ridx, struct radeon_vm *vm) | |||
| 2867 | radeon_ring_write(ring, VM_INVALIDATE_REQUEST >> 2); | 2874 | radeon_ring_write(ring, VM_INVALIDATE_REQUEST >> 2); |
| 2868 | radeon_ring_write(ring, 0); | 2875 | radeon_ring_write(ring, 0); |
| 2869 | radeon_ring_write(ring, 1 << vm->id); | 2876 | radeon_ring_write(ring, 1 << vm->id); |
| 2877 | |||
| 2878 | /* sync PFP to ME, otherwise we might get invalid PFP reads */ | ||
| 2879 | radeon_ring_write(ring, PACKET3(PACKET3_PFP_SYNC_ME, 0)); | ||
| 2880 | radeon_ring_write(ring, 0x0); | ||
| 2870 | } | 2881 | } |
| 2871 | 2882 | ||
| 2872 | /* | 2883 | /* |
diff --git a/drivers/gpu/drm/radeon/sid.h b/drivers/gpu/drm/radeon/sid.h index 7d2a20e56577..a8871afc5b4e 100644 --- a/drivers/gpu/drm/radeon/sid.h +++ b/drivers/gpu/drm/radeon/sid.h | |||
| @@ -424,6 +424,7 @@ | |||
| 424 | # define RDERR_INT_ENABLE (1 << 0) | 424 | # define RDERR_INT_ENABLE (1 << 0) |
| 425 | # define GUI_IDLE_INT_ENABLE (1 << 19) | 425 | # define GUI_IDLE_INT_ENABLE (1 << 19) |
| 426 | 426 | ||
| 427 | #define CP_STRMOUT_CNTL 0x84FC | ||
| 427 | #define SCRATCH_REG0 0x8500 | 428 | #define SCRATCH_REG0 0x8500 |
| 428 | #define SCRATCH_REG1 0x8504 | 429 | #define SCRATCH_REG1 0x8504 |
| 429 | #define SCRATCH_REG2 0x8508 | 430 | #define SCRATCH_REG2 0x8508 |
diff --git a/drivers/gpu/drm/shmobile/shmob_drm_drv.c b/drivers/gpu/drm/shmobile/shmob_drm_drv.c index c71d493fd0c5..1c350fc4e449 100644 --- a/drivers/gpu/drm/shmobile/shmob_drm_drv.c +++ b/drivers/gpu/drm/shmobile/shmob_drm_drv.c | |||
| @@ -201,6 +201,8 @@ static int shmob_drm_load(struct drm_device *dev, unsigned long flags) | |||
| 201 | goto done; | 201 | goto done; |
| 202 | } | 202 | } |
| 203 | 203 | ||
| 204 | platform_set_drvdata(pdev, sdev); | ||
| 205 | |||
| 204 | done: | 206 | done: |
| 205 | if (ret) | 207 | if (ret) |
| 206 | shmob_drm_unload(dev); | 208 | shmob_drm_unload(dev); |
| @@ -299,11 +301,9 @@ static struct drm_driver shmob_drm_driver = { | |||
| 299 | #if CONFIG_PM_SLEEP | 301 | #if CONFIG_PM_SLEEP |
| 300 | static int shmob_drm_pm_suspend(struct device *dev) | 302 | static int shmob_drm_pm_suspend(struct device *dev) |
| 301 | { | 303 | { |
| 302 | struct platform_device *pdev = to_platform_device(dev); | 304 | struct shmob_drm_device *sdev = dev_get_drvdata(dev); |
| 303 | struct drm_device *ddev = platform_get_drvdata(pdev); | ||
| 304 | struct shmob_drm_device *sdev = ddev->dev_private; | ||
| 305 | 305 | ||
| 306 | drm_kms_helper_poll_disable(ddev); | 306 | drm_kms_helper_poll_disable(sdev->ddev); |
| 307 | shmob_drm_crtc_suspend(&sdev->crtc); | 307 | shmob_drm_crtc_suspend(&sdev->crtc); |
| 308 | 308 | ||
| 309 | return 0; | 309 | return 0; |
| @@ -311,9 +311,7 @@ static int shmob_drm_pm_suspend(struct device *dev) | |||
| 311 | 311 | ||
| 312 | static int shmob_drm_pm_resume(struct device *dev) | 312 | static int shmob_drm_pm_resume(struct device *dev) |
| 313 | { | 313 | { |
| 314 | struct platform_device *pdev = to_platform_device(dev); | 314 | struct shmob_drm_device *sdev = dev_get_drvdata(dev); |
| 315 | struct drm_device *ddev = platform_get_drvdata(pdev); | ||
| 316 | struct shmob_drm_device *sdev = ddev->dev_private; | ||
| 317 | 315 | ||
| 318 | mutex_lock(&sdev->ddev->mode_config.mutex); | 316 | mutex_lock(&sdev->ddev->mode_config.mutex); |
| 319 | shmob_drm_crtc_resume(&sdev->crtc); | 317 | shmob_drm_crtc_resume(&sdev->crtc); |
diff --git a/drivers/gpu/drm/ttm/ttm_bo.c b/drivers/gpu/drm/ttm/ttm_bo.c index 402ab69f9f99..bf6e4b5a73b5 100644 --- a/drivers/gpu/drm/ttm/ttm_bo.c +++ b/drivers/gpu/drm/ttm/ttm_bo.c | |||
| @@ -580,6 +580,7 @@ retry: | |||
| 580 | if (unlikely(ret != 0)) | 580 | if (unlikely(ret != 0)) |
| 581 | return ret; | 581 | return ret; |
| 582 | 582 | ||
| 583 | retry_reserve: | ||
| 583 | spin_lock(&glob->lru_lock); | 584 | spin_lock(&glob->lru_lock); |
| 584 | 585 | ||
| 585 | if (unlikely(list_empty(&bo->ddestroy))) { | 586 | if (unlikely(list_empty(&bo->ddestroy))) { |
| @@ -587,14 +588,20 @@ retry: | |||
| 587 | return 0; | 588 | return 0; |
| 588 | } | 589 | } |
| 589 | 590 | ||
| 590 | ret = ttm_bo_reserve_locked(bo, interruptible, | 591 | ret = ttm_bo_reserve_locked(bo, false, true, false, 0); |
| 591 | no_wait_reserve, false, 0); | ||
| 592 | 592 | ||
| 593 | if (unlikely(ret != 0)) { | 593 | if (unlikely(ret == -EBUSY)) { |
| 594 | spin_unlock(&glob->lru_lock); | 594 | spin_unlock(&glob->lru_lock); |
| 595 | return ret; | 595 | if (likely(!no_wait_reserve)) |
| 596 | ret = ttm_bo_wait_unreserved(bo, interruptible); | ||
| 597 | if (unlikely(ret != 0)) | ||
| 598 | return ret; | ||
| 599 | |||
| 600 | goto retry_reserve; | ||
| 596 | } | 601 | } |
| 597 | 602 | ||
| 603 | BUG_ON(ret != 0); | ||
| 604 | |||
| 598 | /** | 605 | /** |
| 599 | * We can re-check for sync object without taking | 606 | * We can re-check for sync object without taking |
| 600 | * the bo::lock since setting the sync object requires | 607 | * the bo::lock since setting the sync object requires |
| @@ -811,17 +818,14 @@ retry: | |||
| 811 | no_wait_reserve, no_wait_gpu); | 818 | no_wait_reserve, no_wait_gpu); |
| 812 | kref_put(&bo->list_kref, ttm_bo_release_list); | 819 | kref_put(&bo->list_kref, ttm_bo_release_list); |
| 813 | 820 | ||
| 814 | if (likely(ret == 0 || ret == -ERESTARTSYS)) | 821 | return ret; |
| 815 | return ret; | ||
| 816 | |||
| 817 | goto retry; | ||
| 818 | } | 822 | } |
| 819 | 823 | ||
| 820 | ret = ttm_bo_reserve_locked(bo, false, no_wait_reserve, false, 0); | 824 | ret = ttm_bo_reserve_locked(bo, false, true, false, 0); |
| 821 | 825 | ||
| 822 | if (unlikely(ret == -EBUSY)) { | 826 | if (unlikely(ret == -EBUSY)) { |
| 823 | spin_unlock(&glob->lru_lock); | 827 | spin_unlock(&glob->lru_lock); |
| 824 | if (likely(!no_wait_gpu)) | 828 | if (likely(!no_wait_reserve)) |
| 825 | ret = ttm_bo_wait_unreserved(bo, interruptible); | 829 | ret = ttm_bo_wait_unreserved(bo, interruptible); |
| 826 | 830 | ||
| 827 | kref_put(&bo->list_kref, ttm_bo_release_list); | 831 | kref_put(&bo->list_kref, ttm_bo_release_list); |
diff --git a/drivers/gpu/drm/ttm/ttm_page_alloc.c b/drivers/gpu/drm/ttm/ttm_page_alloc.c index 860dc4813e99..bd2a3b40cd12 100644 --- a/drivers/gpu/drm/ttm/ttm_page_alloc.c +++ b/drivers/gpu/drm/ttm/ttm_page_alloc.c | |||
| @@ -749,7 +749,10 @@ static int ttm_get_pages(struct page **pages, unsigned npages, int flags, | |||
| 749 | /* clear the pages coming from the pool if requested */ | 749 | /* clear the pages coming from the pool if requested */ |
| 750 | if (flags & TTM_PAGE_FLAG_ZERO_ALLOC) { | 750 | if (flags & TTM_PAGE_FLAG_ZERO_ALLOC) { |
| 751 | list_for_each_entry(p, &plist, lru) { | 751 | list_for_each_entry(p, &plist, lru) { |
| 752 | clear_page(page_address(p)); | 752 | if (PageHighMem(p)) |
| 753 | clear_highpage(p); | ||
| 754 | else | ||
| 755 | clear_page(page_address(p)); | ||
| 753 | } | 756 | } |
| 754 | } | 757 | } |
| 755 | 758 | ||
diff --git a/drivers/gpu/drm/ttm/ttm_tt.c b/drivers/gpu/drm/ttm/ttm_tt.c index bf8260133ea9..7d759a430294 100644 --- a/drivers/gpu/drm/ttm/ttm_tt.c +++ b/drivers/gpu/drm/ttm/ttm_tt.c | |||
| @@ -308,9 +308,7 @@ int ttm_tt_swapin(struct ttm_tt *ttm) | |||
| 308 | if (unlikely(to_page == NULL)) | 308 | if (unlikely(to_page == NULL)) |
| 309 | goto out_err; | 309 | goto out_err; |
| 310 | 310 | ||
| 311 | preempt_disable(); | ||
| 312 | copy_highpage(to_page, from_page); | 311 | copy_highpage(to_page, from_page); |
| 313 | preempt_enable(); | ||
| 314 | page_cache_release(from_page); | 312 | page_cache_release(from_page); |
| 315 | } | 313 | } |
| 316 | 314 | ||
| @@ -358,9 +356,7 @@ int ttm_tt_swapout(struct ttm_tt *ttm, struct file *persistent_swap_storage) | |||
| 358 | ret = PTR_ERR(to_page); | 356 | ret = PTR_ERR(to_page); |
| 359 | goto out_err; | 357 | goto out_err; |
| 360 | } | 358 | } |
| 361 | preempt_disable(); | ||
| 362 | copy_highpage(to_page, from_page); | 359 | copy_highpage(to_page, from_page); |
| 363 | preempt_enable(); | ||
| 364 | set_page_dirty(to_page); | 360 | set_page_dirty(to_page); |
| 365 | mark_page_accessed(to_page); | 361 | mark_page_accessed(to_page); |
| 366 | page_cache_release(to_page); | 362 | page_cache_release(to_page); |
diff --git a/drivers/gpu/drm/udl/udl_drv.h b/drivers/gpu/drm/udl/udl_drv.h index fccd361f7b50..87aa5f5d3c88 100644 --- a/drivers/gpu/drm/udl/udl_drv.h +++ b/drivers/gpu/drm/udl/udl_drv.h | |||
| @@ -104,7 +104,7 @@ udl_fb_user_fb_create(struct drm_device *dev, | |||
| 104 | 104 | ||
| 105 | int udl_render_hline(struct drm_device *dev, int bpp, struct urb **urb_ptr, | 105 | int udl_render_hline(struct drm_device *dev, int bpp, struct urb **urb_ptr, |
| 106 | const char *front, char **urb_buf_ptr, | 106 | const char *front, char **urb_buf_ptr, |
| 107 | u32 byte_offset, u32 byte_width, | 107 | u32 byte_offset, u32 device_byte_offset, u32 byte_width, |
| 108 | int *ident_ptr, int *sent_ptr); | 108 | int *ident_ptr, int *sent_ptr); |
| 109 | 109 | ||
| 110 | int udl_dumb_create(struct drm_file *file_priv, | 110 | int udl_dumb_create(struct drm_file *file_priv, |
diff --git a/drivers/gpu/drm/udl/udl_fb.c b/drivers/gpu/drm/udl/udl_fb.c index 69a2b16f42a6..d4ab3beaada0 100644 --- a/drivers/gpu/drm/udl/udl_fb.c +++ b/drivers/gpu/drm/udl/udl_fb.c | |||
| @@ -114,9 +114,10 @@ static void udlfb_dpy_deferred_io(struct fb_info *info, | |||
| 114 | list_for_each_entry(cur, &fbdefio->pagelist, lru) { | 114 | list_for_each_entry(cur, &fbdefio->pagelist, lru) { |
| 115 | 115 | ||
| 116 | if (udl_render_hline(dev, (ufbdev->ufb.base.bits_per_pixel / 8), | 116 | if (udl_render_hline(dev, (ufbdev->ufb.base.bits_per_pixel / 8), |
| 117 | &urb, (char *) info->fix.smem_start, | 117 | &urb, (char *) info->fix.smem_start, |
| 118 | &cmd, cur->index << PAGE_SHIFT, | 118 | &cmd, cur->index << PAGE_SHIFT, |
| 119 | PAGE_SIZE, &bytes_identical, &bytes_sent)) | 119 | cur->index << PAGE_SHIFT, |
| 120 | PAGE_SIZE, &bytes_identical, &bytes_sent)) | ||
| 120 | goto error; | 121 | goto error; |
| 121 | bytes_rendered += PAGE_SIZE; | 122 | bytes_rendered += PAGE_SIZE; |
| 122 | } | 123 | } |
| @@ -187,10 +188,11 @@ int udl_handle_damage(struct udl_framebuffer *fb, int x, int y, | |||
| 187 | for (i = y; i < y + height ; i++) { | 188 | for (i = y; i < y + height ; i++) { |
| 188 | const int line_offset = fb->base.pitches[0] * i; | 189 | const int line_offset = fb->base.pitches[0] * i; |
| 189 | const int byte_offset = line_offset + (x * bpp); | 190 | const int byte_offset = line_offset + (x * bpp); |
| 190 | 191 | const int dev_byte_offset = (fb->base.width * bpp * i) + (x * bpp); | |
| 191 | if (udl_render_hline(dev, bpp, &urb, | 192 | if (udl_render_hline(dev, bpp, &urb, |
| 192 | (char *) fb->obj->vmapping, | 193 | (char *) fb->obj->vmapping, |
| 193 | &cmd, byte_offset, width * bpp, | 194 | &cmd, byte_offset, dev_byte_offset, |
| 195 | width * bpp, | ||
| 194 | &bytes_identical, &bytes_sent)) | 196 | &bytes_identical, &bytes_sent)) |
| 195 | goto error; | 197 | goto error; |
| 196 | } | 198 | } |
diff --git a/drivers/gpu/drm/udl/udl_transfer.c b/drivers/gpu/drm/udl/udl_transfer.c index dc095526ffb7..142fee5f983f 100644 --- a/drivers/gpu/drm/udl/udl_transfer.c +++ b/drivers/gpu/drm/udl/udl_transfer.c | |||
| @@ -213,11 +213,12 @@ static void udl_compress_hline16( | |||
| 213 | */ | 213 | */ |
| 214 | int udl_render_hline(struct drm_device *dev, int bpp, struct urb **urb_ptr, | 214 | int udl_render_hline(struct drm_device *dev, int bpp, struct urb **urb_ptr, |
| 215 | const char *front, char **urb_buf_ptr, | 215 | const char *front, char **urb_buf_ptr, |
| 216 | u32 byte_offset, u32 byte_width, | 216 | u32 byte_offset, u32 device_byte_offset, |
| 217 | u32 byte_width, | ||
| 217 | int *ident_ptr, int *sent_ptr) | 218 | int *ident_ptr, int *sent_ptr) |
| 218 | { | 219 | { |
| 219 | const u8 *line_start, *line_end, *next_pixel; | 220 | const u8 *line_start, *line_end, *next_pixel; |
| 220 | u32 base16 = 0 + (byte_offset / bpp) * 2; | 221 | u32 base16 = 0 + (device_byte_offset / bpp) * 2; |
| 221 | struct urb *urb = *urb_ptr; | 222 | struct urb *urb = *urb_ptr; |
| 222 | u8 *cmd = *urb_buf_ptr; | 223 | u8 *cmd = *urb_buf_ptr; |
| 223 | u8 *cmd_end = (u8 *) urb->transfer_buffer + urb->transfer_buffer_length; | 224 | u8 *cmd_end = (u8 *) urb->transfer_buffer + urb->transfer_buffer_length; |
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_dmabuf.c b/drivers/gpu/drm/vmwgfx/vmwgfx_dmabuf.c index 3ce68a2e312d..d1498bfd7873 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_dmabuf.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_dmabuf.c | |||
| @@ -306,7 +306,7 @@ void vmw_bo_pin(struct ttm_buffer_object *bo, bool pin) | |||
| 306 | 306 | ||
| 307 | BUG_ON(!atomic_read(&bo->reserved)); | 307 | BUG_ON(!atomic_read(&bo->reserved)); |
| 308 | BUG_ON(old_mem_type != TTM_PL_VRAM && | 308 | BUG_ON(old_mem_type != TTM_PL_VRAM && |
| 309 | old_mem_type != VMW_PL_FLAG_GMR); | 309 | old_mem_type != VMW_PL_GMR); |
| 310 | 310 | ||
| 311 | pl_flags = TTM_PL_FLAG_VRAM | VMW_PL_FLAG_GMR | TTM_PL_FLAG_CACHED; | 311 | pl_flags = TTM_PL_FLAG_VRAM | VMW_PL_FLAG_GMR | TTM_PL_FLAG_CACHED; |
| 312 | if (pin) | 312 | if (pin) |
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c index ed3c1e7ddde9..2dd185e42f21 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c | |||
| @@ -1098,6 +1098,11 @@ static void vmw_pm_complete(struct device *kdev) | |||
| 1098 | struct drm_device *dev = pci_get_drvdata(pdev); | 1098 | struct drm_device *dev = pci_get_drvdata(pdev); |
| 1099 | struct vmw_private *dev_priv = vmw_priv(dev); | 1099 | struct vmw_private *dev_priv = vmw_priv(dev); |
| 1100 | 1100 | ||
| 1101 | mutex_lock(&dev_priv->hw_mutex); | ||
| 1102 | vmw_write(dev_priv, SVGA_REG_ID, SVGA_ID_2); | ||
| 1103 | (void) vmw_read(dev_priv, SVGA_REG_ID); | ||
| 1104 | mutex_unlock(&dev_priv->hw_mutex); | ||
| 1105 | |||
| 1101 | /** | 1106 | /** |
| 1102 | * Reclaim 3d reference held by fbdev and potentially | 1107 | * Reclaim 3d reference held by fbdev and potentially |
| 1103 | * start fifo. | 1108 | * start fifo. |
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c b/drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c index b07ca2e4d04b..7290811f89be 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c | |||
| @@ -110,6 +110,8 @@ int vmw_get_cap_3d_ioctl(struct drm_device *dev, void *data, | |||
| 110 | memcpy_fromio(bounce, &fifo_mem[SVGA_FIFO_3D_CAPS], size); | 110 | memcpy_fromio(bounce, &fifo_mem[SVGA_FIFO_3D_CAPS], size); |
| 111 | 111 | ||
| 112 | ret = copy_to_user(buffer, bounce, size); | 112 | ret = copy_to_user(buffer, bounce, size); |
| 113 | if (ret) | ||
| 114 | ret = -EFAULT; | ||
| 113 | vfree(bounce); | 115 | vfree(bounce); |
| 114 | 116 | ||
| 115 | if (unlikely(ret != 0)) | 117 | if (unlikely(ret != 0)) |
diff --git a/drivers/hid/hid-apple.c b/drivers/hid/hid-apple.c index 06ebdbb6ea02..fd7722aecf77 100644 --- a/drivers/hid/hid-apple.c +++ b/drivers/hid/hid-apple.c | |||
| @@ -522,6 +522,12 @@ static const struct hid_device_id apple_devices[] = { | |||
| 522 | .driver_data = APPLE_HAS_FN | APPLE_ISO_KEYBOARD }, | 522 | .driver_data = APPLE_HAS_FN | APPLE_ISO_KEYBOARD }, |
| 523 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING7_JIS), | 523 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING7_JIS), |
| 524 | .driver_data = APPLE_HAS_FN | APPLE_RDESC_JIS }, | 524 | .driver_data = APPLE_HAS_FN | APPLE_RDESC_JIS }, |
| 525 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING7A_ANSI), | ||
| 526 | .driver_data = APPLE_HAS_FN }, | ||
| 527 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING7A_ISO), | ||
| 528 | .driver_data = APPLE_HAS_FN | APPLE_ISO_KEYBOARD }, | ||
| 529 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING7A_JIS), | ||
| 530 | .driver_data = APPLE_HAS_FN | APPLE_RDESC_JIS }, | ||
| 525 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ANSI), | 531 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ANSI), |
| 526 | .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN }, | 532 | .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN }, |
| 527 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ISO), | 533 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ISO), |
diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index bd3971bf31bf..f4109fd657ff 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c | |||
| @@ -1532,6 +1532,9 @@ static const struct hid_device_id hid_have_special_driver[] = { | |||
| 1532 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING7_ANSI) }, | 1532 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING7_ANSI) }, |
| 1533 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING7_ISO) }, | 1533 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING7_ISO) }, |
| 1534 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING7_JIS) }, | 1534 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING7_JIS) }, |
| 1535 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING7A_ANSI) }, | ||
| 1536 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING7A_ISO) }, | ||
| 1537 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING7A_JIS) }, | ||
| 1535 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ANSI) }, | 1538 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ANSI) }, |
| 1536 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ISO) }, | 1539 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ISO) }, |
| 1537 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_JIS) }, | 1540 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_JIS) }, |
| @@ -2139,6 +2142,9 @@ static const struct hid_device_id hid_mouse_ignore_list[] = { | |||
| 2139 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING7_ANSI) }, | 2142 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING7_ANSI) }, |
| 2140 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING7_ISO) }, | 2143 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING7_ISO) }, |
| 2141 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING7_JIS) }, | 2144 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING7_JIS) }, |
| 2145 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING7A_ANSI) }, | ||
| 2146 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING7A_ISO) }, | ||
| 2147 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING7A_JIS) }, | ||
| 2142 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_TP_ONLY) }, | 2148 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_TP_ONLY) }, |
| 2143 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY) }, | 2149 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY) }, |
| 2144 | { } | 2150 | { } |
diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h index 269b50912a4a..9d7a42857ea1 100644 --- a/drivers/hid/hid-ids.h +++ b/drivers/hid/hid-ids.h | |||
| @@ -118,6 +118,9 @@ | |||
| 118 | #define USB_DEVICE_ID_APPLE_WELLSPRING5A_ANSI 0x0252 | 118 | #define USB_DEVICE_ID_APPLE_WELLSPRING5A_ANSI 0x0252 |
| 119 | #define USB_DEVICE_ID_APPLE_WELLSPRING5A_ISO 0x0253 | 119 | #define USB_DEVICE_ID_APPLE_WELLSPRING5A_ISO 0x0253 |
| 120 | #define USB_DEVICE_ID_APPLE_WELLSPRING5A_JIS 0x0254 | 120 | #define USB_DEVICE_ID_APPLE_WELLSPRING5A_JIS 0x0254 |
| 121 | #define USB_DEVICE_ID_APPLE_WELLSPRING7A_ANSI 0x0259 | ||
| 122 | #define USB_DEVICE_ID_APPLE_WELLSPRING7A_ISO 0x025a | ||
| 123 | #define USB_DEVICE_ID_APPLE_WELLSPRING7A_JIS 0x025b | ||
| 121 | #define USB_DEVICE_ID_APPLE_WELLSPRING6A_ANSI 0x0249 | 124 | #define USB_DEVICE_ID_APPLE_WELLSPRING6A_ANSI 0x0249 |
| 122 | #define USB_DEVICE_ID_APPLE_WELLSPRING6A_ISO 0x024a | 125 | #define USB_DEVICE_ID_APPLE_WELLSPRING6A_ISO 0x024a |
| 123 | #define USB_DEVICE_ID_APPLE_WELLSPRING6A_JIS 0x024b | 126 | #define USB_DEVICE_ID_APPLE_WELLSPRING6A_JIS 0x024b |
diff --git a/drivers/hid/hid-microsoft.c b/drivers/hid/hid-microsoft.c index 3acdcfcc17df..6fcd466d0825 100644 --- a/drivers/hid/hid-microsoft.c +++ b/drivers/hid/hid-microsoft.c | |||
| @@ -28,22 +28,30 @@ | |||
| 28 | #define MS_RDESC 0x08 | 28 | #define MS_RDESC 0x08 |
| 29 | #define MS_NOGET 0x10 | 29 | #define MS_NOGET 0x10 |
| 30 | #define MS_DUPLICATE_USAGES 0x20 | 30 | #define MS_DUPLICATE_USAGES 0x20 |
| 31 | #define MS_RDESC_3K 0x40 | ||
| 31 | 32 | ||
| 32 | /* | ||
| 33 | * Microsoft Wireless Desktop Receiver (Model 1028) has | ||
| 34 | * 'Usage Min/Max' where it ought to have 'Physical Min/Max' | ||
| 35 | */ | ||
| 36 | static __u8 *ms_report_fixup(struct hid_device *hdev, __u8 *rdesc, | 33 | static __u8 *ms_report_fixup(struct hid_device *hdev, __u8 *rdesc, |
| 37 | unsigned int *rsize) | 34 | unsigned int *rsize) |
| 38 | { | 35 | { |
| 39 | unsigned long quirks = (unsigned long)hid_get_drvdata(hdev); | 36 | unsigned long quirks = (unsigned long)hid_get_drvdata(hdev); |
| 40 | 37 | ||
| 38 | /* | ||
| 39 | * Microsoft Wireless Desktop Receiver (Model 1028) has | ||
| 40 | * 'Usage Min/Max' where it ought to have 'Physical Min/Max' | ||
| 41 | */ | ||
| 41 | if ((quirks & MS_RDESC) && *rsize == 571 && rdesc[557] == 0x19 && | 42 | if ((quirks & MS_RDESC) && *rsize == 571 && rdesc[557] == 0x19 && |
| 42 | rdesc[559] == 0x29) { | 43 | rdesc[559] == 0x29) { |
| 43 | hid_info(hdev, "fixing up Microsoft Wireless Receiver Model 1028 report descriptor\n"); | 44 | hid_info(hdev, "fixing up Microsoft Wireless Receiver Model 1028 report descriptor\n"); |
| 44 | rdesc[557] = 0x35; | 45 | rdesc[557] = 0x35; |
| 45 | rdesc[559] = 0x45; | 46 | rdesc[559] = 0x45; |
| 46 | } | 47 | } |
| 48 | /* the same as above (s/usage/physical/) */ | ||
| 49 | if ((quirks & MS_RDESC_3K) && *rsize == 106 && rdesc[94] == 0x19 && | ||
| 50 | rdesc[95] == 0x00 && rdesc[96] == 0x29 && | ||
| 51 | rdesc[97] == 0xff) { | ||
| 52 | rdesc[94] = 0x35; | ||
| 53 | rdesc[96] = 0x45; | ||
| 54 | } | ||
| 47 | return rdesc; | 55 | return rdesc; |
| 48 | } | 56 | } |
| 49 | 57 | ||
| @@ -192,7 +200,7 @@ static const struct hid_device_id ms_devices[] = { | |||
| 192 | { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_PRESENTER_8K_USB), | 200 | { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_PRESENTER_8K_USB), |
| 193 | .driver_data = MS_PRESENTER }, | 201 | .driver_data = MS_PRESENTER }, |
| 194 | { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_DIGITAL_MEDIA_3K), | 202 | { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_DIGITAL_MEDIA_3K), |
| 195 | .driver_data = MS_ERGONOMY }, | 203 | .driver_data = MS_ERGONOMY | MS_RDESC_3K }, |
| 196 | { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_WIRELESS_OPTICAL_DESKTOP_3_0), | 204 | { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_WIRELESS_OPTICAL_DESKTOP_3_0), |
| 197 | .driver_data = MS_NOGET }, | 205 | .driver_data = MS_NOGET }, |
| 198 | { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_COMFORT_MOUSE_4500), | 206 | { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_COMFORT_MOUSE_4500), |
diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c index 3eb02b94fc87..7867d69f0efe 100644 --- a/drivers/hid/hid-multitouch.c +++ b/drivers/hid/hid-multitouch.c | |||
| @@ -210,8 +210,7 @@ static struct mt_class mt_classes[] = { | |||
| 210 | }, | 210 | }, |
| 211 | { .name = MT_CLS_GENERALTOUCH_PWT_TENFINGERS, | 211 | { .name = MT_CLS_GENERALTOUCH_PWT_TENFINGERS, |
| 212 | .quirks = MT_QUIRK_NOT_SEEN_MEANS_UP | | 212 | .quirks = MT_QUIRK_NOT_SEEN_MEANS_UP | |
| 213 | MT_QUIRK_SLOT_IS_CONTACTNUMBER, | 213 | MT_QUIRK_SLOT_IS_CONTACTNUMBER |
| 214 | .maxcontacts = 10 | ||
| 215 | }, | 214 | }, |
| 216 | 215 | ||
| 217 | { .name = MT_CLS_FLATFROG, | 216 | { .name = MT_CLS_FLATFROG, |
| @@ -421,11 +420,11 @@ static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi, | |||
| 421 | * contact max are global to the report */ | 420 | * contact max are global to the report */ |
| 422 | td->last_field_index = field->index; | 421 | td->last_field_index = field->index; |
| 423 | return -1; | 422 | return -1; |
| 424 | } | ||
| 425 | case HID_DG_TOUCH: | 423 | case HID_DG_TOUCH: |
| 426 | /* Legacy devices use TIPSWITCH and not TOUCH. | 424 | /* Legacy devices use TIPSWITCH and not TOUCH. |
| 427 | * Let's just ignore this field. */ | 425 | * Let's just ignore this field. */ |
| 428 | return -1; | 426 | return -1; |
| 427 | } | ||
| 429 | /* let hid-input decide for the others */ | 428 | /* let hid-input decide for the others */ |
| 430 | return 0; | 429 | return 0; |
| 431 | 430 | ||
diff --git a/drivers/hid/hidraw.c b/drivers/hid/hidraw.c index 17d15bb610d1..7c47fc3f7b2b 100644 --- a/drivers/hid/hidraw.c +++ b/drivers/hid/hidraw.c | |||
| @@ -42,7 +42,6 @@ static struct cdev hidraw_cdev; | |||
| 42 | static struct class *hidraw_class; | 42 | static struct class *hidraw_class; |
| 43 | static struct hidraw *hidraw_table[HIDRAW_MAX_DEVICES]; | 43 | static struct hidraw *hidraw_table[HIDRAW_MAX_DEVICES]; |
| 44 | static DEFINE_MUTEX(minors_lock); | 44 | static DEFINE_MUTEX(minors_lock); |
| 45 | static void drop_ref(struct hidraw *hid, int exists_bit); | ||
| 46 | 45 | ||
| 47 | static ssize_t hidraw_read(struct file *file, char __user *buffer, size_t count, loff_t *ppos) | 46 | static ssize_t hidraw_read(struct file *file, char __user *buffer, size_t count, loff_t *ppos) |
| 48 | { | 47 | { |
| @@ -114,7 +113,7 @@ static ssize_t hidraw_send_report(struct file *file, const char __user *buffer, | |||
| 114 | __u8 *buf; | 113 | __u8 *buf; |
| 115 | int ret = 0; | 114 | int ret = 0; |
| 116 | 115 | ||
| 117 | if (!hidraw_table[minor] || !hidraw_table[minor]->exist) { | 116 | if (!hidraw_table[minor]) { |
| 118 | ret = -ENODEV; | 117 | ret = -ENODEV; |
| 119 | goto out; | 118 | goto out; |
| 120 | } | 119 | } |
| @@ -262,7 +261,7 @@ static int hidraw_open(struct inode *inode, struct file *file) | |||
| 262 | } | 261 | } |
| 263 | 262 | ||
| 264 | mutex_lock(&minors_lock); | 263 | mutex_lock(&minors_lock); |
| 265 | if (!hidraw_table[minor] || !hidraw_table[minor]->exist) { | 264 | if (!hidraw_table[minor]) { |
| 266 | err = -ENODEV; | 265 | err = -ENODEV; |
| 267 | goto out_unlock; | 266 | goto out_unlock; |
| 268 | } | 267 | } |
| @@ -299,12 +298,36 @@ out: | |||
| 299 | static int hidraw_release(struct inode * inode, struct file * file) | 298 | static int hidraw_release(struct inode * inode, struct file * file) |
| 300 | { | 299 | { |
| 301 | unsigned int minor = iminor(inode); | 300 | unsigned int minor = iminor(inode); |
| 301 | struct hidraw *dev; | ||
| 302 | struct hidraw_list *list = file->private_data; | 302 | struct hidraw_list *list = file->private_data; |
| 303 | int ret; | ||
| 304 | int i; | ||
| 305 | |||
| 306 | mutex_lock(&minors_lock); | ||
| 307 | if (!hidraw_table[minor]) { | ||
| 308 | ret = -ENODEV; | ||
| 309 | goto unlock; | ||
| 310 | } | ||
| 303 | 311 | ||
| 304 | drop_ref(hidraw_table[minor], 0); | ||
| 305 | list_del(&list->node); | 312 | list_del(&list->node); |
| 313 | dev = hidraw_table[minor]; | ||
| 314 | if (!--dev->open) { | ||
| 315 | if (list->hidraw->exist) { | ||
| 316 | hid_hw_power(dev->hid, PM_HINT_NORMAL); | ||
| 317 | hid_hw_close(dev->hid); | ||
| 318 | } else { | ||
| 319 | kfree(list->hidraw); | ||
| 320 | } | ||
| 321 | } | ||
| 322 | |||
| 323 | for (i = 0; i < HIDRAW_BUFFER_SIZE; ++i) | ||
| 324 | kfree(list->buffer[i].value); | ||
| 306 | kfree(list); | 325 | kfree(list); |
| 307 | return 0; | 326 | ret = 0; |
| 327 | unlock: | ||
| 328 | mutex_unlock(&minors_lock); | ||
| 329 | |||
| 330 | return ret; | ||
| 308 | } | 331 | } |
| 309 | 332 | ||
| 310 | static long hidraw_ioctl(struct file *file, unsigned int cmd, | 333 | static long hidraw_ioctl(struct file *file, unsigned int cmd, |
| @@ -506,7 +529,21 @@ EXPORT_SYMBOL_GPL(hidraw_connect); | |||
| 506 | void hidraw_disconnect(struct hid_device *hid) | 529 | void hidraw_disconnect(struct hid_device *hid) |
| 507 | { | 530 | { |
| 508 | struct hidraw *hidraw = hid->hidraw; | 531 | struct hidraw *hidraw = hid->hidraw; |
| 509 | drop_ref(hidraw, 1); | 532 | |
| 533 | mutex_lock(&minors_lock); | ||
| 534 | hidraw->exist = 0; | ||
| 535 | |||
| 536 | device_destroy(hidraw_class, MKDEV(hidraw_major, hidraw->minor)); | ||
| 537 | |||
| 538 | hidraw_table[hidraw->minor] = NULL; | ||
| 539 | |||
| 540 | if (hidraw->open) { | ||
| 541 | hid_hw_close(hid); | ||
| 542 | wake_up_interruptible(&hidraw->wait); | ||
| 543 | } else { | ||
| 544 | kfree(hidraw); | ||
| 545 | } | ||
| 546 | mutex_unlock(&minors_lock); | ||
| 510 | } | 547 | } |
| 511 | EXPORT_SYMBOL_GPL(hidraw_disconnect); | 548 | EXPORT_SYMBOL_GPL(hidraw_disconnect); |
| 512 | 549 | ||
| @@ -555,23 +592,3 @@ void hidraw_exit(void) | |||
| 555 | unregister_chrdev_region(dev_id, HIDRAW_MAX_DEVICES); | 592 | unregister_chrdev_region(dev_id, HIDRAW_MAX_DEVICES); |
| 556 | 593 | ||
| 557 | } | 594 | } |
| 558 | |||
| 559 | static void drop_ref(struct hidraw *hidraw, int exists_bit) | ||
| 560 | { | ||
| 561 | mutex_lock(&minors_lock); | ||
| 562 | if (exists_bit) { | ||
| 563 | hid_hw_close(hidraw->hid); | ||
| 564 | hidraw->exist = 0; | ||
| 565 | if (hidraw->open) | ||
| 566 | wake_up_interruptible(&hidraw->wait); | ||
| 567 | } else { | ||
| 568 | --hidraw->open; | ||
| 569 | } | ||
| 570 | |||
| 571 | if (!hidraw->open && !hidraw->exist) { | ||
| 572 | device_destroy(hidraw_class, MKDEV(hidraw_major, hidraw->minor)); | ||
| 573 | hidraw_table[hidraw->minor] = NULL; | ||
| 574 | kfree(hidraw); | ||
| 575 | } | ||
| 576 | mutex_unlock(&minors_lock); | ||
| 577 | } | ||
diff --git a/drivers/hv/channel.c b/drivers/hv/channel.c index 406537420fff..f4c3d28cd1fc 100644 --- a/drivers/hv/channel.c +++ b/drivers/hv/channel.c | |||
| @@ -146,14 +146,14 @@ int vmbus_open(struct vmbus_channel *newchannel, u32 send_ringbuffer_size, | |||
| 146 | 146 | ||
| 147 | if (ret != 0) { | 147 | if (ret != 0) { |
| 148 | err = ret; | 148 | err = ret; |
| 149 | goto errorout; | 149 | goto error0; |
| 150 | } | 150 | } |
| 151 | 151 | ||
| 152 | ret = hv_ringbuffer_init( | 152 | ret = hv_ringbuffer_init( |
| 153 | &newchannel->inbound, in, recv_ringbuffer_size); | 153 | &newchannel->inbound, in, recv_ringbuffer_size); |
| 154 | if (ret != 0) { | 154 | if (ret != 0) { |
| 155 | err = ret; | 155 | err = ret; |
| 156 | goto errorout; | 156 | goto error0; |
| 157 | } | 157 | } |
| 158 | 158 | ||
| 159 | 159 | ||
| @@ -168,7 +168,7 @@ int vmbus_open(struct vmbus_channel *newchannel, u32 send_ringbuffer_size, | |||
| 168 | 168 | ||
| 169 | if (ret != 0) { | 169 | if (ret != 0) { |
| 170 | err = ret; | 170 | err = ret; |
| 171 | goto errorout; | 171 | goto error0; |
| 172 | } | 172 | } |
| 173 | 173 | ||
| 174 | /* Create and init the channel open message */ | 174 | /* Create and init the channel open message */ |
| @@ -177,7 +177,7 @@ int vmbus_open(struct vmbus_channel *newchannel, u32 send_ringbuffer_size, | |||
| 177 | GFP_KERNEL); | 177 | GFP_KERNEL); |
| 178 | if (!open_info) { | 178 | if (!open_info) { |
| 179 | err = -ENOMEM; | 179 | err = -ENOMEM; |
| 180 | goto errorout; | 180 | goto error0; |
| 181 | } | 181 | } |
| 182 | 182 | ||
| 183 | init_completion(&open_info->waitevent); | 183 | init_completion(&open_info->waitevent); |
| @@ -193,7 +193,7 @@ int vmbus_open(struct vmbus_channel *newchannel, u32 send_ringbuffer_size, | |||
| 193 | 193 | ||
| 194 | if (userdatalen > MAX_USER_DEFINED_BYTES) { | 194 | if (userdatalen > MAX_USER_DEFINED_BYTES) { |
| 195 | err = -EINVAL; | 195 | err = -EINVAL; |
| 196 | goto errorout; | 196 | goto error0; |
| 197 | } | 197 | } |
| 198 | 198 | ||
| 199 | if (userdatalen) | 199 | if (userdatalen) |
| @@ -208,19 +208,18 @@ int vmbus_open(struct vmbus_channel *newchannel, u32 send_ringbuffer_size, | |||
| 208 | sizeof(struct vmbus_channel_open_channel)); | 208 | sizeof(struct vmbus_channel_open_channel)); |
| 209 | 209 | ||
| 210 | if (ret != 0) | 210 | if (ret != 0) |
| 211 | goto cleanup; | 211 | goto error1; |
| 212 | 212 | ||
| 213 | t = wait_for_completion_timeout(&open_info->waitevent, 5*HZ); | 213 | t = wait_for_completion_timeout(&open_info->waitevent, 5*HZ); |
| 214 | if (t == 0) { | 214 | if (t == 0) { |
| 215 | err = -ETIMEDOUT; | 215 | err = -ETIMEDOUT; |
| 216 | goto errorout; | 216 | goto error1; |
| 217 | } | 217 | } |
| 218 | 218 | ||
| 219 | 219 | ||
| 220 | if (open_info->response.open_result.status) | 220 | if (open_info->response.open_result.status) |
| 221 | err = open_info->response.open_result.status; | 221 | err = open_info->response.open_result.status; |
| 222 | 222 | ||
| 223 | cleanup: | ||
| 224 | spin_lock_irqsave(&vmbus_connection.channelmsg_lock, flags); | 223 | spin_lock_irqsave(&vmbus_connection.channelmsg_lock, flags); |
| 225 | list_del(&open_info->msglistentry); | 224 | list_del(&open_info->msglistentry); |
| 226 | spin_unlock_irqrestore(&vmbus_connection.channelmsg_lock, flags); | 225 | spin_unlock_irqrestore(&vmbus_connection.channelmsg_lock, flags); |
| @@ -228,9 +227,12 @@ cleanup: | |||
| 228 | kfree(open_info); | 227 | kfree(open_info); |
| 229 | return err; | 228 | return err; |
| 230 | 229 | ||
| 231 | errorout: | 230 | error1: |
| 232 | hv_ringbuffer_cleanup(&newchannel->outbound); | 231 | spin_lock_irqsave(&vmbus_connection.channelmsg_lock, flags); |
| 233 | hv_ringbuffer_cleanup(&newchannel->inbound); | 232 | list_del(&open_info->msglistentry); |
| 233 | spin_unlock_irqrestore(&vmbus_connection.channelmsg_lock, flags); | ||
| 234 | |||
| 235 | error0: | ||
| 234 | free_pages((unsigned long)out, | 236 | free_pages((unsigned long)out, |
| 235 | get_order(send_ringbuffer_size + recv_ringbuffer_size)); | 237 | get_order(send_ringbuffer_size + recv_ringbuffer_size)); |
| 236 | kfree(open_info); | 238 | kfree(open_info); |
diff --git a/drivers/hwmon/asb100.c b/drivers/hwmon/asb100.c index a227be47149f..520e5bf4f76d 100644 --- a/drivers/hwmon/asb100.c +++ b/drivers/hwmon/asb100.c | |||
| @@ -32,7 +32,7 @@ | |||
| 32 | * ASB100-A supports pwm1, while plain ASB100 does not. There is no known | 32 | * ASB100-A supports pwm1, while plain ASB100 does not. There is no known |
| 33 | * way for the driver to tell which one is there. | 33 | * way for the driver to tell which one is there. |
| 34 | * | 34 | * |
| 35 | * Chip #vin #fanin #pwm #temp wchipid vendid i2c ISA | 35 | * Chip #vin #fanin #pwm #temp wchipid vendid i2c ISA |
| 36 | * asb100 7 3 1 4 0x31 0x0694 yes no | 36 | * asb100 7 3 1 4 0x31 0x0694 yes no |
| 37 | */ | 37 | */ |
| 38 | 38 | ||
diff --git a/drivers/hwmon/coretemp.c b/drivers/hwmon/coretemp.c index 984a3f13923b..47b8d84b489d 100644 --- a/drivers/hwmon/coretemp.c +++ b/drivers/hwmon/coretemp.c | |||
| @@ -205,8 +205,11 @@ static const struct tjmax __cpuinitconst tjmax_table[] = { | |||
| 205 | { "CPU N455", 100000 }, | 205 | { "CPU N455", 100000 }, |
| 206 | { "CPU N470", 100000 }, | 206 | { "CPU N470", 100000 }, |
| 207 | { "CPU N475", 100000 }, | 207 | { "CPU N475", 100000 }, |
| 208 | { "CPU 230", 100000 }, | 208 | { "CPU 230", 100000 }, /* Model 0x1c, stepping 2 */ |
| 209 | { "CPU 330", 125000 }, | 209 | { "CPU 330", 125000 }, /* Model 0x1c, stepping 2 */ |
| 210 | { "CPU CE4110", 110000 }, /* Model 0x1c, stepping 10 */ | ||
| 211 | { "CPU CE4150", 110000 }, /* Model 0x1c, stepping 10 */ | ||
| 212 | { "CPU CE4170", 110000 }, /* Model 0x1c, stepping 10 */ | ||
| 210 | }; | 213 | }; |
| 211 | 214 | ||
| 212 | static int __cpuinit adjust_tjmax(struct cpuinfo_x86 *c, u32 id, | 215 | static int __cpuinit adjust_tjmax(struct cpuinfo_x86 *c, u32 id, |
diff --git a/drivers/hwmon/fam15h_power.c b/drivers/hwmon/fam15h_power.c index 68ad7d255512..4f4110407387 100644 --- a/drivers/hwmon/fam15h_power.c +++ b/drivers/hwmon/fam15h_power.c | |||
| @@ -2,7 +2,7 @@ | |||
| 2 | * fam15h_power.c - AMD Family 15h processor power monitoring | 2 | * fam15h_power.c - AMD Family 15h processor power monitoring |
| 3 | * | 3 | * |
| 4 | * Copyright (c) 2011 Advanced Micro Devices, Inc. | 4 | * Copyright (c) 2011 Advanced Micro Devices, Inc. |
| 5 | * Author: Andreas Herrmann <andreas.herrmann3@amd.com> | 5 | * Author: Andreas Herrmann <herrmann.der.user@googlemail.com> |
| 6 | * | 6 | * |
| 7 | * | 7 | * |
| 8 | * This driver is free software; you can redistribute it and/or | 8 | * This driver is free software; you can redistribute it and/or |
| @@ -28,7 +28,7 @@ | |||
| 28 | #include <asm/processor.h> | 28 | #include <asm/processor.h> |
| 29 | 29 | ||
| 30 | MODULE_DESCRIPTION("AMD Family 15h CPU processor power monitor"); | 30 | MODULE_DESCRIPTION("AMD Family 15h CPU processor power monitor"); |
| 31 | MODULE_AUTHOR("Andreas Herrmann <andreas.herrmann3@amd.com>"); | 31 | MODULE_AUTHOR("Andreas Herrmann <herrmann.der.user@googlemail.com>"); |
| 32 | MODULE_LICENSE("GPL"); | 32 | MODULE_LICENSE("GPL"); |
| 33 | 33 | ||
| 34 | /* D18F3 */ | 34 | /* D18F3 */ |
diff --git a/drivers/hwmon/gpio-fan.c b/drivers/hwmon/gpio-fan.c index 36509ae32083..1381a2e3bbd4 100644 --- a/drivers/hwmon/gpio-fan.c +++ b/drivers/hwmon/gpio-fan.c | |||
| @@ -630,7 +630,9 @@ static struct platform_driver gpio_fan_driver = { | |||
| 630 | .driver = { | 630 | .driver = { |
| 631 | .name = "gpio-fan", | 631 | .name = "gpio-fan", |
| 632 | .pm = GPIO_FAN_PM, | 632 | .pm = GPIO_FAN_PM, |
| 633 | #ifdef CONFIG_OF_GPIO | ||
| 633 | .of_match_table = of_match_ptr(of_gpio_fan_match), | 634 | .of_match_table = of_match_ptr(of_gpio_fan_match), |
| 635 | #endif | ||
| 634 | }, | 636 | }, |
| 635 | }; | 637 | }; |
| 636 | 638 | ||
diff --git a/drivers/hwmon/pmbus/Kconfig b/drivers/hwmon/pmbus/Kconfig index 2ca6a5a4f5a7..60745a535821 100644 --- a/drivers/hwmon/pmbus/Kconfig +++ b/drivers/hwmon/pmbus/Kconfig | |||
| @@ -4,7 +4,7 @@ | |||
| 4 | 4 | ||
| 5 | menuconfig PMBUS | 5 | menuconfig PMBUS |
| 6 | tristate "PMBus support" | 6 | tristate "PMBus support" |
| 7 | depends on I2C && EXPERIMENTAL | 7 | depends on I2C |
| 8 | default n | 8 | default n |
| 9 | help | 9 | help |
| 10 | Say yes here if you want to enable PMBus support. | 10 | Say yes here if you want to enable PMBus support. |
diff --git a/drivers/hwmon/w83627ehf.c b/drivers/hwmon/w83627ehf.c index 1821b7423d5b..de3c7e04c3b5 100644 --- a/drivers/hwmon/w83627ehf.c +++ b/drivers/hwmon/w83627ehf.c | |||
| @@ -2083,6 +2083,7 @@ static int __devinit w83627ehf_probe(struct platform_device *pdev) | |||
| 2083 | mutex_init(&data->lock); | 2083 | mutex_init(&data->lock); |
| 2084 | mutex_init(&data->update_lock); | 2084 | mutex_init(&data->update_lock); |
| 2085 | data->name = w83627ehf_device_names[sio_data->kind]; | 2085 | data->name = w83627ehf_device_names[sio_data->kind]; |
| 2086 | data->bank = 0xff; /* Force initial bank selection */ | ||
| 2086 | platform_set_drvdata(pdev, data); | 2087 | platform_set_drvdata(pdev, data); |
| 2087 | 2088 | ||
| 2088 | /* 627EHG and 627EHF have 10 voltage inputs; 627DHG and 667HG have 9 */ | 2089 | /* 627EHG and 627EHF have 10 voltage inputs; 627DHG and 667HG have 9 */ |
diff --git a/drivers/hwmon/w83627hf.c b/drivers/hwmon/w83627hf.c index 5b1a6a666441..af1589908709 100644 --- a/drivers/hwmon/w83627hf.c +++ b/drivers/hwmon/w83627hf.c | |||
| @@ -25,7 +25,7 @@ | |||
| 25 | /* | 25 | /* |
| 26 | * Supports following chips: | 26 | * Supports following chips: |
| 27 | * | 27 | * |
| 28 | * Chip #vin #fanin #pwm #temp wchipid vendid i2c ISA | 28 | * Chip #vin #fanin #pwm #temp wchipid vendid i2c ISA |
| 29 | * w83627hf 9 3 2 3 0x20 0x5ca3 no yes(LPC) | 29 | * w83627hf 9 3 2 3 0x20 0x5ca3 no yes(LPC) |
| 30 | * w83627thf 7 3 3 3 0x90 0x5ca3 no yes(LPC) | 30 | * w83627thf 7 3 3 3 0x90 0x5ca3 no yes(LPC) |
| 31 | * w83637hf 7 3 3 3 0x80 0x5ca3 no yes(LPC) | 31 | * w83637hf 7 3 3 3 0x80 0x5ca3 no yes(LPC) |
diff --git a/drivers/hwmon/w83781d.c b/drivers/hwmon/w83781d.c index 5a5046d94c3e..20f11d31da40 100644 --- a/drivers/hwmon/w83781d.c +++ b/drivers/hwmon/w83781d.c | |||
| @@ -24,7 +24,7 @@ | |||
| 24 | /* | 24 | /* |
| 25 | * Supports following chips: | 25 | * Supports following chips: |
| 26 | * | 26 | * |
| 27 | * Chip #vin #fanin #pwm #temp wchipid vendid i2c ISA | 27 | * Chip #vin #fanin #pwm #temp wchipid vendid i2c ISA |
| 28 | * as99127f 7 3 0 3 0x31 0x12c3 yes no | 28 | * as99127f 7 3 0 3 0x31 0x12c3 yes no |
| 29 | * as99127f rev.2 (type_name = as99127f) 0x31 0x5ca3 yes no | 29 | * as99127f rev.2 (type_name = as99127f) 0x31 0x5ca3 yes no |
| 30 | * w83781d 7 3 0 3 0x10-1 0x5ca3 yes yes | 30 | * w83781d 7 3 0 3 0x10-1 0x5ca3 yes yes |
diff --git a/drivers/hwmon/w83791d.c b/drivers/hwmon/w83791d.c index 39ab7bcc616e..ed397c645198 100644 --- a/drivers/hwmon/w83791d.c +++ b/drivers/hwmon/w83791d.c | |||
| @@ -22,7 +22,7 @@ | |||
| 22 | /* | 22 | /* |
| 23 | * Supports following chips: | 23 | * Supports following chips: |
| 24 | * | 24 | * |
| 25 | * Chip #vin #fanin #pwm #temp wchipid vendid i2c ISA | 25 | * Chip #vin #fanin #pwm #temp wchipid vendid i2c ISA |
| 26 | * w83791d 10 5 5 3 0x71 0x5ca3 yes no | 26 | * w83791d 10 5 5 3 0x71 0x5ca3 yes no |
| 27 | * | 27 | * |
| 28 | * The w83791d chip appears to be part way between the 83781d and the | 28 | * The w83791d chip appears to be part way between the 83781d and the |
diff --git a/drivers/hwmon/w83792d.c b/drivers/hwmon/w83792d.c index 053645279f38..301942d08453 100644 --- a/drivers/hwmon/w83792d.c +++ b/drivers/hwmon/w83792d.c | |||
| @@ -31,7 +31,7 @@ | |||
| 31 | /* | 31 | /* |
| 32 | * Supports following chips: | 32 | * Supports following chips: |
| 33 | * | 33 | * |
| 34 | * Chip #vin #fanin #pwm #temp wchipid vendid i2c ISA | 34 | * Chip #vin #fanin #pwm #temp wchipid vendid i2c ISA |
| 35 | * w83792d 9 7 7 3 0x7a 0x5ca3 yes no | 35 | * w83792d 9 7 7 3 0x7a 0x5ca3 yes no |
| 36 | */ | 36 | */ |
| 37 | 37 | ||
diff --git a/drivers/hwmon/w83l786ng.c b/drivers/hwmon/w83l786ng.c index f0e8286c3c70..79710bcac2f7 100644 --- a/drivers/hwmon/w83l786ng.c +++ b/drivers/hwmon/w83l786ng.c | |||
| @@ -20,7 +20,7 @@ | |||
| 20 | /* | 20 | /* |
| 21 | * Supports following chips: | 21 | * Supports following chips: |
| 22 | * | 22 | * |
| 23 | * Chip #vin #fanin #pwm #temp wchipid vendid i2c ISA | 23 | * Chip #vin #fanin #pwm #temp wchipid vendid i2c ISA |
| 24 | * w83l786ng 3 2 2 2 0x7b 0x5ca3 yes no | 24 | * w83l786ng 3 2 2 2 0x7b 0x5ca3 yes no |
| 25 | */ | 25 | */ |
| 26 | 26 | ||
diff --git a/drivers/i2c/Makefile b/drivers/i2c/Makefile index beee6b2d361d..1722f50f2473 100644 --- a/drivers/i2c/Makefile +++ b/drivers/i2c/Makefile | |||
| @@ -8,6 +8,7 @@ obj-$(CONFIG_I2C_SMBUS) += i2c-smbus.o | |||
| 8 | obj-$(CONFIG_I2C_CHARDEV) += i2c-dev.o | 8 | obj-$(CONFIG_I2C_CHARDEV) += i2c-dev.o |
| 9 | obj-$(CONFIG_I2C_MUX) += i2c-mux.o | 9 | obj-$(CONFIG_I2C_MUX) += i2c-mux.o |
| 10 | obj-y += algos/ busses/ muxes/ | 10 | obj-y += algos/ busses/ muxes/ |
| 11 | obj-$(CONFIG_I2C_STUB) += i2c-stub.o | ||
| 11 | 12 | ||
| 12 | ccflags-$(CONFIG_I2C_DEBUG_CORE) := -DDEBUG | 13 | ccflags-$(CONFIG_I2C_DEBUG_CORE) := -DDEBUG |
| 13 | CFLAGS_i2c-core.o := -Wno-deprecated-declarations | 14 | CFLAGS_i2c-core.o := -Wno-deprecated-declarations |
diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig index 65dd599a0262..e9df4612b7eb 100644 --- a/drivers/i2c/busses/Kconfig +++ b/drivers/i2c/busses/Kconfig | |||
| @@ -81,7 +81,6 @@ config I2C_I801 | |||
| 81 | tristate "Intel 82801 (ICH/PCH)" | 81 | tristate "Intel 82801 (ICH/PCH)" |
| 82 | depends on PCI | 82 | depends on PCI |
| 83 | select CHECK_SIGNATURE if X86 && DMI | 83 | select CHECK_SIGNATURE if X86 && DMI |
| 84 | select GPIOLIB if I2C_MUX | ||
| 85 | help | 84 | help |
| 86 | If you say yes to this option, support will be included for the Intel | 85 | If you say yes to this option, support will be included for the Intel |
| 87 | 801 family of mainboard I2C interfaces. Specifically, the following | 86 | 801 family of mainboard I2C interfaces. Specifically, the following |
diff --git a/drivers/i2c/busses/Makefile b/drivers/i2c/busses/Makefile index 2d33d62952c1..395b516ffa08 100644 --- a/drivers/i2c/busses/Makefile +++ b/drivers/i2c/busses/Makefile | |||
| @@ -85,7 +85,6 @@ obj-$(CONFIG_I2C_ACORN) += i2c-acorn.o | |||
| 85 | obj-$(CONFIG_I2C_ELEKTOR) += i2c-elektor.o | 85 | obj-$(CONFIG_I2C_ELEKTOR) += i2c-elektor.o |
| 86 | obj-$(CONFIG_I2C_PCA_ISA) += i2c-pca-isa.o | 86 | obj-$(CONFIG_I2C_PCA_ISA) += i2c-pca-isa.o |
| 87 | obj-$(CONFIG_I2C_SIBYTE) += i2c-sibyte.o | 87 | obj-$(CONFIG_I2C_SIBYTE) += i2c-sibyte.o |
| 88 | obj-$(CONFIG_I2C_STUB) += i2c-stub.o | ||
| 89 | obj-$(CONFIG_SCx200_ACB) += scx200_acb.o | 88 | obj-$(CONFIG_SCx200_ACB) += scx200_acb.o |
| 90 | obj-$(CONFIG_SCx200_I2C) += scx200_i2c.o | 89 | obj-$(CONFIG_SCx200_I2C) += scx200_i2c.o |
| 91 | 90 | ||
diff --git a/drivers/i2c/busses/i2c-at91.c b/drivers/i2c/busses/i2c-at91.c index aa59a254be2c..c02bf208084f 100644 --- a/drivers/i2c/busses/i2c-at91.c +++ b/drivers/i2c/busses/i2c-at91.c | |||
| @@ -39,6 +39,7 @@ | |||
| 39 | #define AT91_TWI_STOP 0x0002 /* Send a Stop Condition */ | 39 | #define AT91_TWI_STOP 0x0002 /* Send a Stop Condition */ |
| 40 | #define AT91_TWI_MSEN 0x0004 /* Master Transfer Enable */ | 40 | #define AT91_TWI_MSEN 0x0004 /* Master Transfer Enable */ |
| 41 | #define AT91_TWI_SVDIS 0x0020 /* Slave Transfer Disable */ | 41 | #define AT91_TWI_SVDIS 0x0020 /* Slave Transfer Disable */ |
| 42 | #define AT91_TWI_QUICK 0x0040 /* SMBus quick command */ | ||
| 42 | #define AT91_TWI_SWRST 0x0080 /* Software Reset */ | 43 | #define AT91_TWI_SWRST 0x0080 /* Software Reset */ |
| 43 | 44 | ||
| 44 | #define AT91_TWI_MMR 0x0004 /* Master Mode Register */ | 45 | #define AT91_TWI_MMR 0x0004 /* Master Mode Register */ |
| @@ -212,7 +213,11 @@ static int at91_do_twi_transfer(struct at91_twi_dev *dev) | |||
| 212 | 213 | ||
| 213 | INIT_COMPLETION(dev->cmd_complete); | 214 | INIT_COMPLETION(dev->cmd_complete); |
| 214 | dev->transfer_status = 0; | 215 | dev->transfer_status = 0; |
| 215 | if (dev->msg->flags & I2C_M_RD) { | 216 | |
| 217 | if (!dev->buf_len) { | ||
| 218 | at91_twi_write(dev, AT91_TWI_CR, AT91_TWI_QUICK); | ||
| 219 | at91_twi_write(dev, AT91_TWI_IER, AT91_TWI_TXCOMP); | ||
| 220 | } else if (dev->msg->flags & I2C_M_RD) { | ||
| 216 | unsigned start_flags = AT91_TWI_START; | 221 | unsigned start_flags = AT91_TWI_START; |
| 217 | 222 | ||
| 218 | if (at91_twi_read(dev, AT91_TWI_SR) & AT91_TWI_RXRDY) { | 223 | if (at91_twi_read(dev, AT91_TWI_SR) & AT91_TWI_RXRDY) { |
diff --git a/drivers/i2c/busses/i2c-i801.c b/drivers/i2c/busses/i2c-i801.c index 37793156bd93..6abc00d59881 100644 --- a/drivers/i2c/busses/i2c-i801.c +++ b/drivers/i2c/busses/i2c-i801.c | |||
| @@ -82,7 +82,8 @@ | |||
| 82 | #include <linux/wait.h> | 82 | #include <linux/wait.h> |
| 83 | #include <linux/err.h> | 83 | #include <linux/err.h> |
| 84 | 84 | ||
| 85 | #if defined CONFIG_I2C_MUX || defined CONFIG_I2C_MUX_MODULE | 85 | #if (defined CONFIG_I2C_MUX_GPIO || defined CONFIG_I2C_MUX_GPIO_MODULE) && \ |
| 86 | defined CONFIG_DMI | ||
| 86 | #include <linux/gpio.h> | 87 | #include <linux/gpio.h> |
| 87 | #include <linux/i2c-mux-gpio.h> | 88 | #include <linux/i2c-mux-gpio.h> |
| 88 | #include <linux/platform_device.h> | 89 | #include <linux/platform_device.h> |
| @@ -192,7 +193,8 @@ struct i801_priv { | |||
| 192 | int len; | 193 | int len; |
| 193 | u8 *data; | 194 | u8 *data; |
| 194 | 195 | ||
| 195 | #if defined CONFIG_I2C_MUX || defined CONFIG_I2C_MUX_MODULE | 196 | #if (defined CONFIG_I2C_MUX_GPIO || defined CONFIG_I2C_MUX_GPIO_MODULE) && \ |
| 197 | defined CONFIG_DMI | ||
| 196 | const struct i801_mux_config *mux_drvdata; | 198 | const struct i801_mux_config *mux_drvdata; |
| 197 | struct platform_device *mux_pdev; | 199 | struct platform_device *mux_pdev; |
| 198 | #endif | 200 | #endif |
| @@ -921,7 +923,8 @@ static void __init input_apanel_init(void) {} | |||
| 921 | static void __devinit i801_probe_optional_slaves(struct i801_priv *priv) {} | 923 | static void __devinit i801_probe_optional_slaves(struct i801_priv *priv) {} |
| 922 | #endif /* CONFIG_X86 && CONFIG_DMI */ | 924 | #endif /* CONFIG_X86 && CONFIG_DMI */ |
| 923 | 925 | ||
| 924 | #if defined CONFIG_I2C_MUX || defined CONFIG_I2C_MUX_MODULE | 926 | #if (defined CONFIG_I2C_MUX_GPIO || defined CONFIG_I2C_MUX_GPIO_MODULE) && \ |
| 927 | defined CONFIG_DMI | ||
| 925 | static struct i801_mux_config i801_mux_config_asus_z8_d12 = { | 928 | static struct i801_mux_config i801_mux_config_asus_z8_d12 = { |
| 926 | .gpio_chip = "gpio_ich", | 929 | .gpio_chip = "gpio_ich", |
| 927 | .values = { 0x02, 0x03 }, | 930 | .values = { 0x02, 0x03 }, |
| @@ -1059,7 +1062,7 @@ static unsigned int __devinit i801_get_adapter_class(struct i801_priv *priv) | |||
| 1059 | 1062 | ||
| 1060 | id = dmi_first_match(mux_dmi_table); | 1063 | id = dmi_first_match(mux_dmi_table); |
| 1061 | if (id) { | 1064 | if (id) { |
| 1062 | /* Remove from branch classes from trunk */ | 1065 | /* Remove branch classes from trunk */ |
| 1063 | mux_config = id->driver_data; | 1066 | mux_config = id->driver_data; |
| 1064 | for (i = 0; i < mux_config->n_values; i++) | 1067 | for (i = 0; i < mux_config->n_values; i++) |
| 1065 | class &= ~mux_config->classes[i]; | 1068 | class &= ~mux_config->classes[i]; |
diff --git a/drivers/i2c/busses/i2c-mxs.c b/drivers/i2c/busses/i2c-mxs.c index 1f58197062cf..0670da79ee5e 100644 --- a/drivers/i2c/busses/i2c-mxs.c +++ b/drivers/i2c/busses/i2c-mxs.c | |||
| @@ -1,7 +1,7 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * Freescale MXS I2C bus driver | 2 | * Freescale MXS I2C bus driver |
| 3 | * | 3 | * |
| 4 | * Copyright (C) 2011 Wolfram Sang, Pengutronix e.K. | 4 | * Copyright (C) 2011-2012 Wolfram Sang, Pengutronix e.K. |
| 5 | * | 5 | * |
| 6 | * based on a (non-working) driver which was: | 6 | * based on a (non-working) driver which was: |
| 7 | * | 7 | * |
| @@ -35,10 +35,6 @@ | |||
| 35 | 35 | ||
| 36 | #define DRIVER_NAME "mxs-i2c" | 36 | #define DRIVER_NAME "mxs-i2c" |
| 37 | 37 | ||
| 38 | static bool use_pioqueue; | ||
| 39 | module_param(use_pioqueue, bool, 0); | ||
| 40 | MODULE_PARM_DESC(use_pioqueue, "Use PIOQUEUE mode for transfer instead of DMA"); | ||
| 41 | |||
| 42 | #define MXS_I2C_CTRL0 (0x00) | 38 | #define MXS_I2C_CTRL0 (0x00) |
| 43 | #define MXS_I2C_CTRL0_SET (0x04) | 39 | #define MXS_I2C_CTRL0_SET (0x04) |
| 44 | 40 | ||
| @@ -75,23 +71,6 @@ MODULE_PARM_DESC(use_pioqueue, "Use PIOQUEUE mode for transfer instead of DMA"); | |||
| 75 | MXS_I2C_CTRL1_SLAVE_STOP_IRQ | \ | 71 | MXS_I2C_CTRL1_SLAVE_STOP_IRQ | \ |
| 76 | MXS_I2C_CTRL1_SLAVE_IRQ) | 72 | MXS_I2C_CTRL1_SLAVE_IRQ) |
| 77 | 73 | ||
| 78 | #define MXS_I2C_QUEUECTRL (0x60) | ||
| 79 | #define MXS_I2C_QUEUECTRL_SET (0x64) | ||
| 80 | #define MXS_I2C_QUEUECTRL_CLR (0x68) | ||
| 81 | |||
| 82 | #define MXS_I2C_QUEUECTRL_QUEUE_RUN 0x20 | ||
| 83 | #define MXS_I2C_QUEUECTRL_PIO_QUEUE_MODE 0x04 | ||
| 84 | |||
| 85 | #define MXS_I2C_QUEUESTAT (0x70) | ||
| 86 | #define MXS_I2C_QUEUESTAT_RD_QUEUE_EMPTY 0x00002000 | ||
| 87 | #define MXS_I2C_QUEUESTAT_WRITE_QUEUE_CNT_MASK 0x0000001F | ||
| 88 | |||
| 89 | #define MXS_I2C_QUEUECMD (0x80) | ||
| 90 | |||
| 91 | #define MXS_I2C_QUEUEDATA (0x90) | ||
| 92 | |||
| 93 | #define MXS_I2C_DATA (0xa0) | ||
| 94 | |||
| 95 | 74 | ||
| 96 | #define MXS_CMD_I2C_SELECT (MXS_I2C_CTRL0_RETAIN_CLOCK | \ | 75 | #define MXS_CMD_I2C_SELECT (MXS_I2C_CTRL0_RETAIN_CLOCK | \ |
| 97 | MXS_I2C_CTRL0_PRE_SEND_START | \ | 76 | MXS_I2C_CTRL0_PRE_SEND_START | \ |
| @@ -153,7 +132,6 @@ struct mxs_i2c_dev { | |||
| 153 | const struct mxs_i2c_speed_config *speed; | 132 | const struct mxs_i2c_speed_config *speed; |
| 154 | 133 | ||
| 155 | /* DMA support components */ | 134 | /* DMA support components */ |
| 156 | bool dma_mode; | ||
| 157 | int dma_channel; | 135 | int dma_channel; |
| 158 | struct dma_chan *dmach; | 136 | struct dma_chan *dmach; |
| 159 | struct mxs_dma_data dma_data; | 137 | struct mxs_dma_data dma_data; |
| @@ -172,99 +150,6 @@ static void mxs_i2c_reset(struct mxs_i2c_dev *i2c) | |||
| 172 | writel(i2c->speed->timing2, i2c->regs + MXS_I2C_TIMING2); | 150 | writel(i2c->speed->timing2, i2c->regs + MXS_I2C_TIMING2); |
| 173 | 151 | ||
| 174 | writel(MXS_I2C_IRQ_MASK << 8, i2c->regs + MXS_I2C_CTRL1_SET); | 152 | writel(MXS_I2C_IRQ_MASK << 8, i2c->regs + MXS_I2C_CTRL1_SET); |
| 175 | if (i2c->dma_mode) | ||
| 176 | writel(MXS_I2C_QUEUECTRL_PIO_QUEUE_MODE, | ||
| 177 | i2c->regs + MXS_I2C_QUEUECTRL_CLR); | ||
| 178 | else | ||
| 179 | writel(MXS_I2C_QUEUECTRL_PIO_QUEUE_MODE, | ||
| 180 | i2c->regs + MXS_I2C_QUEUECTRL_SET); | ||
| 181 | } | ||
| 182 | |||
| 183 | static void mxs_i2c_pioq_setup_read(struct mxs_i2c_dev *i2c, u8 addr, int len, | ||
| 184 | int flags) | ||
| 185 | { | ||
| 186 | u32 data; | ||
| 187 | |||
| 188 | writel(MXS_CMD_I2C_SELECT, i2c->regs + MXS_I2C_QUEUECMD); | ||
| 189 | |||
| 190 | data = (addr << 1) | I2C_SMBUS_READ; | ||
| 191 | writel(data, i2c->regs + MXS_I2C_DATA); | ||
| 192 | |||
| 193 | data = MXS_CMD_I2C_READ | MXS_I2C_CTRL0_XFER_COUNT(len) | flags; | ||
| 194 | writel(data, i2c->regs + MXS_I2C_QUEUECMD); | ||
| 195 | } | ||
| 196 | |||
| 197 | static void mxs_i2c_pioq_setup_write(struct mxs_i2c_dev *i2c, | ||
| 198 | u8 addr, u8 *buf, int len, int flags) | ||
| 199 | { | ||
| 200 | u32 data; | ||
| 201 | int i, shifts_left; | ||
| 202 | |||
| 203 | data = MXS_CMD_I2C_WRITE | MXS_I2C_CTRL0_XFER_COUNT(len + 1) | flags; | ||
| 204 | writel(data, i2c->regs + MXS_I2C_QUEUECMD); | ||
| 205 | |||
| 206 | /* | ||
| 207 | * We have to copy the slave address (u8) and buffer (arbitrary number | ||
| 208 | * of u8) into the data register (u32). To achieve that, the u8 are put | ||
| 209 | * into the MSBs of 'data' which is then shifted for the next u8. When | ||
| 210 | * appropriate, 'data' is written to MXS_I2C_DATA. So, the first u32 | ||
| 211 | * looks like this: | ||
| 212 | * | ||
| 213 | * 3 2 1 0 | ||
| 214 | * 10987654|32109876|54321098|76543210 | ||
| 215 | * --------+--------+--------+-------- | ||
| 216 | * buffer+2|buffer+1|buffer+0|slave_addr | ||
| 217 | */ | ||
| 218 | |||
| 219 | data = ((addr << 1) | I2C_SMBUS_WRITE) << 24; | ||
| 220 | |||
| 221 | for (i = 0; i < len; i++) { | ||
| 222 | data >>= 8; | ||
| 223 | data |= buf[i] << 24; | ||
| 224 | if ((i & 3) == 2) | ||
| 225 | writel(data, i2c->regs + MXS_I2C_DATA); | ||
| 226 | } | ||
| 227 | |||
| 228 | /* Write out the remaining bytes if any */ | ||
| 229 | shifts_left = 24 - (i & 3) * 8; | ||
| 230 | if (shifts_left) | ||
| 231 | writel(data >> shifts_left, i2c->regs + MXS_I2C_DATA); | ||
| 232 | } | ||
| 233 | |||
| 234 | /* | ||
| 235 | * TODO: should be replaceable with a waitqueue and RD_QUEUE_IRQ (setting the | ||
| 236 | * rd_threshold to 1). Couldn't get this to work, though. | ||
| 237 | */ | ||
| 238 | static int mxs_i2c_wait_for_data(struct mxs_i2c_dev *i2c) | ||
| 239 | { | ||
| 240 | unsigned long timeout = jiffies + msecs_to_jiffies(1000); | ||
| 241 | |||
| 242 | while (readl(i2c->regs + MXS_I2C_QUEUESTAT) | ||
| 243 | & MXS_I2C_QUEUESTAT_RD_QUEUE_EMPTY) { | ||
| 244 | if (time_after(jiffies, timeout)) | ||
| 245 | return -ETIMEDOUT; | ||
| 246 | cond_resched(); | ||
| 247 | } | ||
| 248 | |||
| 249 | return 0; | ||
| 250 | } | ||
| 251 | |||
| 252 | static int mxs_i2c_finish_read(struct mxs_i2c_dev *i2c, u8 *buf, int len) | ||
| 253 | { | ||
| 254 | u32 uninitialized_var(data); | ||
| 255 | int i; | ||
| 256 | |||
| 257 | for (i = 0; i < len; i++) { | ||
| 258 | if ((i & 3) == 0) { | ||
| 259 | if (mxs_i2c_wait_for_data(i2c)) | ||
| 260 | return -ETIMEDOUT; | ||
| 261 | data = readl(i2c->regs + MXS_I2C_QUEUEDATA); | ||
| 262 | } | ||
| 263 | buf[i] = data & 0xff; | ||
| 264 | data >>= 8; | ||
| 265 | } | ||
| 266 | |||
| 267 | return 0; | ||
| 268 | } | 153 | } |
| 269 | 154 | ||
| 270 | static void mxs_i2c_dma_finish(struct mxs_i2c_dev *i2c) | 155 | static void mxs_i2c_dma_finish(struct mxs_i2c_dev *i2c) |
| @@ -402,12 +287,14 @@ read_init_dma_fail: | |||
| 402 | select_init_dma_fail: | 287 | select_init_dma_fail: |
| 403 | dma_unmap_sg(i2c->dev, &i2c->sg_io[0], 1, DMA_TO_DEVICE); | 288 | dma_unmap_sg(i2c->dev, &i2c->sg_io[0], 1, DMA_TO_DEVICE); |
| 404 | select_init_pio_fail: | 289 | select_init_pio_fail: |
| 290 | dmaengine_terminate_all(i2c->dmach); | ||
| 405 | return -EINVAL; | 291 | return -EINVAL; |
| 406 | 292 | ||
| 407 | /* Write failpath. */ | 293 | /* Write failpath. */ |
| 408 | write_init_dma_fail: | 294 | write_init_dma_fail: |
| 409 | dma_unmap_sg(i2c->dev, i2c->sg_io, 2, DMA_TO_DEVICE); | 295 | dma_unmap_sg(i2c->dev, i2c->sg_io, 2, DMA_TO_DEVICE); |
| 410 | write_init_pio_fail: | 296 | write_init_pio_fail: |
| 297 | dmaengine_terminate_all(i2c->dmach); | ||
| 411 | return -EINVAL; | 298 | return -EINVAL; |
| 412 | } | 299 | } |
| 413 | 300 | ||
| @@ -432,39 +319,17 @@ static int mxs_i2c_xfer_msg(struct i2c_adapter *adap, struct i2c_msg *msg, | |||
| 432 | init_completion(&i2c->cmd_complete); | 319 | init_completion(&i2c->cmd_complete); |
| 433 | i2c->cmd_err = 0; | 320 | i2c->cmd_err = 0; |
| 434 | 321 | ||
| 435 | if (i2c->dma_mode) { | 322 | ret = mxs_i2c_dma_setup_xfer(adap, msg, flags); |
| 436 | ret = mxs_i2c_dma_setup_xfer(adap, msg, flags); | 323 | if (ret) |
| 437 | if (ret) | 324 | return ret; |
| 438 | return ret; | ||
| 439 | } else { | ||
| 440 | if (msg->flags & I2C_M_RD) { | ||
| 441 | mxs_i2c_pioq_setup_read(i2c, msg->addr, | ||
| 442 | msg->len, flags); | ||
| 443 | } else { | ||
| 444 | mxs_i2c_pioq_setup_write(i2c, msg->addr, msg->buf, | ||
| 445 | msg->len, flags); | ||
| 446 | } | ||
| 447 | |||
| 448 | writel(MXS_I2C_QUEUECTRL_QUEUE_RUN, | ||
| 449 | i2c->regs + MXS_I2C_QUEUECTRL_SET); | ||
| 450 | } | ||
| 451 | 325 | ||
| 452 | ret = wait_for_completion_timeout(&i2c->cmd_complete, | 326 | ret = wait_for_completion_timeout(&i2c->cmd_complete, |
| 453 | msecs_to_jiffies(1000)); | 327 | msecs_to_jiffies(1000)); |
| 454 | if (ret == 0) | 328 | if (ret == 0) |
| 455 | goto timeout; | 329 | goto timeout; |
| 456 | 330 | ||
| 457 | if (!i2c->dma_mode && !i2c->cmd_err && (msg->flags & I2C_M_RD)) { | ||
| 458 | ret = mxs_i2c_finish_read(i2c, msg->buf, msg->len); | ||
| 459 | if (ret) | ||
| 460 | goto timeout; | ||
| 461 | } | ||
| 462 | |||
| 463 | if (i2c->cmd_err == -ENXIO) | 331 | if (i2c->cmd_err == -ENXIO) |
| 464 | mxs_i2c_reset(i2c); | 332 | mxs_i2c_reset(i2c); |
| 465 | else | ||
| 466 | writel(MXS_I2C_QUEUECTRL_QUEUE_RUN, | ||
| 467 | i2c->regs + MXS_I2C_QUEUECTRL_CLR); | ||
| 468 | 333 | ||
| 469 | dev_dbg(i2c->dev, "Done with err=%d\n", i2c->cmd_err); | 334 | dev_dbg(i2c->dev, "Done with err=%d\n", i2c->cmd_err); |
| 470 | 335 | ||
| @@ -472,8 +337,7 @@ static int mxs_i2c_xfer_msg(struct i2c_adapter *adap, struct i2c_msg *msg, | |||
| 472 | 337 | ||
| 473 | timeout: | 338 | timeout: |
| 474 | dev_dbg(i2c->dev, "Timeout!\n"); | 339 | dev_dbg(i2c->dev, "Timeout!\n"); |
| 475 | if (i2c->dma_mode) | 340 | mxs_i2c_dma_finish(i2c); |
| 476 | mxs_i2c_dma_finish(i2c); | ||
| 477 | mxs_i2c_reset(i2c); | 341 | mxs_i2c_reset(i2c); |
| 478 | return -ETIMEDOUT; | 342 | return -ETIMEDOUT; |
| 479 | } | 343 | } |
| @@ -502,7 +366,6 @@ static irqreturn_t mxs_i2c_isr(int this_irq, void *dev_id) | |||
| 502 | { | 366 | { |
| 503 | struct mxs_i2c_dev *i2c = dev_id; | 367 | struct mxs_i2c_dev *i2c = dev_id; |
| 504 | u32 stat = readl(i2c->regs + MXS_I2C_CTRL1) & MXS_I2C_IRQ_MASK; | 368 | u32 stat = readl(i2c->regs + MXS_I2C_CTRL1) & MXS_I2C_IRQ_MASK; |
| 505 | bool is_last_cmd; | ||
| 506 | 369 | ||
| 507 | if (!stat) | 370 | if (!stat) |
| 508 | return IRQ_NONE; | 371 | return IRQ_NONE; |
| @@ -515,14 +378,6 @@ static irqreturn_t mxs_i2c_isr(int this_irq, void *dev_id) | |||
| 515 | /* MXS_I2C_CTRL1_OVERSIZE_XFER_TERM_IRQ is only for slaves */ | 378 | /* MXS_I2C_CTRL1_OVERSIZE_XFER_TERM_IRQ is only for slaves */ |
| 516 | i2c->cmd_err = -EIO; | 379 | i2c->cmd_err = -EIO; |
| 517 | 380 | ||
| 518 | if (!i2c->dma_mode) { | ||
| 519 | is_last_cmd = (readl(i2c->regs + MXS_I2C_QUEUESTAT) & | ||
| 520 | MXS_I2C_QUEUESTAT_WRITE_QUEUE_CNT_MASK) == 0; | ||
| 521 | |||
| 522 | if (is_last_cmd || i2c->cmd_err) | ||
| 523 | complete(&i2c->cmd_complete); | ||
| 524 | } | ||
| 525 | |||
| 526 | writel(stat, i2c->regs + MXS_I2C_CTRL1_CLR); | 381 | writel(stat, i2c->regs + MXS_I2C_CTRL1_CLR); |
| 527 | 382 | ||
| 528 | return IRQ_HANDLED; | 383 | return IRQ_HANDLED; |
| @@ -556,23 +411,14 @@ static int mxs_i2c_get_ofdata(struct mxs_i2c_dev *i2c) | |||
| 556 | int ret; | 411 | int ret; |
| 557 | 412 | ||
| 558 | /* | 413 | /* |
| 559 | * The MXS I2C DMA mode is prefered and enabled by default. | ||
| 560 | * The PIO mode is still supported, but should be used only | ||
| 561 | * for debuging purposes etc. | ||
| 562 | */ | ||
| 563 | i2c->dma_mode = !use_pioqueue; | ||
| 564 | if (!i2c->dma_mode) | ||
| 565 | dev_info(dev, "Using PIOQUEUE mode for I2C transfers!\n"); | ||
| 566 | |||
| 567 | /* | ||
| 568 | * TODO: This is a temporary solution and should be changed | 414 | * TODO: This is a temporary solution and should be changed |
| 569 | * to use generic DMA binding later when the helpers get in. | 415 | * to use generic DMA binding later when the helpers get in. |
| 570 | */ | 416 | */ |
| 571 | ret = of_property_read_u32(node, "fsl,i2c-dma-channel", | 417 | ret = of_property_read_u32(node, "fsl,i2c-dma-channel", |
| 572 | &i2c->dma_channel); | 418 | &i2c->dma_channel); |
| 573 | if (ret) { | 419 | if (ret) { |
| 574 | dev_warn(dev, "Failed to get DMA channel, using PIOQUEUE!\n"); | 420 | dev_err(dev, "Failed to get DMA channel!\n"); |
| 575 | i2c->dma_mode = 0; | 421 | return -ENODEV; |
| 576 | } | 422 | } |
| 577 | 423 | ||
| 578 | ret = of_property_read_u32(node, "clock-frequency", &speed); | 424 | ret = of_property_read_u32(node, "clock-frequency", &speed); |
| @@ -634,15 +480,13 @@ static int __devinit mxs_i2c_probe(struct platform_device *pdev) | |||
| 634 | } | 480 | } |
| 635 | 481 | ||
| 636 | /* Setup the DMA */ | 482 | /* Setup the DMA */ |
| 637 | if (i2c->dma_mode) { | 483 | dma_cap_zero(mask); |
| 638 | dma_cap_zero(mask); | 484 | dma_cap_set(DMA_SLAVE, mask); |
| 639 | dma_cap_set(DMA_SLAVE, mask); | 485 | i2c->dma_data.chan_irq = dmairq; |
| 640 | i2c->dma_data.chan_irq = dmairq; | 486 | i2c->dmach = dma_request_channel(mask, mxs_i2c_dma_filter, i2c); |
| 641 | i2c->dmach = dma_request_channel(mask, mxs_i2c_dma_filter, i2c); | 487 | if (!i2c->dmach) { |
| 642 | if (!i2c->dmach) { | 488 | dev_err(dev, "Failed to request dma\n"); |
| 643 | dev_err(dev, "Failed to request dma\n"); | 489 | return -ENODEV; |
| 644 | return -ENODEV; | ||
| 645 | } | ||
| 646 | } | 490 | } |
| 647 | 491 | ||
| 648 | platform_set_drvdata(pdev, i2c); | 492 | platform_set_drvdata(pdev, i2c); |
diff --git a/drivers/i2c/busses/i2c-nomadik.c b/drivers/i2c/busses/i2c-nomadik.c index 698d7acb0f08..02c3115a2dfa 100644 --- a/drivers/i2c/busses/i2c-nomadik.c +++ b/drivers/i2c/busses/i2c-nomadik.c | |||
| @@ -644,7 +644,11 @@ static int nmk_i2c_xfer(struct i2c_adapter *i2c_adap, | |||
| 644 | 644 | ||
| 645 | pm_runtime_get_sync(&dev->adev->dev); | 645 | pm_runtime_get_sync(&dev->adev->dev); |
| 646 | 646 | ||
| 647 | clk_enable(dev->clk); | 647 | status = clk_prepare_enable(dev->clk); |
| 648 | if (status) { | ||
| 649 | dev_err(&dev->adev->dev, "can't prepare_enable clock\n"); | ||
| 650 | goto out_clk; | ||
| 651 | } | ||
| 648 | 652 | ||
| 649 | status = init_hw(dev); | 653 | status = init_hw(dev); |
| 650 | if (status) | 654 | if (status) |
| @@ -671,7 +675,8 @@ static int nmk_i2c_xfer(struct i2c_adapter *i2c_adap, | |||
| 671 | } | 675 | } |
| 672 | 676 | ||
| 673 | out: | 677 | out: |
| 674 | clk_disable(dev->clk); | 678 | clk_disable_unprepare(dev->clk); |
| 679 | out_clk: | ||
| 675 | pm_runtime_put_sync(&dev->adev->dev); | 680 | pm_runtime_put_sync(&dev->adev->dev); |
| 676 | 681 | ||
| 677 | dev->busy = false; | 682 | dev->busy = false; |
diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c index db31eaed6ea5..3525c9e62cb0 100644 --- a/drivers/i2c/busses/i2c-omap.c +++ b/drivers/i2c/busses/i2c-omap.c | |||
| @@ -43,7 +43,6 @@ | |||
| 43 | #include <linux/slab.h> | 43 | #include <linux/slab.h> |
| 44 | #include <linux/i2c-omap.h> | 44 | #include <linux/i2c-omap.h> |
| 45 | #include <linux/pm_runtime.h> | 45 | #include <linux/pm_runtime.h> |
| 46 | #include <linux/pm_qos.h> | ||
| 47 | 46 | ||
| 48 | /* I2C controller revisions */ | 47 | /* I2C controller revisions */ |
| 49 | #define OMAP_I2C_OMAP1_REV_2 0x20 | 48 | #define OMAP_I2C_OMAP1_REV_2 0x20 |
| @@ -187,8 +186,9 @@ struct omap_i2c_dev { | |||
| 187 | int reg_shift; /* bit shift for I2C register addresses */ | 186 | int reg_shift; /* bit shift for I2C register addresses */ |
| 188 | struct completion cmd_complete; | 187 | struct completion cmd_complete; |
| 189 | struct resource *ioarea; | 188 | struct resource *ioarea; |
| 190 | u32 latency; /* maximum MPU wkup latency */ | 189 | u32 latency; /* maximum mpu wkup latency */ |
| 191 | struct pm_qos_request pm_qos_request; | 190 | void (*set_mpu_wkup_lat)(struct device *dev, |
| 191 | long latency); | ||
| 192 | u32 speed; /* Speed of bus in kHz */ | 192 | u32 speed; /* Speed of bus in kHz */ |
| 193 | u32 dtrev; /* extra revision from DT */ | 193 | u32 dtrev; /* extra revision from DT */ |
| 194 | u32 flags; | 194 | u32 flags; |
| @@ -494,7 +494,9 @@ static void omap_i2c_resize_fifo(struct omap_i2c_dev *dev, u8 size, bool is_rx) | |||
| 494 | dev->b_hw = 1; /* Enable hardware fixes */ | 494 | dev->b_hw = 1; /* Enable hardware fixes */ |
| 495 | 495 | ||
| 496 | /* calculate wakeup latency constraint for MPU */ | 496 | /* calculate wakeup latency constraint for MPU */ |
| 497 | dev->latency = (1000000 * dev->threshold) / (1000 * dev->speed / 8); | 497 | if (dev->set_mpu_wkup_lat != NULL) |
| 498 | dev->latency = (1000000 * dev->threshold) / | ||
| 499 | (1000 * dev->speed / 8); | ||
| 498 | } | 500 | } |
| 499 | 501 | ||
| 500 | /* | 502 | /* |
| @@ -522,6 +524,9 @@ static int omap_i2c_xfer_msg(struct i2c_adapter *adap, | |||
| 522 | dev->buf = msg->buf; | 524 | dev->buf = msg->buf; |
| 523 | dev->buf_len = msg->len; | 525 | dev->buf_len = msg->len; |
| 524 | 526 | ||
| 527 | /* make sure writes to dev->buf_len are ordered */ | ||
| 528 | barrier(); | ||
| 529 | |||
| 525 | omap_i2c_write_reg(dev, OMAP_I2C_CNT_REG, dev->buf_len); | 530 | omap_i2c_write_reg(dev, OMAP_I2C_CNT_REG, dev->buf_len); |
| 526 | 531 | ||
| 527 | /* Clear the FIFO Buffers */ | 532 | /* Clear the FIFO Buffers */ |
| @@ -579,7 +584,6 @@ static int omap_i2c_xfer_msg(struct i2c_adapter *adap, | |||
| 579 | */ | 584 | */ |
| 580 | timeout = wait_for_completion_timeout(&dev->cmd_complete, | 585 | timeout = wait_for_completion_timeout(&dev->cmd_complete, |
| 581 | OMAP_I2C_TIMEOUT); | 586 | OMAP_I2C_TIMEOUT); |
| 582 | dev->buf_len = 0; | ||
| 583 | if (timeout == 0) { | 587 | if (timeout == 0) { |
| 584 | dev_err(dev->dev, "controller timed out\n"); | 588 | dev_err(dev->dev, "controller timed out\n"); |
| 585 | omap_i2c_init(dev); | 589 | omap_i2c_init(dev); |
| @@ -629,16 +633,8 @@ omap_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num) | |||
| 629 | if (r < 0) | 633 | if (r < 0) |
| 630 | goto out; | 634 | goto out; |
| 631 | 635 | ||
| 632 | /* | 636 | if (dev->set_mpu_wkup_lat != NULL) |
| 633 | * When waiting for completion of a i2c transfer, we need to | 637 | dev->set_mpu_wkup_lat(dev->dev, dev->latency); |
| 634 | * set a wake up latency constraint for the MPU. This is to | ||
| 635 | * ensure quick enough wakeup from idle, when transfer | ||
| 636 | * completes. | ||
| 637 | */ | ||
| 638 | if (dev->latency) | ||
| 639 | pm_qos_add_request(&dev->pm_qos_request, | ||
| 640 | PM_QOS_CPU_DMA_LATENCY, | ||
| 641 | dev->latency); | ||
| 642 | 638 | ||
| 643 | for (i = 0; i < num; i++) { | 639 | for (i = 0; i < num; i++) { |
| 644 | r = omap_i2c_xfer_msg(adap, &msgs[i], (i == (num - 1))); | 640 | r = omap_i2c_xfer_msg(adap, &msgs[i], (i == (num - 1))); |
| @@ -646,8 +642,8 @@ omap_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num) | |||
| 646 | break; | 642 | break; |
| 647 | } | 643 | } |
| 648 | 644 | ||
| 649 | if (dev->latency) | 645 | if (dev->set_mpu_wkup_lat != NULL) |
| 650 | pm_qos_remove_request(&dev->pm_qos_request); | 646 | dev->set_mpu_wkup_lat(dev->dev, -1); |
| 651 | 647 | ||
| 652 | if (r == 0) | 648 | if (r == 0) |
| 653 | r = num; | 649 | r = num; |
| @@ -1104,6 +1100,7 @@ omap_i2c_probe(struct platform_device *pdev) | |||
| 1104 | } else if (pdata != NULL) { | 1100 | } else if (pdata != NULL) { |
| 1105 | dev->speed = pdata->clkrate; | 1101 | dev->speed = pdata->clkrate; |
| 1106 | dev->flags = pdata->flags; | 1102 | dev->flags = pdata->flags; |
| 1103 | dev->set_mpu_wkup_lat = pdata->set_mpu_wkup_lat; | ||
| 1107 | dev->dtrev = pdata->rev; | 1104 | dev->dtrev = pdata->rev; |
| 1108 | } | 1105 | } |
| 1109 | 1106 | ||
| @@ -1159,8 +1156,9 @@ omap_i2c_probe(struct platform_device *pdev) | |||
| 1159 | dev->b_hw = 1; /* Enable hardware fixes */ | 1156 | dev->b_hw = 1; /* Enable hardware fixes */ |
| 1160 | 1157 | ||
| 1161 | /* calculate wakeup latency constraint for MPU */ | 1158 | /* calculate wakeup latency constraint for MPU */ |
| 1162 | dev->latency = (1000000 * dev->fifo_size) / | 1159 | if (dev->set_mpu_wkup_lat != NULL) |
| 1163 | (1000 * dev->speed / 8); | 1160 | dev->latency = (1000000 * dev->fifo_size) / |
| 1161 | (1000 * dev->speed / 8); | ||
| 1164 | } | 1162 | } |
| 1165 | 1163 | ||
| 1166 | /* reset ASAP, clearing any IRQs */ | 1164 | /* reset ASAP, clearing any IRQs */ |
diff --git a/drivers/i2c/busses/i2c-s3c2410.c b/drivers/i2c/busses/i2c-s3c2410.c index 3e0335f1fc60..9d902725bac9 100644 --- a/drivers/i2c/busses/i2c-s3c2410.c +++ b/drivers/i2c/busses/i2c-s3c2410.c | |||
| @@ -806,6 +806,7 @@ static int s3c24xx_i2c_parse_dt_gpio(struct s3c24xx_i2c *i2c) | |||
| 806 | dev_err(i2c->dev, "invalid gpio[%d]: %d\n", idx, gpio); | 806 | dev_err(i2c->dev, "invalid gpio[%d]: %d\n", idx, gpio); |
| 807 | goto free_gpio; | 807 | goto free_gpio; |
| 808 | } | 808 | } |
| 809 | i2c->gpios[idx] = gpio; | ||
| 809 | 810 | ||
| 810 | ret = gpio_request(gpio, "i2c-bus"); | 811 | ret = gpio_request(gpio, "i2c-bus"); |
| 811 | if (ret) { | 812 | if (ret) { |
diff --git a/drivers/i2c/busses/i2c-tegra.c b/drivers/i2c/busses/i2c-tegra.c index f981ac4e6783..dcea77bf6f50 100644 --- a/drivers/i2c/busses/i2c-tegra.c +++ b/drivers/i2c/busses/i2c-tegra.c | |||
| @@ -742,7 +742,7 @@ static int __devinit tegra_i2c_probe(struct platform_device *pdev) | |||
| 742 | } | 742 | } |
| 743 | 743 | ||
| 744 | ret = devm_request_irq(&pdev->dev, i2c_dev->irq, | 744 | ret = devm_request_irq(&pdev->dev, i2c_dev->irq, |
| 745 | tegra_i2c_isr, 0, pdev->name, i2c_dev); | 745 | tegra_i2c_isr, 0, dev_name(&pdev->dev), i2c_dev); |
| 746 | if (ret) { | 746 | if (ret) { |
| 747 | dev_err(&pdev->dev, "Failed to request irq %i\n", i2c_dev->irq); | 747 | dev_err(&pdev->dev, "Failed to request irq %i\n", i2c_dev->irq); |
| 748 | return ret; | 748 | return ret; |
diff --git a/drivers/i2c/busses/i2c-stub.c b/drivers/i2c/i2c-stub.c index b1b3447942c9..d0a9c590c3cd 100644 --- a/drivers/i2c/busses/i2c-stub.c +++ b/drivers/i2c/i2c-stub.c | |||
| @@ -2,7 +2,7 @@ | |||
| 2 | i2c-stub.c - I2C/SMBus chip emulator | 2 | i2c-stub.c - I2C/SMBus chip emulator |
| 3 | 3 | ||
| 4 | Copyright (c) 2004 Mark M. Hoffman <mhoffman@lightlink.com> | 4 | Copyright (c) 2004 Mark M. Hoffman <mhoffman@lightlink.com> |
| 5 | Copyright (C) 2007 Jean Delvare <khali@linux-fr.org> | 5 | Copyright (C) 2007, 2012 Jean Delvare <khali@linux-fr.org> |
| 6 | 6 | ||
| 7 | This program is free software; you can redistribute it and/or modify | 7 | This program is free software; you can redistribute it and/or modify |
| 8 | it under the terms of the GNU General Public License as published by | 8 | it under the terms of the GNU General Public License as published by |
| @@ -51,8 +51,8 @@ struct stub_chip { | |||
| 51 | static struct stub_chip *stub_chips; | 51 | static struct stub_chip *stub_chips; |
| 52 | 52 | ||
| 53 | /* Return negative errno on error. */ | 53 | /* Return negative errno on error. */ |
| 54 | static s32 stub_xfer(struct i2c_adapter * adap, u16 addr, unsigned short flags, | 54 | static s32 stub_xfer(struct i2c_adapter *adap, u16 addr, unsigned short flags, |
| 55 | char read_write, u8 command, int size, union i2c_smbus_data * data) | 55 | char read_write, u8 command, int size, union i2c_smbus_data *data) |
| 56 | { | 56 | { |
| 57 | s32 ret; | 57 | s32 ret; |
| 58 | int i, len; | 58 | int i, len; |
| @@ -78,14 +78,14 @@ static s32 stub_xfer(struct i2c_adapter * adap, u16 addr, unsigned short flags, | |||
| 78 | case I2C_SMBUS_BYTE: | 78 | case I2C_SMBUS_BYTE: |
| 79 | if (read_write == I2C_SMBUS_WRITE) { | 79 | if (read_write == I2C_SMBUS_WRITE) { |
| 80 | chip->pointer = command; | 80 | chip->pointer = command; |
| 81 | dev_dbg(&adap->dev, "smbus byte - addr 0x%02x, " | 81 | dev_dbg(&adap->dev, |
| 82 | "wrote 0x%02x.\n", | 82 | "smbus byte - addr 0x%02x, wrote 0x%02x.\n", |
| 83 | addr, command); | 83 | addr, command); |
| 84 | } else { | 84 | } else { |
| 85 | data->byte = chip->words[chip->pointer++] & 0xff; | 85 | data->byte = chip->words[chip->pointer++] & 0xff; |
| 86 | dev_dbg(&adap->dev, "smbus byte - addr 0x%02x, " | 86 | dev_dbg(&adap->dev, |
| 87 | "read 0x%02x.\n", | 87 | "smbus byte - addr 0x%02x, read 0x%02x.\n", |
| 88 | addr, data->byte); | 88 | addr, data->byte); |
| 89 | } | 89 | } |
| 90 | 90 | ||
| 91 | ret = 0; | 91 | ret = 0; |
| @@ -95,14 +95,14 @@ static s32 stub_xfer(struct i2c_adapter * adap, u16 addr, unsigned short flags, | |||
| 95 | if (read_write == I2C_SMBUS_WRITE) { | 95 | if (read_write == I2C_SMBUS_WRITE) { |
| 96 | chip->words[command] &= 0xff00; | 96 | chip->words[command] &= 0xff00; |
| 97 | chip->words[command] |= data->byte; | 97 | chip->words[command] |= data->byte; |
| 98 | dev_dbg(&adap->dev, "smbus byte data - addr 0x%02x, " | 98 | dev_dbg(&adap->dev, |
| 99 | "wrote 0x%02x at 0x%02x.\n", | 99 | "smbus byte data - addr 0x%02x, wrote 0x%02x at 0x%02x.\n", |
| 100 | addr, data->byte, command); | 100 | addr, data->byte, command); |
| 101 | } else { | 101 | } else { |
| 102 | data->byte = chip->words[command] & 0xff; | 102 | data->byte = chip->words[command] & 0xff; |
| 103 | dev_dbg(&adap->dev, "smbus byte data - addr 0x%02x, " | 103 | dev_dbg(&adap->dev, |
| 104 | "read 0x%02x at 0x%02x.\n", | 104 | "smbus byte data - addr 0x%02x, read 0x%02x at 0x%02x.\n", |
| 105 | addr, data->byte, command); | 105 | addr, data->byte, command); |
| 106 | } | 106 | } |
| 107 | chip->pointer = command + 1; | 107 | chip->pointer = command + 1; |
| 108 | 108 | ||
| @@ -112,14 +112,14 @@ static s32 stub_xfer(struct i2c_adapter * adap, u16 addr, unsigned short flags, | |||
| 112 | case I2C_SMBUS_WORD_DATA: | 112 | case I2C_SMBUS_WORD_DATA: |
| 113 | if (read_write == I2C_SMBUS_WRITE) { | 113 | if (read_write == I2C_SMBUS_WRITE) { |
| 114 | chip->words[command] = data->word; | 114 | chip->words[command] = data->word; |
| 115 | dev_dbg(&adap->dev, "smbus word data - addr 0x%02x, " | 115 | dev_dbg(&adap->dev, |
| 116 | "wrote 0x%04x at 0x%02x.\n", | 116 | "smbus word data - addr 0x%02x, wrote 0x%04x at 0x%02x.\n", |
| 117 | addr, data->word, command); | 117 | addr, data->word, command); |
| 118 | } else { | 118 | } else { |
| 119 | data->word = chip->words[command]; | 119 | data->word = chip->words[command]; |
| 120 | dev_dbg(&adap->dev, "smbus word data - addr 0x%02x, " | 120 | dev_dbg(&adap->dev, |
| 121 | "read 0x%04x at 0x%02x.\n", | 121 | "smbus word data - addr 0x%02x, read 0x%04x at 0x%02x.\n", |
| 122 | addr, data->word, command); | 122 | addr, data->word, command); |
| 123 | } | 123 | } |
| 124 | 124 | ||
| 125 | ret = 0; | 125 | ret = 0; |
| @@ -132,17 +132,17 @@ static s32 stub_xfer(struct i2c_adapter * adap, u16 addr, unsigned short flags, | |||
| 132 | chip->words[command + i] &= 0xff00; | 132 | chip->words[command + i] &= 0xff00; |
| 133 | chip->words[command + i] |= data->block[1 + i]; | 133 | chip->words[command + i] |= data->block[1 + i]; |
| 134 | } | 134 | } |
| 135 | dev_dbg(&adap->dev, "i2c block data - addr 0x%02x, " | 135 | dev_dbg(&adap->dev, |
| 136 | "wrote %d bytes at 0x%02x.\n", | 136 | "i2c block data - addr 0x%02x, wrote %d bytes at 0x%02x.\n", |
| 137 | addr, len, command); | 137 | addr, len, command); |
| 138 | } else { | 138 | } else { |
| 139 | for (i = 0; i < len; i++) { | 139 | for (i = 0; i < len; i++) { |
| 140 | data->block[1 + i] = | 140 | data->block[1 + i] = |
| 141 | chip->words[command + i] & 0xff; | 141 | chip->words[command + i] & 0xff; |
| 142 | } | 142 | } |
| 143 | dev_dbg(&adap->dev, "i2c block data - addr 0x%02x, " | 143 | dev_dbg(&adap->dev, |
| 144 | "read %d bytes at 0x%02x.\n", | 144 | "i2c block data - addr 0x%02x, read %d bytes at 0x%02x.\n", |
| 145 | addr, len, command); | 145 | addr, len, command); |
| 146 | } | 146 | } |
| 147 | 147 | ||
| 148 | ret = 0; | 148 | ret = 0; |
| @@ -179,25 +179,24 @@ static int __init i2c_stub_init(void) | |||
| 179 | int i, ret; | 179 | int i, ret; |
| 180 | 180 | ||
| 181 | if (!chip_addr[0]) { | 181 | if (!chip_addr[0]) { |
| 182 | printk(KERN_ERR "i2c-stub: Please specify a chip address\n"); | 182 | pr_err("i2c-stub: Please specify a chip address\n"); |
| 183 | return -ENODEV; | 183 | return -ENODEV; |
| 184 | } | 184 | } |
| 185 | 185 | ||
| 186 | for (i = 0; i < MAX_CHIPS && chip_addr[i]; i++) { | 186 | for (i = 0; i < MAX_CHIPS && chip_addr[i]; i++) { |
| 187 | if (chip_addr[i] < 0x03 || chip_addr[i] > 0x77) { | 187 | if (chip_addr[i] < 0x03 || chip_addr[i] > 0x77) { |
| 188 | printk(KERN_ERR "i2c-stub: Invalid chip address " | 188 | pr_err("i2c-stub: Invalid chip address 0x%02x\n", |
| 189 | "0x%02x\n", chip_addr[i]); | 189 | chip_addr[i]); |
| 190 | return -EINVAL; | 190 | return -EINVAL; |
| 191 | } | 191 | } |
| 192 | 192 | ||
| 193 | printk(KERN_INFO "i2c-stub: Virtual chip at 0x%02x\n", | 193 | pr_info("i2c-stub: Virtual chip at 0x%02x\n", chip_addr[i]); |
| 194 | chip_addr[i]); | ||
| 195 | } | 194 | } |
| 196 | 195 | ||
| 197 | /* Allocate memory for all chips at once */ | 196 | /* Allocate memory for all chips at once */ |
| 198 | stub_chips = kzalloc(i * sizeof(struct stub_chip), GFP_KERNEL); | 197 | stub_chips = kzalloc(i * sizeof(struct stub_chip), GFP_KERNEL); |
| 199 | if (!stub_chips) { | 198 | if (!stub_chips) { |
| 200 | printk(KERN_ERR "i2c-stub: Out of memory\n"); | 199 | pr_err("i2c-stub: Out of memory\n"); |
| 201 | return -ENOMEM; | 200 | return -ENOMEM; |
| 202 | } | 201 | } |
| 203 | 202 | ||
| @@ -219,4 +218,3 @@ MODULE_LICENSE("GPL"); | |||
| 219 | 218 | ||
| 220 | module_init(i2c_stub_init); | 219 | module_init(i2c_stub_init); |
| 221 | module_exit(i2c_stub_exit); | 220 | module_exit(i2c_stub_exit); |
| 222 | |||
diff --git a/drivers/i2c/muxes/i2c-mux-pinctrl.c b/drivers/i2c/muxes/i2c-mux-pinctrl.c index 5f097f309b9f..7fa5b24b16db 100644 --- a/drivers/i2c/muxes/i2c-mux-pinctrl.c +++ b/drivers/i2c/muxes/i2c-mux-pinctrl.c | |||
| @@ -169,7 +169,7 @@ static int __devinit i2c_mux_pinctrl_probe(struct platform_device *pdev) | |||
| 169 | mux->busses = devm_kzalloc(&pdev->dev, | 169 | mux->busses = devm_kzalloc(&pdev->dev, |
| 170 | sizeof(mux->busses) * mux->pdata->bus_count, | 170 | sizeof(mux->busses) * mux->pdata->bus_count, |
| 171 | GFP_KERNEL); | 171 | GFP_KERNEL); |
| 172 | if (!mux->states) { | 172 | if (!mux->busses) { |
| 173 | dev_err(&pdev->dev, "Cannot allocate busses\n"); | 173 | dev_err(&pdev->dev, "Cannot allocate busses\n"); |
| 174 | ret = -ENOMEM; | 174 | ret = -ENOMEM; |
| 175 | goto err; | 175 | goto err; |
diff --git a/drivers/iio/Kconfig b/drivers/iio/Kconfig index 6e3f143fc71d..fc937aca71fb 100644 --- a/drivers/iio/Kconfig +++ b/drivers/iio/Kconfig | |||
| @@ -62,7 +62,6 @@ source "drivers/iio/frequency/Kconfig" | |||
| 62 | source "drivers/iio/dac/Kconfig" | 62 | source "drivers/iio/dac/Kconfig" |
| 63 | source "drivers/iio/common/Kconfig" | 63 | source "drivers/iio/common/Kconfig" |
| 64 | source "drivers/iio/gyro/Kconfig" | 64 | source "drivers/iio/gyro/Kconfig" |
| 65 | source "drivers/iio/light/Kconfig" | ||
| 66 | source "drivers/iio/magnetometer/Kconfig" | 65 | source "drivers/iio/magnetometer/Kconfig" |
| 67 | 66 | ||
| 68 | endif # IIO | 67 | endif # IIO |
diff --git a/drivers/iio/Makefile b/drivers/iio/Makefile index f7fa3c0867b4..761f2b65ac52 100644 --- a/drivers/iio/Makefile +++ b/drivers/iio/Makefile | |||
| @@ -18,5 +18,4 @@ obj-y += frequency/ | |||
| 18 | obj-y += dac/ | 18 | obj-y += dac/ |
| 19 | obj-y += common/ | 19 | obj-y += common/ |
| 20 | obj-y += gyro/ | 20 | obj-y += gyro/ |
| 21 | obj-y += light/ | ||
| 22 | obj-y += magnetometer/ | 21 | obj-y += magnetometer/ |
diff --git a/drivers/infiniband/hw/cxgb4/mem.c b/drivers/infiniband/hw/cxgb4/mem.c index 57e07c61ace2..afd81790ab3c 100644 --- a/drivers/infiniband/hw/cxgb4/mem.c +++ b/drivers/infiniband/hw/cxgb4/mem.c | |||
| @@ -468,7 +468,7 @@ struct ib_mr *c4iw_register_phys_mem(struct ib_pd *pd, | |||
| 468 | ret = alloc_pbl(mhp, npages); | 468 | ret = alloc_pbl(mhp, npages); |
| 469 | if (ret) { | 469 | if (ret) { |
| 470 | kfree(page_list); | 470 | kfree(page_list); |
| 471 | goto err_pbl; | 471 | goto err; |
| 472 | } | 472 | } |
| 473 | 473 | ||
| 474 | ret = write_pbl(&mhp->rhp->rdev, page_list, mhp->attr.pbl_addr, | 474 | ret = write_pbl(&mhp->rhp->rdev, page_list, mhp->attr.pbl_addr, |
diff --git a/drivers/infiniband/hw/mlx4/alias_GUID.c b/drivers/infiniband/hw/mlx4/alias_GUID.c index d2fb38d43571..2f215b93db6b 100644 --- a/drivers/infiniband/hw/mlx4/alias_GUID.c +++ b/drivers/infiniband/hw/mlx4/alias_GUID.c | |||
| @@ -107,7 +107,7 @@ static __be64 get_cached_alias_guid(struct mlx4_ib_dev *dev, int port, int index | |||
| 107 | { | 107 | { |
| 108 | if (index >= NUM_ALIAS_GUID_PER_PORT) { | 108 | if (index >= NUM_ALIAS_GUID_PER_PORT) { |
| 109 | pr_err("%s: ERROR: asked for index:%d\n", __func__, index); | 109 | pr_err("%s: ERROR: asked for index:%d\n", __func__, index); |
| 110 | return (__force __be64) ((u64) 0xFFFFFFFFFFFFFFFFUL); | 110 | return (__force __be64) -1; |
| 111 | } | 111 | } |
| 112 | return *(__be64 *)&dev->sriov.demux[port - 1].guid_cache[index]; | 112 | return *(__be64 *)&dev->sriov.demux[port - 1].guid_cache[index]; |
| 113 | } | 113 | } |
diff --git a/drivers/infiniband/hw/mlx4/mad.c b/drivers/infiniband/hw/mlx4/mad.c index 21a794152d15..0a903c129f0a 100644 --- a/drivers/infiniband/hw/mlx4/mad.c +++ b/drivers/infiniband/hw/mlx4/mad.c | |||
| @@ -409,38 +409,45 @@ int mlx4_ib_find_real_gid(struct ib_device *ibdev, u8 port, __be64 guid) | |||
| 409 | } | 409 | } |
| 410 | 410 | ||
| 411 | 411 | ||
| 412 | static int get_pkey_phys_indices(struct mlx4_ib_dev *ibdev, u8 port, u8 ph_pkey_ix, | 412 | static int find_slave_port_pkey_ix(struct mlx4_ib_dev *dev, int slave, |
| 413 | u8 *full_pk_ix, u8 *partial_pk_ix, | 413 | u8 port, u16 pkey, u16 *ix) |
| 414 | int *is_full_member) | ||
| 415 | { | 414 | { |
| 416 | u16 search_pkey; | 415 | int i, ret; |
| 417 | int fm; | 416 | u8 unassigned_pkey_ix, pkey_ix, partial_ix = 0xFF; |
| 418 | int err = 0; | 417 | u16 slot_pkey; |
| 419 | u16 pk; | ||
| 420 | 418 | ||
| 421 | err = ib_get_cached_pkey(&ibdev->ib_dev, port, ph_pkey_ix, &search_pkey); | 419 | if (slave == mlx4_master_func_num(dev->dev)) |
| 422 | if (err) | 420 | return ib_find_cached_pkey(&dev->ib_dev, port, pkey, ix); |
| 423 | return err; | ||
| 424 | 421 | ||
| 425 | fm = (search_pkey & 0x8000) ? 1 : 0; | 422 | unassigned_pkey_ix = dev->dev->phys_caps.pkey_phys_table_len[port] - 1; |
| 426 | if (fm) { | ||
| 427 | *full_pk_ix = ph_pkey_ix; | ||
| 428 | search_pkey &= 0x7FFF; | ||
| 429 | } else { | ||
| 430 | *partial_pk_ix = ph_pkey_ix; | ||
| 431 | search_pkey |= 0x8000; | ||
| 432 | } | ||
| 433 | 423 | ||
| 434 | if (ib_find_exact_cached_pkey(&ibdev->ib_dev, port, search_pkey, &pk)) | 424 | for (i = 0; i < dev->dev->caps.pkey_table_len[port]; i++) { |
| 435 | pk = 0xFFFF; | 425 | if (dev->pkeys.virt2phys_pkey[slave][port - 1][i] == unassigned_pkey_ix) |
| 426 | continue; | ||
| 436 | 427 | ||
| 437 | if (fm) | 428 | pkey_ix = dev->pkeys.virt2phys_pkey[slave][port - 1][i]; |
| 438 | *partial_pk_ix = (pk & 0xFF); | ||
| 439 | else | ||
| 440 | *full_pk_ix = (pk & 0xFF); | ||
| 441 | 429 | ||
| 442 | *is_full_member = fm; | 430 | ret = ib_get_cached_pkey(&dev->ib_dev, port, pkey_ix, &slot_pkey); |
| 443 | return err; | 431 | if (ret) |
| 432 | continue; | ||
| 433 | if ((slot_pkey & 0x7FFF) == (pkey & 0x7FFF)) { | ||
| 434 | if (slot_pkey & 0x8000) { | ||
| 435 | *ix = (u16) pkey_ix; | ||
| 436 | return 0; | ||
| 437 | } else { | ||
| 438 | /* take first partial pkey index found */ | ||
| 439 | if (partial_ix == 0xFF) | ||
| 440 | partial_ix = pkey_ix; | ||
| 441 | } | ||
| 442 | } | ||
| 443 | } | ||
| 444 | |||
| 445 | if (partial_ix < 0xFF) { | ||
| 446 | *ix = (u16) partial_ix; | ||
| 447 | return 0; | ||
| 448 | } | ||
| 449 | |||
| 450 | return -EINVAL; | ||
| 444 | } | 451 | } |
| 445 | 452 | ||
| 446 | int mlx4_ib_send_to_slave(struct mlx4_ib_dev *dev, int slave, u8 port, | 453 | int mlx4_ib_send_to_slave(struct mlx4_ib_dev *dev, int slave, u8 port, |
| @@ -458,10 +465,8 @@ int mlx4_ib_send_to_slave(struct mlx4_ib_dev *dev, int slave, u8 port, | |||
| 458 | unsigned tun_tx_ix = 0; | 465 | unsigned tun_tx_ix = 0; |
| 459 | int dqpn; | 466 | int dqpn; |
| 460 | int ret = 0; | 467 | int ret = 0; |
| 461 | int i; | ||
| 462 | int is_full_member = 0; | ||
| 463 | u16 tun_pkey_ix; | 468 | u16 tun_pkey_ix; |
| 464 | u8 ph_pkey_ix, full_pk_ix = 0, partial_pk_ix = 0; | 469 | u16 cached_pkey; |
| 465 | 470 | ||
| 466 | if (dest_qpt > IB_QPT_GSI) | 471 | if (dest_qpt > IB_QPT_GSI) |
| 467 | return -EINVAL; | 472 | return -EINVAL; |
| @@ -481,27 +486,17 @@ int mlx4_ib_send_to_slave(struct mlx4_ib_dev *dev, int slave, u8 port, | |||
| 481 | else | 486 | else |
| 482 | tun_qp = &tun_ctx->qp[1]; | 487 | tun_qp = &tun_ctx->qp[1]; |
| 483 | 488 | ||
| 484 | /* compute pkey index for slave */ | 489 | /* compute P_Key index to put in tunnel header for slave */ |
| 485 | /* get physical pkey -- virtualized Dom0 pkey to phys*/ | ||
| 486 | if (dest_qpt) { | 490 | if (dest_qpt) { |
| 487 | ph_pkey_ix = | 491 | u16 pkey_ix; |
| 488 | dev->pkeys.virt2phys_pkey[mlx4_master_func_num(dev->dev)][port - 1][wc->pkey_index]; | 492 | ret = ib_get_cached_pkey(&dev->ib_dev, port, wc->pkey_index, &cached_pkey); |
| 489 | |||
| 490 | /* now, translate this to the slave pkey index */ | ||
| 491 | ret = get_pkey_phys_indices(dev, port, ph_pkey_ix, &full_pk_ix, | ||
| 492 | &partial_pk_ix, &is_full_member); | ||
| 493 | if (ret) | 493 | if (ret) |
| 494 | return -EINVAL; | 494 | return -EINVAL; |
| 495 | 495 | ||
| 496 | for (i = 0; i < dev->dev->caps.pkey_table_len[port]; i++) { | 496 | ret = find_slave_port_pkey_ix(dev, slave, port, cached_pkey, &pkey_ix); |
| 497 | if ((dev->pkeys.virt2phys_pkey[slave][port - 1][i] == full_pk_ix) || | 497 | if (ret) |
| 498 | (is_full_member && | ||
| 499 | (dev->pkeys.virt2phys_pkey[slave][port - 1][i] == partial_pk_ix))) | ||
| 500 | break; | ||
| 501 | } | ||
| 502 | if (i == dev->dev->caps.pkey_table_len[port]) | ||
| 503 | return -EINVAL; | 498 | return -EINVAL; |
| 504 | tun_pkey_ix = i; | 499 | tun_pkey_ix = pkey_ix; |
| 505 | } else | 500 | } else |
| 506 | tun_pkey_ix = dev->pkeys.virt2phys_pkey[slave][port - 1][0]; | 501 | tun_pkey_ix = dev->pkeys.virt2phys_pkey[slave][port - 1][0]; |
| 507 | 502 | ||
diff --git a/drivers/infiniband/hw/mlx4/mcg.c b/drivers/infiniband/hw/mlx4/mcg.c index 3c3b54c3fdd9..25b2cdff00f8 100644 --- a/drivers/infiniband/hw/mlx4/mcg.c +++ b/drivers/infiniband/hw/mlx4/mcg.c | |||
| @@ -233,7 +233,8 @@ static int send_mad_to_slave(int slave, struct mlx4_ib_demux_ctx *ctx, | |||
| 233 | 233 | ||
| 234 | ib_query_ah(dev->sm_ah[ctx->port - 1], &ah_attr); | 234 | ib_query_ah(dev->sm_ah[ctx->port - 1], &ah_attr); |
| 235 | 235 | ||
| 236 | wc.pkey_index = 0; | 236 | if (ib_find_cached_pkey(&dev->ib_dev, ctx->port, IB_DEFAULT_PKEY_FULL, &wc.pkey_index)) |
| 237 | return -EINVAL; | ||
| 237 | wc.sl = 0; | 238 | wc.sl = 0; |
| 238 | wc.dlid_path_bits = 0; | 239 | wc.dlid_path_bits = 0; |
| 239 | wc.port_num = ctx->port; | 240 | wc.port_num = ctx->port; |
| @@ -1074,10 +1075,6 @@ static void _mlx4_ib_mcg_port_cleanup(struct mlx4_ib_demux_ctx *ctx, int destroy | |||
| 1074 | unsigned long end; | 1075 | unsigned long end; |
| 1075 | int count; | 1076 | int count; |
| 1076 | 1077 | ||
| 1077 | if (ctx->flushing) | ||
| 1078 | return; | ||
| 1079 | |||
| 1080 | ctx->flushing = 1; | ||
| 1081 | for (i = 0; i < MAX_VFS; ++i) | 1078 | for (i = 0; i < MAX_VFS; ++i) |
| 1082 | clean_vf_mcast(ctx, i); | 1079 | clean_vf_mcast(ctx, i); |
| 1083 | 1080 | ||
| @@ -1107,9 +1104,6 @@ static void _mlx4_ib_mcg_port_cleanup(struct mlx4_ib_demux_ctx *ctx, int destroy | |||
| 1107 | force_clean_group(group); | 1104 | force_clean_group(group); |
| 1108 | } | 1105 | } |
| 1109 | mutex_unlock(&ctx->mcg_table_lock); | 1106 | mutex_unlock(&ctx->mcg_table_lock); |
| 1110 | |||
| 1111 | if (!destroy_wq) | ||
| 1112 | ctx->flushing = 0; | ||
| 1113 | } | 1107 | } |
| 1114 | 1108 | ||
| 1115 | struct clean_work { | 1109 | struct clean_work { |
| @@ -1123,6 +1117,7 @@ static void mcg_clean_task(struct work_struct *work) | |||
| 1123 | struct clean_work *cw = container_of(work, struct clean_work, work); | 1117 | struct clean_work *cw = container_of(work, struct clean_work, work); |
| 1124 | 1118 | ||
| 1125 | _mlx4_ib_mcg_port_cleanup(cw->ctx, cw->destroy_wq); | 1119 | _mlx4_ib_mcg_port_cleanup(cw->ctx, cw->destroy_wq); |
| 1120 | cw->ctx->flushing = 0; | ||
| 1126 | kfree(cw); | 1121 | kfree(cw); |
| 1127 | } | 1122 | } |
| 1128 | 1123 | ||
| @@ -1130,13 +1125,20 @@ void mlx4_ib_mcg_port_cleanup(struct mlx4_ib_demux_ctx *ctx, int destroy_wq) | |||
| 1130 | { | 1125 | { |
| 1131 | struct clean_work *work; | 1126 | struct clean_work *work; |
| 1132 | 1127 | ||
| 1128 | if (ctx->flushing) | ||
| 1129 | return; | ||
| 1130 | |||
| 1131 | ctx->flushing = 1; | ||
| 1132 | |||
| 1133 | if (destroy_wq) { | 1133 | if (destroy_wq) { |
| 1134 | _mlx4_ib_mcg_port_cleanup(ctx, destroy_wq); | 1134 | _mlx4_ib_mcg_port_cleanup(ctx, destroy_wq); |
| 1135 | ctx->flushing = 0; | ||
| 1135 | return; | 1136 | return; |
| 1136 | } | 1137 | } |
| 1137 | 1138 | ||
| 1138 | work = kmalloc(sizeof *work, GFP_KERNEL); | 1139 | work = kmalloc(sizeof *work, GFP_KERNEL); |
| 1139 | if (!work) { | 1140 | if (!work) { |
| 1141 | ctx->flushing = 0; | ||
| 1140 | mcg_warn("failed allocating work for cleanup\n"); | 1142 | mcg_warn("failed allocating work for cleanup\n"); |
| 1141 | return; | 1143 | return; |
| 1142 | } | 1144 | } |
diff --git a/drivers/input/evdev.c b/drivers/input/evdev.c index 6ae2ac47c9c8..f0f8928b3c8a 100644 --- a/drivers/input/evdev.c +++ b/drivers/input/evdev.c | |||
| @@ -292,7 +292,6 @@ static int evdev_release(struct inode *inode, struct file *file) | |||
| 292 | kfree(client); | 292 | kfree(client); |
| 293 | 293 | ||
| 294 | evdev_close_device(evdev); | 294 | evdev_close_device(evdev); |
| 295 | put_device(&evdev->dev); | ||
| 296 | 295 | ||
| 297 | return 0; | 296 | return 0; |
| 298 | } | 297 | } |
| @@ -331,7 +330,6 @@ static int evdev_open(struct inode *inode, struct file *file) | |||
| 331 | file->private_data = client; | 330 | file->private_data = client; |
| 332 | nonseekable_open(inode, file); | 331 | nonseekable_open(inode, file); |
| 333 | 332 | ||
| 334 | get_device(&evdev->dev); | ||
| 335 | return 0; | 333 | return 0; |
| 336 | 334 | ||
| 337 | err_free_client: | 335 | err_free_client: |
| @@ -1001,6 +999,7 @@ static int evdev_connect(struct input_handler *handler, struct input_dev *dev, | |||
| 1001 | goto err_free_evdev; | 999 | goto err_free_evdev; |
| 1002 | 1000 | ||
| 1003 | cdev_init(&evdev->cdev, &evdev_fops); | 1001 | cdev_init(&evdev->cdev, &evdev_fops); |
| 1002 | evdev->cdev.kobj.parent = &evdev->dev.kobj; | ||
| 1004 | error = cdev_add(&evdev->cdev, evdev->dev.devt, 1); | 1003 | error = cdev_add(&evdev->cdev, evdev->dev.devt, 1); |
| 1005 | if (error) | 1004 | if (error) |
| 1006 | goto err_unregister_handle; | 1005 | goto err_unregister_handle; |
diff --git a/drivers/input/input-mt.c b/drivers/input/input-mt.c index c0ec7d42c3be..1abbc170d8b7 100644 --- a/drivers/input/input-mt.c +++ b/drivers/input/input-mt.c | |||
| @@ -26,10 +26,14 @@ static void copy_abs(struct input_dev *dev, unsigned int dst, unsigned int src) | |||
| 26 | * input_mt_init_slots() - initialize MT input slots | 26 | * input_mt_init_slots() - initialize MT input slots |
| 27 | * @dev: input device supporting MT events and finger tracking | 27 | * @dev: input device supporting MT events and finger tracking |
| 28 | * @num_slots: number of slots used by the device | 28 | * @num_slots: number of slots used by the device |
| 29 | * @flags: mt tasks to handle in core | ||
| 29 | * | 30 | * |
| 30 | * This function allocates all necessary memory for MT slot handling | 31 | * This function allocates all necessary memory for MT slot handling |
| 31 | * in the input device, prepares the ABS_MT_SLOT and | 32 | * in the input device, prepares the ABS_MT_SLOT and |
| 32 | * ABS_MT_TRACKING_ID events for use and sets up appropriate buffers. | 33 | * ABS_MT_TRACKING_ID events for use and sets up appropriate buffers. |
| 34 | * Depending on the flags set, it also performs pointer emulation and | ||
| 35 | * frame synchronization. | ||
| 36 | * | ||
| 33 | * May be called repeatedly. Returns -EINVAL if attempting to | 37 | * May be called repeatedly. Returns -EINVAL if attempting to |
| 34 | * reinitialize with a different number of slots. | 38 | * reinitialize with a different number of slots. |
| 35 | */ | 39 | */ |
diff --git a/drivers/input/joydev.c b/drivers/input/joydev.c index b62b5891f399..f362883c94e3 100644 --- a/drivers/input/joydev.c +++ b/drivers/input/joydev.c | |||
| @@ -243,7 +243,6 @@ static int joydev_release(struct inode *inode, struct file *file) | |||
| 243 | kfree(client); | 243 | kfree(client); |
| 244 | 244 | ||
| 245 | joydev_close_device(joydev); | 245 | joydev_close_device(joydev); |
| 246 | put_device(&joydev->dev); | ||
| 247 | 246 | ||
| 248 | return 0; | 247 | return 0; |
| 249 | } | 248 | } |
| @@ -270,7 +269,6 @@ static int joydev_open(struct inode *inode, struct file *file) | |||
| 270 | file->private_data = client; | 269 | file->private_data = client; |
| 271 | nonseekable_open(inode, file); | 270 | nonseekable_open(inode, file); |
| 272 | 271 | ||
| 273 | get_device(&joydev->dev); | ||
| 274 | return 0; | 272 | return 0; |
| 275 | 273 | ||
| 276 | err_free_client: | 274 | err_free_client: |
| @@ -858,6 +856,7 @@ static int joydev_connect(struct input_handler *handler, struct input_dev *dev, | |||
| 858 | goto err_free_joydev; | 856 | goto err_free_joydev; |
| 859 | 857 | ||
| 860 | cdev_init(&joydev->cdev, &joydev_fops); | 858 | cdev_init(&joydev->cdev, &joydev_fops); |
| 859 | joydev->cdev.kobj.parent = &joydev->dev.kobj; | ||
| 861 | error = cdev_add(&joydev->cdev, joydev->dev.devt, 1); | 860 | error = cdev_add(&joydev->cdev, joydev->dev.devt, 1); |
| 862 | if (error) | 861 | if (error) |
| 863 | goto err_unregister_handle; | 862 | goto err_unregister_handle; |
diff --git a/drivers/input/keyboard/Kconfig b/drivers/input/keyboard/Kconfig index b4b65af8612a..de0874054e9f 100644 --- a/drivers/input/keyboard/Kconfig +++ b/drivers/input/keyboard/Kconfig | |||
| @@ -335,6 +335,7 @@ config KEYBOARD_LOCOMO | |||
| 335 | config KEYBOARD_LPC32XX | 335 | config KEYBOARD_LPC32XX |
| 336 | tristate "LPC32XX matrix key scanner support" | 336 | tristate "LPC32XX matrix key scanner support" |
| 337 | depends on ARCH_LPC32XX && OF | 337 | depends on ARCH_LPC32XX && OF |
| 338 | select INPUT_MATRIXKMAP | ||
| 338 | help | 339 | help |
| 339 | Say Y here if you want to use NXP LPC32XX SoC key scanner interface, | 340 | Say Y here if you want to use NXP LPC32XX SoC key scanner interface, |
| 340 | connected to a key matrix. | 341 | connected to a key matrix. |
diff --git a/drivers/input/keyboard/pxa27x_keypad.c b/drivers/input/keyboard/pxa27x_keypad.c index 803ff6fe021e..cad9d5dd5973 100644 --- a/drivers/input/keyboard/pxa27x_keypad.c +++ b/drivers/input/keyboard/pxa27x_keypad.c | |||
| @@ -368,6 +368,9 @@ static void pxa27x_keypad_config(struct pxa27x_keypad *keypad) | |||
| 368 | unsigned int mask = 0, direct_key_num = 0; | 368 | unsigned int mask = 0, direct_key_num = 0; |
| 369 | unsigned long kpc = 0; | 369 | unsigned long kpc = 0; |
| 370 | 370 | ||
| 371 | /* clear pending interrupt bit */ | ||
| 372 | keypad_readl(KPC); | ||
| 373 | |||
| 371 | /* enable matrix keys with automatic scan */ | 374 | /* enable matrix keys with automatic scan */ |
| 372 | if (pdata->matrix_key_rows && pdata->matrix_key_cols) { | 375 | if (pdata->matrix_key_rows && pdata->matrix_key_cols) { |
| 373 | kpc |= KPC_ASACT | KPC_MIE | KPC_ME | KPC_MS_ALL; | 376 | kpc |= KPC_ASACT | KPC_MIE | KPC_ME | KPC_MS_ALL; |
diff --git a/drivers/input/matrix-keymap.c b/drivers/input/matrix-keymap.c index 443ad64b7f2a..d88d9be1d1b7 100644 --- a/drivers/input/matrix-keymap.c +++ b/drivers/input/matrix-keymap.c | |||
| @@ -23,6 +23,7 @@ | |||
| 23 | #include <linux/input.h> | 23 | #include <linux/input.h> |
| 24 | #include <linux/of.h> | 24 | #include <linux/of.h> |
| 25 | #include <linux/export.h> | 25 | #include <linux/export.h> |
| 26 | #include <linux/module.h> | ||
| 26 | #include <linux/input/matrix_keypad.h> | 27 | #include <linux/input/matrix_keypad.h> |
| 27 | 28 | ||
| 28 | static bool matrix_keypad_map_key(struct input_dev *input_dev, | 29 | static bool matrix_keypad_map_key(struct input_dev *input_dev, |
| @@ -161,3 +162,5 @@ int matrix_keypad_build_keymap(const struct matrix_keymap_data *keymap_data, | |||
| 161 | return 0; | 162 | return 0; |
| 162 | } | 163 | } |
| 163 | EXPORT_SYMBOL(matrix_keypad_build_keymap); | 164 | EXPORT_SYMBOL(matrix_keypad_build_keymap); |
| 165 | |||
| 166 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/input/misc/xen-kbdfront.c b/drivers/input/misc/xen-kbdfront.c index 02ca8680ea5b..6f7d99013031 100644 --- a/drivers/input/misc/xen-kbdfront.c +++ b/drivers/input/misc/xen-kbdfront.c | |||
| @@ -311,7 +311,6 @@ static void xenkbd_backend_changed(struct xenbus_device *dev, | |||
| 311 | case XenbusStateReconfiguring: | 311 | case XenbusStateReconfiguring: |
| 312 | case XenbusStateReconfigured: | 312 | case XenbusStateReconfigured: |
| 313 | case XenbusStateUnknown: | 313 | case XenbusStateUnknown: |
| 314 | case XenbusStateClosed: | ||
| 315 | break; | 314 | break; |
| 316 | 315 | ||
| 317 | case XenbusStateInitWait: | 316 | case XenbusStateInitWait: |
| @@ -350,6 +349,10 @@ InitWait: | |||
| 350 | 349 | ||
| 351 | break; | 350 | break; |
| 352 | 351 | ||
| 352 | case XenbusStateClosed: | ||
| 353 | if (dev->state == XenbusStateClosed) | ||
| 354 | break; | ||
| 355 | /* Missed the backend's CLOSING state -- fallthrough */ | ||
| 353 | case XenbusStateClosing: | 356 | case XenbusStateClosing: |
| 354 | xenbus_frontend_closed(dev); | 357 | xenbus_frontend_closed(dev); |
| 355 | break; | 358 | break; |
diff --git a/drivers/input/mouse/bcm5974.c b/drivers/input/mouse/bcm5974.c index 3a78f235fa3e..2baff1b79a55 100644 --- a/drivers/input/mouse/bcm5974.c +++ b/drivers/input/mouse/bcm5974.c | |||
| @@ -84,6 +84,10 @@ | |||
| 84 | #define USB_DEVICE_ID_APPLE_WELLSPRING7_ANSI 0x0262 | 84 | #define USB_DEVICE_ID_APPLE_WELLSPRING7_ANSI 0x0262 |
| 85 | #define USB_DEVICE_ID_APPLE_WELLSPRING7_ISO 0x0263 | 85 | #define USB_DEVICE_ID_APPLE_WELLSPRING7_ISO 0x0263 |
| 86 | #define USB_DEVICE_ID_APPLE_WELLSPRING7_JIS 0x0264 | 86 | #define USB_DEVICE_ID_APPLE_WELLSPRING7_JIS 0x0264 |
| 87 | /* MacbookPro10,2 (unibody, October 2012) */ | ||
| 88 | #define USB_DEVICE_ID_APPLE_WELLSPRING7A_ANSI 0x0259 | ||
| 89 | #define USB_DEVICE_ID_APPLE_WELLSPRING7A_ISO 0x025a | ||
| 90 | #define USB_DEVICE_ID_APPLE_WELLSPRING7A_JIS 0x025b | ||
| 87 | 91 | ||
| 88 | #define BCM5974_DEVICE(prod) { \ | 92 | #define BCM5974_DEVICE(prod) { \ |
| 89 | .match_flags = (USB_DEVICE_ID_MATCH_DEVICE | \ | 93 | .match_flags = (USB_DEVICE_ID_MATCH_DEVICE | \ |
| @@ -137,6 +141,10 @@ static const struct usb_device_id bcm5974_table[] = { | |||
| 137 | BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING7_ANSI), | 141 | BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING7_ANSI), |
| 138 | BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING7_ISO), | 142 | BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING7_ISO), |
| 139 | BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING7_JIS), | 143 | BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING7_JIS), |
| 144 | /* MacbookPro10,2 */ | ||
| 145 | BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING7A_ANSI), | ||
| 146 | BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING7A_ISO), | ||
| 147 | BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING7A_JIS), | ||
| 140 | /* Terminating entry */ | 148 | /* Terminating entry */ |
| 141 | {} | 149 | {} |
| 142 | }; | 150 | }; |
| @@ -379,6 +387,19 @@ static const struct bcm5974_config bcm5974_config_table[] = { | |||
| 379 | { SN_COORD, -150, 6730 }, | 387 | { SN_COORD, -150, 6730 }, |
| 380 | { SN_ORIENT, -MAX_FINGER_ORIENTATION, MAX_FINGER_ORIENTATION } | 388 | { SN_ORIENT, -MAX_FINGER_ORIENTATION, MAX_FINGER_ORIENTATION } |
| 381 | }, | 389 | }, |
| 390 | { | ||
| 391 | USB_DEVICE_ID_APPLE_WELLSPRING7A_ANSI, | ||
| 392 | USB_DEVICE_ID_APPLE_WELLSPRING7A_ISO, | ||
| 393 | USB_DEVICE_ID_APPLE_WELLSPRING7A_JIS, | ||
| 394 | HAS_INTEGRATED_BUTTON, | ||
| 395 | 0x84, sizeof(struct bt_data), | ||
| 396 | 0x81, TYPE2, FINGER_TYPE2, FINGER_TYPE2 + SIZEOF_ALL_FINGERS, | ||
| 397 | { SN_PRESSURE, 0, 300 }, | ||
| 398 | { SN_WIDTH, 0, 2048 }, | ||
| 399 | { SN_COORD, -4750, 5280 }, | ||
| 400 | { SN_COORD, -150, 6730 }, | ||
| 401 | { SN_ORIENT, -MAX_FINGER_ORIENTATION, MAX_FINGER_ORIENTATION } | ||
| 402 | }, | ||
| 382 | {} | 403 | {} |
| 383 | }; | 404 | }; |
| 384 | 405 | ||
diff --git a/drivers/input/mousedev.c b/drivers/input/mousedev.c index a1b4c37956b2..4c842c320c2e 100644 --- a/drivers/input/mousedev.c +++ b/drivers/input/mousedev.c | |||
| @@ -12,8 +12,8 @@ | |||
| 12 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | 12 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt |
| 13 | 13 | ||
| 14 | #define MOUSEDEV_MINOR_BASE 32 | 14 | #define MOUSEDEV_MINOR_BASE 32 |
| 15 | #define MOUSEDEV_MINORS 32 | 15 | #define MOUSEDEV_MINORS 31 |
| 16 | #define MOUSEDEV_MIX 31 | 16 | #define MOUSEDEV_MIX 63 |
| 17 | 17 | ||
| 18 | #include <linux/sched.h> | 18 | #include <linux/sched.h> |
| 19 | #include <linux/slab.h> | 19 | #include <linux/slab.h> |
| @@ -523,7 +523,6 @@ static int mousedev_release(struct inode *inode, struct file *file) | |||
| 523 | kfree(client); | 523 | kfree(client); |
| 524 | 524 | ||
| 525 | mousedev_close_device(mousedev); | 525 | mousedev_close_device(mousedev); |
| 526 | put_device(&mousedev->dev); | ||
| 527 | 526 | ||
| 528 | return 0; | 527 | return 0; |
| 529 | } | 528 | } |
| @@ -558,7 +557,6 @@ static int mousedev_open(struct inode *inode, struct file *file) | |||
| 558 | file->private_data = client; | 557 | file->private_data = client; |
| 559 | nonseekable_open(inode, file); | 558 | nonseekable_open(inode, file); |
| 560 | 559 | ||
| 561 | get_device(&mousedev->dev); | ||
| 562 | return 0; | 560 | return 0; |
| 563 | 561 | ||
| 564 | err_free_client: | 562 | err_free_client: |
| @@ -892,6 +890,7 @@ static struct mousedev *mousedev_create(struct input_dev *dev, | |||
| 892 | } | 890 | } |
| 893 | 891 | ||
| 894 | cdev_init(&mousedev->cdev, &mousedev_fops); | 892 | cdev_init(&mousedev->cdev, &mousedev_fops); |
| 893 | mousedev->cdev.kobj.parent = &mousedev->dev.kobj; | ||
| 895 | error = cdev_add(&mousedev->cdev, mousedev->dev.devt, 1); | 894 | error = cdev_add(&mousedev->cdev, mousedev->dev.devt, 1); |
| 896 | if (error) | 895 | if (error) |
| 897 | goto err_unregister_handle; | 896 | goto err_unregister_handle; |
diff --git a/drivers/input/tablet/wacom_sys.c b/drivers/input/tablet/wacom_sys.c index 9edf9806cff9..858ad446de91 100644 --- a/drivers/input/tablet/wacom_sys.c +++ b/drivers/input/tablet/wacom_sys.c | |||
| @@ -391,7 +391,7 @@ static int wacom_parse_hid(struct usb_interface *intf, | |||
| 391 | features->pktlen = WACOM_PKGLEN_TPC2FG; | 391 | features->pktlen = WACOM_PKGLEN_TPC2FG; |
| 392 | } | 392 | } |
| 393 | 393 | ||
| 394 | if (features->type == MTSCREEN) | 394 | if (features->type == MTSCREEN || features->type == WACOM_24HDT) |
| 395 | features->pktlen = WACOM_PKGLEN_MTOUCH; | 395 | features->pktlen = WACOM_PKGLEN_MTOUCH; |
| 396 | 396 | ||
| 397 | if (features->type == BAMBOO_PT) { | 397 | if (features->type == BAMBOO_PT) { |
| @@ -402,6 +402,14 @@ static int wacom_parse_hid(struct usb_interface *intf, | |||
| 402 | features->x_max = | 402 | features->x_max = |
| 403 | get_unaligned_le16(&report[i + 8]); | 403 | get_unaligned_le16(&report[i + 8]); |
| 404 | i += 15; | 404 | i += 15; |
| 405 | } else if (features->type == WACOM_24HDT) { | ||
| 406 | features->x_max = | ||
| 407 | get_unaligned_le16(&report[i + 3]); | ||
| 408 | features->x_phy = | ||
| 409 | get_unaligned_le16(&report[i + 8]); | ||
| 410 | features->unit = report[i - 1]; | ||
| 411 | features->unitExpo = report[i - 3]; | ||
| 412 | i += 12; | ||
| 405 | } else { | 413 | } else { |
| 406 | features->x_max = | 414 | features->x_max = |
| 407 | get_unaligned_le16(&report[i + 3]); | 415 | get_unaligned_le16(&report[i + 3]); |
| @@ -434,6 +442,12 @@ static int wacom_parse_hid(struct usb_interface *intf, | |||
| 434 | features->y_phy = | 442 | features->y_phy = |
| 435 | get_unaligned_le16(&report[i + 6]); | 443 | get_unaligned_le16(&report[i + 6]); |
| 436 | i += 7; | 444 | i += 7; |
| 445 | } else if (type == WACOM_24HDT) { | ||
| 446 | features->y_max = | ||
| 447 | get_unaligned_le16(&report[i + 3]); | ||
| 448 | features->y_phy = | ||
| 449 | get_unaligned_le16(&report[i - 2]); | ||
| 450 | i += 7; | ||
| 437 | } else if (type == BAMBOO_PT) { | 451 | } else if (type == BAMBOO_PT) { |
| 438 | features->y_phy = | 452 | features->y_phy = |
| 439 | get_unaligned_le16(&report[i + 3]); | 453 | get_unaligned_le16(&report[i + 3]); |
| @@ -541,6 +555,9 @@ static int wacom_query_tablet_data(struct usb_interface *intf, struct wacom_feat | |||
| 541 | /* MT Tablet PC touch */ | 555 | /* MT Tablet PC touch */ |
| 542 | return wacom_set_device_mode(intf, 3, 4, 4); | 556 | return wacom_set_device_mode(intf, 3, 4, 4); |
| 543 | } | 557 | } |
| 558 | else if (features->type == WACOM_24HDT) { | ||
| 559 | return wacom_set_device_mode(intf, 18, 3, 2); | ||
| 560 | } | ||
| 544 | } else if (features->device_type == BTN_TOOL_PEN) { | 561 | } else if (features->device_type == BTN_TOOL_PEN) { |
| 545 | if (features->type <= BAMBOO_PT && features->type != WIRELESS) { | 562 | if (features->type <= BAMBOO_PT && features->type != WIRELESS) { |
| 546 | return wacom_set_device_mode(intf, 2, 2, 2); | 563 | return wacom_set_device_mode(intf, 2, 2, 2); |
| @@ -613,6 +630,30 @@ struct wacom_usbdev_data { | |||
| 613 | static LIST_HEAD(wacom_udev_list); | 630 | static LIST_HEAD(wacom_udev_list); |
| 614 | static DEFINE_MUTEX(wacom_udev_list_lock); | 631 | static DEFINE_MUTEX(wacom_udev_list_lock); |
| 615 | 632 | ||
| 633 | static struct usb_device *wacom_get_sibling(struct usb_device *dev, int vendor, int product) | ||
| 634 | { | ||
| 635 | int port1; | ||
| 636 | struct usb_device *sibling; | ||
| 637 | |||
| 638 | if (vendor == 0 && product == 0) | ||
| 639 | return dev; | ||
| 640 | |||
| 641 | if (dev->parent == NULL) | ||
| 642 | return NULL; | ||
| 643 | |||
| 644 | usb_hub_for_each_child(dev->parent, port1, sibling) { | ||
| 645 | struct usb_device_descriptor *d; | ||
| 646 | if (sibling == NULL) | ||
| 647 | continue; | ||
| 648 | |||
| 649 | d = &sibling->descriptor; | ||
| 650 | if (d->idVendor == vendor && d->idProduct == product) | ||
| 651 | return sibling; | ||
| 652 | } | ||
| 653 | |||
| 654 | return NULL; | ||
| 655 | } | ||
| 656 | |||
| 616 | static struct wacom_usbdev_data *wacom_get_usbdev_data(struct usb_device *dev) | 657 | static struct wacom_usbdev_data *wacom_get_usbdev_data(struct usb_device *dev) |
| 617 | { | 658 | { |
| 618 | struct wacom_usbdev_data *data; | 659 | struct wacom_usbdev_data *data; |
| @@ -1257,13 +1298,19 @@ static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *i | |||
| 1257 | strlcpy(wacom_wac->name, features->name, sizeof(wacom_wac->name)); | 1298 | strlcpy(wacom_wac->name, features->name, sizeof(wacom_wac->name)); |
| 1258 | 1299 | ||
| 1259 | if (features->quirks & WACOM_QUIRK_MULTI_INPUT) { | 1300 | if (features->quirks & WACOM_QUIRK_MULTI_INPUT) { |
| 1301 | struct usb_device *other_dev; | ||
| 1302 | |||
| 1260 | /* Append the device type to the name */ | 1303 | /* Append the device type to the name */ |
| 1261 | strlcat(wacom_wac->name, | 1304 | strlcat(wacom_wac->name, |
| 1262 | features->device_type == BTN_TOOL_PEN ? | 1305 | features->device_type == BTN_TOOL_PEN ? |
| 1263 | " Pen" : " Finger", | 1306 | " Pen" : " Finger", |
| 1264 | sizeof(wacom_wac->name)); | 1307 | sizeof(wacom_wac->name)); |
| 1265 | 1308 | ||
| 1266 | error = wacom_add_shared_data(wacom_wac, dev); | 1309 | |
| 1310 | other_dev = wacom_get_sibling(dev, features->oVid, features->oPid); | ||
| 1311 | if (other_dev == NULL || wacom_get_usbdev_data(other_dev) == NULL) | ||
| 1312 | other_dev = dev; | ||
| 1313 | error = wacom_add_shared_data(wacom_wac, other_dev); | ||
| 1267 | if (error) | 1314 | if (error) |
| 1268 | goto fail3; | 1315 | goto fail3; |
| 1269 | } | 1316 | } |
diff --git a/drivers/input/tablet/wacom_wac.c b/drivers/input/tablet/wacom_wac.c index c3468c8dbd89..0a67031ffc13 100644 --- a/drivers/input/tablet/wacom_wac.c +++ b/drivers/input/tablet/wacom_wac.c | |||
| @@ -806,6 +806,70 @@ static int find_slot_from_contactid(struct wacom_wac *wacom, int contactid) | |||
| 806 | return -1; | 806 | return -1; |
| 807 | } | 807 | } |
| 808 | 808 | ||
| 809 | static int int_dist(int x1, int y1, int x2, int y2) | ||
| 810 | { | ||
| 811 | int x = x2 - x1; | ||
| 812 | int y = y2 - y1; | ||
| 813 | |||
| 814 | return int_sqrt(x*x + y*y); | ||
| 815 | } | ||
| 816 | |||
| 817 | static int wacom_24hdt_irq(struct wacom_wac *wacom) | ||
| 818 | { | ||
| 819 | struct input_dev *input = wacom->input; | ||
| 820 | char *data = wacom->data; | ||
| 821 | int i; | ||
| 822 | int current_num_contacts = data[61]; | ||
| 823 | int contacts_to_send = 0; | ||
| 824 | |||
| 825 | /* | ||
| 826 | * First packet resets the counter since only the first | ||
| 827 | * packet in series will have non-zero current_num_contacts. | ||
| 828 | */ | ||
| 829 | if (current_num_contacts) | ||
| 830 | wacom->num_contacts_left = current_num_contacts; | ||
| 831 | |||
| 832 | /* There are at most 4 contacts per packet */ | ||
| 833 | contacts_to_send = min(4, wacom->num_contacts_left); | ||
| 834 | |||
| 835 | for (i = 0; i < contacts_to_send; i++) { | ||
| 836 | int offset = (WACOM_BYTES_PER_24HDT_PACKET * i) + 1; | ||
| 837 | bool touch = data[offset] & 0x1 && !wacom->shared->stylus_in_proximity; | ||
| 838 | int id = data[offset + 1]; | ||
| 839 | int slot = find_slot_from_contactid(wacom, id); | ||
| 840 | |||
| 841 | if (slot < 0) | ||
| 842 | continue; | ||
| 843 | input_mt_slot(input, slot); | ||
| 844 | input_mt_report_slot_state(input, MT_TOOL_FINGER, touch); | ||
| 845 | |||
| 846 | if (touch) { | ||
| 847 | int t_x = le16_to_cpup((__le16 *)&data[offset + 2]); | ||
| 848 | int c_x = le16_to_cpup((__le16 *)&data[offset + 4]); | ||
| 849 | int t_y = le16_to_cpup((__le16 *)&data[offset + 6]); | ||
| 850 | int c_y = le16_to_cpup((__le16 *)&data[offset + 8]); | ||
| 851 | int w = le16_to_cpup((__le16 *)&data[offset + 10]); | ||
| 852 | int h = le16_to_cpup((__le16 *)&data[offset + 12]); | ||
| 853 | |||
| 854 | input_report_abs(input, ABS_MT_POSITION_X, t_x); | ||
| 855 | input_report_abs(input, ABS_MT_POSITION_Y, t_y); | ||
| 856 | input_report_abs(input, ABS_MT_TOUCH_MAJOR, min(w,h)); | ||
| 857 | input_report_abs(input, ABS_MT_WIDTH_MAJOR, min(w, h) + int_dist(t_x, t_y, c_x, c_y)); | ||
| 858 | input_report_abs(input, ABS_MT_WIDTH_MINOR, min(w, h)); | ||
| 859 | input_report_abs(input, ABS_MT_ORIENTATION, w > h); | ||
| 860 | } | ||
| 861 | wacom->slots[slot] = touch ? id : -1; | ||
| 862 | } | ||
| 863 | |||
| 864 | input_mt_report_pointer_emulation(input, true); | ||
| 865 | |||
| 866 | wacom->num_contacts_left -= contacts_to_send; | ||
| 867 | if (wacom->num_contacts_left <= 0) | ||
| 868 | wacom->num_contacts_left = 0; | ||
| 869 | |||
| 870 | return 1; | ||
| 871 | } | ||
| 872 | |||
| 809 | static int wacom_mt_touch(struct wacom_wac *wacom) | 873 | static int wacom_mt_touch(struct wacom_wac *wacom) |
| 810 | { | 874 | { |
| 811 | struct input_dev *input = wacom->input; | 875 | struct input_dev *input = wacom->input; |
| @@ -1255,6 +1319,10 @@ void wacom_wac_irq(struct wacom_wac *wacom_wac, size_t len) | |||
| 1255 | sync = wacom_intuos_irq(wacom_wac); | 1319 | sync = wacom_intuos_irq(wacom_wac); |
| 1256 | break; | 1320 | break; |
| 1257 | 1321 | ||
| 1322 | case WACOM_24HDT: | ||
| 1323 | sync = wacom_24hdt_irq(wacom_wac); | ||
| 1324 | break; | ||
| 1325 | |||
| 1258 | case INTUOS5S: | 1326 | case INTUOS5S: |
| 1259 | case INTUOS5: | 1327 | case INTUOS5: |
| 1260 | case INTUOS5L: | 1328 | case INTUOS5L: |
| @@ -1340,7 +1408,8 @@ void wacom_setup_device_quirks(struct wacom_features *features) | |||
| 1340 | 1408 | ||
| 1341 | /* these device have multiple inputs */ | 1409 | /* these device have multiple inputs */ |
| 1342 | if (features->type >= WIRELESS || | 1410 | if (features->type >= WIRELESS || |
| 1343 | (features->type >= INTUOS5S && features->type <= INTUOS5L)) | 1411 | (features->type >= INTUOS5S && features->type <= INTUOS5L) || |
| 1412 | (features->oVid && features->oPid)) | ||
| 1344 | features->quirks |= WACOM_QUIRK_MULTI_INPUT; | 1413 | features->quirks |= WACOM_QUIRK_MULTI_INPUT; |
| 1345 | 1414 | ||
| 1346 | /* quirk for bamboo touch with 2 low res touches */ | 1415 | /* quirk for bamboo touch with 2 low res touches */ |
| @@ -1449,6 +1518,9 @@ int wacom_setup_input_capabilities(struct input_dev *input_dev, | |||
| 1449 | 1518 | ||
| 1450 | input_set_abs_params(input_dev, ABS_Z, -900, 899, 0, 0); | 1519 | input_set_abs_params(input_dev, ABS_Z, -900, 899, 0, 0); |
| 1451 | input_set_abs_params(input_dev, ABS_THROTTLE, 0, 71, 0, 0); | 1520 | input_set_abs_params(input_dev, ABS_THROTTLE, 0, 71, 0, 0); |
| 1521 | |||
| 1522 | __set_bit(INPUT_PROP_DIRECT, input_dev->propbit); | ||
| 1523 | |||
| 1452 | wacom_setup_cintiq(wacom_wac); | 1524 | wacom_setup_cintiq(wacom_wac); |
| 1453 | break; | 1525 | break; |
| 1454 | 1526 | ||
| @@ -1575,6 +1647,15 @@ int wacom_setup_input_capabilities(struct input_dev *input_dev, | |||
| 1575 | __set_bit(INPUT_PROP_POINTER, input_dev->propbit); | 1647 | __set_bit(INPUT_PROP_POINTER, input_dev->propbit); |
| 1576 | break; | 1648 | break; |
| 1577 | 1649 | ||
| 1650 | case WACOM_24HDT: | ||
| 1651 | if (features->device_type == BTN_TOOL_FINGER) { | ||
| 1652 | input_set_abs_params(input_dev, ABS_MT_TOUCH_MAJOR, 0, features->x_max, 0, 0); | ||
| 1653 | input_set_abs_params(input_dev, ABS_MT_WIDTH_MAJOR, 0, features->x_max, 0, 0); | ||
| 1654 | input_set_abs_params(input_dev, ABS_MT_WIDTH_MINOR, 0, features->y_max, 0, 0); | ||
| 1655 | input_set_abs_params(input_dev, ABS_MT_ORIENTATION, 0, 1, 0, 0); | ||
| 1656 | } | ||
| 1657 | /* fall through */ | ||
| 1658 | |||
| 1578 | case MTSCREEN: | 1659 | case MTSCREEN: |
| 1579 | if (features->device_type == BTN_TOOL_FINGER) { | 1660 | if (features->device_type == BTN_TOOL_FINGER) { |
| 1580 | wacom_wac->slots = kmalloc(features->touch_max * | 1661 | wacom_wac->slots = kmalloc(features->touch_max * |
| @@ -1869,8 +1950,11 @@ static const struct wacom_features wacom_features_0xF4 = | |||
| 1869 | { "Wacom Cintiq 24HD", WACOM_PKGLEN_INTUOS, 104480, 65600, 2047, | 1950 | { "Wacom Cintiq 24HD", WACOM_PKGLEN_INTUOS, 104480, 65600, 2047, |
| 1870 | 63, WACOM_24HD, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES }; | 1951 | 63, WACOM_24HD, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES }; |
| 1871 | static const struct wacom_features wacom_features_0xF8 = | 1952 | static const struct wacom_features wacom_features_0xF8 = |
| 1872 | { "Wacom Cintiq 24HD touch", WACOM_PKGLEN_INTUOS, 104480, 65600, 2047, | 1953 | { "Wacom Cintiq 24HD touch", WACOM_PKGLEN_INTUOS, 104480, 65600, 2047, /* Pen */ |
| 1873 | 63, WACOM_24HD, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES }; | 1954 | 63, WACOM_24HD, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, .oVid = USB_VENDOR_ID_WACOM, .oPid = 0xf6 }; |
| 1955 | static const struct wacom_features wacom_features_0xF6 = | ||
| 1956 | { "Wacom Cintiq 24HD touch", .type = WACOM_24HDT, /* Touch */ | ||
| 1957 | .oVid = USB_VENDOR_ID_WACOM, .oPid = 0xf8, .touch_max = 10 }; | ||
| 1874 | static const struct wacom_features wacom_features_0x3F = | 1958 | static const struct wacom_features wacom_features_0x3F = |
| 1875 | { "Wacom Cintiq 21UX", WACOM_PKGLEN_INTUOS, 87200, 65600, 1023, | 1959 | { "Wacom Cintiq 21UX", WACOM_PKGLEN_INTUOS, 87200, 65600, 1023, |
| 1876 | 63, CINTIQ, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES }; | 1960 | 63, CINTIQ, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES }; |
| @@ -2113,6 +2197,7 @@ const struct usb_device_id wacom_ids[] = { | |||
| 2113 | { USB_DEVICE_WACOM(0x47) }, | 2197 | { USB_DEVICE_WACOM(0x47) }, |
| 2114 | { USB_DEVICE_WACOM(0xF4) }, | 2198 | { USB_DEVICE_WACOM(0xF4) }, |
| 2115 | { USB_DEVICE_WACOM(0xF8) }, | 2199 | { USB_DEVICE_WACOM(0xF8) }, |
| 2200 | { USB_DEVICE_WACOM(0xF6) }, | ||
| 2116 | { USB_DEVICE_WACOM(0xFA) }, | 2201 | { USB_DEVICE_WACOM(0xFA) }, |
| 2117 | { USB_DEVICE_LENOVO(0x6004) }, | 2202 | { USB_DEVICE_LENOVO(0x6004) }, |
| 2118 | { } | 2203 | { } |
diff --git a/drivers/input/tablet/wacom_wac.h b/drivers/input/tablet/wacom_wac.h index 96c185cc301e..345f1e76975e 100644 --- a/drivers/input/tablet/wacom_wac.h +++ b/drivers/input/tablet/wacom_wac.h | |||
| @@ -29,6 +29,7 @@ | |||
| 29 | 29 | ||
| 30 | /* wacom data size per MT contact */ | 30 | /* wacom data size per MT contact */ |
| 31 | #define WACOM_BYTES_PER_MT_PACKET 11 | 31 | #define WACOM_BYTES_PER_MT_PACKET 11 |
| 32 | #define WACOM_BYTES_PER_24HDT_PACKET 14 | ||
| 32 | 33 | ||
| 33 | /* device IDs */ | 34 | /* device IDs */ |
| 34 | #define STYLUS_DEVICE_ID 0x02 | 35 | #define STYLUS_DEVICE_ID 0x02 |
| @@ -49,6 +50,7 @@ | |||
| 49 | #define WACOM_REPORT_TPCHID 15 | 50 | #define WACOM_REPORT_TPCHID 15 |
| 50 | #define WACOM_REPORT_TPCST 16 | 51 | #define WACOM_REPORT_TPCST 16 |
| 51 | #define WACOM_REPORT_TPC1FGE 18 | 52 | #define WACOM_REPORT_TPC1FGE 18 |
| 53 | #define WACOM_REPORT_24HDT 1 | ||
| 52 | 54 | ||
| 53 | /* device quirks */ | 55 | /* device quirks */ |
| 54 | #define WACOM_QUIRK_MULTI_INPUT 0x0001 | 56 | #define WACOM_QUIRK_MULTI_INPUT 0x0001 |
| @@ -81,6 +83,7 @@ enum { | |||
| 81 | WACOM_MO, | 83 | WACOM_MO, |
| 82 | WIRELESS, | 84 | WIRELESS, |
| 83 | BAMBOO_PT, | 85 | BAMBOO_PT, |
| 86 | WACOM_24HDT, | ||
| 84 | TABLETPC, /* add new TPC below */ | 87 | TABLETPC, /* add new TPC below */ |
| 85 | TABLETPCE, | 88 | TABLETPCE, |
| 86 | TABLETPC2FG, | 89 | TABLETPC2FG, |
| @@ -109,6 +112,8 @@ struct wacom_features { | |||
| 109 | int distance_fuzz; | 112 | int distance_fuzz; |
| 110 | unsigned quirks; | 113 | unsigned quirks; |
| 111 | unsigned touch_max; | 114 | unsigned touch_max; |
| 115 | int oVid; | ||
| 116 | int oPid; | ||
| 112 | }; | 117 | }; |
| 113 | 118 | ||
| 114 | struct wacom_shared { | 119 | struct wacom_shared { |
diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig index 1ba232cbc09d..f7668b24c378 100644 --- a/drivers/input/touchscreen/Kconfig +++ b/drivers/input/touchscreen/Kconfig | |||
| @@ -239,7 +239,7 @@ config TOUCHSCREEN_EETI | |||
| 239 | 239 | ||
| 240 | config TOUCHSCREEN_EGALAX | 240 | config TOUCHSCREEN_EGALAX |
| 241 | tristate "EETI eGalax multi-touch panel support" | 241 | tristate "EETI eGalax multi-touch panel support" |
| 242 | depends on I2C | 242 | depends on I2C && OF |
| 243 | help | 243 | help |
| 244 | Say Y here to enable support for I2C connected EETI | 244 | Say Y here to enable support for I2C connected EETI |
| 245 | eGalax multi-touch panels. | 245 | eGalax multi-touch panels. |
diff --git a/drivers/input/touchscreen/ads7846.c b/drivers/input/touchscreen/ads7846.c index f02028ec3db6..78e5d9ab0ba7 100644 --- a/drivers/input/touchscreen/ads7846.c +++ b/drivers/input/touchscreen/ads7846.c | |||
| @@ -955,7 +955,8 @@ static int ads7846_resume(struct device *dev) | |||
| 955 | 955 | ||
| 956 | static SIMPLE_DEV_PM_OPS(ads7846_pm, ads7846_suspend, ads7846_resume); | 956 | static SIMPLE_DEV_PM_OPS(ads7846_pm, ads7846_suspend, ads7846_resume); |
| 957 | 957 | ||
| 958 | static int __devinit ads7846_setup_pendown(struct spi_device *spi, struct ads7846 *ts) | 958 | static int __devinit ads7846_setup_pendown(struct spi_device *spi, |
| 959 | struct ads7846 *ts) | ||
| 959 | { | 960 | { |
| 960 | struct ads7846_platform_data *pdata = spi->dev.platform_data; | 961 | struct ads7846_platform_data *pdata = spi->dev.platform_data; |
| 961 | int err; | 962 | int err; |
| @@ -981,6 +982,9 @@ static int __devinit ads7846_setup_pendown(struct spi_device *spi, struct ads784 | |||
| 981 | 982 | ||
| 982 | ts->gpio_pendown = pdata->gpio_pendown; | 983 | ts->gpio_pendown = pdata->gpio_pendown; |
| 983 | 984 | ||
| 985 | if (pdata->gpio_pendown_debounce) | ||
| 986 | gpio_set_debounce(pdata->gpio_pendown, | ||
| 987 | pdata->gpio_pendown_debounce); | ||
| 984 | } else { | 988 | } else { |
| 985 | dev_err(&spi->dev, "no get_pendown_state nor gpio_pendown?\n"); | 989 | dev_err(&spi->dev, "no get_pendown_state nor gpio_pendown?\n"); |
| 986 | return -EINVAL; | 990 | return -EINVAL; |
diff --git a/drivers/input/touchscreen/egalax_ts.c b/drivers/input/touchscreen/egalax_ts.c index c1e3460f1195..13fa62fdfb0b 100644 --- a/drivers/input/touchscreen/egalax_ts.c +++ b/drivers/input/touchscreen/egalax_ts.c | |||
| @@ -28,6 +28,7 @@ | |||
| 28 | #include <linux/slab.h> | 28 | #include <linux/slab.h> |
| 29 | #include <linux/bitops.h> | 29 | #include <linux/bitops.h> |
| 30 | #include <linux/input/mt.h> | 30 | #include <linux/input/mt.h> |
| 31 | #include <linux/of_gpio.h> | ||
| 31 | 32 | ||
| 32 | /* | 33 | /* |
| 33 | * Mouse Mode: some panel may configure the controller to mouse mode, | 34 | * Mouse Mode: some panel may configure the controller to mouse mode, |
| @@ -122,9 +123,17 @@ static irqreturn_t egalax_ts_interrupt(int irq, void *dev_id) | |||
| 122 | /* wake up controller by an falling edge of interrupt gpio. */ | 123 | /* wake up controller by an falling edge of interrupt gpio. */ |
| 123 | static int egalax_wake_up_device(struct i2c_client *client) | 124 | static int egalax_wake_up_device(struct i2c_client *client) |
| 124 | { | 125 | { |
| 125 | int gpio = irq_to_gpio(client->irq); | 126 | struct device_node *np = client->dev.of_node; |
| 127 | int gpio; | ||
| 126 | int ret; | 128 | int ret; |
| 127 | 129 | ||
| 130 | if (!np) | ||
| 131 | return -ENODEV; | ||
| 132 | |||
| 133 | gpio = of_get_named_gpio(np, "wakeup-gpios", 0); | ||
| 134 | if (!gpio_is_valid(gpio)) | ||
| 135 | return -ENODEV; | ||
| 136 | |||
| 128 | ret = gpio_request(gpio, "egalax_irq"); | 137 | ret = gpio_request(gpio, "egalax_irq"); |
| 129 | if (ret < 0) { | 138 | if (ret < 0) { |
| 130 | dev_err(&client->dev, | 139 | dev_err(&client->dev, |
| @@ -181,7 +190,11 @@ static int __devinit egalax_ts_probe(struct i2c_client *client, | |||
| 181 | ts->input_dev = input_dev; | 190 | ts->input_dev = input_dev; |
| 182 | 191 | ||
| 183 | /* controller may be in sleep, wake it up. */ | 192 | /* controller may be in sleep, wake it up. */ |
| 184 | egalax_wake_up_device(client); | 193 | error = egalax_wake_up_device(client); |
| 194 | if (error) { | ||
| 195 | dev_err(&client->dev, "Failed to wake up the controller\n"); | ||
| 196 | goto err_free_dev; | ||
| 197 | } | ||
| 185 | 198 | ||
| 186 | ret = egalax_firmware_version(client); | 199 | ret = egalax_firmware_version(client); |
| 187 | if (ret < 0) { | 200 | if (ret < 0) { |
| @@ -274,11 +287,17 @@ static int egalax_ts_resume(struct device *dev) | |||
| 274 | 287 | ||
| 275 | static SIMPLE_DEV_PM_OPS(egalax_ts_pm_ops, egalax_ts_suspend, egalax_ts_resume); | 288 | static SIMPLE_DEV_PM_OPS(egalax_ts_pm_ops, egalax_ts_suspend, egalax_ts_resume); |
| 276 | 289 | ||
| 290 | static struct of_device_id egalax_ts_dt_ids[] = { | ||
| 291 | { .compatible = "eeti,egalax_ts" }, | ||
| 292 | { /* sentinel */ } | ||
| 293 | }; | ||
| 294 | |||
| 277 | static struct i2c_driver egalax_ts_driver = { | 295 | static struct i2c_driver egalax_ts_driver = { |
| 278 | .driver = { | 296 | .driver = { |
| 279 | .name = "egalax_ts", | 297 | .name = "egalax_ts", |
| 280 | .owner = THIS_MODULE, | 298 | .owner = THIS_MODULE, |
| 281 | .pm = &egalax_ts_pm_ops, | 299 | .pm = &egalax_ts_pm_ops, |
| 300 | .of_match_table = of_match_ptr(egalax_ts_dt_ids), | ||
| 282 | }, | 301 | }, |
| 283 | .id_table = egalax_ts_id, | 302 | .id_table = egalax_ts_id, |
| 284 | .probe = egalax_ts_probe, | 303 | .probe = egalax_ts_probe, |
diff --git a/drivers/input/touchscreen/tsc40.c b/drivers/input/touchscreen/tsc40.c index 63209aaa55f0..eb96f168fb9d 100644 --- a/drivers/input/touchscreen/tsc40.c +++ b/drivers/input/touchscreen/tsc40.c | |||
| @@ -107,7 +107,6 @@ static int tsc_connect(struct serio *serio, struct serio_driver *drv) | |||
| 107 | __set_bit(BTN_TOUCH, input_dev->keybit); | 107 | __set_bit(BTN_TOUCH, input_dev->keybit); |
| 108 | input_set_abs_params(ptsc->dev, ABS_X, 0, 0x3ff, 0, 0); | 108 | input_set_abs_params(ptsc->dev, ABS_X, 0, 0x3ff, 0, 0); |
| 109 | input_set_abs_params(ptsc->dev, ABS_Y, 0, 0x3ff, 0, 0); | 109 | input_set_abs_params(ptsc->dev, ABS_Y, 0, 0x3ff, 0, 0); |
| 110 | input_set_abs_params(ptsc->dev, ABS_PRESSURE, 0, 0, 0, 0); | ||
| 111 | 110 | ||
| 112 | serio_set_drvdata(serio, ptsc); | 111 | serio_set_drvdata(serio, ptsc); |
| 113 | 112 | ||
diff --git a/drivers/iommu/amd_iommu_init.c b/drivers/iommu/amd_iommu_init.c index 18b0d99bd4d6..81837b0710a9 100644 --- a/drivers/iommu/amd_iommu_init.c +++ b/drivers/iommu/amd_iommu_init.c | |||
| @@ -1599,21 +1599,46 @@ static void __init free_on_init_error(void) | |||
| 1599 | #endif | 1599 | #endif |
| 1600 | } | 1600 | } |
| 1601 | 1601 | ||
| 1602 | /* SB IOAPIC is always on this device in AMD systems */ | ||
| 1603 | #define IOAPIC_SB_DEVID ((0x00 << 8) | PCI_DEVFN(0x14, 0)) | ||
| 1604 | |||
| 1602 | static bool __init check_ioapic_information(void) | 1605 | static bool __init check_ioapic_information(void) |
| 1603 | { | 1606 | { |
| 1607 | bool ret, has_sb_ioapic; | ||
| 1604 | int idx; | 1608 | int idx; |
| 1605 | 1609 | ||
| 1606 | for (idx = 0; idx < nr_ioapics; idx++) { | 1610 | has_sb_ioapic = false; |
| 1607 | int id = mpc_ioapic_id(idx); | 1611 | ret = false; |
| 1608 | 1612 | ||
| 1609 | if (get_ioapic_devid(id) < 0) { | 1613 | for (idx = 0; idx < nr_ioapics; idx++) { |
| 1610 | pr_err(FW_BUG "AMD-Vi: IO-APIC[%d] not in IVRS table\n", id); | 1614 | int devid, id = mpc_ioapic_id(idx); |
| 1611 | pr_err("AMD-Vi: Disabling interrupt remapping due to BIOS Bug\n"); | 1615 | |
| 1612 | return false; | 1616 | devid = get_ioapic_devid(id); |
| 1617 | if (devid < 0) { | ||
| 1618 | pr_err(FW_BUG "AMD-Vi: IOAPIC[%d] not in IVRS table\n", id); | ||
| 1619 | ret = false; | ||
| 1620 | } else if (devid == IOAPIC_SB_DEVID) { | ||
| 1621 | has_sb_ioapic = true; | ||
| 1622 | ret = true; | ||
| 1613 | } | 1623 | } |
| 1614 | } | 1624 | } |
| 1615 | 1625 | ||
| 1616 | return true; | 1626 | if (!has_sb_ioapic) { |
| 1627 | /* | ||
| 1628 | * We expect the SB IOAPIC to be listed in the IVRS | ||
| 1629 | * table. The system timer is connected to the SB IOAPIC | ||
| 1630 | * and if we don't have it in the list the system will | ||
| 1631 | * panic at boot time. This situation usually happens | ||
| 1632 | * when the BIOS is buggy and provides us the wrong | ||
| 1633 | * device id for the IOAPIC in the system. | ||
| 1634 | */ | ||
| 1635 | pr_err(FW_BUG "AMD-Vi: No southbridge IOAPIC found in IVRS table\n"); | ||
| 1636 | } | ||
| 1637 | |||
| 1638 | if (!ret) | ||
| 1639 | pr_err("AMD-Vi: Disabling interrupt remapping due to BIOS Bug(s)\n"); | ||
| 1640 | |||
| 1641 | return ret; | ||
| 1617 | } | 1642 | } |
| 1618 | 1643 | ||
| 1619 | static void __init free_dma_resources(void) | 1644 | static void __init free_dma_resources(void) |
diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c index d4a4cd445cab..0badfa48b32b 100644 --- a/drivers/iommu/intel-iommu.c +++ b/drivers/iommu/intel-iommu.c | |||
| @@ -4108,7 +4108,7 @@ static void swap_pci_ref(struct pci_dev **from, struct pci_dev *to) | |||
| 4108 | static int intel_iommu_add_device(struct device *dev) | 4108 | static int intel_iommu_add_device(struct device *dev) |
| 4109 | { | 4109 | { |
| 4110 | struct pci_dev *pdev = to_pci_dev(dev); | 4110 | struct pci_dev *pdev = to_pci_dev(dev); |
| 4111 | struct pci_dev *bridge, *dma_pdev; | 4111 | struct pci_dev *bridge, *dma_pdev = NULL; |
| 4112 | struct iommu_group *group; | 4112 | struct iommu_group *group; |
| 4113 | int ret; | 4113 | int ret; |
| 4114 | 4114 | ||
| @@ -4122,7 +4122,7 @@ static int intel_iommu_add_device(struct device *dev) | |||
| 4122 | dma_pdev = pci_get_domain_bus_and_slot( | 4122 | dma_pdev = pci_get_domain_bus_and_slot( |
| 4123 | pci_domain_nr(pdev->bus), | 4123 | pci_domain_nr(pdev->bus), |
| 4124 | bridge->subordinate->number, 0); | 4124 | bridge->subordinate->number, 0); |
| 4125 | else | 4125 | if (!dma_pdev) |
| 4126 | dma_pdev = pci_dev_get(bridge); | 4126 | dma_pdev = pci_dev_get(bridge); |
| 4127 | } else | 4127 | } else |
| 4128 | dma_pdev = pci_dev_get(pdev); | 4128 | dma_pdev = pci_dev_get(pdev); |
diff --git a/drivers/iommu/tegra-smmu.c b/drivers/iommu/tegra-smmu.c index 0b4d62e0c645..c0f7a4266263 100644 --- a/drivers/iommu/tegra-smmu.c +++ b/drivers/iommu/tegra-smmu.c | |||
| @@ -200,7 +200,7 @@ enum { | |||
| 200 | 200 | ||
| 201 | #define SMMU_ADDR_TO_PFN(addr) ((addr) >> 12) | 201 | #define SMMU_ADDR_TO_PFN(addr) ((addr) >> 12) |
| 202 | #define SMMU_ADDR_TO_PDN(addr) ((addr) >> 22) | 202 | #define SMMU_ADDR_TO_PDN(addr) ((addr) >> 22) |
| 203 | #define SMMU_PDN_TO_ADDR(addr) ((pdn) << 22) | 203 | #define SMMU_PDN_TO_ADDR(pdn) ((pdn) << 22) |
| 204 | 204 | ||
| 205 | #define _READABLE (1 << SMMU_PTB_DATA_ASID_READABLE_SHIFT) | 205 | #define _READABLE (1 << SMMU_PTB_DATA_ASID_READABLE_SHIFT) |
| 206 | #define _WRITABLE (1 << SMMU_PTB_DATA_ASID_WRITABLE_SHIFT) | 206 | #define _WRITABLE (1 << SMMU_PTB_DATA_ASID_WRITABLE_SHIFT) |
| @@ -1054,6 +1054,7 @@ static int smmu_debugfs_stats_show(struct seq_file *s, void *v) | |||
| 1054 | stats[i], val, offs); | 1054 | stats[i], val, offs); |
| 1055 | } | 1055 | } |
| 1056 | seq_printf(s, "\n"); | 1056 | seq_printf(s, "\n"); |
| 1057 | dput(dent); | ||
| 1057 | 1058 | ||
| 1058 | return 0; | 1059 | return 0; |
| 1059 | } | 1060 | } |
diff --git a/drivers/irqchip/irq-bcm2835.c b/drivers/irqchip/irq-bcm2835.c index dc670ccc6978..16c78f1c5ef2 100644 --- a/drivers/irqchip/irq-bcm2835.c +++ b/drivers/irqchip/irq-bcm2835.c | |||
| @@ -168,7 +168,8 @@ static int __init armctrl_of_init(struct device_node *node, | |||
| 168 | } | 168 | } |
| 169 | 169 | ||
| 170 | static struct of_device_id irq_of_match[] __initconst = { | 170 | static struct of_device_id irq_of_match[] __initconst = { |
| 171 | { .compatible = "brcm,bcm2835-armctrl-ic", .data = armctrl_of_init } | 171 | { .compatible = "brcm,bcm2835-armctrl-ic", .data = armctrl_of_init }, |
| 172 | { } | ||
| 172 | }; | 173 | }; |
| 173 | 174 | ||
| 174 | void __init bcm2835_init_irq(void) | 175 | void __init bcm2835_init_irq(void) |
diff --git a/drivers/isdn/Kconfig b/drivers/isdn/Kconfig index a233ed53913a..86cd75a0e84d 100644 --- a/drivers/isdn/Kconfig +++ b/drivers/isdn/Kconfig | |||
| @@ -4,7 +4,7 @@ | |||
| 4 | 4 | ||
| 5 | menuconfig ISDN | 5 | menuconfig ISDN |
| 6 | bool "ISDN support" | 6 | bool "ISDN support" |
| 7 | depends on NET | 7 | depends on NET && NETDEVICES |
| 8 | depends on !S390 && !UML | 8 | depends on !S390 && !UML |
| 9 | ---help--- | 9 | ---help--- |
| 10 | ISDN ("Integrated Services Digital Network", called RNIS in France) | 10 | ISDN ("Integrated Services Digital Network", called RNIS in France) |
diff --git a/drivers/isdn/gigaset/bas-gigaset.c b/drivers/isdn/gigaset/bas-gigaset.c index 527588708948..c44950d3eb7b 100644 --- a/drivers/isdn/gigaset/bas-gigaset.c +++ b/drivers/isdn/gigaset/bas-gigaset.c | |||
| @@ -617,7 +617,13 @@ static void int_in_work(struct work_struct *work) | |||
| 617 | if (rc == 0) | 617 | if (rc == 0) |
| 618 | /* success, resubmit interrupt read URB */ | 618 | /* success, resubmit interrupt read URB */ |
| 619 | rc = usb_submit_urb(urb, GFP_ATOMIC); | 619 | rc = usb_submit_urb(urb, GFP_ATOMIC); |
| 620 | if (rc != 0 && rc != -ENODEV) { | 620 | |
| 621 | switch (rc) { | ||
| 622 | case 0: /* success */ | ||
| 623 | case -ENODEV: /* device gone */ | ||
| 624 | case -EINVAL: /* URB already resubmitted, or terminal badness */ | ||
| 625 | break; | ||
| 626 | default: /* failure: try to recover by resetting the device */ | ||
| 621 | dev_err(cs->dev, "clear halt failed: %s\n", get_usb_rcmsg(rc)); | 627 | dev_err(cs->dev, "clear halt failed: %s\n", get_usb_rcmsg(rc)); |
| 622 | rc = usb_lock_device_for_reset(ucs->udev, ucs->interface); | 628 | rc = usb_lock_device_for_reset(ucs->udev, ucs->interface); |
| 623 | if (rc == 0) { | 629 | if (rc == 0) { |
| @@ -2442,7 +2448,9 @@ static void gigaset_disconnect(struct usb_interface *interface) | |||
| 2442 | } | 2448 | } |
| 2443 | 2449 | ||
| 2444 | /* gigaset_suspend | 2450 | /* gigaset_suspend |
| 2445 | * This function is called before the USB connection is suspended. | 2451 | * This function is called before the USB connection is suspended |
| 2452 | * or before the USB device is reset. | ||
| 2453 | * In the latter case, message == PMSG_ON. | ||
| 2446 | */ | 2454 | */ |
| 2447 | static int gigaset_suspend(struct usb_interface *intf, pm_message_t message) | 2455 | static int gigaset_suspend(struct usb_interface *intf, pm_message_t message) |
| 2448 | { | 2456 | { |
| @@ -2498,7 +2506,12 @@ static int gigaset_suspend(struct usb_interface *intf, pm_message_t message) | |||
| 2498 | del_timer_sync(&ucs->timer_atrdy); | 2506 | del_timer_sync(&ucs->timer_atrdy); |
| 2499 | del_timer_sync(&ucs->timer_cmd_in); | 2507 | del_timer_sync(&ucs->timer_cmd_in); |
| 2500 | del_timer_sync(&ucs->timer_int_in); | 2508 | del_timer_sync(&ucs->timer_int_in); |
| 2501 | cancel_work_sync(&ucs->int_in_wq); | 2509 | |
| 2510 | /* don't try to cancel int_in_wq from within reset as it | ||
| 2511 | * might be the one requesting the reset | ||
| 2512 | */ | ||
| 2513 | if (message.event != PM_EVENT_ON) | ||
| 2514 | cancel_work_sync(&ucs->int_in_wq); | ||
| 2502 | 2515 | ||
| 2503 | gig_dbg(DEBUG_SUSPEND, "suspend complete"); | 2516 | gig_dbg(DEBUG_SUSPEND, "suspend complete"); |
| 2504 | return 0; | 2517 | return 0; |
diff --git a/drivers/isdn/i4l/Kconfig b/drivers/isdn/i4l/Kconfig index 2302fbe70ac6..9c6650ea848e 100644 --- a/drivers/isdn/i4l/Kconfig +++ b/drivers/isdn/i4l/Kconfig | |||
| @@ -6,7 +6,7 @@ if ISDN_I4L | |||
| 6 | 6 | ||
| 7 | config ISDN_PPP | 7 | config ISDN_PPP |
| 8 | bool "Support synchronous PPP" | 8 | bool "Support synchronous PPP" |
| 9 | depends on INET && NETDEVICES | 9 | depends on INET |
| 10 | select SLHC | 10 | select SLHC |
| 11 | help | 11 | help |
| 12 | Over digital connections such as ISDN, there is no need to | 12 | Over digital connections such as ISDN, there is no need to |
diff --git a/drivers/isdn/i4l/isdn_common.c b/drivers/isdn/i4l/isdn_common.c index 8c610fa6782b..e2a945ee9f05 100644 --- a/drivers/isdn/i4l/isdn_common.c +++ b/drivers/isdn/i4l/isdn_common.c | |||
| @@ -1312,7 +1312,6 @@ isdn_ioctl(struct file *file, uint cmd, ulong arg) | |||
| 1312 | } else | 1312 | } else |
| 1313 | return -EINVAL; | 1313 | return -EINVAL; |
| 1314 | break; | 1314 | break; |
| 1315 | #ifdef CONFIG_NETDEVICES | ||
| 1316 | case IIOCNETGPN: | 1315 | case IIOCNETGPN: |
| 1317 | /* Get peer phone number of a connected | 1316 | /* Get peer phone number of a connected |
| 1318 | * isdn network interface */ | 1317 | * isdn network interface */ |
| @@ -1322,7 +1321,6 @@ isdn_ioctl(struct file *file, uint cmd, ulong arg) | |||
| 1322 | return isdn_net_getpeer(&phone, argp); | 1321 | return isdn_net_getpeer(&phone, argp); |
| 1323 | } else | 1322 | } else |
| 1324 | return -EINVAL; | 1323 | return -EINVAL; |
| 1325 | #endif | ||
| 1326 | default: | 1324 | default: |
| 1327 | return -EINVAL; | 1325 | return -EINVAL; |
| 1328 | } | 1326 | } |
| @@ -1352,7 +1350,6 @@ isdn_ioctl(struct file *file, uint cmd, ulong arg) | |||
| 1352 | case IIOCNETLCR: | 1350 | case IIOCNETLCR: |
| 1353 | printk(KERN_INFO "INFO: ISDN_ABC_LCR_SUPPORT not enabled\n"); | 1351 | printk(KERN_INFO "INFO: ISDN_ABC_LCR_SUPPORT not enabled\n"); |
| 1354 | return -ENODEV; | 1352 | return -ENODEV; |
| 1355 | #ifdef CONFIG_NETDEVICES | ||
| 1356 | case IIOCNETAIF: | 1353 | case IIOCNETAIF: |
| 1357 | /* Add a network-interface */ | 1354 | /* Add a network-interface */ |
| 1358 | if (arg) { | 1355 | if (arg) { |
| @@ -1491,7 +1488,6 @@ isdn_ioctl(struct file *file, uint cmd, ulong arg) | |||
| 1491 | return -EFAULT; | 1488 | return -EFAULT; |
| 1492 | return isdn_net_force_hangup(name); | 1489 | return isdn_net_force_hangup(name); |
| 1493 | break; | 1490 | break; |
| 1494 | #endif /* CONFIG_NETDEVICES */ | ||
| 1495 | case IIOCSETVER: | 1491 | case IIOCSETVER: |
| 1496 | dev->net_verbose = arg; | 1492 | dev->net_verbose = arg; |
| 1497 | printk(KERN_INFO "isdn: Verbose-Level is %d\n", dev->net_verbose); | 1493 | printk(KERN_INFO "isdn: Verbose-Level is %d\n", dev->net_verbose); |
diff --git a/drivers/leds/ledtrig-cpu.c b/drivers/leds/ledtrig-cpu.c index b312056da14d..4239b3955ff0 100644 --- a/drivers/leds/ledtrig-cpu.c +++ b/drivers/leds/ledtrig-cpu.c | |||
| @@ -33,8 +33,6 @@ | |||
| 33 | struct led_trigger_cpu { | 33 | struct led_trigger_cpu { |
| 34 | char name[MAX_NAME_LEN]; | 34 | char name[MAX_NAME_LEN]; |
| 35 | struct led_trigger *_trig; | 35 | struct led_trigger *_trig; |
| 36 | struct mutex lock; | ||
| 37 | int lock_is_inited; | ||
| 38 | }; | 36 | }; |
| 39 | 37 | ||
| 40 | static DEFINE_PER_CPU(struct led_trigger_cpu, cpu_trig); | 38 | static DEFINE_PER_CPU(struct led_trigger_cpu, cpu_trig); |
| @@ -50,12 +48,6 @@ void ledtrig_cpu(enum cpu_led_event ledevt) | |||
| 50 | { | 48 | { |
| 51 | struct led_trigger_cpu *trig = &__get_cpu_var(cpu_trig); | 49 | struct led_trigger_cpu *trig = &__get_cpu_var(cpu_trig); |
| 52 | 50 | ||
| 53 | /* mutex lock should be initialized before calling mutex_call() */ | ||
| 54 | if (!trig->lock_is_inited) | ||
| 55 | return; | ||
| 56 | |||
| 57 | mutex_lock(&trig->lock); | ||
| 58 | |||
| 59 | /* Locate the correct CPU LED */ | 51 | /* Locate the correct CPU LED */ |
| 60 | switch (ledevt) { | 52 | switch (ledevt) { |
| 61 | case CPU_LED_IDLE_END: | 53 | case CPU_LED_IDLE_END: |
| @@ -75,8 +67,6 @@ void ledtrig_cpu(enum cpu_led_event ledevt) | |||
| 75 | /* Will leave the LED as it is */ | 67 | /* Will leave the LED as it is */ |
| 76 | break; | 68 | break; |
| 77 | } | 69 | } |
| 78 | |||
| 79 | mutex_unlock(&trig->lock); | ||
| 80 | } | 70 | } |
| 81 | EXPORT_SYMBOL(ledtrig_cpu); | 71 | EXPORT_SYMBOL(ledtrig_cpu); |
| 82 | 72 | ||
| @@ -117,14 +107,9 @@ static int __init ledtrig_cpu_init(void) | |||
| 117 | for_each_possible_cpu(cpu) { | 107 | for_each_possible_cpu(cpu) { |
| 118 | struct led_trigger_cpu *trig = &per_cpu(cpu_trig, cpu); | 108 | struct led_trigger_cpu *trig = &per_cpu(cpu_trig, cpu); |
| 119 | 109 | ||
| 120 | mutex_init(&trig->lock); | ||
| 121 | |||
| 122 | snprintf(trig->name, MAX_NAME_LEN, "cpu%d", cpu); | 110 | snprintf(trig->name, MAX_NAME_LEN, "cpu%d", cpu); |
| 123 | 111 | ||
| 124 | mutex_lock(&trig->lock); | ||
| 125 | led_trigger_register_simple(trig->name, &trig->_trig); | 112 | led_trigger_register_simple(trig->name, &trig->_trig); |
| 126 | trig->lock_is_inited = 1; | ||
| 127 | mutex_unlock(&trig->lock); | ||
| 128 | } | 113 | } |
| 129 | 114 | ||
| 130 | register_syscore_ops(&ledtrig_cpu_syscore_ops); | 115 | register_syscore_ops(&ledtrig_cpu_syscore_ops); |
| @@ -142,15 +127,9 @@ static void __exit ledtrig_cpu_exit(void) | |||
| 142 | for_each_possible_cpu(cpu) { | 127 | for_each_possible_cpu(cpu) { |
| 143 | struct led_trigger_cpu *trig = &per_cpu(cpu_trig, cpu); | 128 | struct led_trigger_cpu *trig = &per_cpu(cpu_trig, cpu); |
| 144 | 129 | ||
| 145 | mutex_lock(&trig->lock); | ||
| 146 | |||
| 147 | led_trigger_unregister_simple(trig->_trig); | 130 | led_trigger_unregister_simple(trig->_trig); |
| 148 | trig->_trig = NULL; | 131 | trig->_trig = NULL; |
| 149 | memset(trig->name, 0, MAX_NAME_LEN); | 132 | memset(trig->name, 0, MAX_NAME_LEN); |
| 150 | trig->lock_is_inited = 0; | ||
| 151 | |||
| 152 | mutex_unlock(&trig->lock); | ||
| 153 | mutex_destroy(&trig->lock); | ||
| 154 | } | 133 | } |
| 155 | 134 | ||
| 156 | unregister_syscore_ops(&ledtrig_cpu_syscore_ops); | 135 | unregister_syscore_ops(&ledtrig_cpu_syscore_ops); |
diff --git a/drivers/md/dm.c b/drivers/md/dm.c index 02db9183ca01..77e6eff41cae 100644 --- a/drivers/md/dm.c +++ b/drivers/md/dm.c | |||
| @@ -740,8 +740,14 @@ static void rq_completed(struct mapped_device *md, int rw, int run_queue) | |||
| 740 | if (!md_in_flight(md)) | 740 | if (!md_in_flight(md)) |
| 741 | wake_up(&md->wait); | 741 | wake_up(&md->wait); |
| 742 | 742 | ||
| 743 | /* | ||
| 744 | * Run this off this callpath, as drivers could invoke end_io while | ||
| 745 | * inside their request_fn (and holding the queue lock). Calling | ||
| 746 | * back into ->request_fn() could deadlock attempting to grab the | ||
| 747 | * queue lock again. | ||
| 748 | */ | ||
| 743 | if (run_queue) | 749 | if (run_queue) |
| 744 | blk_run_queue(md->queue); | 750 | blk_run_queue_async(md->queue); |
| 745 | 751 | ||
| 746 | /* | 752 | /* |
| 747 | * dm_put() must be at the end of this function. See the comment above | 753 | * dm_put() must be at the end of this function. See the comment above |
diff --git a/drivers/md/faulty.c b/drivers/md/faulty.c index 45135f69509c..5e7dc772f5de 100644 --- a/drivers/md/faulty.c +++ b/drivers/md/faulty.c | |||
| @@ -315,8 +315,11 @@ static int run(struct mddev *mddev) | |||
| 315 | } | 315 | } |
| 316 | conf->nfaults = 0; | 316 | conf->nfaults = 0; |
| 317 | 317 | ||
| 318 | rdev_for_each(rdev, mddev) | 318 | rdev_for_each(rdev, mddev) { |
| 319 | conf->rdev = rdev; | 319 | conf->rdev = rdev; |
| 320 | disk_stack_limits(mddev->gendisk, rdev->bdev, | ||
| 321 | rdev->data_offset << 9); | ||
| 322 | } | ||
| 320 | 323 | ||
| 321 | md_set_array_sectors(mddev, faulty_size(mddev, 0, 0)); | 324 | md_set_array_sectors(mddev, faulty_size(mddev, 0, 0)); |
| 322 | mddev->private = conf; | 325 | mddev->private = conf; |
diff --git a/drivers/md/md.c b/drivers/md/md.c index 9ab768acfb62..61200717687b 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c | |||
| @@ -1817,10 +1817,10 @@ retry: | |||
| 1817 | memset(bbp, 0xff, PAGE_SIZE); | 1817 | memset(bbp, 0xff, PAGE_SIZE); |
| 1818 | 1818 | ||
| 1819 | for (i = 0 ; i < bb->count ; i++) { | 1819 | for (i = 0 ; i < bb->count ; i++) { |
| 1820 | u64 internal_bb = *p++; | 1820 | u64 internal_bb = p[i]; |
| 1821 | u64 store_bb = ((BB_OFFSET(internal_bb) << 10) | 1821 | u64 store_bb = ((BB_OFFSET(internal_bb) << 10) |
| 1822 | | BB_LEN(internal_bb)); | 1822 | | BB_LEN(internal_bb)); |
| 1823 | *bbp++ = cpu_to_le64(store_bb); | 1823 | bbp[i] = cpu_to_le64(store_bb); |
| 1824 | } | 1824 | } |
| 1825 | bb->changed = 0; | 1825 | bb->changed = 0; |
| 1826 | if (read_seqretry(&bb->lock, seq)) | 1826 | if (read_seqretry(&bb->lock, seq)) |
| @@ -5294,7 +5294,7 @@ void md_stop_writes(struct mddev *mddev) | |||
| 5294 | } | 5294 | } |
| 5295 | EXPORT_SYMBOL_GPL(md_stop_writes); | 5295 | EXPORT_SYMBOL_GPL(md_stop_writes); |
| 5296 | 5296 | ||
| 5297 | void md_stop(struct mddev *mddev) | 5297 | static void __md_stop(struct mddev *mddev) |
| 5298 | { | 5298 | { |
| 5299 | mddev->ready = 0; | 5299 | mddev->ready = 0; |
| 5300 | mddev->pers->stop(mddev); | 5300 | mddev->pers->stop(mddev); |
| @@ -5304,6 +5304,18 @@ void md_stop(struct mddev *mddev) | |||
| 5304 | mddev->pers = NULL; | 5304 | mddev->pers = NULL; |
| 5305 | clear_bit(MD_RECOVERY_FROZEN, &mddev->recovery); | 5305 | clear_bit(MD_RECOVERY_FROZEN, &mddev->recovery); |
| 5306 | } | 5306 | } |
| 5307 | |||
| 5308 | void md_stop(struct mddev *mddev) | ||
| 5309 | { | ||
| 5310 | /* stop the array and free an attached data structures. | ||
| 5311 | * This is called from dm-raid | ||
| 5312 | */ | ||
| 5313 | __md_stop(mddev); | ||
| 5314 | bitmap_destroy(mddev); | ||
| 5315 | if (mddev->bio_set) | ||
| 5316 | bioset_free(mddev->bio_set); | ||
| 5317 | } | ||
| 5318 | |||
| 5307 | EXPORT_SYMBOL_GPL(md_stop); | 5319 | EXPORT_SYMBOL_GPL(md_stop); |
| 5308 | 5320 | ||
| 5309 | static int md_set_readonly(struct mddev *mddev, struct block_device *bdev) | 5321 | static int md_set_readonly(struct mddev *mddev, struct block_device *bdev) |
| @@ -5364,7 +5376,7 @@ static int do_md_stop(struct mddev * mddev, int mode, | |||
| 5364 | set_disk_ro(disk, 0); | 5376 | set_disk_ro(disk, 0); |
| 5365 | 5377 | ||
| 5366 | __md_stop_writes(mddev); | 5378 | __md_stop_writes(mddev); |
| 5367 | md_stop(mddev); | 5379 | __md_stop(mddev); |
| 5368 | mddev->queue->merge_bvec_fn = NULL; | 5380 | mddev->queue->merge_bvec_fn = NULL; |
| 5369 | mddev->queue->backing_dev_info.congested_fn = NULL; | 5381 | mddev->queue->backing_dev_info.congested_fn = NULL; |
| 5370 | 5382 | ||
| @@ -7936,9 +7948,9 @@ int md_is_badblock(struct badblocks *bb, sector_t s, int sectors, | |||
| 7936 | sector_t *first_bad, int *bad_sectors) | 7948 | sector_t *first_bad, int *bad_sectors) |
| 7937 | { | 7949 | { |
| 7938 | int hi; | 7950 | int hi; |
| 7939 | int lo = 0; | 7951 | int lo; |
| 7940 | u64 *p = bb->page; | 7952 | u64 *p = bb->page; |
| 7941 | int rv = 0; | 7953 | int rv; |
| 7942 | sector_t target = s + sectors; | 7954 | sector_t target = s + sectors; |
| 7943 | unsigned seq; | 7955 | unsigned seq; |
| 7944 | 7956 | ||
| @@ -7953,7 +7965,8 @@ int md_is_badblock(struct badblocks *bb, sector_t s, int sectors, | |||
| 7953 | 7965 | ||
| 7954 | retry: | 7966 | retry: |
| 7955 | seq = read_seqbegin(&bb->lock); | 7967 | seq = read_seqbegin(&bb->lock); |
| 7956 | 7968 | lo = 0; | |
| 7969 | rv = 0; | ||
| 7957 | hi = bb->count; | 7970 | hi = bb->count; |
| 7958 | 7971 | ||
| 7959 | /* Binary search between lo and hi for 'target' | 7972 | /* Binary search between lo and hi for 'target' |
diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c index 8034fbd6190c..a0f73092176e 100644 --- a/drivers/md/raid1.c +++ b/drivers/md/raid1.c | |||
| @@ -963,7 +963,7 @@ static void raid1_unplug(struct blk_plug_cb *cb, bool from_schedule) | |||
| 963 | struct r1conf *conf = mddev->private; | 963 | struct r1conf *conf = mddev->private; |
| 964 | struct bio *bio; | 964 | struct bio *bio; |
| 965 | 965 | ||
| 966 | if (from_schedule) { | 966 | if (from_schedule || current->bio_list) { |
| 967 | spin_lock_irq(&conf->device_lock); | 967 | spin_lock_irq(&conf->device_lock); |
| 968 | bio_list_merge(&conf->pending_bio_list, &plug->pending); | 968 | bio_list_merge(&conf->pending_bio_list, &plug->pending); |
| 969 | conf->pending_count += plug->pending_cnt; | 969 | conf->pending_count += plug->pending_cnt; |
| @@ -2710,7 +2710,7 @@ static struct r1conf *setup_conf(struct mddev *mddev) | |||
| 2710 | || disk_idx < 0) | 2710 | || disk_idx < 0) |
| 2711 | continue; | 2711 | continue; |
| 2712 | if (test_bit(Replacement, &rdev->flags)) | 2712 | if (test_bit(Replacement, &rdev->flags)) |
| 2713 | disk = conf->mirrors + conf->raid_disks + disk_idx; | 2713 | disk = conf->mirrors + mddev->raid_disks + disk_idx; |
| 2714 | else | 2714 | else |
| 2715 | disk = conf->mirrors + disk_idx; | 2715 | disk = conf->mirrors + disk_idx; |
| 2716 | 2716 | ||
diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c index 906ccbd0f7dc..c9acbd717131 100644 --- a/drivers/md/raid10.c +++ b/drivers/md/raid10.c | |||
| @@ -499,7 +499,7 @@ static void raid10_end_write_request(struct bio *bio, int error) | |||
| 499 | */ | 499 | */ |
| 500 | one_write_done(r10_bio); | 500 | one_write_done(r10_bio); |
| 501 | if (dec_rdev) | 501 | if (dec_rdev) |
| 502 | rdev_dec_pending(conf->mirrors[dev].rdev, conf->mddev); | 502 | rdev_dec_pending(rdev, conf->mddev); |
| 503 | } | 503 | } |
| 504 | 504 | ||
| 505 | /* | 505 | /* |
| @@ -1069,7 +1069,7 @@ static void raid10_unplug(struct blk_plug_cb *cb, bool from_schedule) | |||
| 1069 | struct r10conf *conf = mddev->private; | 1069 | struct r10conf *conf = mddev->private; |
| 1070 | struct bio *bio; | 1070 | struct bio *bio; |
| 1071 | 1071 | ||
| 1072 | if (from_schedule) { | 1072 | if (from_schedule || current->bio_list) { |
| 1073 | spin_lock_irq(&conf->device_lock); | 1073 | spin_lock_irq(&conf->device_lock); |
| 1074 | bio_list_merge(&conf->pending_bio_list, &plug->pending); | 1074 | bio_list_merge(&conf->pending_bio_list, &plug->pending); |
| 1075 | conf->pending_count += plug->pending_cnt; | 1075 | conf->pending_count += plug->pending_cnt; |
| @@ -1334,18 +1334,21 @@ retry_write: | |||
| 1334 | blocked_rdev = rrdev; | 1334 | blocked_rdev = rrdev; |
| 1335 | break; | 1335 | break; |
| 1336 | } | 1336 | } |
| 1337 | if (rdev && (test_bit(Faulty, &rdev->flags) | ||
| 1338 | || test_bit(Unmerged, &rdev->flags))) | ||
| 1339 | rdev = NULL; | ||
| 1337 | if (rrdev && (test_bit(Faulty, &rrdev->flags) | 1340 | if (rrdev && (test_bit(Faulty, &rrdev->flags) |
| 1338 | || test_bit(Unmerged, &rrdev->flags))) | 1341 | || test_bit(Unmerged, &rrdev->flags))) |
| 1339 | rrdev = NULL; | 1342 | rrdev = NULL; |
| 1340 | 1343 | ||
| 1341 | r10_bio->devs[i].bio = NULL; | 1344 | r10_bio->devs[i].bio = NULL; |
| 1342 | r10_bio->devs[i].repl_bio = NULL; | 1345 | r10_bio->devs[i].repl_bio = NULL; |
| 1343 | if (!rdev || test_bit(Faulty, &rdev->flags) || | 1346 | |
| 1344 | test_bit(Unmerged, &rdev->flags)) { | 1347 | if (!rdev && !rrdev) { |
| 1345 | set_bit(R10BIO_Degraded, &r10_bio->state); | 1348 | set_bit(R10BIO_Degraded, &r10_bio->state); |
| 1346 | continue; | 1349 | continue; |
| 1347 | } | 1350 | } |
| 1348 | if (test_bit(WriteErrorSeen, &rdev->flags)) { | 1351 | if (rdev && test_bit(WriteErrorSeen, &rdev->flags)) { |
| 1349 | sector_t first_bad; | 1352 | sector_t first_bad; |
| 1350 | sector_t dev_sector = r10_bio->devs[i].addr; | 1353 | sector_t dev_sector = r10_bio->devs[i].addr; |
| 1351 | int bad_sectors; | 1354 | int bad_sectors; |
| @@ -1387,8 +1390,10 @@ retry_write: | |||
| 1387 | max_sectors = good_sectors; | 1390 | max_sectors = good_sectors; |
| 1388 | } | 1391 | } |
| 1389 | } | 1392 | } |
| 1390 | r10_bio->devs[i].bio = bio; | 1393 | if (rdev) { |
| 1391 | atomic_inc(&rdev->nr_pending); | 1394 | r10_bio->devs[i].bio = bio; |
| 1395 | atomic_inc(&rdev->nr_pending); | ||
| 1396 | } | ||
| 1392 | if (rrdev) { | 1397 | if (rrdev) { |
| 1393 | r10_bio->devs[i].repl_bio = bio; | 1398 | r10_bio->devs[i].repl_bio = bio; |
| 1394 | atomic_inc(&rrdev->nr_pending); | 1399 | atomic_inc(&rrdev->nr_pending); |
| @@ -1444,69 +1449,71 @@ retry_write: | |||
| 1444 | for (i = 0; i < conf->copies; i++) { | 1449 | for (i = 0; i < conf->copies; i++) { |
| 1445 | struct bio *mbio; | 1450 | struct bio *mbio; |
| 1446 | int d = r10_bio->devs[i].devnum; | 1451 | int d = r10_bio->devs[i].devnum; |
| 1447 | if (!r10_bio->devs[i].bio) | 1452 | if (r10_bio->devs[i].bio) { |
| 1448 | continue; | 1453 | struct md_rdev *rdev = conf->mirrors[d].rdev; |
| 1454 | mbio = bio_clone_mddev(bio, GFP_NOIO, mddev); | ||
| 1455 | md_trim_bio(mbio, r10_bio->sector - bio->bi_sector, | ||
| 1456 | max_sectors); | ||
| 1457 | r10_bio->devs[i].bio = mbio; | ||
| 1458 | |||
| 1459 | mbio->bi_sector = (r10_bio->devs[i].addr+ | ||
| 1460 | choose_data_offset(r10_bio, | ||
| 1461 | rdev)); | ||
| 1462 | mbio->bi_bdev = rdev->bdev; | ||
| 1463 | mbio->bi_end_io = raid10_end_write_request; | ||
| 1464 | mbio->bi_rw = WRITE | do_sync | do_fua | do_discard; | ||
| 1465 | mbio->bi_private = r10_bio; | ||
| 1449 | 1466 | ||
| 1450 | mbio = bio_clone_mddev(bio, GFP_NOIO, mddev); | 1467 | atomic_inc(&r10_bio->remaining); |
| 1451 | md_trim_bio(mbio, r10_bio->sector - bio->bi_sector, | ||
| 1452 | max_sectors); | ||
| 1453 | r10_bio->devs[i].bio = mbio; | ||
| 1454 | 1468 | ||
| 1455 | mbio->bi_sector = (r10_bio->devs[i].addr+ | 1469 | cb = blk_check_plugged(raid10_unplug, mddev, |
| 1456 | choose_data_offset(r10_bio, | 1470 | sizeof(*plug)); |
| 1457 | conf->mirrors[d].rdev)); | 1471 | if (cb) |
| 1458 | mbio->bi_bdev = conf->mirrors[d].rdev->bdev; | 1472 | plug = container_of(cb, struct raid10_plug_cb, |
| 1459 | mbio->bi_end_io = raid10_end_write_request; | 1473 | cb); |
| 1460 | mbio->bi_rw = WRITE | do_sync | do_fua | do_discard; | 1474 | else |
| 1461 | mbio->bi_private = r10_bio; | 1475 | plug = NULL; |
| 1476 | spin_lock_irqsave(&conf->device_lock, flags); | ||
| 1477 | if (plug) { | ||
| 1478 | bio_list_add(&plug->pending, mbio); | ||
| 1479 | plug->pending_cnt++; | ||
| 1480 | } else { | ||
| 1481 | bio_list_add(&conf->pending_bio_list, mbio); | ||
| 1482 | conf->pending_count++; | ||
| 1483 | } | ||
| 1484 | spin_unlock_irqrestore(&conf->device_lock, flags); | ||
| 1485 | if (!plug) | ||
| 1486 | md_wakeup_thread(mddev->thread); | ||
| 1487 | } | ||
| 1462 | 1488 | ||
| 1463 | atomic_inc(&r10_bio->remaining); | 1489 | if (r10_bio->devs[i].repl_bio) { |
| 1490 | struct md_rdev *rdev = conf->mirrors[d].replacement; | ||
| 1491 | if (rdev == NULL) { | ||
| 1492 | /* Replacement just got moved to main 'rdev' */ | ||
| 1493 | smp_mb(); | ||
| 1494 | rdev = conf->mirrors[d].rdev; | ||
| 1495 | } | ||
| 1496 | mbio = bio_clone_mddev(bio, GFP_NOIO, mddev); | ||
| 1497 | md_trim_bio(mbio, r10_bio->sector - bio->bi_sector, | ||
| 1498 | max_sectors); | ||
| 1499 | r10_bio->devs[i].repl_bio = mbio; | ||
| 1500 | |||
| 1501 | mbio->bi_sector = (r10_bio->devs[i].addr + | ||
| 1502 | choose_data_offset( | ||
| 1503 | r10_bio, rdev)); | ||
| 1504 | mbio->bi_bdev = rdev->bdev; | ||
| 1505 | mbio->bi_end_io = raid10_end_write_request; | ||
| 1506 | mbio->bi_rw = WRITE | do_sync | do_fua | do_discard; | ||
| 1507 | mbio->bi_private = r10_bio; | ||
| 1464 | 1508 | ||
| 1465 | cb = blk_check_plugged(raid10_unplug, mddev, sizeof(*plug)); | 1509 | atomic_inc(&r10_bio->remaining); |
| 1466 | if (cb) | 1510 | spin_lock_irqsave(&conf->device_lock, flags); |
| 1467 | plug = container_of(cb, struct raid10_plug_cb, cb); | ||
| 1468 | else | ||
| 1469 | plug = NULL; | ||
| 1470 | spin_lock_irqsave(&conf->device_lock, flags); | ||
| 1471 | if (plug) { | ||
| 1472 | bio_list_add(&plug->pending, mbio); | ||
| 1473 | plug->pending_cnt++; | ||
| 1474 | } else { | ||
| 1475 | bio_list_add(&conf->pending_bio_list, mbio); | 1511 | bio_list_add(&conf->pending_bio_list, mbio); |
| 1476 | conf->pending_count++; | 1512 | conf->pending_count++; |
| 1513 | spin_unlock_irqrestore(&conf->device_lock, flags); | ||
| 1514 | if (!mddev_check_plugged(mddev)) | ||
| 1515 | md_wakeup_thread(mddev->thread); | ||
| 1477 | } | 1516 | } |
| 1478 | spin_unlock_irqrestore(&conf->device_lock, flags); | ||
| 1479 | if (!plug) | ||
| 1480 | md_wakeup_thread(mddev->thread); | ||
| 1481 | |||
| 1482 | if (!r10_bio->devs[i].repl_bio) | ||
| 1483 | continue; | ||
| 1484 | |||
| 1485 | mbio = bio_clone_mddev(bio, GFP_NOIO, mddev); | ||
| 1486 | md_trim_bio(mbio, r10_bio->sector - bio->bi_sector, | ||
| 1487 | max_sectors); | ||
| 1488 | r10_bio->devs[i].repl_bio = mbio; | ||
| 1489 | |||
| 1490 | /* We are actively writing to the original device | ||
| 1491 | * so it cannot disappear, so the replacement cannot | ||
| 1492 | * become NULL here | ||
| 1493 | */ | ||
| 1494 | mbio->bi_sector = (r10_bio->devs[i].addr + | ||
| 1495 | choose_data_offset( | ||
| 1496 | r10_bio, | ||
| 1497 | conf->mirrors[d].replacement)); | ||
| 1498 | mbio->bi_bdev = conf->mirrors[d].replacement->bdev; | ||
| 1499 | mbio->bi_end_io = raid10_end_write_request; | ||
| 1500 | mbio->bi_rw = WRITE | do_sync | do_fua | do_discard; | ||
| 1501 | mbio->bi_private = r10_bio; | ||
| 1502 | |||
| 1503 | atomic_inc(&r10_bio->remaining); | ||
| 1504 | spin_lock_irqsave(&conf->device_lock, flags); | ||
| 1505 | bio_list_add(&conf->pending_bio_list, mbio); | ||
| 1506 | conf->pending_count++; | ||
| 1507 | spin_unlock_irqrestore(&conf->device_lock, flags); | ||
| 1508 | if (!mddev_check_plugged(mddev)) | ||
| 1509 | md_wakeup_thread(mddev->thread); | ||
| 1510 | } | 1517 | } |
| 1511 | 1518 | ||
| 1512 | /* Don't remove the bias on 'remaining' (one_write_done) until | 1519 | /* Don't remove the bias on 'remaining' (one_write_done) until |
| @@ -1783,7 +1790,7 @@ static int raid10_add_disk(struct mddev *mddev, struct md_rdev *rdev) | |||
| 1783 | clear_bit(Unmerged, &rdev->flags); | 1790 | clear_bit(Unmerged, &rdev->flags); |
| 1784 | } | 1791 | } |
| 1785 | md_integrity_add_rdev(rdev, mddev); | 1792 | md_integrity_add_rdev(rdev, mddev); |
| 1786 | if (blk_queue_discard(bdev_get_queue(rdev->bdev))) | 1793 | if (mddev->queue && blk_queue_discard(bdev_get_queue(rdev->bdev))) |
| 1787 | queue_flag_set_unlocked(QUEUE_FLAG_DISCARD, mddev->queue); | 1794 | queue_flag_set_unlocked(QUEUE_FLAG_DISCARD, mddev->queue); |
| 1788 | 1795 | ||
| 1789 | print_conf(conf); | 1796 | print_conf(conf); |
| @@ -3613,11 +3620,14 @@ static int run(struct mddev *mddev) | |||
| 3613 | discard_supported = true; | 3620 | discard_supported = true; |
| 3614 | } | 3621 | } |
| 3615 | 3622 | ||
| 3616 | if (discard_supported) | 3623 | if (mddev->queue) { |
| 3617 | queue_flag_set_unlocked(QUEUE_FLAG_DISCARD, mddev->queue); | 3624 | if (discard_supported) |
| 3618 | else | 3625 | queue_flag_set_unlocked(QUEUE_FLAG_DISCARD, |
| 3619 | queue_flag_clear_unlocked(QUEUE_FLAG_DISCARD, mddev->queue); | 3626 | mddev->queue); |
| 3620 | 3627 | else | |
| 3628 | queue_flag_clear_unlocked(QUEUE_FLAG_DISCARD, | ||
| 3629 | mddev->queue); | ||
| 3630 | } | ||
| 3621 | /* need to check that every block has at least one working mirror */ | 3631 | /* need to check that every block has at least one working mirror */ |
| 3622 | if (!enough(conf, -1)) { | 3632 | if (!enough(conf, -1)) { |
| 3623 | printk(KERN_ERR "md/raid10:%s: not enough operational mirrors.\n", | 3633 | printk(KERN_ERR "md/raid10:%s: not enough operational mirrors.\n", |
diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c index c5439dce0295..a4502686e7a8 100644 --- a/drivers/md/raid5.c +++ b/drivers/md/raid5.c | |||
| @@ -2774,10 +2774,12 @@ static void handle_stripe_clean_event(struct r5conf *conf, | |||
| 2774 | dev = &sh->dev[i]; | 2774 | dev = &sh->dev[i]; |
| 2775 | if (!test_bit(R5_LOCKED, &dev->flags) && | 2775 | if (!test_bit(R5_LOCKED, &dev->flags) && |
| 2776 | (test_bit(R5_UPTODATE, &dev->flags) || | 2776 | (test_bit(R5_UPTODATE, &dev->flags) || |
| 2777 | test_and_clear_bit(R5_Discard, &dev->flags))) { | 2777 | test_bit(R5_Discard, &dev->flags))) { |
| 2778 | /* We can return any write requests */ | 2778 | /* We can return any write requests */ |
| 2779 | struct bio *wbi, *wbi2; | 2779 | struct bio *wbi, *wbi2; |
| 2780 | pr_debug("Return write for disc %d\n", i); | 2780 | pr_debug("Return write for disc %d\n", i); |
| 2781 | if (test_and_clear_bit(R5_Discard, &dev->flags)) | ||
| 2782 | clear_bit(R5_UPTODATE, &dev->flags); | ||
| 2781 | wbi = dev->written; | 2783 | wbi = dev->written; |
| 2782 | dev->written = NULL; | 2784 | dev->written = NULL; |
| 2783 | while (wbi && wbi->bi_sector < | 2785 | while (wbi && wbi->bi_sector < |
| @@ -2795,7 +2797,8 @@ static void handle_stripe_clean_event(struct r5conf *conf, | |||
| 2795 | !test_bit(STRIPE_DEGRADED, &sh->state), | 2797 | !test_bit(STRIPE_DEGRADED, &sh->state), |
| 2796 | 0); | 2798 | 0); |
| 2797 | } | 2799 | } |
| 2798 | } | 2800 | } else if (test_bit(R5_Discard, &sh->dev[i].flags)) |
| 2801 | clear_bit(R5_Discard, &sh->dev[i].flags); | ||
| 2799 | 2802 | ||
| 2800 | if (test_and_clear_bit(STRIPE_FULL_WRITE, &sh->state)) | 2803 | if (test_and_clear_bit(STRIPE_FULL_WRITE, &sh->state)) |
| 2801 | if (atomic_dec_and_test(&conf->pending_full_writes)) | 2804 | if (atomic_dec_and_test(&conf->pending_full_writes)) |
| @@ -3490,40 +3493,6 @@ static void handle_stripe(struct stripe_head *sh) | |||
| 3490 | handle_failed_sync(conf, sh, &s); | 3493 | handle_failed_sync(conf, sh, &s); |
| 3491 | } | 3494 | } |
| 3492 | 3495 | ||
| 3493 | /* | ||
| 3494 | * might be able to return some write requests if the parity blocks | ||
| 3495 | * are safe, or on a failed drive | ||
| 3496 | */ | ||
| 3497 | pdev = &sh->dev[sh->pd_idx]; | ||
| 3498 | s.p_failed = (s.failed >= 1 && s.failed_num[0] == sh->pd_idx) | ||
| 3499 | || (s.failed >= 2 && s.failed_num[1] == sh->pd_idx); | ||
| 3500 | qdev = &sh->dev[sh->qd_idx]; | ||
| 3501 | s.q_failed = (s.failed >= 1 && s.failed_num[0] == sh->qd_idx) | ||
| 3502 | || (s.failed >= 2 && s.failed_num[1] == sh->qd_idx) | ||
| 3503 | || conf->level < 6; | ||
| 3504 | |||
| 3505 | if (s.written && | ||
| 3506 | (s.p_failed || ((test_bit(R5_Insync, &pdev->flags) | ||
| 3507 | && !test_bit(R5_LOCKED, &pdev->flags) | ||
| 3508 | && (test_bit(R5_UPTODATE, &pdev->flags) || | ||
| 3509 | test_bit(R5_Discard, &pdev->flags))))) && | ||
| 3510 | (s.q_failed || ((test_bit(R5_Insync, &qdev->flags) | ||
| 3511 | && !test_bit(R5_LOCKED, &qdev->flags) | ||
| 3512 | && (test_bit(R5_UPTODATE, &qdev->flags) || | ||
| 3513 | test_bit(R5_Discard, &qdev->flags)))))) | ||
| 3514 | handle_stripe_clean_event(conf, sh, disks, &s.return_bi); | ||
| 3515 | |||
| 3516 | /* Now we might consider reading some blocks, either to check/generate | ||
| 3517 | * parity, or to satisfy requests | ||
| 3518 | * or to load a block that is being partially written. | ||
| 3519 | */ | ||
| 3520 | if (s.to_read || s.non_overwrite | ||
| 3521 | || (conf->level == 6 && s.to_write && s.failed) | ||
| 3522 | || (s.syncing && (s.uptodate + s.compute < disks)) | ||
| 3523 | || s.replacing | ||
| 3524 | || s.expanding) | ||
| 3525 | handle_stripe_fill(sh, &s, disks); | ||
| 3526 | |||
| 3527 | /* Now we check to see if any write operations have recently | 3496 | /* Now we check to see if any write operations have recently |
| 3528 | * completed | 3497 | * completed |
| 3529 | */ | 3498 | */ |
| @@ -3561,6 +3530,40 @@ static void handle_stripe(struct stripe_head *sh) | |||
| 3561 | s.dec_preread_active = 1; | 3530 | s.dec_preread_active = 1; |
| 3562 | } | 3531 | } |
| 3563 | 3532 | ||
| 3533 | /* | ||
| 3534 | * might be able to return some write requests if the parity blocks | ||
| 3535 | * are safe, or on a failed drive | ||
| 3536 | */ | ||
| 3537 | pdev = &sh->dev[sh->pd_idx]; | ||
| 3538 | s.p_failed = (s.failed >= 1 && s.failed_num[0] == sh->pd_idx) | ||
| 3539 | || (s.failed >= 2 && s.failed_num[1] == sh->pd_idx); | ||
| 3540 | qdev = &sh->dev[sh->qd_idx]; | ||
| 3541 | s.q_failed = (s.failed >= 1 && s.failed_num[0] == sh->qd_idx) | ||
| 3542 | || (s.failed >= 2 && s.failed_num[1] == sh->qd_idx) | ||
| 3543 | || conf->level < 6; | ||
| 3544 | |||
| 3545 | if (s.written && | ||
| 3546 | (s.p_failed || ((test_bit(R5_Insync, &pdev->flags) | ||
| 3547 | && !test_bit(R5_LOCKED, &pdev->flags) | ||
| 3548 | && (test_bit(R5_UPTODATE, &pdev->flags) || | ||
| 3549 | test_bit(R5_Discard, &pdev->flags))))) && | ||
| 3550 | (s.q_failed || ((test_bit(R5_Insync, &qdev->flags) | ||
| 3551 | && !test_bit(R5_LOCKED, &qdev->flags) | ||
| 3552 | && (test_bit(R5_UPTODATE, &qdev->flags) || | ||
| 3553 | test_bit(R5_Discard, &qdev->flags)))))) | ||
| 3554 | handle_stripe_clean_event(conf, sh, disks, &s.return_bi); | ||
| 3555 | |||
| 3556 | /* Now we might consider reading some blocks, either to check/generate | ||
| 3557 | * parity, or to satisfy requests | ||
| 3558 | * or to load a block that is being partially written. | ||
| 3559 | */ | ||
| 3560 | if (s.to_read || s.non_overwrite | ||
| 3561 | || (conf->level == 6 && s.to_write && s.failed) | ||
| 3562 | || (s.syncing && (s.uptodate + s.compute < disks)) | ||
| 3563 | || s.replacing | ||
| 3564 | || s.expanding) | ||
| 3565 | handle_stripe_fill(sh, &s, disks); | ||
| 3566 | |||
| 3564 | /* Now to consider new write requests and what else, if anything | 3567 | /* Now to consider new write requests and what else, if anything |
| 3565 | * should be read. We do not handle new writes when: | 3568 | * should be read. We do not handle new writes when: |
| 3566 | * 1/ A 'write' operation (copy+xor) is already in flight. | 3569 | * 1/ A 'write' operation (copy+xor) is already in flight. |
| @@ -5529,6 +5532,10 @@ static int run(struct mddev *mddev) | |||
| 5529 | * discard data disk but write parity disk | 5532 | * discard data disk but write parity disk |
| 5530 | */ | 5533 | */ |
| 5531 | stripe = stripe * PAGE_SIZE; | 5534 | stripe = stripe * PAGE_SIZE; |
| 5535 | /* Round up to power of 2, as discard handling | ||
| 5536 | * currently assumes that */ | ||
| 5537 | while ((stripe-1) & stripe) | ||
| 5538 | stripe = (stripe | (stripe-1)) + 1; | ||
| 5532 | mddev->queue->limits.discard_alignment = stripe; | 5539 | mddev->queue->limits.discard_alignment = stripe; |
| 5533 | mddev->queue->limits.discard_granularity = stripe; | 5540 | mddev->queue->limits.discard_granularity = stripe; |
| 5534 | /* | 5541 | /* |
diff --git a/drivers/mfd/arizona-core.c b/drivers/mfd/arizona-core.c index 1b48f2094806..f4f9bf84bc7b 100644 --- a/drivers/mfd/arizona-core.c +++ b/drivers/mfd/arizona-core.c | |||
| @@ -98,9 +98,9 @@ static irqreturn_t arizona_underclocked(int irq, void *data) | |||
| 98 | 98 | ||
| 99 | if (val & ARIZONA_AIF3_UNDERCLOCKED_STS) | 99 | if (val & ARIZONA_AIF3_UNDERCLOCKED_STS) |
| 100 | dev_err(arizona->dev, "AIF3 underclocked\n"); | 100 | dev_err(arizona->dev, "AIF3 underclocked\n"); |
| 101 | if (val & ARIZONA_AIF3_UNDERCLOCKED_STS) | ||
| 102 | dev_err(arizona->dev, "AIF3 underclocked\n"); | ||
| 103 | if (val & ARIZONA_AIF2_UNDERCLOCKED_STS) | 101 | if (val & ARIZONA_AIF2_UNDERCLOCKED_STS) |
| 102 | dev_err(arizona->dev, "AIF2 underclocked\n"); | ||
| 103 | if (val & ARIZONA_AIF1_UNDERCLOCKED_STS) | ||
| 104 | dev_err(arizona->dev, "AIF1 underclocked\n"); | 104 | dev_err(arizona->dev, "AIF1 underclocked\n"); |
| 105 | if (val & ARIZONA_ISRC2_UNDERCLOCKED_STS) | 105 | if (val & ARIZONA_ISRC2_UNDERCLOCKED_STS) |
| 106 | dev_err(arizona->dev, "ISRC2 underclocked\n"); | 106 | dev_err(arizona->dev, "ISRC2 underclocked\n"); |
| @@ -415,11 +415,19 @@ int __devinit arizona_dev_init(struct arizona *arizona) | |||
| 415 | 415 | ||
| 416 | /* If we have a /RESET GPIO we'll already be reset */ | 416 | /* If we have a /RESET GPIO we'll already be reset */ |
| 417 | if (!arizona->pdata.reset) { | 417 | if (!arizona->pdata.reset) { |
| 418 | regcache_mark_dirty(arizona->regmap); | ||
| 419 | |||
| 418 | ret = regmap_write(arizona->regmap, ARIZONA_SOFTWARE_RESET, 0); | 420 | ret = regmap_write(arizona->regmap, ARIZONA_SOFTWARE_RESET, 0); |
| 419 | if (ret != 0) { | 421 | if (ret != 0) { |
| 420 | dev_err(dev, "Failed to reset device: %d\n", ret); | 422 | dev_err(dev, "Failed to reset device: %d\n", ret); |
| 421 | goto err_reset; | 423 | goto err_reset; |
| 422 | } | 424 | } |
| 425 | |||
| 426 | ret = regcache_sync(arizona->regmap); | ||
| 427 | if (ret != 0) { | ||
| 428 | dev_err(dev, "Failed to sync device: %d\n", ret); | ||
| 429 | goto err_reset; | ||
| 430 | } | ||
| 423 | } | 431 | } |
| 424 | 432 | ||
| 425 | ret = arizona_wait_for_boot(arizona); | 433 | ret = arizona_wait_for_boot(arizona); |
| @@ -520,7 +528,7 @@ int __devinit arizona_dev_init(struct arizona *arizona) | |||
| 520 | break; | 528 | break; |
| 521 | case WM5110: | 529 | case WM5110: |
| 522 | ret = mfd_add_devices(arizona->dev, -1, wm5110_devs, | 530 | ret = mfd_add_devices(arizona->dev, -1, wm5110_devs, |
| 523 | ARRAY_SIZE(wm5102_devs), NULL, 0, NULL); | 531 | ARRAY_SIZE(wm5110_devs), NULL, 0, NULL); |
| 524 | break; | 532 | break; |
| 525 | } | 533 | } |
| 526 | 534 | ||
diff --git a/drivers/mfd/arizona-irq.c b/drivers/mfd/arizona-irq.c index ef0f2d001df2..b1b009177405 100644 --- a/drivers/mfd/arizona-irq.c +++ b/drivers/mfd/arizona-irq.c | |||
| @@ -178,6 +178,7 @@ int arizona_irq_init(struct arizona *arizona) | |||
| 178 | 178 | ||
| 179 | switch (arizona->rev) { | 179 | switch (arizona->rev) { |
| 180 | case 0: | 180 | case 0: |
| 181 | case 1: | ||
| 181 | ctrlif_error = false; | 182 | ctrlif_error = false; |
| 182 | break; | 183 | break; |
| 183 | default: | 184 | default: |
diff --git a/drivers/mfd/twl-core.c b/drivers/mfd/twl-core.c index 4ae642320205..a071a8643a47 100644 --- a/drivers/mfd/twl-core.c +++ b/drivers/mfd/twl-core.c | |||
| @@ -671,7 +671,7 @@ add_children(struct twl4030_platform_data *pdata, unsigned irq_base, | |||
| 671 | } | 671 | } |
| 672 | 672 | ||
| 673 | if (IS_ENABLED(CONFIG_PWM_TWL6030) && twl_class_is_6030()) { | 673 | if (IS_ENABLED(CONFIG_PWM_TWL6030) && twl_class_is_6030()) { |
| 674 | child = add_child(TWL6030_MODULE_ID1, "twl6030-pwm", NULL, 0, | 674 | child = add_child(SUB_CHIP_ID1, "twl6030-pwm", NULL, 0, |
| 675 | false, 0, 0); | 675 | false, 0, 0); |
| 676 | if (IS_ERR(child)) | 676 | if (IS_ERR(child)) |
| 677 | return PTR_ERR(child); | 677 | return PTR_ERR(child); |
diff --git a/drivers/mfd/twl4030-irq.c b/drivers/mfd/twl4030-irq.c index ad733d76207a..cdd1173ed4e9 100644 --- a/drivers/mfd/twl4030-irq.c +++ b/drivers/mfd/twl4030-irq.c | |||
| @@ -672,7 +672,8 @@ int twl4030_sih_setup(struct device *dev, int module, int irq_base) | |||
| 672 | irq = sih_mod + twl4030_irq_base; | 672 | irq = sih_mod + twl4030_irq_base; |
| 673 | irq_set_handler_data(irq, agent); | 673 | irq_set_handler_data(irq, agent); |
| 674 | agent->irq_name = kasprintf(GFP_KERNEL, "twl4030_%s", sih->name); | 674 | agent->irq_name = kasprintf(GFP_KERNEL, "twl4030_%s", sih->name); |
| 675 | status = request_threaded_irq(irq, NULL, handle_twl4030_sih, 0, | 675 | status = request_threaded_irq(irq, NULL, handle_twl4030_sih, |
| 676 | IRQF_EARLY_RESUME, | ||
| 676 | agent->irq_name ?: sih->name, NULL); | 677 | agent->irq_name ?: sih->name, NULL); |
| 677 | 678 | ||
| 678 | dev_info(dev, "%s (irq %d) chaining IRQs %d..%d\n", sih->name, | 679 | dev_info(dev, "%s (irq %d) chaining IRQs %d..%d\n", sih->name, |
diff --git a/drivers/mfd/wm5102-tables.c b/drivers/mfd/wm5102-tables.c index 01b9255ed631..14490cc785d2 100644 --- a/drivers/mfd/wm5102-tables.c +++ b/drivers/mfd/wm5102-tables.c | |||
| @@ -43,6 +43,7 @@ static const struct reg_default wm5102_reva_patch[] = { | |||
| 43 | { 0x479, 0x0A30 }, | 43 | { 0x479, 0x0A30 }, |
| 44 | { 0x47B, 0x0810 }, | 44 | { 0x47B, 0x0810 }, |
| 45 | { 0x47D, 0x0510 }, | 45 | { 0x47D, 0x0510 }, |
| 46 | { 0x4D1, 0x017F }, | ||
| 46 | { 0x500, 0x000D }, | 47 | { 0x500, 0x000D }, |
| 47 | { 0x507, 0x1820 }, | 48 | { 0x507, 0x1820 }, |
| 48 | { 0x508, 0x1820 }, | 49 | { 0x508, 0x1820 }, |
| @@ -52,524 +53,6 @@ static const struct reg_default wm5102_reva_patch[] = { | |||
| 52 | { 0x580, 0x000D }, | 53 | { 0x580, 0x000D }, |
| 53 | { 0x587, 0x1820 }, | 54 | { 0x587, 0x1820 }, |
| 54 | { 0x588, 0x1820 }, | 55 | { 0x588, 0x1820 }, |
| 55 | { 0x101, 0x8140 }, | ||
| 56 | { 0x3000, 0x2225 }, | ||
| 57 | { 0x3001, 0x3a03 }, | ||
| 58 | { 0x3002, 0x0225 }, | ||
| 59 | { 0x3003, 0x0801 }, | ||
| 60 | { 0x3004, 0x6249 }, | ||
| 61 | { 0x3005, 0x0c04 }, | ||
| 62 | { 0x3006, 0x0225 }, | ||
| 63 | { 0x3007, 0x5901 }, | ||
| 64 | { 0x3008, 0xe249 }, | ||
| 65 | { 0x3009, 0x030d }, | ||
| 66 | { 0x300a, 0x0249 }, | ||
| 67 | { 0x300b, 0x2c01 }, | ||
| 68 | { 0x300c, 0xe249 }, | ||
| 69 | { 0x300d, 0x4342 }, | ||
| 70 | { 0x300e, 0xe249 }, | ||
| 71 | { 0x300f, 0x73c0 }, | ||
| 72 | { 0x3010, 0x4249 }, | ||
| 73 | { 0x3011, 0x0c00 }, | ||
| 74 | { 0x3012, 0x0225 }, | ||
| 75 | { 0x3013, 0x1f01 }, | ||
| 76 | { 0x3014, 0x0225 }, | ||
| 77 | { 0x3015, 0x1e01 }, | ||
| 78 | { 0x3016, 0x0225 }, | ||
| 79 | { 0x3017, 0xfa00 }, | ||
| 80 | { 0x3018, 0x0000 }, | ||
| 81 | { 0x3019, 0xf000 }, | ||
| 82 | { 0x301a, 0x0000 }, | ||
| 83 | { 0x301b, 0xf000 }, | ||
| 84 | { 0x301c, 0x0000 }, | ||
| 85 | { 0x301d, 0xf000 }, | ||
| 86 | { 0x301e, 0x0000 }, | ||
| 87 | { 0x301f, 0xf000 }, | ||
| 88 | { 0x3020, 0x0000 }, | ||
| 89 | { 0x3021, 0xf000 }, | ||
| 90 | { 0x3022, 0x0000 }, | ||
| 91 | { 0x3023, 0xf000 }, | ||
| 92 | { 0x3024, 0x0000 }, | ||
| 93 | { 0x3025, 0xf000 }, | ||
| 94 | { 0x3026, 0x0000 }, | ||
| 95 | { 0x3027, 0xf000 }, | ||
| 96 | { 0x3028, 0x0000 }, | ||
| 97 | { 0x3029, 0xf000 }, | ||
| 98 | { 0x302a, 0x0000 }, | ||
| 99 | { 0x302b, 0xf000 }, | ||
| 100 | { 0x302c, 0x0000 }, | ||
| 101 | { 0x302d, 0xf000 }, | ||
| 102 | { 0x302e, 0x0000 }, | ||
| 103 | { 0x302f, 0xf000 }, | ||
| 104 | { 0x3030, 0x0225 }, | ||
| 105 | { 0x3031, 0x1a01 }, | ||
| 106 | { 0x3032, 0x0225 }, | ||
| 107 | { 0x3033, 0x1e00 }, | ||
| 108 | { 0x3034, 0x0225 }, | ||
| 109 | { 0x3035, 0x1f00 }, | ||
| 110 | { 0x3036, 0x6225 }, | ||
| 111 | { 0x3037, 0xf800 }, | ||
| 112 | { 0x3038, 0x0000 }, | ||
| 113 | { 0x3039, 0xf000 }, | ||
| 114 | { 0x303a, 0x0000 }, | ||
| 115 | { 0x303b, 0xf000 }, | ||
| 116 | { 0x303c, 0x0000 }, | ||
| 117 | { 0x303d, 0xf000 }, | ||
| 118 | { 0x303e, 0x0000 }, | ||
| 119 | { 0x303f, 0xf000 }, | ||
| 120 | { 0x3040, 0x2226 }, | ||
| 121 | { 0x3041, 0x3a03 }, | ||
| 122 | { 0x3042, 0x0226 }, | ||
| 123 | { 0x3043, 0x0801 }, | ||
| 124 | { 0x3044, 0x6249 }, | ||
| 125 | { 0x3045, 0x0c06 }, | ||
| 126 | { 0x3046, 0x0226 }, | ||
| 127 | { 0x3047, 0x5901 }, | ||
| 128 | { 0x3048, 0xe249 }, | ||
| 129 | { 0x3049, 0x030d }, | ||
| 130 | { 0x304a, 0x0249 }, | ||
| 131 | { 0x304b, 0x2c01 }, | ||
| 132 | { 0x304c, 0xe249 }, | ||
| 133 | { 0x304d, 0x4342 }, | ||
| 134 | { 0x304e, 0xe249 }, | ||
| 135 | { 0x304f, 0x73c0 }, | ||
| 136 | { 0x3050, 0x4249 }, | ||
| 137 | { 0x3051, 0x0c00 }, | ||
| 138 | { 0x3052, 0x0226 }, | ||
| 139 | { 0x3053, 0x1f01 }, | ||
| 140 | { 0x3054, 0x0226 }, | ||
| 141 | { 0x3055, 0x1e01 }, | ||
| 142 | { 0x3056, 0x0226 }, | ||
| 143 | { 0x3057, 0xfa00 }, | ||
| 144 | { 0x3058, 0x0000 }, | ||
| 145 | { 0x3059, 0xf000 }, | ||
| 146 | { 0x305a, 0x0000 }, | ||
| 147 | { 0x305b, 0xf000 }, | ||
| 148 | { 0x305c, 0x0000 }, | ||
| 149 | { 0x305d, 0xf000 }, | ||
| 150 | { 0x305e, 0x0000 }, | ||
| 151 | { 0x305f, 0xf000 }, | ||
| 152 | { 0x3060, 0x0000 }, | ||
| 153 | { 0x3061, 0xf000 }, | ||
| 154 | { 0x3062, 0x0000 }, | ||
| 155 | { 0x3063, 0xf000 }, | ||
| 156 | { 0x3064, 0x0000 }, | ||
| 157 | { 0x3065, 0xf000 }, | ||
| 158 | { 0x3066, 0x0000 }, | ||
| 159 | { 0x3067, 0xf000 }, | ||
| 160 | { 0x3068, 0x0000 }, | ||
| 161 | { 0x3069, 0xf000 }, | ||
| 162 | { 0x306a, 0x0000 }, | ||
| 163 | { 0x306b, 0xf000 }, | ||
| 164 | { 0x306c, 0x0000 }, | ||
| 165 | { 0x306d, 0xf000 }, | ||
| 166 | { 0x306e, 0x0000 }, | ||
| 167 | { 0x306f, 0xf000 }, | ||
| 168 | { 0x3070, 0x0226 }, | ||
| 169 | { 0x3071, 0x1a01 }, | ||
| 170 | { 0x3072, 0x0226 }, | ||
| 171 | { 0x3073, 0x1e00 }, | ||
| 172 | { 0x3074, 0x0226 }, | ||
| 173 | { 0x3075, 0x1f00 }, | ||
| 174 | { 0x3076, 0x6226 }, | ||
| 175 | { 0x3077, 0xf800 }, | ||
| 176 | { 0x3078, 0x0000 }, | ||
| 177 | { 0x3079, 0xf000 }, | ||
| 178 | { 0x307a, 0x0000 }, | ||
| 179 | { 0x307b, 0xf000 }, | ||
| 180 | { 0x307c, 0x0000 }, | ||
| 181 | { 0x307d, 0xf000 }, | ||
| 182 | { 0x307e, 0x0000 }, | ||
| 183 | { 0x307f, 0xf000 }, | ||
| 184 | { 0x3080, 0x2227 }, | ||
| 185 | { 0x3081, 0x3a03 }, | ||
| 186 | { 0x3082, 0x0227 }, | ||
| 187 | { 0x3083, 0x0801 }, | ||
| 188 | { 0x3084, 0x6255 }, | ||
| 189 | { 0x3085, 0x0c04 }, | ||
| 190 | { 0x3086, 0x0227 }, | ||
| 191 | { 0x3087, 0x5901 }, | ||
| 192 | { 0x3088, 0xe255 }, | ||
| 193 | { 0x3089, 0x030d }, | ||
| 194 | { 0x308a, 0x0255 }, | ||
| 195 | { 0x308b, 0x2c01 }, | ||
| 196 | { 0x308c, 0xe255 }, | ||
| 197 | { 0x308d, 0x4342 }, | ||
| 198 | { 0x308e, 0xe255 }, | ||
| 199 | { 0x308f, 0x73c0 }, | ||
| 200 | { 0x3090, 0x4255 }, | ||
| 201 | { 0x3091, 0x0c00 }, | ||
| 202 | { 0x3092, 0x0227 }, | ||
| 203 | { 0x3093, 0x1f01 }, | ||
| 204 | { 0x3094, 0x0227 }, | ||
| 205 | { 0x3095, 0x1e01 }, | ||
| 206 | { 0x3096, 0x0227 }, | ||
| 207 | { 0x3097, 0xfa00 }, | ||
| 208 | { 0x3098, 0x0000 }, | ||
| 209 | { 0x3099, 0xf000 }, | ||
| 210 | { 0x309a, 0x0000 }, | ||
| 211 | { 0x309b, 0xf000 }, | ||
| 212 | { 0x309c, 0x0000 }, | ||
| 213 | { 0x309d, 0xf000 }, | ||
| 214 | { 0x309e, 0x0000 }, | ||
| 215 | { 0x309f, 0xf000 }, | ||
| 216 | { 0x30a0, 0x0000 }, | ||
| 217 | { 0x30a1, 0xf000 }, | ||
| 218 | { 0x30a2, 0x0000 }, | ||
| 219 | { 0x30a3, 0xf000 }, | ||
| 220 | { 0x30a4, 0x0000 }, | ||
| 221 | { 0x30a5, 0xf000 }, | ||
| 222 | { 0x30a6, 0x0000 }, | ||
| 223 | { 0x30a7, 0xf000 }, | ||
| 224 | { 0x30a8, 0x0000 }, | ||
| 225 | { 0x30a9, 0xf000 }, | ||
| 226 | { 0x30aa, 0x0000 }, | ||
| 227 | { 0x30ab, 0xf000 }, | ||
| 228 | { 0x30ac, 0x0000 }, | ||
| 229 | { 0x30ad, 0xf000 }, | ||
| 230 | { 0x30ae, 0x0000 }, | ||
| 231 | { 0x30af, 0xf000 }, | ||
| 232 | { 0x30b0, 0x0227 }, | ||
| 233 | { 0x30b1, 0x1a01 }, | ||
| 234 | { 0x30b2, 0x0227 }, | ||
| 235 | { 0x30b3, 0x1e00 }, | ||
| 236 | { 0x30b4, 0x0227 }, | ||
| 237 | { 0x30b5, 0x1f00 }, | ||
| 238 | { 0x30b6, 0x6227 }, | ||
| 239 | { 0x30b7, 0xf800 }, | ||
| 240 | { 0x30b8, 0x0000 }, | ||
| 241 | { 0x30b9, 0xf000 }, | ||
| 242 | { 0x30ba, 0x0000 }, | ||
| 243 | { 0x30bb, 0xf000 }, | ||
| 244 | { 0x30bc, 0x0000 }, | ||
| 245 | { 0x30bd, 0xf000 }, | ||
| 246 | { 0x30be, 0x0000 }, | ||
| 247 | { 0x30bf, 0xf000 }, | ||
| 248 | { 0x30c0, 0x2228 }, | ||
| 249 | { 0x30c1, 0x3a03 }, | ||
| 250 | { 0x30c2, 0x0228 }, | ||
| 251 | { 0x30c3, 0x0801 }, | ||
| 252 | { 0x30c4, 0x6255 }, | ||
| 253 | { 0x30c5, 0x0c06 }, | ||
| 254 | { 0x30c6, 0x0228 }, | ||
| 255 | { 0x30c7, 0x5901 }, | ||
| 256 | { 0x30c8, 0xe255 }, | ||
| 257 | { 0x30c9, 0x030d }, | ||
| 258 | { 0x30ca, 0x0255 }, | ||
| 259 | { 0x30cb, 0x2c01 }, | ||
| 260 | { 0x30cc, 0xe255 }, | ||
| 261 | { 0x30cd, 0x4342 }, | ||
| 262 | { 0x30ce, 0xe255 }, | ||
| 263 | { 0x30cf, 0x73c0 }, | ||
| 264 | { 0x30d0, 0x4255 }, | ||
| 265 | { 0x30d1, 0x0c00 }, | ||
| 266 | { 0x30d2, 0x0228 }, | ||
| 267 | { 0x30d3, 0x1f01 }, | ||
| 268 | { 0x30d4, 0x0228 }, | ||
| 269 | { 0x30d5, 0x1e01 }, | ||
| 270 | { 0x30d6, 0x0228 }, | ||
| 271 | { 0x30d7, 0xfa00 }, | ||
| 272 | { 0x30d8, 0x0000 }, | ||
| 273 | { 0x30d9, 0xf000 }, | ||
| 274 | { 0x30da, 0x0000 }, | ||
| 275 | { 0x30db, 0xf000 }, | ||
| 276 | { 0x30dc, 0x0000 }, | ||
| 277 | { 0x30dd, 0xf000 }, | ||
| 278 | { 0x30de, 0x0000 }, | ||
| 279 | { 0x30df, 0xf000 }, | ||
| 280 | { 0x30e0, 0x0000 }, | ||
| 281 | { 0x30e1, 0xf000 }, | ||
| 282 | { 0x30e2, 0x0000 }, | ||
| 283 | { 0x30e3, 0xf000 }, | ||
| 284 | { 0x30e4, 0x0000 }, | ||
| 285 | { 0x30e5, 0xf000 }, | ||
| 286 | { 0x30e6, 0x0000 }, | ||
| 287 | { 0x30e7, 0xf000 }, | ||
| 288 | { 0x30e8, 0x0000 }, | ||
| 289 | { 0x30e9, 0xf000 }, | ||
| 290 | { 0x30ea, 0x0000 }, | ||
| 291 | { 0x30eb, 0xf000 }, | ||
| 292 | { 0x30ec, 0x0000 }, | ||
| 293 | { 0x30ed, 0xf000 }, | ||
| 294 | { 0x30ee, 0x0000 }, | ||
| 295 | { 0x30ef, 0xf000 }, | ||
| 296 | { 0x30f0, 0x0228 }, | ||
| 297 | { 0x30f1, 0x1a01 }, | ||
| 298 | { 0x30f2, 0x0228 }, | ||
| 299 | { 0x30f3, 0x1e00 }, | ||
| 300 | { 0x30f4, 0x0228 }, | ||
| 301 | { 0x30f5, 0x1f00 }, | ||
| 302 | { 0x30f6, 0x6228 }, | ||
| 303 | { 0x30f7, 0xf800 }, | ||
| 304 | { 0x30f8, 0x0000 }, | ||
| 305 | { 0x30f9, 0xf000 }, | ||
| 306 | { 0x30fa, 0x0000 }, | ||
| 307 | { 0x30fb, 0xf000 }, | ||
| 308 | { 0x30fc, 0x0000 }, | ||
| 309 | { 0x30fd, 0xf000 }, | ||
| 310 | { 0x30fe, 0x0000 }, | ||
| 311 | { 0x30ff, 0xf000 }, | ||
| 312 | { 0x3100, 0x222b }, | ||
| 313 | { 0x3101, 0x3a03 }, | ||
| 314 | { 0x3102, 0x222b }, | ||
| 315 | { 0x3103, 0x5803 }, | ||
| 316 | { 0x3104, 0xe26f }, | ||
| 317 | { 0x3105, 0x030d }, | ||
| 318 | { 0x3106, 0x626f }, | ||
| 319 | { 0x3107, 0x2c01 }, | ||
| 320 | { 0x3108, 0xe26f }, | ||
| 321 | { 0x3109, 0x4342 }, | ||
| 322 | { 0x310a, 0xe26f }, | ||
| 323 | { 0x310b, 0x73c0 }, | ||
| 324 | { 0x310c, 0x026f }, | ||
| 325 | { 0x310d, 0x0c00 }, | ||
| 326 | { 0x310e, 0x022b }, | ||
| 327 | { 0x310f, 0x1f01 }, | ||
| 328 | { 0x3110, 0x022b }, | ||
| 329 | { 0x3111, 0x1e01 }, | ||
| 330 | { 0x3112, 0x022b }, | ||
| 331 | { 0x3113, 0xfa00 }, | ||
| 332 | { 0x3114, 0x0000 }, | ||
| 333 | { 0x3115, 0xf000 }, | ||
| 334 | { 0x3116, 0x0000 }, | ||
| 335 | { 0x3117, 0xf000 }, | ||
| 336 | { 0x3118, 0x0000 }, | ||
| 337 | { 0x3119, 0xf000 }, | ||
| 338 | { 0x311a, 0x0000 }, | ||
| 339 | { 0x311b, 0xf000 }, | ||
| 340 | { 0x311c, 0x0000 }, | ||
| 341 | { 0x311d, 0xf000 }, | ||
| 342 | { 0x311e, 0x0000 }, | ||
| 343 | { 0x311f, 0xf000 }, | ||
| 344 | { 0x3120, 0x022b }, | ||
| 345 | { 0x3121, 0x0a01 }, | ||
| 346 | { 0x3122, 0x022b }, | ||
| 347 | { 0x3123, 0x1e00 }, | ||
| 348 | { 0x3124, 0x022b }, | ||
| 349 | { 0x3125, 0x1f00 }, | ||
| 350 | { 0x3126, 0x622b }, | ||
| 351 | { 0x3127, 0xf800 }, | ||
| 352 | { 0x3128, 0x0000 }, | ||
| 353 | { 0x3129, 0xf000 }, | ||
| 354 | { 0x312a, 0x0000 }, | ||
| 355 | { 0x312b, 0xf000 }, | ||
| 356 | { 0x312c, 0x0000 }, | ||
| 357 | { 0x312d, 0xf000 }, | ||
| 358 | { 0x312e, 0x0000 }, | ||
| 359 | { 0x312f, 0xf000 }, | ||
| 360 | { 0x3130, 0x0000 }, | ||
| 361 | { 0x3131, 0xf000 }, | ||
| 362 | { 0x3132, 0x0000 }, | ||
| 363 | { 0x3133, 0xf000 }, | ||
| 364 | { 0x3134, 0x0000 }, | ||
| 365 | { 0x3135, 0xf000 }, | ||
| 366 | { 0x3136, 0x0000 }, | ||
| 367 | { 0x3137, 0xf000 }, | ||
| 368 | { 0x3138, 0x0000 }, | ||
| 369 | { 0x3139, 0xf000 }, | ||
| 370 | { 0x313a, 0x0000 }, | ||
| 371 | { 0x313b, 0xf000 }, | ||
| 372 | { 0x313c, 0x0000 }, | ||
| 373 | { 0x313d, 0xf000 }, | ||
| 374 | { 0x313e, 0x0000 }, | ||
| 375 | { 0x313f, 0xf000 }, | ||
| 376 | { 0x3140, 0x0000 }, | ||
| 377 | { 0x3141, 0xf000 }, | ||
| 378 | { 0x3142, 0x0000 }, | ||
| 379 | { 0x3143, 0xf000 }, | ||
| 380 | { 0x3144, 0x0000 }, | ||
| 381 | { 0x3145, 0xf000 }, | ||
| 382 | { 0x3146, 0x0000 }, | ||
| 383 | { 0x3147, 0xf000 }, | ||
| 384 | { 0x3148, 0x0000 }, | ||
| 385 | { 0x3149, 0xf000 }, | ||
| 386 | { 0x314a, 0x0000 }, | ||
| 387 | { 0x314b, 0xf000 }, | ||
| 388 | { 0x314c, 0x0000 }, | ||
| 389 | { 0x314d, 0xf000 }, | ||
| 390 | { 0x314e, 0x0000 }, | ||
| 391 | { 0x314f, 0xf000 }, | ||
| 392 | { 0x3150, 0x0000 }, | ||
| 393 | { 0x3151, 0xf000 }, | ||
| 394 | { 0x3152, 0x0000 }, | ||
| 395 | { 0x3153, 0xf000 }, | ||
| 396 | { 0x3154, 0x0000 }, | ||
| 397 | { 0x3155, 0xf000 }, | ||
| 398 | { 0x3156, 0x0000 }, | ||
| 399 | { 0x3157, 0xf000 }, | ||
| 400 | { 0x3158, 0x0000 }, | ||
| 401 | { 0x3159, 0xf000 }, | ||
| 402 | { 0x315a, 0x0000 }, | ||
| 403 | { 0x315b, 0xf000 }, | ||
| 404 | { 0x315c, 0x0000 }, | ||
| 405 | { 0x315d, 0xf000 }, | ||
| 406 | { 0x315e, 0x0000 }, | ||
| 407 | { 0x315f, 0xf000 }, | ||
| 408 | { 0x3160, 0x0000 }, | ||
| 409 | { 0x3161, 0xf000 }, | ||
| 410 | { 0x3162, 0x0000 }, | ||
| 411 | { 0x3163, 0xf000 }, | ||
| 412 | { 0x3164, 0x0000 }, | ||
| 413 | { 0x3165, 0xf000 }, | ||
| 414 | { 0x3166, 0x0000 }, | ||
| 415 | { 0x3167, 0xf000 }, | ||
| 416 | { 0x3168, 0x0000 }, | ||
| 417 | { 0x3169, 0xf000 }, | ||
| 418 | { 0x316a, 0x0000 }, | ||
| 419 | { 0x316b, 0xf000 }, | ||
| 420 | { 0x316c, 0x0000 }, | ||
| 421 | { 0x316d, 0xf000 }, | ||
| 422 | { 0x316e, 0x0000 }, | ||
| 423 | { 0x316f, 0xf000 }, | ||
| 424 | { 0x3170, 0x0000 }, | ||
| 425 | { 0x3171, 0xf000 }, | ||
| 426 | { 0x3172, 0x0000 }, | ||
| 427 | { 0x3173, 0xf000 }, | ||
| 428 | { 0x3174, 0x0000 }, | ||
| 429 | { 0x3175, 0xf000 }, | ||
| 430 | { 0x3176, 0x0000 }, | ||
| 431 | { 0x3177, 0xf000 }, | ||
| 432 | { 0x3178, 0x0000 }, | ||
| 433 | { 0x3179, 0xf000 }, | ||
| 434 | { 0x317a, 0x0000 }, | ||
| 435 | { 0x317b, 0xf000 }, | ||
| 436 | { 0x317c, 0x0000 }, | ||
| 437 | { 0x317d, 0xf000 }, | ||
| 438 | { 0x317e, 0x0000 }, | ||
| 439 | { 0x317f, 0xf000 }, | ||
| 440 | { 0x3180, 0x2001 }, | ||
| 441 | { 0x3181, 0xf101 }, | ||
| 442 | { 0x3182, 0x0000 }, | ||
| 443 | { 0x3183, 0xf000 }, | ||
| 444 | { 0x3184, 0x0000 }, | ||
| 445 | { 0x3185, 0xf000 }, | ||
| 446 | { 0x3186, 0x0000 }, | ||
| 447 | { 0x3187, 0xf000 }, | ||
| 448 | { 0x3188, 0x0000 }, | ||
| 449 | { 0x3189, 0xf000 }, | ||
| 450 | { 0x318a, 0x0000 }, | ||
| 451 | { 0x318b, 0xf000 }, | ||
| 452 | { 0x318c, 0x0000 }, | ||
| 453 | { 0x318d, 0xf000 }, | ||
| 454 | { 0x318e, 0x0000 }, | ||
| 455 | { 0x318f, 0xf000 }, | ||
| 456 | { 0x3190, 0x0000 }, | ||
| 457 | { 0x3191, 0xf000 }, | ||
| 458 | { 0x3192, 0x0000 }, | ||
| 459 | { 0x3193, 0xf000 }, | ||
| 460 | { 0x3194, 0x0000 }, | ||
| 461 | { 0x3195, 0xf000 }, | ||
| 462 | { 0x3196, 0x0000 }, | ||
| 463 | { 0x3197, 0xf000 }, | ||
| 464 | { 0x3198, 0x0000 }, | ||
| 465 | { 0x3199, 0xf000 }, | ||
| 466 | { 0x319a, 0x0000 }, | ||
| 467 | { 0x319b, 0xf000 }, | ||
| 468 | { 0x319c, 0x0000 }, | ||
| 469 | { 0x319d, 0xf000 }, | ||
| 470 | { 0x319e, 0x0000 }, | ||
| 471 | { 0x319f, 0xf000 }, | ||
| 472 | { 0x31a0, 0x0000 }, | ||
| 473 | { 0x31a1, 0xf000 }, | ||
| 474 | { 0x31a2, 0x0000 }, | ||
| 475 | { 0x31a3, 0xf000 }, | ||
| 476 | { 0x31a4, 0x0000 }, | ||
| 477 | { 0x31a5, 0xf000 }, | ||
| 478 | { 0x31a6, 0x0000 }, | ||
| 479 | { 0x31a7, 0xf000 }, | ||
| 480 | { 0x31a8, 0x0000 }, | ||
| 481 | { 0x31a9, 0xf000 }, | ||
| 482 | { 0x31aa, 0x0000 }, | ||
| 483 | { 0x31ab, 0xf000 }, | ||
| 484 | { 0x31ac, 0x0000 }, | ||
| 485 | { 0x31ad, 0xf000 }, | ||
| 486 | { 0x31ae, 0x0000 }, | ||
| 487 | { 0x31af, 0xf000 }, | ||
| 488 | { 0x31b0, 0x0000 }, | ||
| 489 | { 0x31b1, 0xf000 }, | ||
| 490 | { 0x31b2, 0x0000 }, | ||
| 491 | { 0x31b3, 0xf000 }, | ||
| 492 | { 0x31b4, 0x0000 }, | ||
| 493 | { 0x31b5, 0xf000 }, | ||
| 494 | { 0x31b6, 0x0000 }, | ||
| 495 | { 0x31b7, 0xf000 }, | ||
| 496 | { 0x31b8, 0x0000 }, | ||
| 497 | { 0x31b9, 0xf000 }, | ||
| 498 | { 0x31ba, 0x0000 }, | ||
| 499 | { 0x31bb, 0xf000 }, | ||
| 500 | { 0x31bc, 0x0000 }, | ||
| 501 | { 0x31bd, 0xf000 }, | ||
| 502 | { 0x31be, 0x0000 }, | ||
| 503 | { 0x31bf, 0xf000 }, | ||
| 504 | { 0x31c0, 0x0000 }, | ||
| 505 | { 0x31c1, 0xf000 }, | ||
| 506 | { 0x31c2, 0x0000 }, | ||
| 507 | { 0x31c3, 0xf000 }, | ||
| 508 | { 0x31c4, 0x0000 }, | ||
| 509 | { 0x31c5, 0xf000 }, | ||
| 510 | { 0x31c6, 0x0000 }, | ||
| 511 | { 0x31c7, 0xf000 }, | ||
| 512 | { 0x31c8, 0x0000 }, | ||
| 513 | { 0x31c9, 0xf000 }, | ||
| 514 | { 0x31ca, 0x0000 }, | ||
| 515 | { 0x31cb, 0xf000 }, | ||
| 516 | { 0x31cc, 0x0000 }, | ||
| 517 | { 0x31cd, 0xf000 }, | ||
| 518 | { 0x31ce, 0x0000 }, | ||
| 519 | { 0x31cf, 0xf000 }, | ||
| 520 | { 0x31d0, 0x0000 }, | ||
| 521 | { 0x31d1, 0xf000 }, | ||
| 522 | { 0x31d2, 0x0000 }, | ||
| 523 | { 0x31d3, 0xf000 }, | ||
| 524 | { 0x31d4, 0x0000 }, | ||
| 525 | { 0x31d5, 0xf000 }, | ||
| 526 | { 0x31d6, 0x0000 }, | ||
| 527 | { 0x31d7, 0xf000 }, | ||
| 528 | { 0x31d8, 0x0000 }, | ||
| 529 | { 0x31d9, 0xf000 }, | ||
| 530 | { 0x31da, 0x0000 }, | ||
| 531 | { 0x31db, 0xf000 }, | ||
| 532 | { 0x31dc, 0x0000 }, | ||
| 533 | { 0x31dd, 0xf000 }, | ||
| 534 | { 0x31de, 0x0000 }, | ||
| 535 | { 0x31df, 0xf000 }, | ||
| 536 | { 0x31e0, 0x0000 }, | ||
| 537 | { 0x31e1, 0xf000 }, | ||
| 538 | { 0x31e2, 0x0000 }, | ||
| 539 | { 0x31e3, 0xf000 }, | ||
| 540 | { 0x31e4, 0x0000 }, | ||
| 541 | { 0x31e5, 0xf000 }, | ||
| 542 | { 0x31e6, 0x0000 }, | ||
| 543 | { 0x31e7, 0xf000 }, | ||
| 544 | { 0x31e8, 0x0000 }, | ||
| 545 | { 0x31e9, 0xf000 }, | ||
| 546 | { 0x31ea, 0x0000 }, | ||
| 547 | { 0x31eb, 0xf000 }, | ||
| 548 | { 0x31ec, 0x0000 }, | ||
| 549 | { 0x31ed, 0xf000 }, | ||
| 550 | { 0x31ee, 0x0000 }, | ||
| 551 | { 0x31ef, 0xf000 }, | ||
| 552 | { 0x31f0, 0x0000 }, | ||
| 553 | { 0x31f1, 0xf000 }, | ||
| 554 | { 0x31f2, 0x0000 }, | ||
| 555 | { 0x31f3, 0xf000 }, | ||
| 556 | { 0x31f4, 0x0000 }, | ||
| 557 | { 0x31f5, 0xf000 }, | ||
| 558 | { 0x31f6, 0x0000 }, | ||
| 559 | { 0x31f7, 0xf000 }, | ||
| 560 | { 0x31f8, 0x0000 }, | ||
| 561 | { 0x31f9, 0xf000 }, | ||
| 562 | { 0x31fa, 0x0000 }, | ||
| 563 | { 0x31fb, 0xf000 }, | ||
| 564 | { 0x31fc, 0x0000 }, | ||
| 565 | { 0x31fd, 0xf000 }, | ||
| 566 | { 0x31fe, 0x0000 }, | ||
| 567 | { 0x31ff, 0xf000 }, | ||
| 568 | { 0x024d, 0xff50 }, | ||
| 569 | { 0x0252, 0xff50 }, | ||
| 570 | { 0x0259, 0x0112 }, | ||
| 571 | { 0x025e, 0x0112 }, | ||
| 572 | { 0x101, 0x0304 }, | ||
| 573 | { 0x80, 0x0000 }, | 56 | { 0x80, 0x0000 }, |
| 574 | }; | 57 | }; |
| 575 | 58 | ||
diff --git a/drivers/mmc/host/dw_mmc-exynos.c b/drivers/mmc/host/dw_mmc-exynos.c index 660bbc528862..4d50da618166 100644 --- a/drivers/mmc/host/dw_mmc-exynos.c +++ b/drivers/mmc/host/dw_mmc-exynos.c | |||
| @@ -208,7 +208,7 @@ static unsigned long exynos5250_dwmmc_caps[4] = { | |||
| 208 | MMC_CAP_CMD23, | 208 | MMC_CAP_CMD23, |
| 209 | }; | 209 | }; |
| 210 | 210 | ||
| 211 | static struct dw_mci_drv_data exynos5250_drv_data = { | 211 | static const struct dw_mci_drv_data exynos5250_drv_data = { |
| 212 | .caps = exynos5250_dwmmc_caps, | 212 | .caps = exynos5250_dwmmc_caps, |
| 213 | .init = dw_mci_exynos_priv_init, | 213 | .init = dw_mci_exynos_priv_init, |
| 214 | .setup_clock = dw_mci_exynos_setup_clock, | 214 | .setup_clock = dw_mci_exynos_setup_clock, |
| @@ -220,14 +220,14 @@ static struct dw_mci_drv_data exynos5250_drv_data = { | |||
| 220 | 220 | ||
| 221 | static const struct of_device_id dw_mci_exynos_match[] = { | 221 | static const struct of_device_id dw_mci_exynos_match[] = { |
| 222 | { .compatible = "samsung,exynos5250-dw-mshc", | 222 | { .compatible = "samsung,exynos5250-dw-mshc", |
| 223 | .data = (void *)&exynos5250_drv_data, }, | 223 | .data = &exynos5250_drv_data, }, |
| 224 | {}, | 224 | {}, |
| 225 | }; | 225 | }; |
| 226 | MODULE_DEVICE_TABLE(of, dw_mci_pltfm_match); | 226 | MODULE_DEVICE_TABLE(of, dw_mci_exynos_match); |
| 227 | 227 | ||
| 228 | int dw_mci_exynos_probe(struct platform_device *pdev) | 228 | int dw_mci_exynos_probe(struct platform_device *pdev) |
| 229 | { | 229 | { |
| 230 | struct dw_mci_drv_data *drv_data; | 230 | const struct dw_mci_drv_data *drv_data; |
| 231 | const struct of_device_id *match; | 231 | const struct of_device_id *match; |
| 232 | 232 | ||
| 233 | match = of_match_node(dw_mci_exynos_match, pdev->dev.of_node); | 233 | match = of_match_node(dw_mci_exynos_match, pdev->dev.of_node); |
diff --git a/drivers/mmc/host/dw_mmc-pltfm.c b/drivers/mmc/host/dw_mmc-pltfm.c index c960ca7ffbe6..917936bee5d5 100644 --- a/drivers/mmc/host/dw_mmc-pltfm.c +++ b/drivers/mmc/host/dw_mmc-pltfm.c | |||
| @@ -24,7 +24,7 @@ | |||
| 24 | #include "dw_mmc.h" | 24 | #include "dw_mmc.h" |
| 25 | 25 | ||
| 26 | int dw_mci_pltfm_register(struct platform_device *pdev, | 26 | int dw_mci_pltfm_register(struct platform_device *pdev, |
| 27 | struct dw_mci_drv_data *drv_data) | 27 | const struct dw_mci_drv_data *drv_data) |
| 28 | { | 28 | { |
| 29 | struct dw_mci *host; | 29 | struct dw_mci *host; |
| 30 | struct resource *regs; | 30 | struct resource *regs; |
| @@ -50,8 +50,8 @@ int dw_mci_pltfm_register(struct platform_device *pdev, | |||
| 50 | if (!host->regs) | 50 | if (!host->regs) |
| 51 | return -ENOMEM; | 51 | return -ENOMEM; |
| 52 | 52 | ||
| 53 | if (host->drv_data->init) { | 53 | if (drv_data && drv_data->init) { |
| 54 | ret = host->drv_data->init(host); | 54 | ret = drv_data->init(host); |
| 55 | if (ret) | 55 | if (ret) |
| 56 | return ret; | 56 | return ret; |
| 57 | } | 57 | } |
diff --git a/drivers/mmc/host/dw_mmc-pltfm.h b/drivers/mmc/host/dw_mmc-pltfm.h index 301f24541fc2..2ac37b81de4d 100644 --- a/drivers/mmc/host/dw_mmc-pltfm.h +++ b/drivers/mmc/host/dw_mmc-pltfm.h | |||
| @@ -13,7 +13,7 @@ | |||
| 13 | #define _DW_MMC_PLTFM_H_ | 13 | #define _DW_MMC_PLTFM_H_ |
| 14 | 14 | ||
| 15 | extern int dw_mci_pltfm_register(struct platform_device *pdev, | 15 | extern int dw_mci_pltfm_register(struct platform_device *pdev, |
| 16 | struct dw_mci_drv_data *drv_data); | 16 | const struct dw_mci_drv_data *drv_data); |
| 17 | extern int __devexit dw_mci_pltfm_remove(struct platform_device *pdev); | 17 | extern int __devexit dw_mci_pltfm_remove(struct platform_device *pdev); |
| 18 | extern const struct dev_pm_ops dw_mci_pltfm_pmops; | 18 | extern const struct dev_pm_ops dw_mci_pltfm_pmops; |
| 19 | 19 | ||
diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c index c2828f35c3b8..c0667c8af2bd 100644 --- a/drivers/mmc/host/dw_mmc.c +++ b/drivers/mmc/host/dw_mmc.c | |||
| @@ -232,6 +232,7 @@ static u32 dw_mci_prepare_command(struct mmc_host *mmc, struct mmc_command *cmd) | |||
| 232 | { | 232 | { |
| 233 | struct mmc_data *data; | 233 | struct mmc_data *data; |
| 234 | struct dw_mci_slot *slot = mmc_priv(mmc); | 234 | struct dw_mci_slot *slot = mmc_priv(mmc); |
| 235 | struct dw_mci_drv_data *drv_data = slot->host->drv_data; | ||
| 235 | u32 cmdr; | 236 | u32 cmdr; |
| 236 | cmd->error = -EINPROGRESS; | 237 | cmd->error = -EINPROGRESS; |
| 237 | 238 | ||
| @@ -261,8 +262,8 @@ static u32 dw_mci_prepare_command(struct mmc_host *mmc, struct mmc_command *cmd) | |||
| 261 | cmdr |= SDMMC_CMD_DAT_WR; | 262 | cmdr |= SDMMC_CMD_DAT_WR; |
| 262 | } | 263 | } |
| 263 | 264 | ||
| 264 | if (slot->host->drv_data->prepare_command) | 265 | if (drv_data && drv_data->prepare_command) |
| 265 | slot->host->drv_data->prepare_command(slot->host, &cmdr); | 266 | drv_data->prepare_command(slot->host, &cmdr); |
| 266 | 267 | ||
| 267 | return cmdr; | 268 | return cmdr; |
| 268 | } | 269 | } |
| @@ -434,7 +435,7 @@ static int dw_mci_idmac_init(struct dw_mci *host) | |||
| 434 | return 0; | 435 | return 0; |
| 435 | } | 436 | } |
| 436 | 437 | ||
| 437 | static struct dw_mci_dma_ops dw_mci_idmac_ops = { | 438 | static const struct dw_mci_dma_ops dw_mci_idmac_ops = { |
| 438 | .init = dw_mci_idmac_init, | 439 | .init = dw_mci_idmac_init, |
| 439 | .start = dw_mci_idmac_start_dma, | 440 | .start = dw_mci_idmac_start_dma, |
| 440 | .stop = dw_mci_idmac_stop_dma, | 441 | .stop = dw_mci_idmac_stop_dma, |
| @@ -772,6 +773,7 @@ static void dw_mci_request(struct mmc_host *mmc, struct mmc_request *mrq) | |||
| 772 | static void dw_mci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) | 773 | static void dw_mci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) |
| 773 | { | 774 | { |
| 774 | struct dw_mci_slot *slot = mmc_priv(mmc); | 775 | struct dw_mci_slot *slot = mmc_priv(mmc); |
| 776 | struct dw_mci_drv_data *drv_data = slot->host->drv_data; | ||
| 775 | u32 regs; | 777 | u32 regs; |
| 776 | 778 | ||
| 777 | /* set default 1 bit mode */ | 779 | /* set default 1 bit mode */ |
| @@ -807,8 +809,8 @@ static void dw_mci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) | |||
| 807 | slot->clock = ios->clock; | 809 | slot->clock = ios->clock; |
| 808 | } | 810 | } |
| 809 | 811 | ||
| 810 | if (slot->host->drv_data->set_ios) | 812 | if (drv_data && drv_data->set_ios) |
| 811 | slot->host->drv_data->set_ios(slot->host, ios); | 813 | drv_data->set_ios(slot->host, ios); |
| 812 | 814 | ||
| 813 | switch (ios->power_mode) { | 815 | switch (ios->power_mode) { |
| 814 | case MMC_POWER_UP: | 816 | case MMC_POWER_UP: |
| @@ -1815,6 +1817,7 @@ static int dw_mci_init_slot(struct dw_mci *host, unsigned int id) | |||
| 1815 | { | 1817 | { |
| 1816 | struct mmc_host *mmc; | 1818 | struct mmc_host *mmc; |
| 1817 | struct dw_mci_slot *slot; | 1819 | struct dw_mci_slot *slot; |
| 1820 | struct dw_mci_drv_data *drv_data = host->drv_data; | ||
| 1818 | int ctrl_id, ret; | 1821 | int ctrl_id, ret; |
| 1819 | u8 bus_width; | 1822 | u8 bus_width; |
| 1820 | 1823 | ||
| @@ -1854,8 +1857,8 @@ static int dw_mci_init_slot(struct dw_mci *host, unsigned int id) | |||
| 1854 | } else { | 1857 | } else { |
| 1855 | ctrl_id = to_platform_device(host->dev)->id; | 1858 | ctrl_id = to_platform_device(host->dev)->id; |
| 1856 | } | 1859 | } |
| 1857 | if (host->drv_data && host->drv_data->caps) | 1860 | if (drv_data && drv_data->caps) |
| 1858 | mmc->caps |= host->drv_data->caps[ctrl_id]; | 1861 | mmc->caps |= drv_data->caps[ctrl_id]; |
| 1859 | 1862 | ||
| 1860 | if (host->pdata->caps2) | 1863 | if (host->pdata->caps2) |
| 1861 | mmc->caps2 = host->pdata->caps2; | 1864 | mmc->caps2 = host->pdata->caps2; |
| @@ -1867,10 +1870,10 @@ static int dw_mci_init_slot(struct dw_mci *host, unsigned int id) | |||
| 1867 | else | 1870 | else |
| 1868 | bus_width = 1; | 1871 | bus_width = 1; |
| 1869 | 1872 | ||
| 1870 | if (host->drv_data->setup_bus) { | 1873 | if (drv_data && drv_data->setup_bus) { |
| 1871 | struct device_node *slot_np; | 1874 | struct device_node *slot_np; |
| 1872 | slot_np = dw_mci_of_find_slot_node(host->dev, slot->id); | 1875 | slot_np = dw_mci_of_find_slot_node(host->dev, slot->id); |
| 1873 | ret = host->drv_data->setup_bus(host, slot_np, bus_width); | 1876 | ret = drv_data->setup_bus(host, slot_np, bus_width); |
| 1874 | if (ret) | 1877 | if (ret) |
| 1875 | goto err_setup_bus; | 1878 | goto err_setup_bus; |
| 1876 | } | 1879 | } |
| @@ -1968,7 +1971,7 @@ static void dw_mci_init_dma(struct dw_mci *host) | |||
| 1968 | /* Determine which DMA interface to use */ | 1971 | /* Determine which DMA interface to use */ |
| 1969 | #ifdef CONFIG_MMC_DW_IDMAC | 1972 | #ifdef CONFIG_MMC_DW_IDMAC |
| 1970 | host->dma_ops = &dw_mci_idmac_ops; | 1973 | host->dma_ops = &dw_mci_idmac_ops; |
| 1971 | dev_info(&host->dev, "Using internal DMA controller.\n"); | 1974 | dev_info(host->dev, "Using internal DMA controller.\n"); |
| 1972 | #endif | 1975 | #endif |
| 1973 | 1976 | ||
| 1974 | if (!host->dma_ops) | 1977 | if (!host->dma_ops) |
| @@ -2035,6 +2038,7 @@ static struct dw_mci_board *dw_mci_parse_dt(struct dw_mci *host) | |||
| 2035 | struct dw_mci_board *pdata; | 2038 | struct dw_mci_board *pdata; |
| 2036 | struct device *dev = host->dev; | 2039 | struct device *dev = host->dev; |
| 2037 | struct device_node *np = dev->of_node; | 2040 | struct device_node *np = dev->of_node; |
| 2041 | struct dw_mci_drv_data *drv_data = host->drv_data; | ||
| 2038 | int idx, ret; | 2042 | int idx, ret; |
| 2039 | 2043 | ||
| 2040 | pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL); | 2044 | pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL); |
| @@ -2062,8 +2066,8 @@ static struct dw_mci_board *dw_mci_parse_dt(struct dw_mci *host) | |||
| 2062 | 2066 | ||
| 2063 | of_property_read_u32(np, "card-detect-delay", &pdata->detect_delay_ms); | 2067 | of_property_read_u32(np, "card-detect-delay", &pdata->detect_delay_ms); |
| 2064 | 2068 | ||
| 2065 | if (host->drv_data->parse_dt) { | 2069 | if (drv_data && drv_data->parse_dt) { |
| 2066 | ret = host->drv_data->parse_dt(host); | 2070 | ret = drv_data->parse_dt(host); |
| 2067 | if (ret) | 2071 | if (ret) |
| 2068 | return ERR_PTR(ret); | 2072 | return ERR_PTR(ret); |
| 2069 | } | 2073 | } |
| @@ -2080,6 +2084,7 @@ static struct dw_mci_board *dw_mci_parse_dt(struct dw_mci *host) | |||
| 2080 | 2084 | ||
| 2081 | int dw_mci_probe(struct dw_mci *host) | 2085 | int dw_mci_probe(struct dw_mci *host) |
| 2082 | { | 2086 | { |
| 2087 | struct dw_mci_drv_data *drv_data = host->drv_data; | ||
| 2083 | int width, i, ret = 0; | 2088 | int width, i, ret = 0; |
| 2084 | u32 fifo_size; | 2089 | u32 fifo_size; |
| 2085 | int init_slots = 0; | 2090 | int init_slots = 0; |
| @@ -2127,8 +2132,8 @@ int dw_mci_probe(struct dw_mci *host) | |||
| 2127 | else | 2132 | else |
| 2128 | host->bus_hz = clk_get_rate(host->ciu_clk); | 2133 | host->bus_hz = clk_get_rate(host->ciu_clk); |
| 2129 | 2134 | ||
| 2130 | if (host->drv_data->setup_clock) { | 2135 | if (drv_data && drv_data->setup_clock) { |
| 2131 | ret = host->drv_data->setup_clock(host); | 2136 | ret = drv_data->setup_clock(host); |
| 2132 | if (ret) { | 2137 | if (ret) { |
| 2133 | dev_err(host->dev, | 2138 | dev_err(host->dev, |
| 2134 | "implementation specific clock setup failed\n"); | 2139 | "implementation specific clock setup failed\n"); |
| @@ -2228,6 +2233,21 @@ int dw_mci_probe(struct dw_mci *host) | |||
| 2228 | else | 2233 | else |
| 2229 | host->num_slots = ((mci_readl(host, HCON) >> 1) & 0x1F) + 1; | 2234 | host->num_slots = ((mci_readl(host, HCON) >> 1) & 0x1F) + 1; |
| 2230 | 2235 | ||
| 2236 | /* | ||
| 2237 | * Enable interrupts for command done, data over, data empty, card det, | ||
| 2238 | * receive ready and error such as transmit, receive timeout, crc error | ||
| 2239 | */ | ||
| 2240 | mci_writel(host, RINTSTS, 0xFFFFFFFF); | ||
| 2241 | mci_writel(host, INTMASK, SDMMC_INT_CMD_DONE | SDMMC_INT_DATA_OVER | | ||
| 2242 | SDMMC_INT_TXDR | SDMMC_INT_RXDR | | ||
| 2243 | DW_MCI_ERROR_FLAGS | SDMMC_INT_CD); | ||
| 2244 | mci_writel(host, CTRL, SDMMC_CTRL_INT_ENABLE); /* Enable mci interrupt */ | ||
| 2245 | |||
| 2246 | dev_info(host->dev, "DW MMC controller at irq %d, " | ||
| 2247 | "%d bit host data width, " | ||
| 2248 | "%u deep fifo\n", | ||
| 2249 | host->irq, width, fifo_size); | ||
| 2250 | |||
| 2231 | /* We need at least one slot to succeed */ | 2251 | /* We need at least one slot to succeed */ |
| 2232 | for (i = 0; i < host->num_slots; i++) { | 2252 | for (i = 0; i < host->num_slots; i++) { |
| 2233 | ret = dw_mci_init_slot(host, i); | 2253 | ret = dw_mci_init_slot(host, i); |
| @@ -2257,20 +2277,6 @@ int dw_mci_probe(struct dw_mci *host) | |||
| 2257 | else | 2277 | else |
| 2258 | host->data_offset = DATA_240A_OFFSET; | 2278 | host->data_offset = DATA_240A_OFFSET; |
| 2259 | 2279 | ||
| 2260 | /* | ||
| 2261 | * Enable interrupts for command done, data over, data empty, card det, | ||
| 2262 | * receive ready and error such as transmit, receive timeout, crc error | ||
| 2263 | */ | ||
| 2264 | mci_writel(host, RINTSTS, 0xFFFFFFFF); | ||
| 2265 | mci_writel(host, INTMASK, SDMMC_INT_CMD_DONE | SDMMC_INT_DATA_OVER | | ||
| 2266 | SDMMC_INT_TXDR | SDMMC_INT_RXDR | | ||
| 2267 | DW_MCI_ERROR_FLAGS | SDMMC_INT_CD); | ||
| 2268 | mci_writel(host, CTRL, SDMMC_CTRL_INT_ENABLE); /* Enable mci interrupt */ | ||
| 2269 | |||
| 2270 | dev_info(host->dev, "DW MMC controller at irq %d, " | ||
| 2271 | "%d bit host data width, " | ||
| 2272 | "%u deep fifo\n", | ||
| 2273 | host->irq, width, fifo_size); | ||
| 2274 | if (host->quirks & DW_MCI_QUIRK_IDMAC_DTO) | 2280 | if (host->quirks & DW_MCI_QUIRK_IDMAC_DTO) |
| 2275 | dev_info(host->dev, "Internal DMAC interrupt fix enabled.\n"); | 2281 | dev_info(host->dev, "Internal DMAC interrupt fix enabled.\n"); |
| 2276 | 2282 | ||
diff --git a/drivers/mmc/host/mxcmmc.c b/drivers/mmc/host/mxcmmc.c index 565c2e4fac75..6290b7f1ccfe 100644 --- a/drivers/mmc/host/mxcmmc.c +++ b/drivers/mmc/host/mxcmmc.c | |||
| @@ -1134,4 +1134,4 @@ module_platform_driver(mxcmci_driver); | |||
| 1134 | MODULE_DESCRIPTION("i.MX Multimedia Card Interface Driver"); | 1134 | MODULE_DESCRIPTION("i.MX Multimedia Card Interface Driver"); |
| 1135 | MODULE_AUTHOR("Sascha Hauer, Pengutronix"); | 1135 | MODULE_AUTHOR("Sascha Hauer, Pengutronix"); |
| 1136 | MODULE_LICENSE("GPL"); | 1136 | MODULE_LICENSE("GPL"); |
| 1137 | MODULE_ALIAS("platform:imx-mmc"); | 1137 | MODULE_ALIAS("platform:mxc-mmc"); |
diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c index 54bfd0cc106b..fedd258cc4ea 100644 --- a/drivers/mmc/host/omap_hsmmc.c +++ b/drivers/mmc/host/omap_hsmmc.c | |||
| @@ -178,7 +178,8 @@ struct omap_hsmmc_host { | |||
| 178 | 178 | ||
| 179 | static int omap_hsmmc_card_detect(struct device *dev, int slot) | 179 | static int omap_hsmmc_card_detect(struct device *dev, int slot) |
| 180 | { | 180 | { |
| 181 | struct omap_mmc_platform_data *mmc = dev->platform_data; | 181 | struct omap_hsmmc_host *host = dev_get_drvdata(dev); |
| 182 | struct omap_mmc_platform_data *mmc = host->pdata; | ||
| 182 | 183 | ||
| 183 | /* NOTE: assumes card detect signal is active-low */ | 184 | /* NOTE: assumes card detect signal is active-low */ |
| 184 | return !gpio_get_value_cansleep(mmc->slots[0].switch_pin); | 185 | return !gpio_get_value_cansleep(mmc->slots[0].switch_pin); |
| @@ -186,7 +187,8 @@ static int omap_hsmmc_card_detect(struct device *dev, int slot) | |||
| 186 | 187 | ||
| 187 | static int omap_hsmmc_get_wp(struct device *dev, int slot) | 188 | static int omap_hsmmc_get_wp(struct device *dev, int slot) |
| 188 | { | 189 | { |
| 189 | struct omap_mmc_platform_data *mmc = dev->platform_data; | 190 | struct omap_hsmmc_host *host = dev_get_drvdata(dev); |
| 191 | struct omap_mmc_platform_data *mmc = host->pdata; | ||
| 190 | 192 | ||
| 191 | /* NOTE: assumes write protect signal is active-high */ | 193 | /* NOTE: assumes write protect signal is active-high */ |
| 192 | return gpio_get_value_cansleep(mmc->slots[0].gpio_wp); | 194 | return gpio_get_value_cansleep(mmc->slots[0].gpio_wp); |
| @@ -194,7 +196,8 @@ static int omap_hsmmc_get_wp(struct device *dev, int slot) | |||
| 194 | 196 | ||
| 195 | static int omap_hsmmc_get_cover_state(struct device *dev, int slot) | 197 | static int omap_hsmmc_get_cover_state(struct device *dev, int slot) |
| 196 | { | 198 | { |
| 197 | struct omap_mmc_platform_data *mmc = dev->platform_data; | 199 | struct omap_hsmmc_host *host = dev_get_drvdata(dev); |
| 200 | struct omap_mmc_platform_data *mmc = host->pdata; | ||
| 198 | 201 | ||
| 199 | /* NOTE: assumes card detect signal is active-low */ | 202 | /* NOTE: assumes card detect signal is active-low */ |
| 200 | return !gpio_get_value_cansleep(mmc->slots[0].switch_pin); | 203 | return !gpio_get_value_cansleep(mmc->slots[0].switch_pin); |
| @@ -204,7 +207,8 @@ static int omap_hsmmc_get_cover_state(struct device *dev, int slot) | |||
| 204 | 207 | ||
| 205 | static int omap_hsmmc_suspend_cdirq(struct device *dev, int slot) | 208 | static int omap_hsmmc_suspend_cdirq(struct device *dev, int slot) |
| 206 | { | 209 | { |
| 207 | struct omap_mmc_platform_data *mmc = dev->platform_data; | 210 | struct omap_hsmmc_host *host = dev_get_drvdata(dev); |
| 211 | struct omap_mmc_platform_data *mmc = host->pdata; | ||
| 208 | 212 | ||
| 209 | disable_irq(mmc->slots[0].card_detect_irq); | 213 | disable_irq(mmc->slots[0].card_detect_irq); |
| 210 | return 0; | 214 | return 0; |
| @@ -212,7 +216,8 @@ static int omap_hsmmc_suspend_cdirq(struct device *dev, int slot) | |||
| 212 | 216 | ||
| 213 | static int omap_hsmmc_resume_cdirq(struct device *dev, int slot) | 217 | static int omap_hsmmc_resume_cdirq(struct device *dev, int slot) |
| 214 | { | 218 | { |
| 215 | struct omap_mmc_platform_data *mmc = dev->platform_data; | 219 | struct omap_hsmmc_host *host = dev_get_drvdata(dev); |
| 220 | struct omap_mmc_platform_data *mmc = host->pdata; | ||
| 216 | 221 | ||
| 217 | enable_irq(mmc->slots[0].card_detect_irq); | 222 | enable_irq(mmc->slots[0].card_detect_irq); |
| 218 | return 0; | 223 | return 0; |
| @@ -2009,9 +2014,9 @@ static int __devexit omap_hsmmc_remove(struct platform_device *pdev) | |||
| 2009 | clk_put(host->dbclk); | 2014 | clk_put(host->dbclk); |
| 2010 | } | 2015 | } |
| 2011 | 2016 | ||
| 2012 | mmc_free_host(host->mmc); | 2017 | omap_hsmmc_gpio_free(host->pdata); |
| 2013 | iounmap(host->base); | 2018 | iounmap(host->base); |
| 2014 | omap_hsmmc_gpio_free(pdev->dev.platform_data); | 2019 | mmc_free_host(host->mmc); |
| 2015 | 2020 | ||
| 2016 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 2021 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
| 2017 | if (res) | 2022 | if (res) |
diff --git a/drivers/mmc/host/sdhci-dove.c b/drivers/mmc/host/sdhci-dove.c index 90140eb03e36..8fd50a211037 100644 --- a/drivers/mmc/host/sdhci-dove.c +++ b/drivers/mmc/host/sdhci-dove.c | |||
| @@ -19,6 +19,7 @@ | |||
| 19 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | 19 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
| 20 | */ | 20 | */ |
| 21 | 21 | ||
| 22 | #include <linux/err.h> | ||
| 22 | #include <linux/io.h> | 23 | #include <linux/io.h> |
| 23 | #include <linux/clk.h> | 24 | #include <linux/clk.h> |
| 24 | #include <linux/err.h> | 25 | #include <linux/err.h> |
| @@ -84,30 +85,32 @@ static int __devinit sdhci_dove_probe(struct platform_device *pdev) | |||
| 84 | struct sdhci_dove_priv *priv; | 85 | struct sdhci_dove_priv *priv; |
| 85 | int ret; | 86 | int ret; |
| 86 | 87 | ||
| 87 | ret = sdhci_pltfm_register(pdev, &sdhci_dove_pdata); | ||
| 88 | if (ret) | ||
| 89 | goto sdhci_dove_register_fail; | ||
| 90 | |||
| 91 | priv = devm_kzalloc(&pdev->dev, sizeof(struct sdhci_dove_priv), | 88 | priv = devm_kzalloc(&pdev->dev, sizeof(struct sdhci_dove_priv), |
| 92 | GFP_KERNEL); | 89 | GFP_KERNEL); |
| 93 | if (!priv) { | 90 | if (!priv) { |
| 94 | dev_err(&pdev->dev, "unable to allocate private data"); | 91 | dev_err(&pdev->dev, "unable to allocate private data"); |
| 95 | ret = -ENOMEM; | 92 | return -ENOMEM; |
| 96 | goto sdhci_dove_allocate_fail; | ||
| 97 | } | 93 | } |
| 98 | 94 | ||
| 95 | priv->clk = clk_get(&pdev->dev, NULL); | ||
| 96 | if (!IS_ERR(priv->clk)) | ||
| 97 | clk_prepare_enable(priv->clk); | ||
| 98 | |||
| 99 | ret = sdhci_pltfm_register(pdev, &sdhci_dove_pdata); | ||
| 100 | if (ret) | ||
| 101 | goto sdhci_dove_register_fail; | ||
| 102 | |||
| 99 | host = platform_get_drvdata(pdev); | 103 | host = platform_get_drvdata(pdev); |
| 100 | pltfm_host = sdhci_priv(host); | 104 | pltfm_host = sdhci_priv(host); |
| 101 | pltfm_host->priv = priv; | 105 | pltfm_host->priv = priv; |
| 102 | 106 | ||
| 103 | priv->clk = clk_get(&pdev->dev, NULL); | ||
| 104 | if (!IS_ERR(priv->clk)) | ||
| 105 | clk_prepare_enable(priv->clk); | ||
| 106 | return 0; | 107 | return 0; |
| 107 | 108 | ||
| 108 | sdhci_dove_allocate_fail: | ||
| 109 | sdhci_pltfm_unregister(pdev); | ||
| 110 | sdhci_dove_register_fail: | 109 | sdhci_dove_register_fail: |
| 110 | if (!IS_ERR(priv->clk)) { | ||
| 111 | clk_disable_unprepare(priv->clk); | ||
| 112 | clk_put(priv->clk); | ||
| 113 | } | ||
| 111 | return ret; | 114 | return ret; |
| 112 | } | 115 | } |
| 113 | 116 | ||
| @@ -117,14 +120,13 @@ static int __devexit sdhci_dove_remove(struct platform_device *pdev) | |||
| 117 | struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); | 120 | struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); |
| 118 | struct sdhci_dove_priv *priv = pltfm_host->priv; | 121 | struct sdhci_dove_priv *priv = pltfm_host->priv; |
| 119 | 122 | ||
| 120 | if (priv->clk) { | 123 | sdhci_pltfm_unregister(pdev); |
| 121 | if (!IS_ERR(priv->clk)) { | 124 | |
| 122 | clk_disable_unprepare(priv->clk); | 125 | if (!IS_ERR(priv->clk)) { |
| 123 | clk_put(priv->clk); | 126 | clk_disable_unprepare(priv->clk); |
| 124 | } | 127 | clk_put(priv->clk); |
| 125 | devm_kfree(&pdev->dev, priv->clk); | ||
| 126 | } | 128 | } |
| 127 | return sdhci_pltfm_unregister(pdev); | 129 | return 0; |
| 128 | } | 130 | } |
| 129 | 131 | ||
| 130 | static const struct of_device_id sdhci_dove_of_match_table[] __devinitdata = { | 132 | static const struct of_device_id sdhci_dove_of_match_table[] __devinitdata = { |
diff --git a/drivers/mmc/host/sdhci-of-esdhc.c b/drivers/mmc/host/sdhci-of-esdhc.c index ae5fcbfa1eef..63d219f57cae 100644 --- a/drivers/mmc/host/sdhci-of-esdhc.c +++ b/drivers/mmc/host/sdhci-of-esdhc.c | |||
| @@ -169,6 +169,16 @@ static void esdhc_of_resume(struct sdhci_host *host) | |||
| 169 | } | 169 | } |
| 170 | #endif | 170 | #endif |
| 171 | 171 | ||
| 172 | static void esdhc_of_platform_init(struct sdhci_host *host) | ||
| 173 | { | ||
| 174 | u32 vvn; | ||
| 175 | |||
| 176 | vvn = in_be32(host->ioaddr + SDHCI_SLOT_INT_STATUS); | ||
| 177 | vvn = (vvn & SDHCI_VENDOR_VER_MASK) >> SDHCI_VENDOR_VER_SHIFT; | ||
| 178 | if (vvn == VENDOR_V_22) | ||
| 179 | host->quirks2 |= SDHCI_QUIRK2_HOST_NO_CMD23; | ||
| 180 | } | ||
| 181 | |||
| 172 | static struct sdhci_ops sdhci_esdhc_ops = { | 182 | static struct sdhci_ops sdhci_esdhc_ops = { |
| 173 | .read_l = esdhc_readl, | 183 | .read_l = esdhc_readl, |
| 174 | .read_w = esdhc_readw, | 184 | .read_w = esdhc_readw, |
| @@ -180,6 +190,7 @@ static struct sdhci_ops sdhci_esdhc_ops = { | |||
| 180 | .enable_dma = esdhc_of_enable_dma, | 190 | .enable_dma = esdhc_of_enable_dma, |
| 181 | .get_max_clock = esdhc_of_get_max_clock, | 191 | .get_max_clock = esdhc_of_get_max_clock, |
| 182 | .get_min_clock = esdhc_of_get_min_clock, | 192 | .get_min_clock = esdhc_of_get_min_clock, |
| 193 | .platform_init = esdhc_of_platform_init, | ||
| 183 | #ifdef CONFIG_PM | 194 | #ifdef CONFIG_PM |
| 184 | .platform_suspend = esdhc_of_suspend, | 195 | .platform_suspend = esdhc_of_suspend, |
| 185 | .platform_resume = esdhc_of_resume, | 196 | .platform_resume = esdhc_of_resume, |
diff --git a/drivers/mmc/host/sdhci-pci.c b/drivers/mmc/host/sdhci-pci.c index 4bb74b042a06..04936f353ced 100644 --- a/drivers/mmc/host/sdhci-pci.c +++ b/drivers/mmc/host/sdhci-pci.c | |||
| @@ -1196,7 +1196,7 @@ static struct sdhci_pci_slot * __devinit sdhci_pci_probe_slot( | |||
| 1196 | return ERR_PTR(-ENODEV); | 1196 | return ERR_PTR(-ENODEV); |
| 1197 | } | 1197 | } |
| 1198 | 1198 | ||
| 1199 | if (pci_resource_len(pdev, bar) != 0x100) { | 1199 | if (pci_resource_len(pdev, bar) < 0x100) { |
| 1200 | dev_err(&pdev->dev, "Invalid iomem size. You may " | 1200 | dev_err(&pdev->dev, "Invalid iomem size. You may " |
| 1201 | "experience problems.\n"); | 1201 | "experience problems.\n"); |
| 1202 | } | 1202 | } |
diff --git a/drivers/mmc/host/sdhci-pltfm.c b/drivers/mmc/host/sdhci-pltfm.c index 65551a9709cc..27164457f861 100644 --- a/drivers/mmc/host/sdhci-pltfm.c +++ b/drivers/mmc/host/sdhci-pltfm.c | |||
| @@ -150,6 +150,13 @@ struct sdhci_host *sdhci_pltfm_init(struct platform_device *pdev, | |||
| 150 | goto err_remap; | 150 | goto err_remap; |
| 151 | } | 151 | } |
| 152 | 152 | ||
| 153 | /* | ||
| 154 | * Some platforms need to probe the controller to be able to | ||
| 155 | * determine which caps should be used. | ||
| 156 | */ | ||
| 157 | if (host->ops && host->ops->platform_init) | ||
| 158 | host->ops->platform_init(host); | ||
| 159 | |||
| 153 | platform_set_drvdata(pdev, host); | 160 | platform_set_drvdata(pdev, host); |
| 154 | 161 | ||
| 155 | return host; | 162 | return host; |
diff --git a/drivers/mmc/host/sdhci-s3c.c b/drivers/mmc/host/sdhci-s3c.c index 2903949594c6..c9ec725884e5 100644 --- a/drivers/mmc/host/sdhci-s3c.c +++ b/drivers/mmc/host/sdhci-s3c.c | |||
| @@ -211,8 +211,8 @@ static void sdhci_s3c_set_clock(struct sdhci_host *host, unsigned int clock) | |||
| 211 | if (ourhost->cur_clk != best_src) { | 211 | if (ourhost->cur_clk != best_src) { |
| 212 | struct clk *clk = ourhost->clk_bus[best_src]; | 212 | struct clk *clk = ourhost->clk_bus[best_src]; |
| 213 | 213 | ||
| 214 | clk_enable(clk); | 214 | clk_prepare_enable(clk); |
| 215 | clk_disable(ourhost->clk_bus[ourhost->cur_clk]); | 215 | clk_disable_unprepare(ourhost->clk_bus[ourhost->cur_clk]); |
| 216 | 216 | ||
| 217 | /* turn clock off to card before changing clock source */ | 217 | /* turn clock off to card before changing clock source */ |
| 218 | writew(0, host->ioaddr + SDHCI_CLOCK_CONTROL); | 218 | writew(0, host->ioaddr + SDHCI_CLOCK_CONTROL); |
| @@ -373,18 +373,25 @@ static struct sdhci_ops sdhci_s3c_ops = { | |||
| 373 | static void sdhci_s3c_notify_change(struct platform_device *dev, int state) | 373 | static void sdhci_s3c_notify_change(struct platform_device *dev, int state) |
| 374 | { | 374 | { |
| 375 | struct sdhci_host *host = platform_get_drvdata(dev); | 375 | struct sdhci_host *host = platform_get_drvdata(dev); |
| 376 | struct sdhci_s3c *sc = sdhci_priv(host); | ||
| 376 | unsigned long flags; | 377 | unsigned long flags; |
| 377 | 378 | ||
| 378 | if (host) { | 379 | if (host) { |
| 379 | spin_lock_irqsave(&host->lock, flags); | 380 | spin_lock_irqsave(&host->lock, flags); |
| 380 | if (state) { | 381 | if (state) { |
| 381 | dev_dbg(&dev->dev, "card inserted.\n"); | 382 | dev_dbg(&dev->dev, "card inserted.\n"); |
| 383 | #ifdef CONFIG_PM_RUNTIME | ||
| 384 | clk_prepare_enable(sc->clk_io); | ||
| 385 | #endif | ||
| 382 | host->flags &= ~SDHCI_DEVICE_DEAD; | 386 | host->flags &= ~SDHCI_DEVICE_DEAD; |
| 383 | host->quirks |= SDHCI_QUIRK_BROKEN_CARD_DETECTION; | 387 | host->quirks |= SDHCI_QUIRK_BROKEN_CARD_DETECTION; |
| 384 | } else { | 388 | } else { |
| 385 | dev_dbg(&dev->dev, "card removed.\n"); | 389 | dev_dbg(&dev->dev, "card removed.\n"); |
| 386 | host->flags |= SDHCI_DEVICE_DEAD; | 390 | host->flags |= SDHCI_DEVICE_DEAD; |
| 387 | host->quirks &= ~SDHCI_QUIRK_BROKEN_CARD_DETECTION; | 391 | host->quirks &= ~SDHCI_QUIRK_BROKEN_CARD_DETECTION; |
| 392 | #ifdef CONFIG_PM_RUNTIME | ||
| 393 | clk_disable_unprepare(sc->clk_io); | ||
| 394 | #endif | ||
| 388 | } | 395 | } |
| 389 | tasklet_schedule(&host->card_tasklet); | 396 | tasklet_schedule(&host->card_tasklet); |
| 390 | spin_unlock_irqrestore(&host->lock, flags); | 397 | spin_unlock_irqrestore(&host->lock, flags); |
| @@ -607,7 +614,7 @@ static int __devinit sdhci_s3c_probe(struct platform_device *pdev) | |||
| 607 | } | 614 | } |
| 608 | 615 | ||
| 609 | /* enable the local io clock and keep it running for the moment. */ | 616 | /* enable the local io clock and keep it running for the moment. */ |
| 610 | clk_enable(sc->clk_io); | 617 | clk_prepare_enable(sc->clk_io); |
| 611 | 618 | ||
| 612 | for (clks = 0, ptr = 0; ptr < MAX_BUS_CLK; ptr++) { | 619 | for (clks = 0, ptr = 0; ptr < MAX_BUS_CLK; ptr++) { |
| 613 | struct clk *clk; | 620 | struct clk *clk; |
| @@ -638,7 +645,7 @@ static int __devinit sdhci_s3c_probe(struct platform_device *pdev) | |||
| 638 | } | 645 | } |
| 639 | 646 | ||
| 640 | #ifndef CONFIG_PM_RUNTIME | 647 | #ifndef CONFIG_PM_RUNTIME |
| 641 | clk_enable(sc->clk_bus[sc->cur_clk]); | 648 | clk_prepare_enable(sc->clk_bus[sc->cur_clk]); |
| 642 | #endif | 649 | #endif |
| 643 | 650 | ||
| 644 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 651 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
| @@ -747,13 +754,14 @@ static int __devinit sdhci_s3c_probe(struct platform_device *pdev) | |||
| 747 | sdhci_s3c_setup_card_detect_gpio(sc); | 754 | sdhci_s3c_setup_card_detect_gpio(sc); |
| 748 | 755 | ||
| 749 | #ifdef CONFIG_PM_RUNTIME | 756 | #ifdef CONFIG_PM_RUNTIME |
| 750 | clk_disable(sc->clk_io); | 757 | if (pdata->cd_type != S3C_SDHCI_CD_INTERNAL) |
| 758 | clk_disable_unprepare(sc->clk_io); | ||
| 751 | #endif | 759 | #endif |
| 752 | return 0; | 760 | return 0; |
| 753 | 761 | ||
| 754 | err_req_regs: | 762 | err_req_regs: |
| 755 | #ifndef CONFIG_PM_RUNTIME | 763 | #ifndef CONFIG_PM_RUNTIME |
| 756 | clk_disable(sc->clk_bus[sc->cur_clk]); | 764 | clk_disable_unprepare(sc->clk_bus[sc->cur_clk]); |
| 757 | #endif | 765 | #endif |
| 758 | for (ptr = 0; ptr < MAX_BUS_CLK; ptr++) { | 766 | for (ptr = 0; ptr < MAX_BUS_CLK; ptr++) { |
| 759 | if (sc->clk_bus[ptr]) { | 767 | if (sc->clk_bus[ptr]) { |
| @@ -762,7 +770,7 @@ static int __devinit sdhci_s3c_probe(struct platform_device *pdev) | |||
| 762 | } | 770 | } |
| 763 | 771 | ||
| 764 | err_no_busclks: | 772 | err_no_busclks: |
| 765 | clk_disable(sc->clk_io); | 773 | clk_disable_unprepare(sc->clk_io); |
| 766 | clk_put(sc->clk_io); | 774 | clk_put(sc->clk_io); |
| 767 | 775 | ||
| 768 | err_io_clk: | 776 | err_io_clk: |
| @@ -794,7 +802,8 @@ static int __devexit sdhci_s3c_remove(struct platform_device *pdev) | |||
| 794 | gpio_free(sc->ext_cd_gpio); | 802 | gpio_free(sc->ext_cd_gpio); |
| 795 | 803 | ||
| 796 | #ifdef CONFIG_PM_RUNTIME | 804 | #ifdef CONFIG_PM_RUNTIME |
| 797 | clk_enable(sc->clk_io); | 805 | if (pdata->cd_type != S3C_SDHCI_CD_INTERNAL) |
| 806 | clk_prepare_enable(sc->clk_io); | ||
| 798 | #endif | 807 | #endif |
| 799 | sdhci_remove_host(host, 1); | 808 | sdhci_remove_host(host, 1); |
| 800 | 809 | ||
| @@ -802,14 +811,14 @@ static int __devexit sdhci_s3c_remove(struct platform_device *pdev) | |||
| 802 | pm_runtime_disable(&pdev->dev); | 811 | pm_runtime_disable(&pdev->dev); |
| 803 | 812 | ||
| 804 | #ifndef CONFIG_PM_RUNTIME | 813 | #ifndef CONFIG_PM_RUNTIME |
| 805 | clk_disable(sc->clk_bus[sc->cur_clk]); | 814 | clk_disable_unprepare(sc->clk_bus[sc->cur_clk]); |
| 806 | #endif | 815 | #endif |
| 807 | for (ptr = 0; ptr < MAX_BUS_CLK; ptr++) { | 816 | for (ptr = 0; ptr < MAX_BUS_CLK; ptr++) { |
| 808 | if (sc->clk_bus[ptr]) { | 817 | if (sc->clk_bus[ptr]) { |
| 809 | clk_put(sc->clk_bus[ptr]); | 818 | clk_put(sc->clk_bus[ptr]); |
| 810 | } | 819 | } |
| 811 | } | 820 | } |
| 812 | clk_disable(sc->clk_io); | 821 | clk_disable_unprepare(sc->clk_io); |
| 813 | clk_put(sc->clk_io); | 822 | clk_put(sc->clk_io); |
| 814 | 823 | ||
| 815 | if (pdev->dev.of_node) { | 824 | if (pdev->dev.of_node) { |
| @@ -849,8 +858,8 @@ static int sdhci_s3c_runtime_suspend(struct device *dev) | |||
| 849 | 858 | ||
| 850 | ret = sdhci_runtime_suspend_host(host); | 859 | ret = sdhci_runtime_suspend_host(host); |
| 851 | 860 | ||
| 852 | clk_disable(ourhost->clk_bus[ourhost->cur_clk]); | 861 | clk_disable_unprepare(ourhost->clk_bus[ourhost->cur_clk]); |
| 853 | clk_disable(busclk); | 862 | clk_disable_unprepare(busclk); |
| 854 | return ret; | 863 | return ret; |
| 855 | } | 864 | } |
| 856 | 865 | ||
| @@ -861,8 +870,8 @@ static int sdhci_s3c_runtime_resume(struct device *dev) | |||
| 861 | struct clk *busclk = ourhost->clk_io; | 870 | struct clk *busclk = ourhost->clk_io; |
| 862 | int ret; | 871 | int ret; |
| 863 | 872 | ||
| 864 | clk_enable(busclk); | 873 | clk_prepare_enable(busclk); |
| 865 | clk_enable(ourhost->clk_bus[ourhost->cur_clk]); | 874 | clk_prepare_enable(ourhost->clk_bus[ourhost->cur_clk]); |
| 866 | ret = sdhci_runtime_resume_host(host); | 875 | ret = sdhci_runtime_resume_host(host); |
| 867 | return ret; | 876 | return ret; |
| 868 | } | 877 | } |
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c index 7922adb42386..c7851c0aabce 100644 --- a/drivers/mmc/host/sdhci.c +++ b/drivers/mmc/host/sdhci.c | |||
| @@ -1315,16 +1315,19 @@ static void sdhci_request(struct mmc_host *mmc, struct mmc_request *mrq) | |||
| 1315 | */ | 1315 | */ |
| 1316 | if ((host->flags & SDHCI_NEEDS_RETUNING) && | 1316 | if ((host->flags & SDHCI_NEEDS_RETUNING) && |
| 1317 | !(present_state & (SDHCI_DOING_WRITE | SDHCI_DOING_READ))) { | 1317 | !(present_state & (SDHCI_DOING_WRITE | SDHCI_DOING_READ))) { |
| 1318 | /* eMMC uses cmd21 while sd and sdio use cmd19 */ | 1318 | if (mmc->card) { |
| 1319 | tuning_opcode = mmc->card->type == MMC_TYPE_MMC ? | 1319 | /* eMMC uses cmd21 but sd and sdio use cmd19 */ |
| 1320 | MMC_SEND_TUNING_BLOCK_HS200 : | 1320 | tuning_opcode = |
| 1321 | MMC_SEND_TUNING_BLOCK; | 1321 | mmc->card->type == MMC_TYPE_MMC ? |
| 1322 | spin_unlock_irqrestore(&host->lock, flags); | 1322 | MMC_SEND_TUNING_BLOCK_HS200 : |
| 1323 | sdhci_execute_tuning(mmc, tuning_opcode); | 1323 | MMC_SEND_TUNING_BLOCK; |
| 1324 | spin_lock_irqsave(&host->lock, flags); | 1324 | spin_unlock_irqrestore(&host->lock, flags); |
| 1325 | 1325 | sdhci_execute_tuning(mmc, tuning_opcode); | |
| 1326 | /* Restore original mmc_request structure */ | 1326 | spin_lock_irqsave(&host->lock, flags); |
| 1327 | host->mrq = mrq; | 1327 | |
| 1328 | /* Restore original mmc_request structure */ | ||
| 1329 | host->mrq = mrq; | ||
| 1330 | } | ||
| 1328 | } | 1331 | } |
| 1329 | 1332 | ||
| 1330 | if (mrq->sbc && !(host->flags & SDHCI_AUTO_CMD23)) | 1333 | if (mrq->sbc && !(host->flags & SDHCI_AUTO_CMD23)) |
| @@ -2837,6 +2840,9 @@ int sdhci_add_host(struct sdhci_host *host) | |||
| 2837 | if (!(host->quirks & SDHCI_QUIRK_FORCE_1_BIT_DATA)) | 2840 | if (!(host->quirks & SDHCI_QUIRK_FORCE_1_BIT_DATA)) |
| 2838 | mmc->caps |= MMC_CAP_4_BIT_DATA; | 2841 | mmc->caps |= MMC_CAP_4_BIT_DATA; |
| 2839 | 2842 | ||
| 2843 | if (host->quirks2 & SDHCI_QUIRK2_HOST_NO_CMD23) | ||
| 2844 | mmc->caps &= ~MMC_CAP_CMD23; | ||
| 2845 | |||
| 2840 | if (caps[0] & SDHCI_CAN_DO_HISPD) | 2846 | if (caps[0] & SDHCI_CAN_DO_HISPD) |
| 2841 | mmc->caps |= MMC_CAP_SD_HIGHSPEED | MMC_CAP_MMC_HIGHSPEED; | 2847 | mmc->caps |= MMC_CAP_SD_HIGHSPEED | MMC_CAP_MMC_HIGHSPEED; |
| 2842 | 2848 | ||
| @@ -2846,9 +2852,12 @@ int sdhci_add_host(struct sdhci_host *host) | |||
| 2846 | 2852 | ||
| 2847 | /* If vqmmc regulator and no 1.8V signalling, then there's no UHS */ | 2853 | /* If vqmmc regulator and no 1.8V signalling, then there's no UHS */ |
| 2848 | host->vqmmc = regulator_get(mmc_dev(mmc), "vqmmc"); | 2854 | host->vqmmc = regulator_get(mmc_dev(mmc), "vqmmc"); |
| 2849 | if (IS_ERR(host->vqmmc)) { | 2855 | if (IS_ERR_OR_NULL(host->vqmmc)) { |
| 2850 | pr_info("%s: no vqmmc regulator found\n", mmc_hostname(mmc)); | 2856 | if (PTR_ERR(host->vqmmc) < 0) { |
| 2851 | host->vqmmc = NULL; | 2857 | pr_info("%s: no vqmmc regulator found\n", |
| 2858 | mmc_hostname(mmc)); | ||
| 2859 | host->vqmmc = NULL; | ||
| 2860 | } | ||
| 2852 | } | 2861 | } |
| 2853 | else if (regulator_is_supported_voltage(host->vqmmc, 1800000, 1800000)) | 2862 | else if (regulator_is_supported_voltage(host->vqmmc, 1800000, 1800000)) |
| 2854 | regulator_enable(host->vqmmc); | 2863 | regulator_enable(host->vqmmc); |
| @@ -2904,9 +2913,12 @@ int sdhci_add_host(struct sdhci_host *host) | |||
| 2904 | ocr_avail = 0; | 2913 | ocr_avail = 0; |
| 2905 | 2914 | ||
| 2906 | host->vmmc = regulator_get(mmc_dev(mmc), "vmmc"); | 2915 | host->vmmc = regulator_get(mmc_dev(mmc), "vmmc"); |
| 2907 | if (IS_ERR(host->vmmc)) { | 2916 | if (IS_ERR_OR_NULL(host->vmmc)) { |
| 2908 | pr_info("%s: no vmmc regulator found\n", mmc_hostname(mmc)); | 2917 | if (PTR_ERR(host->vmmc) < 0) { |
| 2909 | host->vmmc = NULL; | 2918 | pr_info("%s: no vmmc regulator found\n", |
| 2919 | mmc_hostname(mmc)); | ||
| 2920 | host->vmmc = NULL; | ||
| 2921 | } | ||
| 2910 | } else | 2922 | } else |
| 2911 | regulator_enable(host->vmmc); | 2923 | regulator_enable(host->vmmc); |
| 2912 | 2924 | ||
diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h index 97653ea8942b..71a4a7ed46c5 100644 --- a/drivers/mmc/host/sdhci.h +++ b/drivers/mmc/host/sdhci.h | |||
| @@ -278,6 +278,7 @@ struct sdhci_ops { | |||
| 278 | void (*hw_reset)(struct sdhci_host *host); | 278 | void (*hw_reset)(struct sdhci_host *host); |
| 279 | void (*platform_suspend)(struct sdhci_host *host); | 279 | void (*platform_suspend)(struct sdhci_host *host); |
| 280 | void (*platform_resume)(struct sdhci_host *host); | 280 | void (*platform_resume)(struct sdhci_host *host); |
| 281 | void (*platform_init)(struct sdhci_host *host); | ||
| 281 | }; | 282 | }; |
| 282 | 283 | ||
| 283 | #ifdef CONFIG_MMC_SDHCI_IO_ACCESSORS | 284 | #ifdef CONFIG_MMC_SDHCI_IO_ACCESSORS |
diff --git a/drivers/mmc/host/sh_mmcif.c b/drivers/mmc/host/sh_mmcif.c index 11d2bc3b51d5..7eaee3eeb6b2 100644 --- a/drivers/mmc/host/sh_mmcif.c +++ b/drivers/mmc/host/sh_mmcif.c | |||
| @@ -1104,7 +1104,6 @@ static irqreturn_t sh_mmcif_irqt(int irq, void *dev_id) | |||
| 1104 | { | 1104 | { |
| 1105 | struct sh_mmcif_host *host = dev_id; | 1105 | struct sh_mmcif_host *host = dev_id; |
| 1106 | struct mmc_request *mrq = host->mrq; | 1106 | struct mmc_request *mrq = host->mrq; |
| 1107 | struct mmc_data *data = mrq->data; | ||
| 1108 | 1107 | ||
| 1109 | cancel_delayed_work_sync(&host->timeout_work); | 1108 | cancel_delayed_work_sync(&host->timeout_work); |
| 1110 | 1109 | ||
| @@ -1152,13 +1151,14 @@ static irqreturn_t sh_mmcif_irqt(int irq, void *dev_id) | |||
| 1152 | case MMCIF_WAIT_FOR_READ_END: | 1151 | case MMCIF_WAIT_FOR_READ_END: |
| 1153 | case MMCIF_WAIT_FOR_WRITE_END: | 1152 | case MMCIF_WAIT_FOR_WRITE_END: |
| 1154 | if (host->sd_error) | 1153 | if (host->sd_error) |
| 1155 | data->error = sh_mmcif_error_manage(host); | 1154 | mrq->data->error = sh_mmcif_error_manage(host); |
| 1156 | break; | 1155 | break; |
| 1157 | default: | 1156 | default: |
| 1158 | BUG(); | 1157 | BUG(); |
| 1159 | } | 1158 | } |
| 1160 | 1159 | ||
| 1161 | if (host->wait_for != MMCIF_WAIT_FOR_STOP) { | 1160 | if (host->wait_for != MMCIF_WAIT_FOR_STOP) { |
| 1161 | struct mmc_data *data = mrq->data; | ||
| 1162 | if (!mrq->cmd->error && data && !data->error) | 1162 | if (!mrq->cmd->error && data && !data->error) |
| 1163 | data->bytes_xfered = | 1163 | data->bytes_xfered = |
| 1164 | data->blocks * data->blksz; | 1164 | data->blocks * data->blksz; |
| @@ -1231,10 +1231,6 @@ static irqreturn_t sh_mmcif_intr(int irq, void *dev_id) | |||
| 1231 | host->sd_error = true; | 1231 | host->sd_error = true; |
| 1232 | dev_dbg(&host->pd->dev, "int err state = %08x\n", state); | 1232 | dev_dbg(&host->pd->dev, "int err state = %08x\n", state); |
| 1233 | } | 1233 | } |
| 1234 | if (host->state == STATE_IDLE) { | ||
| 1235 | dev_info(&host->pd->dev, "Spurious IRQ status 0x%x", state); | ||
| 1236 | return IRQ_HANDLED; | ||
| 1237 | } | ||
| 1238 | if (state & ~(INT_CMD12RBE | INT_CMD12CRE)) { | 1234 | if (state & ~(INT_CMD12RBE | INT_CMD12CRE)) { |
| 1239 | if (!host->dma_active) | 1235 | if (!host->dma_active) |
| 1240 | return IRQ_WAKE_THREAD; | 1236 | return IRQ_WAKE_THREAD; |
| @@ -1466,9 +1462,9 @@ static int __devexit sh_mmcif_remove(struct platform_device *pdev) | |||
| 1466 | 1462 | ||
| 1467 | platform_set_drvdata(pdev, NULL); | 1463 | platform_set_drvdata(pdev, NULL); |
| 1468 | 1464 | ||
| 1465 | clk_disable(host->hclk); | ||
| 1469 | mmc_free_host(host->mmc); | 1466 | mmc_free_host(host->mmc); |
| 1470 | pm_runtime_put_sync(&pdev->dev); | 1467 | pm_runtime_put_sync(&pdev->dev); |
| 1471 | clk_disable(host->hclk); | ||
| 1472 | pm_runtime_disable(&pdev->dev); | 1468 | pm_runtime_disable(&pdev->dev); |
| 1473 | 1469 | ||
| 1474 | return 0; | 1470 | return 0; |
diff --git a/drivers/mtd/devices/slram.c b/drivers/mtd/devices/slram.c index 8f52fc858e48..5a5cd2ace4a6 100644 --- a/drivers/mtd/devices/slram.c +++ b/drivers/mtd/devices/slram.c | |||
| @@ -240,7 +240,7 @@ static int parse_cmdline(char *devname, char *szstart, char *szlength) | |||
| 240 | 240 | ||
| 241 | if (*(szlength) != '+') { | 241 | if (*(szlength) != '+') { |
| 242 | devlength = simple_strtoul(szlength, &buffer, 0); | 242 | devlength = simple_strtoul(szlength, &buffer, 0); |
| 243 | devlength = handle_unit(devlength, buffer) - devstart; | 243 | devlength = handle_unit(devlength, buffer); |
| 244 | if (devlength < devstart) | 244 | if (devlength < devstart) |
| 245 | goto err_out; | 245 | goto err_out; |
| 246 | 246 | ||
diff --git a/drivers/mtd/mtdcore.c b/drivers/mtd/mtdcore.c index 374c46dff7dd..ec794a72975d 100644 --- a/drivers/mtd/mtdcore.c +++ b/drivers/mtd/mtdcore.c | |||
| @@ -1077,7 +1077,8 @@ EXPORT_SYMBOL_GPL(mtd_writev); | |||
| 1077 | * until the request succeeds or until the allocation size falls below | 1077 | * until the request succeeds or until the allocation size falls below |
| 1078 | * the system page size. This attempts to make sure it does not adversely | 1078 | * the system page size. This attempts to make sure it does not adversely |
| 1079 | * impact system performance, so when allocating more than one page, we | 1079 | * impact system performance, so when allocating more than one page, we |
| 1080 | * ask the memory allocator to avoid re-trying. | 1080 | * ask the memory allocator to avoid re-trying, swapping, writing back |
| 1081 | * or performing I/O. | ||
| 1081 | * | 1082 | * |
| 1082 | * Note, this function also makes sure that the allocated buffer is aligned to | 1083 | * Note, this function also makes sure that the allocated buffer is aligned to |
| 1083 | * the MTD device's min. I/O unit, i.e. the "mtd->writesize" value. | 1084 | * the MTD device's min. I/O unit, i.e. the "mtd->writesize" value. |
| @@ -1091,7 +1092,8 @@ EXPORT_SYMBOL_GPL(mtd_writev); | |||
| 1091 | */ | 1092 | */ |
| 1092 | void *mtd_kmalloc_up_to(const struct mtd_info *mtd, size_t *size) | 1093 | void *mtd_kmalloc_up_to(const struct mtd_info *mtd, size_t *size) |
| 1093 | { | 1094 | { |
| 1094 | gfp_t flags = __GFP_NOWARN | __GFP_WAIT | __GFP_NORETRY; | 1095 | gfp_t flags = __GFP_NOWARN | __GFP_WAIT | |
| 1096 | __GFP_NORETRY | __GFP_NO_KSWAPD; | ||
| 1095 | size_t min_alloc = max_t(size_t, mtd->writesize, PAGE_SIZE); | 1097 | size_t min_alloc = max_t(size_t, mtd->writesize, PAGE_SIZE); |
| 1096 | void *kbuf; | 1098 | void *kbuf; |
| 1097 | 1099 | ||
diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c index ec6841d8e956..1a03b7f673ce 100644 --- a/drivers/mtd/nand/nand_base.c +++ b/drivers/mtd/nand/nand_base.c | |||
| @@ -2983,13 +2983,15 @@ static void nand_decode_ext_id(struct mtd_info *mtd, struct nand_chip *chip, | |||
| 2983 | /* | 2983 | /* |
| 2984 | * Field definitions are in the following datasheets: | 2984 | * Field definitions are in the following datasheets: |
| 2985 | * Old style (4,5 byte ID): Samsung K9GAG08U0M (p.32) | 2985 | * Old style (4,5 byte ID): Samsung K9GAG08U0M (p.32) |
| 2986 | * New style (6 byte ID): Samsung K9GAG08U0F (p.44) | 2986 | * New Samsung (6 byte ID): Samsung K9GAG08U0F (p.44) |
| 2987 | * Hynix MLC (6 byte ID): Hynix H27UBG8T2B (p.22) | 2987 | * Hynix MLC (6 byte ID): Hynix H27UBG8T2B (p.22) |
| 2988 | * | 2988 | * |
| 2989 | * Check for ID length, cell type, and Hynix/Samsung ID to decide what | 2989 | * Check for ID length, non-zero 6th byte, cell type, and Hynix/Samsung |
| 2990 | * to do. | 2990 | * ID to decide what to do. |
| 2991 | */ | 2991 | */ |
| 2992 | if (id_len == 6 && id_data[0] == NAND_MFR_SAMSUNG) { | 2992 | if (id_len == 6 && id_data[0] == NAND_MFR_SAMSUNG && |
| 2993 | (chip->cellinfo & NAND_CI_CELLTYPE_MSK) && | ||
| 2994 | id_data[5] != 0x00) { | ||
| 2993 | /* Calc pagesize */ | 2995 | /* Calc pagesize */ |
| 2994 | mtd->writesize = 2048 << (extid & 0x03); | 2996 | mtd->writesize = 2048 << (extid & 0x03); |
| 2995 | extid >>= 2; | 2997 | extid >>= 2; |
diff --git a/drivers/mtd/ofpart.c b/drivers/mtd/ofpart.c index 64be8f0848b0..d9127e2ed808 100644 --- a/drivers/mtd/ofpart.c +++ b/drivers/mtd/ofpart.c | |||
| @@ -121,7 +121,7 @@ static int parse_ofoldpart_partitions(struct mtd_info *master, | |||
| 121 | nr_parts = plen / sizeof(part[0]); | 121 | nr_parts = plen / sizeof(part[0]); |
| 122 | 122 | ||
| 123 | *pparts = kzalloc(nr_parts * sizeof(*(*pparts)), GFP_KERNEL); | 123 | *pparts = kzalloc(nr_parts * sizeof(*(*pparts)), GFP_KERNEL); |
| 124 | if (!pparts) | 124 | if (!*pparts) |
| 125 | return -ENOMEM; | 125 | return -ENOMEM; |
| 126 | 126 | ||
| 127 | names = of_get_property(dp, "partition-names", &plen); | 127 | names = of_get_property(dp, "partition-names", &plen); |
diff --git a/drivers/mtd/onenand/onenand_base.c b/drivers/mtd/onenand/onenand_base.c index 7153e0d27101..b3f41f200622 100644 --- a/drivers/mtd/onenand/onenand_base.c +++ b/drivers/mtd/onenand/onenand_base.c | |||
| @@ -3694,7 +3694,7 @@ static int flexonenand_check_blocks_erased(struct mtd_info *mtd, int start, int | |||
| 3694 | * flexonenand_set_boundary - Writes the SLC boundary | 3694 | * flexonenand_set_boundary - Writes the SLC boundary |
| 3695 | * @param mtd - mtd info structure | 3695 | * @param mtd - mtd info structure |
| 3696 | */ | 3696 | */ |
| 3697 | int flexonenand_set_boundary(struct mtd_info *mtd, int die, | 3697 | static int flexonenand_set_boundary(struct mtd_info *mtd, int die, |
| 3698 | int boundary, int lock) | 3698 | int boundary, int lock) |
| 3699 | { | 3699 | { |
| 3700 | struct onenand_chip *this = mtd->priv; | 3700 | struct onenand_chip *this = mtd->priv; |
diff --git a/drivers/mtd/ubi/wl.c b/drivers/mtd/ubi/wl.c index da7b44998b40..2144f611196e 100644 --- a/drivers/mtd/ubi/wl.c +++ b/drivers/mtd/ubi/wl.c | |||
| @@ -498,7 +498,7 @@ out: | |||
| 498 | * @ubi: UBI device description object | 498 | * @ubi: UBI device description object |
| 499 | * | 499 | * |
| 500 | * This function returns a physical eraseblock in case of success and a | 500 | * This function returns a physical eraseblock in case of success and a |
| 501 | * negative error code in case of failure. Might sleep. | 501 | * negative error code in case of failure. |
| 502 | */ | 502 | */ |
| 503 | static int __wl_get_peb(struct ubi_device *ubi) | 503 | static int __wl_get_peb(struct ubi_device *ubi) |
| 504 | { | 504 | { |
| @@ -540,13 +540,6 @@ retry: | |||
| 540 | * ubi_wl_get_peb() after removing e from the pool. */ | 540 | * ubi_wl_get_peb() after removing e from the pool. */ |
| 541 | prot_queue_add(ubi, e); | 541 | prot_queue_add(ubi, e); |
| 542 | #endif | 542 | #endif |
| 543 | err = ubi_self_check_all_ff(ubi, e->pnum, ubi->vid_hdr_aloffset, | ||
| 544 | ubi->peb_size - ubi->vid_hdr_aloffset); | ||
| 545 | if (err) { | ||
| 546 | ubi_err("new PEB %d does not contain all 0xFF bytes", e->pnum); | ||
| 547 | return err; | ||
| 548 | } | ||
| 549 | |||
| 550 | return e->pnum; | 543 | return e->pnum; |
| 551 | } | 544 | } |
| 552 | 545 | ||
| @@ -679,17 +672,30 @@ static struct ubi_wl_entry *get_peb_for_wl(struct ubi_device *ubi) | |||
| 679 | #else | 672 | #else |
| 680 | static struct ubi_wl_entry *get_peb_for_wl(struct ubi_device *ubi) | 673 | static struct ubi_wl_entry *get_peb_for_wl(struct ubi_device *ubi) |
| 681 | { | 674 | { |
| 682 | return find_wl_entry(ubi, &ubi->free, WL_FREE_MAX_DIFF); | 675 | struct ubi_wl_entry *e; |
| 676 | |||
| 677 | e = find_wl_entry(ubi, &ubi->free, WL_FREE_MAX_DIFF); | ||
| 678 | self_check_in_wl_tree(ubi, e, &ubi->free); | ||
| 679 | rb_erase(&e->u.rb, &ubi->free); | ||
| 680 | |||
| 681 | return e; | ||
| 683 | } | 682 | } |
| 684 | 683 | ||
| 685 | int ubi_wl_get_peb(struct ubi_device *ubi) | 684 | int ubi_wl_get_peb(struct ubi_device *ubi) |
| 686 | { | 685 | { |
| 687 | int peb; | 686 | int peb, err; |
| 688 | 687 | ||
| 689 | spin_lock(&ubi->wl_lock); | 688 | spin_lock(&ubi->wl_lock); |
| 690 | peb = __wl_get_peb(ubi); | 689 | peb = __wl_get_peb(ubi); |
| 691 | spin_unlock(&ubi->wl_lock); | 690 | spin_unlock(&ubi->wl_lock); |
| 692 | 691 | ||
| 692 | err = ubi_self_check_all_ff(ubi, peb, ubi->vid_hdr_aloffset, | ||
| 693 | ubi->peb_size - ubi->vid_hdr_aloffset); | ||
| 694 | if (err) { | ||
| 695 | ubi_err("new PEB %d does not contain all 0xFF bytes", peb); | ||
| 696 | return err; | ||
| 697 | } | ||
| 698 | |||
| 693 | return peb; | 699 | return peb; |
| 694 | } | 700 | } |
| 695 | #endif | 701 | #endif |
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index b721902bb6b4..a7d47350ea4b 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c | |||
| @@ -1379,6 +1379,8 @@ static void bond_compute_features(struct bonding *bond) | |||
| 1379 | struct net_device *bond_dev = bond->dev; | 1379 | struct net_device *bond_dev = bond->dev; |
| 1380 | netdev_features_t vlan_features = BOND_VLAN_FEATURES; | 1380 | netdev_features_t vlan_features = BOND_VLAN_FEATURES; |
| 1381 | unsigned short max_hard_header_len = ETH_HLEN; | 1381 | unsigned short max_hard_header_len = ETH_HLEN; |
| 1382 | unsigned int gso_max_size = GSO_MAX_SIZE; | ||
| 1383 | u16 gso_max_segs = GSO_MAX_SEGS; | ||
| 1382 | int i; | 1384 | int i; |
| 1383 | unsigned int flags, dst_release_flag = IFF_XMIT_DST_RELEASE; | 1385 | unsigned int flags, dst_release_flag = IFF_XMIT_DST_RELEASE; |
| 1384 | 1386 | ||
| @@ -1394,11 +1396,16 @@ static void bond_compute_features(struct bonding *bond) | |||
| 1394 | dst_release_flag &= slave->dev->priv_flags; | 1396 | dst_release_flag &= slave->dev->priv_flags; |
| 1395 | if (slave->dev->hard_header_len > max_hard_header_len) | 1397 | if (slave->dev->hard_header_len > max_hard_header_len) |
| 1396 | max_hard_header_len = slave->dev->hard_header_len; | 1398 | max_hard_header_len = slave->dev->hard_header_len; |
| 1399 | |||
| 1400 | gso_max_size = min(gso_max_size, slave->dev->gso_max_size); | ||
| 1401 | gso_max_segs = min(gso_max_segs, slave->dev->gso_max_segs); | ||
| 1397 | } | 1402 | } |
| 1398 | 1403 | ||
| 1399 | done: | 1404 | done: |
| 1400 | bond_dev->vlan_features = vlan_features; | 1405 | bond_dev->vlan_features = vlan_features; |
| 1401 | bond_dev->hard_header_len = max_hard_header_len; | 1406 | bond_dev->hard_header_len = max_hard_header_len; |
| 1407 | bond_dev->gso_max_segs = gso_max_segs; | ||
| 1408 | netif_set_gso_max_size(bond_dev, gso_max_size); | ||
| 1402 | 1409 | ||
| 1403 | flags = bond_dev->priv_flags & ~IFF_XMIT_DST_RELEASE; | 1410 | flags = bond_dev->priv_flags & ~IFF_XMIT_DST_RELEASE; |
| 1404 | bond_dev->priv_flags = flags | dst_release_flag; | 1411 | bond_dev->priv_flags = flags | dst_release_flag; |
| @@ -1519,7 +1526,7 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev) | |||
| 1519 | /* no need to lock since we're protected by rtnl_lock */ | 1526 | /* no need to lock since we're protected by rtnl_lock */ |
| 1520 | if (slave_dev->features & NETIF_F_VLAN_CHALLENGED) { | 1527 | if (slave_dev->features & NETIF_F_VLAN_CHALLENGED) { |
| 1521 | pr_debug("%s: NETIF_F_VLAN_CHALLENGED\n", slave_dev->name); | 1528 | pr_debug("%s: NETIF_F_VLAN_CHALLENGED\n", slave_dev->name); |
| 1522 | if (bond_vlan_used(bond)) { | 1529 | if (vlan_uses_dev(bond_dev)) { |
| 1523 | pr_err("%s: Error: cannot enslave VLAN challenged slave %s on VLAN enabled bond %s\n", | 1530 | pr_err("%s: Error: cannot enslave VLAN challenged slave %s on VLAN enabled bond %s\n", |
| 1524 | bond_dev->name, slave_dev->name, bond_dev->name); | 1531 | bond_dev->name, slave_dev->name, bond_dev->name); |
| 1525 | return -EPERM; | 1532 | return -EPERM; |
| @@ -3452,6 +3459,28 @@ static int bond_xmit_hash_policy_l34(struct sk_buff *skb, int count) | |||
| 3452 | 3459 | ||
| 3453 | /*-------------------------- Device entry points ----------------------------*/ | 3460 | /*-------------------------- Device entry points ----------------------------*/ |
| 3454 | 3461 | ||
| 3462 | static void bond_work_init_all(struct bonding *bond) | ||
| 3463 | { | ||
| 3464 | INIT_DELAYED_WORK(&bond->mcast_work, | ||
| 3465 | bond_resend_igmp_join_requests_delayed); | ||
| 3466 | INIT_DELAYED_WORK(&bond->alb_work, bond_alb_monitor); | ||
| 3467 | INIT_DELAYED_WORK(&bond->mii_work, bond_mii_monitor); | ||
| 3468 | if (bond->params.mode == BOND_MODE_ACTIVEBACKUP) | ||
| 3469 | INIT_DELAYED_WORK(&bond->arp_work, bond_activebackup_arp_mon); | ||
| 3470 | else | ||
| 3471 | INIT_DELAYED_WORK(&bond->arp_work, bond_loadbalance_arp_mon); | ||
| 3472 | INIT_DELAYED_WORK(&bond->ad_work, bond_3ad_state_machine_handler); | ||
| 3473 | } | ||
| 3474 | |||
| 3475 | static void bond_work_cancel_all(struct bonding *bond) | ||
| 3476 | { | ||
| 3477 | cancel_delayed_work_sync(&bond->mii_work); | ||
| 3478 | cancel_delayed_work_sync(&bond->arp_work); | ||
| 3479 | cancel_delayed_work_sync(&bond->alb_work); | ||
| 3480 | cancel_delayed_work_sync(&bond->ad_work); | ||
| 3481 | cancel_delayed_work_sync(&bond->mcast_work); | ||
| 3482 | } | ||
| 3483 | |||
| 3455 | static int bond_open(struct net_device *bond_dev) | 3484 | static int bond_open(struct net_device *bond_dev) |
| 3456 | { | 3485 | { |
| 3457 | struct bonding *bond = netdev_priv(bond_dev); | 3486 | struct bonding *bond = netdev_priv(bond_dev); |
| @@ -3474,41 +3503,27 @@ static int bond_open(struct net_device *bond_dev) | |||
| 3474 | } | 3503 | } |
| 3475 | read_unlock(&bond->lock); | 3504 | read_unlock(&bond->lock); |
| 3476 | 3505 | ||
| 3477 | INIT_DELAYED_WORK(&bond->mcast_work, bond_resend_igmp_join_requests_delayed); | 3506 | bond_work_init_all(bond); |
| 3478 | 3507 | ||
| 3479 | if (bond_is_lb(bond)) { | 3508 | if (bond_is_lb(bond)) { |
| 3480 | /* bond_alb_initialize must be called before the timer | 3509 | /* bond_alb_initialize must be called before the timer |
| 3481 | * is started. | 3510 | * is started. |
| 3482 | */ | 3511 | */ |
| 3483 | if (bond_alb_initialize(bond, (bond->params.mode == BOND_MODE_ALB))) { | 3512 | if (bond_alb_initialize(bond, (bond->params.mode == BOND_MODE_ALB))) |
| 3484 | /* something went wrong - fail the open operation */ | ||
| 3485 | return -ENOMEM; | 3513 | return -ENOMEM; |
| 3486 | } | ||
| 3487 | |||
| 3488 | INIT_DELAYED_WORK(&bond->alb_work, bond_alb_monitor); | ||
| 3489 | queue_delayed_work(bond->wq, &bond->alb_work, 0); | 3514 | queue_delayed_work(bond->wq, &bond->alb_work, 0); |
| 3490 | } | 3515 | } |
| 3491 | 3516 | ||
| 3492 | if (bond->params.miimon) { /* link check interval, in milliseconds. */ | 3517 | if (bond->params.miimon) /* link check interval, in milliseconds. */ |
| 3493 | INIT_DELAYED_WORK(&bond->mii_work, bond_mii_monitor); | ||
| 3494 | queue_delayed_work(bond->wq, &bond->mii_work, 0); | 3518 | queue_delayed_work(bond->wq, &bond->mii_work, 0); |
| 3495 | } | ||
| 3496 | 3519 | ||
| 3497 | if (bond->params.arp_interval) { /* arp interval, in milliseconds. */ | 3520 | if (bond->params.arp_interval) { /* arp interval, in milliseconds. */ |
| 3498 | if (bond->params.mode == BOND_MODE_ACTIVEBACKUP) | ||
| 3499 | INIT_DELAYED_WORK(&bond->arp_work, | ||
| 3500 | bond_activebackup_arp_mon); | ||
| 3501 | else | ||
| 3502 | INIT_DELAYED_WORK(&bond->arp_work, | ||
| 3503 | bond_loadbalance_arp_mon); | ||
| 3504 | |||
| 3505 | queue_delayed_work(bond->wq, &bond->arp_work, 0); | 3521 | queue_delayed_work(bond->wq, &bond->arp_work, 0); |
| 3506 | if (bond->params.arp_validate) | 3522 | if (bond->params.arp_validate) |
| 3507 | bond->recv_probe = bond_arp_rcv; | 3523 | bond->recv_probe = bond_arp_rcv; |
| 3508 | } | 3524 | } |
| 3509 | 3525 | ||
| 3510 | if (bond->params.mode == BOND_MODE_8023AD) { | 3526 | if (bond->params.mode == BOND_MODE_8023AD) { |
| 3511 | INIT_DELAYED_WORK(&bond->ad_work, bond_3ad_state_machine_handler); | ||
| 3512 | queue_delayed_work(bond->wq, &bond->ad_work, 0); | 3527 | queue_delayed_work(bond->wq, &bond->ad_work, 0); |
| 3513 | /* register to receive LACPDUs */ | 3528 | /* register to receive LACPDUs */ |
| 3514 | bond->recv_probe = bond_3ad_lacpdu_recv; | 3529 | bond->recv_probe = bond_3ad_lacpdu_recv; |
| @@ -3523,34 +3538,10 @@ static int bond_close(struct net_device *bond_dev) | |||
| 3523 | struct bonding *bond = netdev_priv(bond_dev); | 3538 | struct bonding *bond = netdev_priv(bond_dev); |
| 3524 | 3539 | ||
| 3525 | write_lock_bh(&bond->lock); | 3540 | write_lock_bh(&bond->lock); |
| 3526 | |||
| 3527 | bond->send_peer_notif = 0; | 3541 | bond->send_peer_notif = 0; |
| 3528 | |||
| 3529 | write_unlock_bh(&bond->lock); | 3542 | write_unlock_bh(&bond->lock); |
| 3530 | 3543 | ||
| 3531 | if (bond->params.miimon) { /* link check interval, in milliseconds. */ | 3544 | bond_work_cancel_all(bond); |
| 3532 | cancel_delayed_work_sync(&bond->mii_work); | ||
| 3533 | } | ||
| 3534 | |||
| 3535 | if (bond->params.arp_interval) { /* arp interval, in milliseconds. */ | ||
| 3536 | cancel_delayed_work_sync(&bond->arp_work); | ||
| 3537 | } | ||
| 3538 | |||
| 3539 | switch (bond->params.mode) { | ||
| 3540 | case BOND_MODE_8023AD: | ||
| 3541 | cancel_delayed_work_sync(&bond->ad_work); | ||
| 3542 | break; | ||
| 3543 | case BOND_MODE_TLB: | ||
| 3544 | case BOND_MODE_ALB: | ||
| 3545 | cancel_delayed_work_sync(&bond->alb_work); | ||
| 3546 | break; | ||
| 3547 | default: | ||
| 3548 | break; | ||
| 3549 | } | ||
| 3550 | |||
| 3551 | if (delayed_work_pending(&bond->mcast_work)) | ||
| 3552 | cancel_delayed_work_sync(&bond->mcast_work); | ||
| 3553 | |||
| 3554 | if (bond_is_lb(bond)) { | 3545 | if (bond_is_lb(bond)) { |
| 3555 | /* Must be called only after all | 3546 | /* Must be called only after all |
| 3556 | * slaves have been released | 3547 | * slaves have been released |
| @@ -4429,26 +4420,6 @@ static void bond_setup(struct net_device *bond_dev) | |||
| 4429 | bond_dev->features |= bond_dev->hw_features; | 4420 | bond_dev->features |= bond_dev->hw_features; |
| 4430 | } | 4421 | } |
| 4431 | 4422 | ||
| 4432 | static void bond_work_cancel_all(struct bonding *bond) | ||
| 4433 | { | ||
| 4434 | if (bond->params.miimon && delayed_work_pending(&bond->mii_work)) | ||
| 4435 | cancel_delayed_work_sync(&bond->mii_work); | ||
| 4436 | |||
| 4437 | if (bond->params.arp_interval && delayed_work_pending(&bond->arp_work)) | ||
| 4438 | cancel_delayed_work_sync(&bond->arp_work); | ||
| 4439 | |||
| 4440 | if (bond->params.mode == BOND_MODE_ALB && | ||
| 4441 | delayed_work_pending(&bond->alb_work)) | ||
| 4442 | cancel_delayed_work_sync(&bond->alb_work); | ||
| 4443 | |||
| 4444 | if (bond->params.mode == BOND_MODE_8023AD && | ||
| 4445 | delayed_work_pending(&bond->ad_work)) | ||
| 4446 | cancel_delayed_work_sync(&bond->ad_work); | ||
| 4447 | |||
| 4448 | if (delayed_work_pending(&bond->mcast_work)) | ||
| 4449 | cancel_delayed_work_sync(&bond->mcast_work); | ||
| 4450 | } | ||
| 4451 | |||
| 4452 | /* | 4423 | /* |
| 4453 | * Destroy a bonding device. | 4424 | * Destroy a bonding device. |
| 4454 | * Must be under rtnl_lock when this function is called. | 4425 | * Must be under rtnl_lock when this function is called. |
| @@ -4699,12 +4670,13 @@ static int bond_check_params(struct bond_params *params) | |||
| 4699 | arp_ip_count++) { | 4670 | arp_ip_count++) { |
| 4700 | /* not complete check, but should be good enough to | 4671 | /* not complete check, but should be good enough to |
| 4701 | catch mistakes */ | 4672 | catch mistakes */ |
| 4702 | if (!isdigit(arp_ip_target[arp_ip_count][0])) { | 4673 | __be32 ip = in_aton(arp_ip_target[arp_ip_count]); |
| 4674 | if (!isdigit(arp_ip_target[arp_ip_count][0]) || | ||
| 4675 | ip == 0 || ip == htonl(INADDR_BROADCAST)) { | ||
| 4703 | pr_warning("Warning: bad arp_ip_target module parameter (%s), ARP monitoring will not be performed\n", | 4676 | pr_warning("Warning: bad arp_ip_target module parameter (%s), ARP monitoring will not be performed\n", |
| 4704 | arp_ip_target[arp_ip_count]); | 4677 | arp_ip_target[arp_ip_count]); |
| 4705 | arp_interval = 0; | 4678 | arp_interval = 0; |
| 4706 | } else { | 4679 | } else { |
| 4707 | __be32 ip = in_aton(arp_ip_target[arp_ip_count]); | ||
| 4708 | arp_target[arp_ip_count] = ip; | 4680 | arp_target[arp_ip_count] = ip; |
| 4709 | } | 4681 | } |
| 4710 | } | 4682 | } |
diff --git a/drivers/net/bonding/bond_sysfs.c b/drivers/net/bonding/bond_sysfs.c index dc15d248443f..1877ed7ca086 100644 --- a/drivers/net/bonding/bond_sysfs.c +++ b/drivers/net/bonding/bond_sysfs.c | |||
| @@ -513,6 +513,8 @@ static ssize_t bonding_store_arp_interval(struct device *d, | |||
| 513 | int new_value, ret = count; | 513 | int new_value, ret = count; |
| 514 | struct bonding *bond = to_bond(d); | 514 | struct bonding *bond = to_bond(d); |
| 515 | 515 | ||
| 516 | if (!rtnl_trylock()) | ||
| 517 | return restart_syscall(); | ||
| 516 | if (sscanf(buf, "%d", &new_value) != 1) { | 518 | if (sscanf(buf, "%d", &new_value) != 1) { |
| 517 | pr_err("%s: no arp_interval value specified.\n", | 519 | pr_err("%s: no arp_interval value specified.\n", |
| 518 | bond->dev->name); | 520 | bond->dev->name); |
| @@ -539,10 +541,6 @@ static ssize_t bonding_store_arp_interval(struct device *d, | |||
| 539 | pr_info("%s: ARP monitoring cannot be used with MII monitoring. %s Disabling MII monitoring.\n", | 541 | pr_info("%s: ARP monitoring cannot be used with MII monitoring. %s Disabling MII monitoring.\n", |
| 540 | bond->dev->name, bond->dev->name); | 542 | bond->dev->name, bond->dev->name); |
| 541 | bond->params.miimon = 0; | 543 | bond->params.miimon = 0; |
| 542 | if (delayed_work_pending(&bond->mii_work)) { | ||
| 543 | cancel_delayed_work(&bond->mii_work); | ||
| 544 | flush_workqueue(bond->wq); | ||
| 545 | } | ||
| 546 | } | 544 | } |
| 547 | if (!bond->params.arp_targets[0]) { | 545 | if (!bond->params.arp_targets[0]) { |
| 548 | pr_info("%s: ARP monitoring has been set up, but no ARP targets have been specified.\n", | 546 | pr_info("%s: ARP monitoring has been set up, but no ARP targets have been specified.\n", |
| @@ -554,19 +552,12 @@ static ssize_t bonding_store_arp_interval(struct device *d, | |||
| 554 | * timer will get fired off when the open function | 552 | * timer will get fired off when the open function |
| 555 | * is called. | 553 | * is called. |
| 556 | */ | 554 | */ |
| 557 | if (!delayed_work_pending(&bond->arp_work)) { | 555 | cancel_delayed_work_sync(&bond->mii_work); |
| 558 | if (bond->params.mode == BOND_MODE_ACTIVEBACKUP) | 556 | queue_delayed_work(bond->wq, &bond->arp_work, 0); |
| 559 | INIT_DELAYED_WORK(&bond->arp_work, | ||
| 560 | bond_activebackup_arp_mon); | ||
| 561 | else | ||
| 562 | INIT_DELAYED_WORK(&bond->arp_work, | ||
| 563 | bond_loadbalance_arp_mon); | ||
| 564 | |||
| 565 | queue_delayed_work(bond->wq, &bond->arp_work, 0); | ||
| 566 | } | ||
| 567 | } | 557 | } |
| 568 | 558 | ||
| 569 | out: | 559 | out: |
| 560 | rtnl_unlock(); | ||
| 570 | return ret; | 561 | return ret; |
| 571 | } | 562 | } |
| 572 | static DEVICE_ATTR(arp_interval, S_IRUGO | S_IWUSR, | 563 | static DEVICE_ATTR(arp_interval, S_IRUGO | S_IWUSR, |
| @@ -962,6 +953,8 @@ static ssize_t bonding_store_miimon(struct device *d, | |||
| 962 | int new_value, ret = count; | 953 | int new_value, ret = count; |
| 963 | struct bonding *bond = to_bond(d); | 954 | struct bonding *bond = to_bond(d); |
| 964 | 955 | ||
| 956 | if (!rtnl_trylock()) | ||
| 957 | return restart_syscall(); | ||
| 965 | if (sscanf(buf, "%d", &new_value) != 1) { | 958 | if (sscanf(buf, "%d", &new_value) != 1) { |
| 966 | pr_err("%s: no miimon value specified.\n", | 959 | pr_err("%s: no miimon value specified.\n", |
| 967 | bond->dev->name); | 960 | bond->dev->name); |
| @@ -993,10 +986,6 @@ static ssize_t bonding_store_miimon(struct device *d, | |||
| 993 | bond->params.arp_validate = | 986 | bond->params.arp_validate = |
| 994 | BOND_ARP_VALIDATE_NONE; | 987 | BOND_ARP_VALIDATE_NONE; |
| 995 | } | 988 | } |
| 996 | if (delayed_work_pending(&bond->arp_work)) { | ||
| 997 | cancel_delayed_work(&bond->arp_work); | ||
| 998 | flush_workqueue(bond->wq); | ||
| 999 | } | ||
| 1000 | } | 989 | } |
| 1001 | 990 | ||
| 1002 | if (bond->dev->flags & IFF_UP) { | 991 | if (bond->dev->flags & IFF_UP) { |
| @@ -1005,15 +994,12 @@ static ssize_t bonding_store_miimon(struct device *d, | |||
| 1005 | * timer will get fired off when the open function | 994 | * timer will get fired off when the open function |
| 1006 | * is called. | 995 | * is called. |
| 1007 | */ | 996 | */ |
| 1008 | if (!delayed_work_pending(&bond->mii_work)) { | 997 | cancel_delayed_work_sync(&bond->arp_work); |
| 1009 | INIT_DELAYED_WORK(&bond->mii_work, | 998 | queue_delayed_work(bond->wq, &bond->mii_work, 0); |
| 1010 | bond_mii_monitor); | ||
| 1011 | queue_delayed_work(bond->wq, | ||
| 1012 | &bond->mii_work, 0); | ||
| 1013 | } | ||
| 1014 | } | 999 | } |
| 1015 | } | 1000 | } |
| 1016 | out: | 1001 | out: |
| 1002 | rtnl_unlock(); | ||
| 1017 | return ret; | 1003 | return ret; |
| 1018 | } | 1004 | } |
| 1019 | static DEVICE_ATTR(miimon, S_IRUGO | S_IWUSR, | 1005 | static DEVICE_ATTR(miimon, S_IRUGO | S_IWUSR, |
| @@ -1060,7 +1046,7 @@ static ssize_t bonding_store_primary(struct device *d, | |||
| 1060 | goto out; | 1046 | goto out; |
| 1061 | } | 1047 | } |
| 1062 | 1048 | ||
| 1063 | sscanf(buf, "%16s", ifname); /* IFNAMSIZ */ | 1049 | sscanf(buf, "%15s", ifname); /* IFNAMSIZ */ |
| 1064 | 1050 | ||
| 1065 | /* check to see if we are clearing primary */ | 1051 | /* check to see if we are clearing primary */ |
| 1066 | if (!strlen(ifname) || buf[0] == '\n') { | 1052 | if (!strlen(ifname) || buf[0] == '\n') { |
| @@ -1237,7 +1223,7 @@ static ssize_t bonding_store_active_slave(struct device *d, | |||
| 1237 | goto out; | 1223 | goto out; |
| 1238 | } | 1224 | } |
| 1239 | 1225 | ||
| 1240 | sscanf(buf, "%16s", ifname); /* IFNAMSIZ */ | 1226 | sscanf(buf, "%15s", ifname); /* IFNAMSIZ */ |
| 1241 | 1227 | ||
| 1242 | /* check to see if we are clearing active */ | 1228 | /* check to see if we are clearing active */ |
| 1243 | if (!strlen(ifname) || buf[0] == '\n') { | 1229 | if (!strlen(ifname) || buf[0] == '\n') { |
| @@ -1582,6 +1568,7 @@ static ssize_t bonding_store_slaves_active(struct device *d, | |||
| 1582 | goto out; | 1568 | goto out; |
| 1583 | } | 1569 | } |
| 1584 | 1570 | ||
| 1571 | read_lock(&bond->lock); | ||
| 1585 | bond_for_each_slave(bond, slave, i) { | 1572 | bond_for_each_slave(bond, slave, i) { |
| 1586 | if (!bond_is_active_slave(slave)) { | 1573 | if (!bond_is_active_slave(slave)) { |
| 1587 | if (new_value) | 1574 | if (new_value) |
| @@ -1590,6 +1577,7 @@ static ssize_t bonding_store_slaves_active(struct device *d, | |||
| 1590 | slave->inactive = 1; | 1577 | slave->inactive = 1; |
| 1591 | } | 1578 | } |
| 1592 | } | 1579 | } |
| 1580 | read_unlock(&bond->lock); | ||
| 1593 | out: | 1581 | out: |
| 1594 | return ret; | 1582 | return ret; |
| 1595 | } | 1583 | } |
diff --git a/drivers/net/can/flexcan.c b/drivers/net/can/flexcan.c index c78ecfca1e45..a412bf6d73ef 100644 --- a/drivers/net/can/flexcan.c +++ b/drivers/net/can/flexcan.c | |||
| @@ -144,9 +144,22 @@ | |||
| 144 | 144 | ||
| 145 | #define FLEXCAN_MB_CODE_MASK (0xf0ffffff) | 145 | #define FLEXCAN_MB_CODE_MASK (0xf0ffffff) |
| 146 | 146 | ||
| 147 | /* FLEXCAN hardware feature flags */ | 147 | /* |
| 148 | * FLEXCAN hardware feature flags | ||
| 149 | * | ||
| 150 | * Below is some version info we got: | ||
| 151 | * SOC Version IP-Version Glitch- [TR]WRN_INT | ||
| 152 | * Filter? connected? | ||
| 153 | * MX25 FlexCAN2 03.00.00.00 no no | ||
| 154 | * MX28 FlexCAN2 03.00.04.00 yes yes | ||
| 155 | * MX35 FlexCAN2 03.00.00.00 no no | ||
| 156 | * MX53 FlexCAN2 03.00.00.00 yes no | ||
| 157 | * MX6s FlexCAN3 10.00.12.00 yes yes | ||
| 158 | * | ||
| 159 | * Some SOCs do not have the RX_WARN & TX_WARN interrupt line connected. | ||
| 160 | */ | ||
| 148 | #define FLEXCAN_HAS_V10_FEATURES BIT(1) /* For core version >= 10 */ | 161 | #define FLEXCAN_HAS_V10_FEATURES BIT(1) /* For core version >= 10 */ |
| 149 | #define FLEXCAN_HAS_BROKEN_ERR_STATE BIT(2) /* Broken error state handling */ | 162 | #define FLEXCAN_HAS_BROKEN_ERR_STATE BIT(2) /* [TR]WRN_INT not connected */ |
| 150 | 163 | ||
| 151 | /* Structure of the message buffer */ | 164 | /* Structure of the message buffer */ |
| 152 | struct flexcan_mb { | 165 | struct flexcan_mb { |
| @@ -205,7 +218,7 @@ static struct flexcan_devtype_data fsl_p1010_devtype_data = { | |||
| 205 | }; | 218 | }; |
| 206 | static struct flexcan_devtype_data fsl_imx28_devtype_data; | 219 | static struct flexcan_devtype_data fsl_imx28_devtype_data; |
| 207 | static struct flexcan_devtype_data fsl_imx6q_devtype_data = { | 220 | static struct flexcan_devtype_data fsl_imx6q_devtype_data = { |
| 208 | .features = FLEXCAN_HAS_V10_FEATURES | FLEXCAN_HAS_BROKEN_ERR_STATE, | 221 | .features = FLEXCAN_HAS_V10_FEATURES, |
| 209 | }; | 222 | }; |
| 210 | 223 | ||
| 211 | static const struct can_bittiming_const flexcan_bittiming_const = { | 224 | static const struct can_bittiming_const flexcan_bittiming_const = { |
diff --git a/drivers/net/can/sja1000/peak_pci.c b/drivers/net/can/sja1000/peak_pci.c index f5b82aeb2540..6525dbcca4e3 100644 --- a/drivers/net/can/sja1000/peak_pci.c +++ b/drivers/net/can/sja1000/peak_pci.c | |||
| @@ -30,9 +30,10 @@ | |||
| 30 | 30 | ||
| 31 | #include "sja1000.h" | 31 | #include "sja1000.h" |
| 32 | 32 | ||
| 33 | MODULE_AUTHOR("Wolfgang Grandegger <wg@grandegger.com>"); | 33 | MODULE_AUTHOR("Stephane Grosjean <s.grosjean@peak-system.com>"); |
| 34 | MODULE_DESCRIPTION("Socket-CAN driver for PEAK PCAN PCI family cards"); | 34 | MODULE_DESCRIPTION("Socket-CAN driver for PEAK PCAN PCI family cards"); |
| 35 | MODULE_SUPPORTED_DEVICE("PEAK PCAN PCI/PCIe/PCIeC miniPCI CAN cards"); | 35 | MODULE_SUPPORTED_DEVICE("PEAK PCAN PCI/PCIe/PCIeC miniPCI CAN cards"); |
| 36 | MODULE_SUPPORTED_DEVICE("PEAK PCAN miniPCIe/cPCI PC/104+ PCI/104e CAN Cards"); | ||
| 36 | MODULE_LICENSE("GPL v2"); | 37 | MODULE_LICENSE("GPL v2"); |
| 37 | 38 | ||
| 38 | #define DRV_NAME "peak_pci" | 39 | #define DRV_NAME "peak_pci" |
| @@ -64,7 +65,11 @@ struct peak_pci_chan { | |||
| 64 | #define PEAK_PCI_DEVICE_ID 0x0001 /* for PCI/PCIe slot cards */ | 65 | #define PEAK_PCI_DEVICE_ID 0x0001 /* for PCI/PCIe slot cards */ |
| 65 | #define PEAK_PCIEC_DEVICE_ID 0x0002 /* for ExpressCard slot cards */ | 66 | #define PEAK_PCIEC_DEVICE_ID 0x0002 /* for ExpressCard slot cards */ |
| 66 | #define PEAK_PCIE_DEVICE_ID 0x0003 /* for nextgen PCIe slot cards */ | 67 | #define PEAK_PCIE_DEVICE_ID 0x0003 /* for nextgen PCIe slot cards */ |
| 67 | #define PEAK_MPCI_DEVICE_ID 0x0008 /* The miniPCI slot cards */ | 68 | #define PEAK_CPCI_DEVICE_ID 0x0004 /* for nextgen cPCI slot cards */ |
| 69 | #define PEAK_MPCI_DEVICE_ID 0x0005 /* for nextgen miniPCI slot cards */ | ||
| 70 | #define PEAK_PC_104P_DEVICE_ID 0x0006 /* PCAN-PC/104+ cards */ | ||
| 71 | #define PEAK_PCI_104E_DEVICE_ID 0x0007 /* PCAN-PCI/104 Express cards */ | ||
| 72 | #define PEAK_MPCIE_DEVICE_ID 0x0008 /* The miniPCIe slot cards */ | ||
| 68 | 73 | ||
| 69 | #define PEAK_PCI_CHAN_MAX 4 | 74 | #define PEAK_PCI_CHAN_MAX 4 |
| 70 | 75 | ||
| @@ -76,6 +81,10 @@ static DEFINE_PCI_DEVICE_TABLE(peak_pci_tbl) = { | |||
| 76 | {PEAK_PCI_VENDOR_ID, PEAK_PCI_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID,}, | 81 | {PEAK_PCI_VENDOR_ID, PEAK_PCI_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID,}, |
| 77 | {PEAK_PCI_VENDOR_ID, PEAK_PCIE_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID,}, | 82 | {PEAK_PCI_VENDOR_ID, PEAK_PCIE_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID,}, |
| 78 | {PEAK_PCI_VENDOR_ID, PEAK_MPCI_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID,}, | 83 | {PEAK_PCI_VENDOR_ID, PEAK_MPCI_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID,}, |
| 84 | {PEAK_PCI_VENDOR_ID, PEAK_MPCIE_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID,}, | ||
| 85 | {PEAK_PCI_VENDOR_ID, PEAK_PC_104P_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID,}, | ||
| 86 | {PEAK_PCI_VENDOR_ID, PEAK_PCI_104E_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID,}, | ||
| 87 | {PEAK_PCI_VENDOR_ID, PEAK_CPCI_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID,}, | ||
| 79 | #ifdef CONFIG_CAN_PEAK_PCIEC | 88 | #ifdef CONFIG_CAN_PEAK_PCIEC |
| 80 | {PEAK_PCI_VENDOR_ID, PEAK_PCIEC_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID,}, | 89 | {PEAK_PCI_VENDOR_ID, PEAK_PCIEC_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID,}, |
| 81 | #endif | 90 | #endif |
diff --git a/drivers/net/can/usb/peak_usb/pcan_usb.c b/drivers/net/can/usb/peak_usb/pcan_usb.c index 86f26a1ede4c..25723d8ee201 100644 --- a/drivers/net/can/usb/peak_usb/pcan_usb.c +++ b/drivers/net/can/usb/peak_usb/pcan_usb.c | |||
| @@ -519,8 +519,10 @@ static int pcan_usb_decode_error(struct pcan_usb_msg_context *mc, u8 n, | |||
| 519 | mc->pdev->dev.can.state = new_state; | 519 | mc->pdev->dev.can.state = new_state; |
| 520 | 520 | ||
| 521 | if (status_len & PCAN_USB_STATUSLEN_TIMESTAMP) { | 521 | if (status_len & PCAN_USB_STATUSLEN_TIMESTAMP) { |
| 522 | struct skb_shared_hwtstamps *hwts = skb_hwtstamps(skb); | ||
| 523 | |||
| 522 | peak_usb_get_ts_tv(&mc->pdev->time_ref, mc->ts16, &tv); | 524 | peak_usb_get_ts_tv(&mc->pdev->time_ref, mc->ts16, &tv); |
| 523 | skb->tstamp = timeval_to_ktime(tv); | 525 | hwts->hwtstamp = timeval_to_ktime(tv); |
| 524 | } | 526 | } |
| 525 | 527 | ||
| 526 | netif_rx(skb); | 528 | netif_rx(skb); |
| @@ -605,6 +607,7 @@ static int pcan_usb_decode_data(struct pcan_usb_msg_context *mc, u8 status_len) | |||
| 605 | struct sk_buff *skb; | 607 | struct sk_buff *skb; |
| 606 | struct can_frame *cf; | 608 | struct can_frame *cf; |
| 607 | struct timeval tv; | 609 | struct timeval tv; |
| 610 | struct skb_shared_hwtstamps *hwts; | ||
| 608 | 611 | ||
| 609 | skb = alloc_can_skb(mc->netdev, &cf); | 612 | skb = alloc_can_skb(mc->netdev, &cf); |
| 610 | if (!skb) | 613 | if (!skb) |
| @@ -652,7 +655,8 @@ static int pcan_usb_decode_data(struct pcan_usb_msg_context *mc, u8 status_len) | |||
| 652 | 655 | ||
| 653 | /* convert timestamp into kernel time */ | 656 | /* convert timestamp into kernel time */ |
| 654 | peak_usb_get_ts_tv(&mc->pdev->time_ref, mc->ts16, &tv); | 657 | peak_usb_get_ts_tv(&mc->pdev->time_ref, mc->ts16, &tv); |
| 655 | skb->tstamp = timeval_to_ktime(tv); | 658 | hwts = skb_hwtstamps(skb); |
| 659 | hwts->hwtstamp = timeval_to_ktime(tv); | ||
| 656 | 660 | ||
| 657 | /* push the skb */ | 661 | /* push the skb */ |
| 658 | netif_rx(skb); | 662 | netif_rx(skb); |
diff --git a/drivers/net/can/usb/peak_usb/pcan_usb_pro.c b/drivers/net/can/usb/peak_usb/pcan_usb_pro.c index e1626d92511a..30d79bfa5b10 100644 --- a/drivers/net/can/usb/peak_usb/pcan_usb_pro.c +++ b/drivers/net/can/usb/peak_usb/pcan_usb_pro.c | |||
| @@ -532,6 +532,7 @@ static int pcan_usb_pro_handle_canmsg(struct pcan_usb_pro_interface *usb_if, | |||
| 532 | struct can_frame *can_frame; | 532 | struct can_frame *can_frame; |
| 533 | struct sk_buff *skb; | 533 | struct sk_buff *skb; |
| 534 | struct timeval tv; | 534 | struct timeval tv; |
| 535 | struct skb_shared_hwtstamps *hwts; | ||
| 535 | 536 | ||
| 536 | skb = alloc_can_skb(netdev, &can_frame); | 537 | skb = alloc_can_skb(netdev, &can_frame); |
| 537 | if (!skb) | 538 | if (!skb) |
| @@ -549,7 +550,8 @@ static int pcan_usb_pro_handle_canmsg(struct pcan_usb_pro_interface *usb_if, | |||
| 549 | memcpy(can_frame->data, rx->data, can_frame->can_dlc); | 550 | memcpy(can_frame->data, rx->data, can_frame->can_dlc); |
| 550 | 551 | ||
| 551 | peak_usb_get_ts_tv(&usb_if->time_ref, le32_to_cpu(rx->ts32), &tv); | 552 | peak_usb_get_ts_tv(&usb_if->time_ref, le32_to_cpu(rx->ts32), &tv); |
| 552 | skb->tstamp = timeval_to_ktime(tv); | 553 | hwts = skb_hwtstamps(skb); |
| 554 | hwts->hwtstamp = timeval_to_ktime(tv); | ||
| 553 | 555 | ||
| 554 | netif_rx(skb); | 556 | netif_rx(skb); |
| 555 | netdev->stats.rx_packets++; | 557 | netdev->stats.rx_packets++; |
| @@ -570,6 +572,7 @@ static int pcan_usb_pro_handle_error(struct pcan_usb_pro_interface *usb_if, | |||
| 570 | u8 err_mask = 0; | 572 | u8 err_mask = 0; |
| 571 | struct sk_buff *skb; | 573 | struct sk_buff *skb; |
| 572 | struct timeval tv; | 574 | struct timeval tv; |
| 575 | struct skb_shared_hwtstamps *hwts; | ||
| 573 | 576 | ||
| 574 | /* nothing should be sent while in BUS_OFF state */ | 577 | /* nothing should be sent while in BUS_OFF state */ |
| 575 | if (dev->can.state == CAN_STATE_BUS_OFF) | 578 | if (dev->can.state == CAN_STATE_BUS_OFF) |
| @@ -664,7 +667,8 @@ static int pcan_usb_pro_handle_error(struct pcan_usb_pro_interface *usb_if, | |||
| 664 | dev->can.state = new_state; | 667 | dev->can.state = new_state; |
| 665 | 668 | ||
| 666 | peak_usb_get_ts_tv(&usb_if->time_ref, le32_to_cpu(er->ts32), &tv); | 669 | peak_usb_get_ts_tv(&usb_if->time_ref, le32_to_cpu(er->ts32), &tv); |
| 667 | skb->tstamp = timeval_to_ktime(tv); | 670 | hwts = skb_hwtstamps(skb); |
| 671 | hwts->hwtstamp = timeval_to_ktime(tv); | ||
| 668 | netif_rx(skb); | 672 | netif_rx(skb); |
| 669 | netdev->stats.rx_packets++; | 673 | netdev->stats.rx_packets++; |
| 670 | netdev->stats.rx_bytes += can_frame->can_dlc; | 674 | netdev->stats.rx_bytes += can_frame->can_dlc; |
diff --git a/drivers/net/ethernet/8390/ne.c b/drivers/net/ethernet/8390/ne.c index d04911d33b64..47618e505355 100644 --- a/drivers/net/ethernet/8390/ne.c +++ b/drivers/net/ethernet/8390/ne.c | |||
| @@ -813,6 +813,7 @@ static int __init ne_drv_probe(struct platform_device *pdev) | |||
| 813 | dev->irq = irq[this_dev]; | 813 | dev->irq = irq[this_dev]; |
| 814 | dev->mem_end = bad[this_dev]; | 814 | dev->mem_end = bad[this_dev]; |
| 815 | } | 815 | } |
| 816 | SET_NETDEV_DEV(dev, &pdev->dev); | ||
| 816 | err = do_ne_probe(dev); | 817 | err = do_ne_probe(dev); |
| 817 | if (err) { | 818 | if (err) { |
| 818 | free_netdev(dev); | 819 | free_netdev(dev); |
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c index 24220992413f..4833b6a9031c 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c | |||
| @@ -2957,9 +2957,13 @@ netdev_tx_t bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
| 2957 | skb_shinfo(skb)->nr_frags + | 2957 | skb_shinfo(skb)->nr_frags + |
| 2958 | BDS_PER_TX_PKT + | 2958 | BDS_PER_TX_PKT + |
| 2959 | NEXT_CNT_PER_TX_PKT(MAX_BDS_PER_TX_PKT))) { | 2959 | NEXT_CNT_PER_TX_PKT(MAX_BDS_PER_TX_PKT))) { |
| 2960 | bnx2x_fp_qstats(bp, txdata->parent_fp)->driver_xoff++; | 2960 | /* Handle special storage cases separately */ |
| 2961 | netif_tx_stop_queue(txq); | 2961 | if (txdata->tx_ring_size != 0) { |
| 2962 | BNX2X_ERR("BUG! Tx ring full when queue awake!\n"); | 2962 | BNX2X_ERR("BUG! Tx ring full when queue awake!\n"); |
| 2963 | bnx2x_fp_qstats(bp, txdata->parent_fp)->driver_xoff++; | ||
| 2964 | netif_tx_stop_queue(txq); | ||
| 2965 | } | ||
| 2966 | |||
| 2963 | return NETDEV_TX_BUSY; | 2967 | return NETDEV_TX_BUSY; |
| 2964 | } | 2968 | } |
| 2965 | 2969 | ||
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c index c65295dded39..6e5bdd1a31d9 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c | |||
| @@ -1702,7 +1702,7 @@ static int bnx2x_set_eee(struct net_device *dev, struct ethtool_eee *edata) | |||
| 1702 | SHMEM_EEE_ADV_STATUS_SHIFT); | 1702 | SHMEM_EEE_ADV_STATUS_SHIFT); |
| 1703 | if ((advertised != (eee_cfg & SHMEM_EEE_ADV_STATUS_MASK))) { | 1703 | if ((advertised != (eee_cfg & SHMEM_EEE_ADV_STATUS_MASK))) { |
| 1704 | DP(BNX2X_MSG_ETHTOOL, | 1704 | DP(BNX2X_MSG_ETHTOOL, |
| 1705 | "Direct manipulation of EEE advertisment is not supported\n"); | 1705 | "Direct manipulation of EEE advertisement is not supported\n"); |
| 1706 | return -EINVAL; | 1706 | return -EINVAL; |
| 1707 | } | 1707 | } |
| 1708 | 1708 | ||
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c index e2e45ee5df33..f6cfdc6cf20f 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c | |||
| @@ -137,7 +137,16 @@ | |||
| 137 | #define LINK_20GTFD LINK_STATUS_SPEED_AND_DUPLEX_20GTFD | 137 | #define LINK_20GTFD LINK_STATUS_SPEED_AND_DUPLEX_20GTFD |
| 138 | #define LINK_20GXFD LINK_STATUS_SPEED_AND_DUPLEX_20GXFD | 138 | #define LINK_20GXFD LINK_STATUS_SPEED_AND_DUPLEX_20GXFD |
| 139 | 139 | ||
| 140 | 140 | #define LINK_UPDATE_MASK \ | |
| 141 | (LINK_STATUS_SPEED_AND_DUPLEX_MASK | \ | ||
| 142 | LINK_STATUS_LINK_UP | \ | ||
| 143 | LINK_STATUS_PHYSICAL_LINK_FLAG | \ | ||
| 144 | LINK_STATUS_AUTO_NEGOTIATE_COMPLETE | \ | ||
| 145 | LINK_STATUS_RX_FLOW_CONTROL_FLAG_MASK | \ | ||
| 146 | LINK_STATUS_TX_FLOW_CONTROL_FLAG_MASK | \ | ||
| 147 | LINK_STATUS_PARALLEL_DETECTION_FLAG_MASK | \ | ||
| 148 | LINK_STATUS_LINK_PARTNER_SYMMETRIC_PAUSE | \ | ||
| 149 | LINK_STATUS_LINK_PARTNER_ASYMMETRIC_PAUSE) | ||
| 141 | 150 | ||
| 142 | #define SFP_EEPROM_CON_TYPE_ADDR 0x2 | 151 | #define SFP_EEPROM_CON_TYPE_ADDR 0x2 |
| 143 | #define SFP_EEPROM_CON_TYPE_VAL_LC 0x7 | 152 | #define SFP_EEPROM_CON_TYPE_VAL_LC 0x7 |
| @@ -3295,6 +3304,21 @@ static void bnx2x_serdes_deassert(struct bnx2x *bp, u8 port) | |||
| 3295 | DEFAULT_PHY_DEV_ADDR); | 3304 | DEFAULT_PHY_DEV_ADDR); |
| 3296 | } | 3305 | } |
| 3297 | 3306 | ||
| 3307 | static void bnx2x_xgxs_specific_func(struct bnx2x_phy *phy, | ||
| 3308 | struct link_params *params, | ||
| 3309 | u32 action) | ||
| 3310 | { | ||
| 3311 | struct bnx2x *bp = params->bp; | ||
| 3312 | switch (action) { | ||
| 3313 | case PHY_INIT: | ||
| 3314 | /* Set correct devad */ | ||
| 3315 | REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_ST + params->port*0x18, 0); | ||
| 3316 | REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_DEVAD + params->port*0x18, | ||
| 3317 | phy->def_md_devad); | ||
| 3318 | break; | ||
| 3319 | } | ||
| 3320 | } | ||
| 3321 | |||
| 3298 | static void bnx2x_xgxs_deassert(struct link_params *params) | 3322 | static void bnx2x_xgxs_deassert(struct link_params *params) |
| 3299 | { | 3323 | { |
| 3300 | struct bnx2x *bp = params->bp; | 3324 | struct bnx2x *bp = params->bp; |
| @@ -3309,10 +3333,8 @@ static void bnx2x_xgxs_deassert(struct link_params *params) | |||
| 3309 | REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_CLEAR, val); | 3333 | REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_CLEAR, val); |
| 3310 | udelay(500); | 3334 | udelay(500); |
| 3311 | REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_SET, val); | 3335 | REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_SET, val); |
| 3312 | 3336 | bnx2x_xgxs_specific_func(¶ms->phy[INT_PHY], params, | |
| 3313 | REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_ST + port*0x18, 0); | 3337 | PHY_INIT); |
| 3314 | REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_DEVAD + port*0x18, | ||
| 3315 | params->phy[INT_PHY].def_md_devad); | ||
| 3316 | } | 3338 | } |
| 3317 | 3339 | ||
| 3318 | static void bnx2x_calc_ieee_aneg_adv(struct bnx2x_phy *phy, | 3340 | static void bnx2x_calc_ieee_aneg_adv(struct bnx2x_phy *phy, |
| @@ -3545,14 +3567,11 @@ static void bnx2x_warpcore_set_lpi_passthrough(struct bnx2x_phy *phy, | |||
| 3545 | static void bnx2x_warpcore_enable_AN_KR(struct bnx2x_phy *phy, | 3567 | static void bnx2x_warpcore_enable_AN_KR(struct bnx2x_phy *phy, |
| 3546 | struct link_params *params, | 3568 | struct link_params *params, |
| 3547 | struct link_vars *vars) { | 3569 | struct link_vars *vars) { |
| 3548 | u16 val16 = 0, lane, i; | 3570 | u16 lane, i, cl72_ctrl, an_adv = 0; |
| 3571 | u16 ucode_ver; | ||
| 3549 | struct bnx2x *bp = params->bp; | 3572 | struct bnx2x *bp = params->bp; |
| 3550 | static struct bnx2x_reg_set reg_set[] = { | 3573 | static struct bnx2x_reg_set reg_set[] = { |
| 3551 | {MDIO_WC_DEVAD, MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X2, 0x7}, | 3574 | {MDIO_WC_DEVAD, MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X2, 0x7}, |
| 3552 | {MDIO_AN_DEVAD, MDIO_WC_REG_PAR_DET_10G_CTRL, 0}, | ||
| 3553 | {MDIO_WC_DEVAD, MDIO_WC_REG_CL72_USERB0_CL72_MISC1_CONTROL, 0}, | ||
| 3554 | {MDIO_WC_DEVAD, MDIO_WC_REG_XGXSBLK1_LANECTRL0, 0xff}, | ||
| 3555 | {MDIO_WC_DEVAD, MDIO_WC_REG_XGXSBLK1_LANECTRL1, 0x5555}, | ||
| 3556 | {MDIO_PMA_DEVAD, MDIO_WC_REG_IEEE0BLK_AUTONEGNP, 0x0}, | 3575 | {MDIO_PMA_DEVAD, MDIO_WC_REG_IEEE0BLK_AUTONEGNP, 0x0}, |
| 3557 | {MDIO_WC_DEVAD, MDIO_WC_REG_RX66_CONTROL, 0x7415}, | 3576 | {MDIO_WC_DEVAD, MDIO_WC_REG_RX66_CONTROL, 0x7415}, |
| 3558 | {MDIO_WC_DEVAD, MDIO_WC_REG_SERDESDIGITAL_MISC2, 0x6190}, | 3577 | {MDIO_WC_DEVAD, MDIO_WC_REG_SERDESDIGITAL_MISC2, 0x6190}, |
| @@ -3565,12 +3584,19 @@ static void bnx2x_warpcore_enable_AN_KR(struct bnx2x_phy *phy, | |||
| 3565 | bnx2x_cl45_write(bp, phy, reg_set[i].devad, reg_set[i].reg, | 3584 | bnx2x_cl45_write(bp, phy, reg_set[i].devad, reg_set[i].reg, |
| 3566 | reg_set[i].val); | 3585 | reg_set[i].val); |
| 3567 | 3586 | ||
| 3587 | bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD, | ||
| 3588 | MDIO_WC_REG_CL72_USERB0_CL72_MISC1_CONTROL, &cl72_ctrl); | ||
| 3589 | cl72_ctrl &= 0xf8ff; | ||
| 3590 | cl72_ctrl |= 0x3800; | ||
| 3591 | bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, | ||
| 3592 | MDIO_WC_REG_CL72_USERB0_CL72_MISC1_CONTROL, cl72_ctrl); | ||
| 3593 | |||
| 3568 | /* Check adding advertisement for 1G KX */ | 3594 | /* Check adding advertisement for 1G KX */ |
| 3569 | if (((vars->line_speed == SPEED_AUTO_NEG) && | 3595 | if (((vars->line_speed == SPEED_AUTO_NEG) && |
| 3570 | (phy->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_1G)) || | 3596 | (phy->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_1G)) || |
| 3571 | (vars->line_speed == SPEED_1000)) { | 3597 | (vars->line_speed == SPEED_1000)) { |
| 3572 | u32 addr = MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X2; | 3598 | u32 addr = MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X2; |
| 3573 | val16 |= (1<<5); | 3599 | an_adv |= (1<<5); |
| 3574 | 3600 | ||
| 3575 | /* Enable CL37 1G Parallel Detect */ | 3601 | /* Enable CL37 1G Parallel Detect */ |
| 3576 | bnx2x_cl45_read_or_write(bp, phy, MDIO_WC_DEVAD, addr, 0x1); | 3602 | bnx2x_cl45_read_or_write(bp, phy, MDIO_WC_DEVAD, addr, 0x1); |
| @@ -3580,11 +3606,14 @@ static void bnx2x_warpcore_enable_AN_KR(struct bnx2x_phy *phy, | |||
| 3580 | (phy->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)) || | 3606 | (phy->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)) || |
| 3581 | (vars->line_speed == SPEED_10000)) { | 3607 | (vars->line_speed == SPEED_10000)) { |
| 3582 | /* Check adding advertisement for 10G KR */ | 3608 | /* Check adding advertisement for 10G KR */ |
| 3583 | val16 |= (1<<7); | 3609 | an_adv |= (1<<7); |
| 3584 | /* Enable 10G Parallel Detect */ | 3610 | /* Enable 10G Parallel Detect */ |
| 3611 | CL22_WR_OVER_CL45(bp, phy, MDIO_REG_BANK_AER_BLOCK, | ||
| 3612 | MDIO_AER_BLOCK_AER_REG, 0); | ||
| 3613 | |||
| 3585 | bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, | 3614 | bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, |
| 3586 | MDIO_WC_REG_PAR_DET_10G_CTRL, 1); | 3615 | MDIO_WC_REG_PAR_DET_10G_CTRL, 1); |
| 3587 | 3616 | bnx2x_set_aer_mmd(params, phy); | |
| 3588 | DP(NETIF_MSG_LINK, "Advertize 10G\n"); | 3617 | DP(NETIF_MSG_LINK, "Advertize 10G\n"); |
| 3589 | } | 3618 | } |
| 3590 | 3619 | ||
| @@ -3604,7 +3633,7 @@ static void bnx2x_warpcore_enable_AN_KR(struct bnx2x_phy *phy, | |||
| 3604 | 3633 | ||
| 3605 | /* Advertised speeds */ | 3634 | /* Advertised speeds */ |
| 3606 | bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, | 3635 | bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, |
| 3607 | MDIO_WC_REG_AN_IEEE1BLK_AN_ADVERTISEMENT1, val16); | 3636 | MDIO_WC_REG_AN_IEEE1BLK_AN_ADVERTISEMENT1, an_adv); |
| 3608 | 3637 | ||
| 3609 | /* Advertised and set FEC (Forward Error Correction) */ | 3638 | /* Advertised and set FEC (Forward Error Correction) */ |
| 3610 | bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, | 3639 | bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, |
| @@ -3628,9 +3657,10 @@ static void bnx2x_warpcore_enable_AN_KR(struct bnx2x_phy *phy, | |||
| 3628 | /* Set KR Autoneg Work-Around flag for Warpcore version older than D108 | 3657 | /* Set KR Autoneg Work-Around flag for Warpcore version older than D108 |
| 3629 | */ | 3658 | */ |
| 3630 | bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD, | 3659 | bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD, |
| 3631 | MDIO_WC_REG_UC_INFO_B1_VERSION, &val16); | 3660 | MDIO_WC_REG_UC_INFO_B1_VERSION, &ucode_ver); |
| 3632 | if (val16 < 0xd108) { | 3661 | if (ucode_ver < 0xd108) { |
| 3633 | DP(NETIF_MSG_LINK, "Enable AN KR work-around\n"); | 3662 | DP(NETIF_MSG_LINK, "Enable AN KR work-around. WC ver:0x%x\n", |
| 3663 | ucode_ver); | ||
| 3634 | vars->rx_tx_asic_rst = MAX_KR_LINK_RETRY; | 3664 | vars->rx_tx_asic_rst = MAX_KR_LINK_RETRY; |
| 3635 | } | 3665 | } |
| 3636 | bnx2x_cl45_read_or_write(bp, phy, MDIO_WC_DEVAD, | 3666 | bnx2x_cl45_read_or_write(bp, phy, MDIO_WC_DEVAD, |
| @@ -3651,21 +3681,16 @@ static void bnx2x_warpcore_set_10G_KR(struct bnx2x_phy *phy, | |||
| 3651 | struct link_vars *vars) | 3681 | struct link_vars *vars) |
| 3652 | { | 3682 | { |
| 3653 | struct bnx2x *bp = params->bp; | 3683 | struct bnx2x *bp = params->bp; |
| 3654 | u16 i; | 3684 | u16 val16, i, lane; |
| 3655 | static struct bnx2x_reg_set reg_set[] = { | 3685 | static struct bnx2x_reg_set reg_set[] = { |
| 3656 | /* Disable Autoneg */ | 3686 | /* Disable Autoneg */ |
| 3657 | {MDIO_WC_DEVAD, MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X2, 0x7}, | 3687 | {MDIO_WC_DEVAD, MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X2, 0x7}, |
| 3658 | {MDIO_AN_DEVAD, MDIO_WC_REG_PAR_DET_10G_CTRL, 0}, | ||
| 3659 | {MDIO_WC_DEVAD, MDIO_WC_REG_CL72_USERB0_CL72_MISC1_CONTROL, | 3688 | {MDIO_WC_DEVAD, MDIO_WC_REG_CL72_USERB0_CL72_MISC1_CONTROL, |
| 3660 | 0x3f00}, | 3689 | 0x3f00}, |
| 3661 | {MDIO_AN_DEVAD, MDIO_WC_REG_AN_IEEE1BLK_AN_ADVERTISEMENT1, 0}, | 3690 | {MDIO_AN_DEVAD, MDIO_WC_REG_AN_IEEE1BLK_AN_ADVERTISEMENT1, 0}, |
| 3662 | {MDIO_AN_DEVAD, MDIO_WC_REG_IEEE0BLK_MIICNTL, 0x0}, | 3691 | {MDIO_AN_DEVAD, MDIO_WC_REG_IEEE0BLK_MIICNTL, 0x0}, |
| 3663 | {MDIO_WC_DEVAD, MDIO_WC_REG_DIGITAL3_UP1, 0x1}, | 3692 | {MDIO_WC_DEVAD, MDIO_WC_REG_DIGITAL3_UP1, 0x1}, |
| 3664 | {MDIO_WC_DEVAD, MDIO_WC_REG_DIGITAL5_MISC7, 0xa}, | 3693 | {MDIO_WC_DEVAD, MDIO_WC_REG_DIGITAL5_MISC7, 0xa}, |
| 3665 | /* Disable CL36 PCS Tx */ | ||
| 3666 | {MDIO_WC_DEVAD, MDIO_WC_REG_XGXSBLK1_LANECTRL0, 0x0}, | ||
| 3667 | /* Double Wide Single Data Rate @ pll rate */ | ||
| 3668 | {MDIO_WC_DEVAD, MDIO_WC_REG_XGXSBLK1_LANECTRL1, 0xFFFF}, | ||
| 3669 | /* Leave cl72 training enable, needed for KR */ | 3694 | /* Leave cl72 training enable, needed for KR */ |
| 3670 | {MDIO_PMA_DEVAD, | 3695 | {MDIO_PMA_DEVAD, |
| 3671 | MDIO_WC_REG_PMD_IEEE9BLK_TENGBASE_KR_PMD_CONTROL_REGISTER_150, | 3696 | MDIO_WC_REG_PMD_IEEE9BLK_TENGBASE_KR_PMD_CONTROL_REGISTER_150, |
| @@ -3676,11 +3701,24 @@ static void bnx2x_warpcore_set_10G_KR(struct bnx2x_phy *phy, | |||
| 3676 | bnx2x_cl45_write(bp, phy, reg_set[i].devad, reg_set[i].reg, | 3701 | bnx2x_cl45_write(bp, phy, reg_set[i].devad, reg_set[i].reg, |
| 3677 | reg_set[i].val); | 3702 | reg_set[i].val); |
| 3678 | 3703 | ||
| 3679 | /* Leave CL72 enabled */ | 3704 | lane = bnx2x_get_warpcore_lane(phy, params); |
| 3680 | bnx2x_cl45_read_or_write(bp, phy, MDIO_WC_DEVAD, | 3705 | /* Global registers */ |
| 3681 | MDIO_WC_REG_CL72_USERB0_CL72_MISC1_CONTROL, | 3706 | CL22_WR_OVER_CL45(bp, phy, MDIO_REG_BANK_AER_BLOCK, |
| 3682 | 0x3800); | 3707 | MDIO_AER_BLOCK_AER_REG, 0); |
| 3708 | /* Disable CL36 PCS Tx */ | ||
| 3709 | bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD, | ||
| 3710 | MDIO_WC_REG_XGXSBLK1_LANECTRL0, &val16); | ||
| 3711 | val16 &= ~(0x0011 << lane); | ||
| 3712 | bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, | ||
| 3713 | MDIO_WC_REG_XGXSBLK1_LANECTRL0, val16); | ||
| 3683 | 3714 | ||
| 3715 | bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD, | ||
| 3716 | MDIO_WC_REG_XGXSBLK1_LANECTRL1, &val16); | ||
| 3717 | val16 |= (0x0303 << (lane << 1)); | ||
| 3718 | bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, | ||
| 3719 | MDIO_WC_REG_XGXSBLK1_LANECTRL1, val16); | ||
| 3720 | /* Restore AER */ | ||
| 3721 | bnx2x_set_aer_mmd(params, phy); | ||
| 3684 | /* Set speed via PMA/PMD register */ | 3722 | /* Set speed via PMA/PMD register */ |
| 3685 | bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, | 3723 | bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, |
| 3686 | MDIO_WC_REG_IEEE0BLK_MIICNTL, 0x2040); | 3724 | MDIO_WC_REG_IEEE0BLK_MIICNTL, 0x2040); |
| @@ -4303,7 +4341,7 @@ static void bnx2x_warpcore_link_reset(struct bnx2x_phy *phy, | |||
| 4303 | struct link_params *params) | 4341 | struct link_params *params) |
| 4304 | { | 4342 | { |
| 4305 | struct bnx2x *bp = params->bp; | 4343 | struct bnx2x *bp = params->bp; |
| 4306 | u16 val16; | 4344 | u16 val16, lane; |
| 4307 | bnx2x_sfp_e3_set_transmitter(params, phy, 0); | 4345 | bnx2x_sfp_e3_set_transmitter(params, phy, 0); |
| 4308 | bnx2x_set_mdio_clk(bp, params->chip_id, params->port); | 4346 | bnx2x_set_mdio_clk(bp, params->chip_id, params->port); |
| 4309 | bnx2x_set_aer_mmd(params, phy); | 4347 | bnx2x_set_aer_mmd(params, phy); |
| @@ -4340,6 +4378,30 @@ static void bnx2x_warpcore_link_reset(struct bnx2x_phy *phy, | |||
| 4340 | MDIO_WC_REG_XGXSBLK1_LANECTRL2, | 4378 | MDIO_WC_REG_XGXSBLK1_LANECTRL2, |
| 4341 | val16 & 0xff00); | 4379 | val16 & 0xff00); |
| 4342 | 4380 | ||
| 4381 | lane = bnx2x_get_warpcore_lane(phy, params); | ||
| 4382 | /* Disable CL36 PCS Tx */ | ||
| 4383 | bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD, | ||
| 4384 | MDIO_WC_REG_XGXSBLK1_LANECTRL0, &val16); | ||
| 4385 | val16 |= (0x11 << lane); | ||
| 4386 | if (phy->flags & FLAGS_WC_DUAL_MODE) | ||
| 4387 | val16 |= (0x22 << lane); | ||
| 4388 | bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, | ||
| 4389 | MDIO_WC_REG_XGXSBLK1_LANECTRL0, val16); | ||
| 4390 | |||
| 4391 | bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD, | ||
| 4392 | MDIO_WC_REG_XGXSBLK1_LANECTRL1, &val16); | ||
| 4393 | val16 &= ~(0x0303 << (lane << 1)); | ||
| 4394 | val16 |= (0x0101 << (lane << 1)); | ||
| 4395 | if (phy->flags & FLAGS_WC_DUAL_MODE) { | ||
| 4396 | val16 &= ~(0x0c0c << (lane << 1)); | ||
| 4397 | val16 |= (0x0404 << (lane << 1)); | ||
| 4398 | } | ||
| 4399 | |||
| 4400 | bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, | ||
| 4401 | MDIO_WC_REG_XGXSBLK1_LANECTRL1, val16); | ||
| 4402 | /* Restore AER */ | ||
| 4403 | bnx2x_set_aer_mmd(params, phy); | ||
| 4404 | |||
| 4343 | } | 4405 | } |
| 4344 | 4406 | ||
| 4345 | static void bnx2x_set_warpcore_loopback(struct bnx2x_phy *phy, | 4407 | static void bnx2x_set_warpcore_loopback(struct bnx2x_phy *phy, |
| @@ -6296,15 +6358,7 @@ static int bnx2x_update_link_down(struct link_params *params, | |||
| 6296 | vars->mac_type = MAC_TYPE_NONE; | 6358 | vars->mac_type = MAC_TYPE_NONE; |
| 6297 | 6359 | ||
| 6298 | /* Update shared memory */ | 6360 | /* Update shared memory */ |
| 6299 | vars->link_status &= ~(LINK_STATUS_SPEED_AND_DUPLEX_MASK | | 6361 | vars->link_status &= ~LINK_UPDATE_MASK; |
| 6300 | LINK_STATUS_LINK_UP | | ||
| 6301 | LINK_STATUS_PHYSICAL_LINK_FLAG | | ||
| 6302 | LINK_STATUS_AUTO_NEGOTIATE_COMPLETE | | ||
| 6303 | LINK_STATUS_RX_FLOW_CONTROL_FLAG_MASK | | ||
| 6304 | LINK_STATUS_TX_FLOW_CONTROL_FLAG_MASK | | ||
| 6305 | LINK_STATUS_PARALLEL_DETECTION_FLAG_MASK | | ||
| 6306 | LINK_STATUS_LINK_PARTNER_SYMMETRIC_PAUSE | | ||
| 6307 | LINK_STATUS_LINK_PARTNER_ASYMMETRIC_PAUSE); | ||
| 6308 | vars->line_speed = 0; | 6362 | vars->line_speed = 0; |
| 6309 | bnx2x_update_mng(params, vars->link_status); | 6363 | bnx2x_update_mng(params, vars->link_status); |
| 6310 | 6364 | ||
| @@ -6452,6 +6506,7 @@ int bnx2x_link_update(struct link_params *params, struct link_vars *vars) | |||
| 6452 | u16 ext_phy_line_speed = 0, prev_line_speed = vars->line_speed; | 6506 | u16 ext_phy_line_speed = 0, prev_line_speed = vars->line_speed; |
| 6453 | u8 active_external_phy = INT_PHY; | 6507 | u8 active_external_phy = INT_PHY; |
| 6454 | vars->phy_flags &= ~PHY_HALF_OPEN_CONN_FLAG; | 6508 | vars->phy_flags &= ~PHY_HALF_OPEN_CONN_FLAG; |
| 6509 | vars->link_status &= ~LINK_UPDATE_MASK; | ||
| 6455 | for (phy_index = INT_PHY; phy_index < params->num_phys; | 6510 | for (phy_index = INT_PHY; phy_index < params->num_phys; |
| 6456 | phy_index++) { | 6511 | phy_index++) { |
| 6457 | phy_vars[phy_index].flow_ctrl = 0; | 6512 | phy_vars[phy_index].flow_ctrl = 0; |
| @@ -7579,7 +7634,7 @@ static void bnx2x_warpcore_power_module(struct link_params *params, | |||
| 7579 | static int bnx2x_warpcore_read_sfp_module_eeprom(struct bnx2x_phy *phy, | 7634 | static int bnx2x_warpcore_read_sfp_module_eeprom(struct bnx2x_phy *phy, |
| 7580 | struct link_params *params, | 7635 | struct link_params *params, |
| 7581 | u16 addr, u8 byte_cnt, | 7636 | u16 addr, u8 byte_cnt, |
| 7582 | u8 *o_buf) | 7637 | u8 *o_buf, u8 is_init) |
| 7583 | { | 7638 | { |
| 7584 | int rc = 0; | 7639 | int rc = 0; |
| 7585 | u8 i, j = 0, cnt = 0; | 7640 | u8 i, j = 0, cnt = 0; |
| @@ -7596,10 +7651,10 @@ static int bnx2x_warpcore_read_sfp_module_eeprom(struct bnx2x_phy *phy, | |||
| 7596 | /* 4 byte aligned address */ | 7651 | /* 4 byte aligned address */ |
| 7597 | addr32 = addr & (~0x3); | 7652 | addr32 = addr & (~0x3); |
| 7598 | do { | 7653 | do { |
| 7599 | if (cnt == I2C_WA_PWR_ITER) { | 7654 | if ((!is_init) && (cnt == I2C_WA_PWR_ITER)) { |
| 7600 | bnx2x_warpcore_power_module(params, phy, 0); | 7655 | bnx2x_warpcore_power_module(params, phy, 0); |
| 7601 | /* Note that 100us are not enough here */ | 7656 | /* Note that 100us are not enough here */ |
| 7602 | usleep_range(1000,1000); | 7657 | usleep_range(1000, 2000); |
| 7603 | bnx2x_warpcore_power_module(params, phy, 1); | 7658 | bnx2x_warpcore_power_module(params, phy, 1); |
| 7604 | } | 7659 | } |
| 7605 | rc = bnx2x_bsc_read(params, phy, 0xa0, addr32, 0, byte_cnt, | 7660 | rc = bnx2x_bsc_read(params, phy, 0xa0, addr32, 0, byte_cnt, |
| @@ -7719,7 +7774,7 @@ int bnx2x_read_sfp_module_eeprom(struct bnx2x_phy *phy, | |||
| 7719 | break; | 7774 | break; |
| 7720 | case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT: | 7775 | case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT: |
| 7721 | rc = bnx2x_warpcore_read_sfp_module_eeprom(phy, params, addr, | 7776 | rc = bnx2x_warpcore_read_sfp_module_eeprom(phy, params, addr, |
| 7722 | byte_cnt, o_buf); | 7777 | byte_cnt, o_buf, 0); |
| 7723 | break; | 7778 | break; |
| 7724 | } | 7779 | } |
| 7725 | return rc; | 7780 | return rc; |
| @@ -7923,6 +7978,7 @@ static int bnx2x_wait_for_sfp_module_initialized(struct bnx2x_phy *phy, | |||
| 7923 | 7978 | ||
| 7924 | { | 7979 | { |
| 7925 | u8 val; | 7980 | u8 val; |
| 7981 | int rc; | ||
| 7926 | struct bnx2x *bp = params->bp; | 7982 | struct bnx2x *bp = params->bp; |
| 7927 | u16 timeout; | 7983 | u16 timeout; |
| 7928 | /* Initialization time after hot-plug may take up to 300ms for | 7984 | /* Initialization time after hot-plug may take up to 300ms for |
| @@ -7930,8 +7986,14 @@ static int bnx2x_wait_for_sfp_module_initialized(struct bnx2x_phy *phy, | |||
| 7930 | */ | 7986 | */ |
| 7931 | 7987 | ||
| 7932 | for (timeout = 0; timeout < 60; timeout++) { | 7988 | for (timeout = 0; timeout < 60; timeout++) { |
| 7933 | if (bnx2x_read_sfp_module_eeprom(phy, params, 1, 1, &val) | 7989 | if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) |
| 7934 | == 0) { | 7990 | rc = bnx2x_warpcore_read_sfp_module_eeprom(phy, |
| 7991 | params, 1, | ||
| 7992 | 1, &val, 1); | ||
| 7993 | else | ||
| 7994 | rc = bnx2x_read_sfp_module_eeprom(phy, params, 1, 1, | ||
| 7995 | &val); | ||
| 7996 | if (rc == 0) { | ||
| 7935 | DP(NETIF_MSG_LINK, | 7997 | DP(NETIF_MSG_LINK, |
| 7936 | "SFP+ module initialization took %d ms\n", | 7998 | "SFP+ module initialization took %d ms\n", |
| 7937 | timeout * 5); | 7999 | timeout * 5); |
| @@ -7939,7 +8001,8 @@ static int bnx2x_wait_for_sfp_module_initialized(struct bnx2x_phy *phy, | |||
| 7939 | } | 8001 | } |
| 7940 | usleep_range(5000, 10000); | 8002 | usleep_range(5000, 10000); |
| 7941 | } | 8003 | } |
| 7942 | return -EINVAL; | 8004 | rc = bnx2x_read_sfp_module_eeprom(phy, params, 1, 1, &val); |
| 8005 | return rc; | ||
| 7943 | } | 8006 | } |
| 7944 | 8007 | ||
| 7945 | static void bnx2x_8727_power_module(struct bnx2x *bp, | 8008 | static void bnx2x_8727_power_module(struct bnx2x *bp, |
| @@ -9878,7 +9941,7 @@ static int bnx2x_848x3_config_init(struct bnx2x_phy *phy, | |||
| 9878 | else | 9941 | else |
| 9879 | rc = bnx2x_8483x_disable_eee(phy, params, vars); | 9942 | rc = bnx2x_8483x_disable_eee(phy, params, vars); |
| 9880 | if (rc) { | 9943 | if (rc) { |
| 9881 | DP(NETIF_MSG_LINK, "Failed to set EEE advertisment\n"); | 9944 | DP(NETIF_MSG_LINK, "Failed to set EEE advertisement\n"); |
| 9882 | return rc; | 9945 | return rc; |
| 9883 | } | 9946 | } |
| 9884 | } else { | 9947 | } else { |
| @@ -10993,7 +11056,7 @@ static struct bnx2x_phy phy_xgxs = { | |||
| 10993 | .format_fw_ver = (format_fw_ver_t)NULL, | 11056 | .format_fw_ver = (format_fw_ver_t)NULL, |
| 10994 | .hw_reset = (hw_reset_t)NULL, | 11057 | .hw_reset = (hw_reset_t)NULL, |
| 10995 | .set_link_led = (set_link_led_t)NULL, | 11058 | .set_link_led = (set_link_led_t)NULL, |
| 10996 | .phy_specific_func = (phy_specific_func_t)NULL | 11059 | .phy_specific_func = (phy_specific_func_t)bnx2x_xgxs_specific_func |
| 10997 | }; | 11060 | }; |
| 10998 | static struct bnx2x_phy phy_warpcore = { | 11061 | static struct bnx2x_phy phy_warpcore = { |
| 10999 | .type = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT, | 11062 | .type = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT, |
| @@ -11465,6 +11528,11 @@ static int bnx2x_populate_int_phy(struct bnx2x *bp, u32 shmem_base, u8 port, | |||
| 11465 | phy->media_type = ETH_PHY_BASE_T; | 11528 | phy->media_type = ETH_PHY_BASE_T; |
| 11466 | break; | 11529 | break; |
| 11467 | case PORT_HW_CFG_NET_SERDES_IF_XFI: | 11530 | case PORT_HW_CFG_NET_SERDES_IF_XFI: |
| 11531 | phy->supported &= (SUPPORTED_1000baseT_Full | | ||
| 11532 | SUPPORTED_10000baseT_Full | | ||
| 11533 | SUPPORTED_FIBRE | | ||
| 11534 | SUPPORTED_Pause | | ||
| 11535 | SUPPORTED_Asym_Pause); | ||
| 11468 | phy->media_type = ETH_PHY_XFP_FIBER; | 11536 | phy->media_type = ETH_PHY_XFP_FIBER; |
| 11469 | break; | 11537 | break; |
| 11470 | case PORT_HW_CFG_NET_SERDES_IF_SFI: | 11538 | case PORT_HW_CFG_NET_SERDES_IF_SFI: |
| @@ -12919,7 +12987,7 @@ static u8 bnx2x_analyze_link_error(struct link_params *params, | |||
| 12919 | DP(NETIF_MSG_LINK, "Analyze TX Fault\n"); | 12987 | DP(NETIF_MSG_LINK, "Analyze TX Fault\n"); |
| 12920 | break; | 12988 | break; |
| 12921 | default: | 12989 | default: |
| 12922 | DP(NETIF_MSG_LINK, "Analyze UNKOWN\n"); | 12990 | DP(NETIF_MSG_LINK, "Analyze UNKNOWN\n"); |
| 12923 | } | 12991 | } |
| 12924 | DP(NETIF_MSG_LINK, "Link changed:[%x %x]->%x\n", vars->link_up, | 12992 | DP(NETIF_MSG_LINK, "Link changed:[%x %x]->%x\n", vars->link_up, |
| 12925 | old_status, status); | 12993 | old_status, status); |
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c index d5648fc666bd..01611b33a93d 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c | |||
| @@ -6794,8 +6794,9 @@ static int bnx2x_init_hw_port(struct bnx2x *bp) | |||
| 6794 | 6794 | ||
| 6795 | bnx2x_init_block(bp, BLOCK_DORQ, init_phase); | 6795 | bnx2x_init_block(bp, BLOCK_DORQ, init_phase); |
| 6796 | 6796 | ||
| 6797 | bnx2x_init_block(bp, BLOCK_BRB1, init_phase); | ||
| 6798 | |||
| 6797 | if (CHIP_IS_E1(bp) || CHIP_IS_E1H(bp)) { | 6799 | if (CHIP_IS_E1(bp) || CHIP_IS_E1H(bp)) { |
| 6798 | bnx2x_init_block(bp, BLOCK_BRB1, init_phase); | ||
| 6799 | 6800 | ||
| 6800 | if (IS_MF(bp)) | 6801 | if (IS_MF(bp)) |
| 6801 | low = ((bp->flags & ONE_PORT_FLAG) ? 160 : 246); | 6802 | low = ((bp->flags & ONE_PORT_FLAG) ? 160 : 246); |
| @@ -9544,10 +9545,13 @@ static int __devinit bnx2x_prev_unload_common(struct bnx2x *bp) | |||
| 9544 | */ | 9545 | */ |
| 9545 | static void __devinit bnx2x_prev_interrupted_dmae(struct bnx2x *bp) | 9546 | static void __devinit bnx2x_prev_interrupted_dmae(struct bnx2x *bp) |
| 9546 | { | 9547 | { |
| 9547 | u32 val = REG_RD(bp, PGLUE_B_REG_PGLUE_B_INT_STS); | 9548 | if (!CHIP_IS_E1x(bp)) { |
| 9548 | if (val & PGLUE_B_PGLUE_B_INT_STS_REG_WAS_ERROR_ATTN) { | 9549 | u32 val = REG_RD(bp, PGLUE_B_REG_PGLUE_B_INT_STS); |
| 9549 | BNX2X_ERR("was error bit was found to be set in pglueb upon startup. Clearing"); | 9550 | if (val & PGLUE_B_PGLUE_B_INT_STS_REG_WAS_ERROR_ATTN) { |
| 9550 | REG_WR(bp, PGLUE_B_REG_WAS_ERROR_PF_7_0_CLR, 1 << BP_FUNC(bp)); | 9551 | BNX2X_ERR("was error bit was found to be set in pglueb upon startup. Clearing"); |
| 9552 | REG_WR(bp, PGLUE_B_REG_WAS_ERROR_PF_7_0_CLR, | ||
| 9553 | 1 << BP_FUNC(bp)); | ||
| 9554 | } | ||
| 9551 | } | 9555 | } |
| 9552 | } | 9556 | } |
| 9553 | 9557 | ||
| @@ -11902,7 +11906,15 @@ static int __devinit bnx2x_init_one(struct pci_dev *pdev, | |||
| 11902 | /* disable FCOE L2 queue for E1x */ | 11906 | /* disable FCOE L2 queue for E1x */ |
| 11903 | if (CHIP_IS_E1x(bp)) | 11907 | if (CHIP_IS_E1x(bp)) |
| 11904 | bp->flags |= NO_FCOE_FLAG; | 11908 | bp->flags |= NO_FCOE_FLAG; |
| 11905 | 11909 | /* disable FCOE for 57840 device, until FW supports it */ | |
| 11910 | switch (ent->driver_data) { | ||
| 11911 | case BCM57840_O: | ||
| 11912 | case BCM57840_4_10: | ||
| 11913 | case BCM57840_2_20: | ||
| 11914 | case BCM57840_MFO: | ||
| 11915 | case BCM57840_MF: | ||
| 11916 | bp->flags |= NO_FCOE_FLAG; | ||
| 11917 | } | ||
| 11906 | #endif | 11918 | #endif |
| 11907 | 11919 | ||
| 11908 | 11920 | ||
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.c index 71971a161bd1..614981c02264 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.c | |||
| @@ -126,7 +126,7 @@ static inline int bnx2x_exe_queue_add(struct bnx2x *bp, | |||
| 126 | /* Check if this request is ok */ | 126 | /* Check if this request is ok */ |
| 127 | rc = o->validate(bp, o->owner, elem); | 127 | rc = o->validate(bp, o->owner, elem); |
| 128 | if (rc) { | 128 | if (rc) { |
| 129 | BNX2X_ERR("Preamble failed: %d\n", rc); | 129 | DP(BNX2X_MSG_SP, "Preamble failed: %d\n", rc); |
| 130 | goto free_and_exit; | 130 | goto free_and_exit; |
| 131 | } | 131 | } |
| 132 | } | 132 | } |
diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h b/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h index a4da893ac1e1..378988b5709a 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h +++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h | |||
| @@ -251,6 +251,8 @@ struct adapter_params { | |||
| 251 | unsigned char rev; /* chip revision */ | 251 | unsigned char rev; /* chip revision */ |
| 252 | unsigned char offload; | 252 | unsigned char offload; |
| 253 | 253 | ||
| 254 | unsigned char bypass; | ||
| 255 | |||
| 254 | unsigned int ofldq_wr_cred; | 256 | unsigned int ofldq_wr_cred; |
| 255 | }; | 257 | }; |
| 256 | 258 | ||
| @@ -642,6 +644,23 @@ extern int dbfifo_int_thresh; | |||
| 642 | #define for_each_port(adapter, iter) \ | 644 | #define for_each_port(adapter, iter) \ |
| 643 | for (iter = 0; iter < (adapter)->params.nports; ++iter) | 645 | for (iter = 0; iter < (adapter)->params.nports; ++iter) |
| 644 | 646 | ||
| 647 | static inline int is_bypass(struct adapter *adap) | ||
| 648 | { | ||
| 649 | return adap->params.bypass; | ||
| 650 | } | ||
| 651 | |||
| 652 | static inline int is_bypass_device(int device) | ||
| 653 | { | ||
| 654 | /* this should be set based upon device capabilities */ | ||
| 655 | switch (device) { | ||
| 656 | case 0x440b: | ||
| 657 | case 0x440c: | ||
| 658 | return 1; | ||
| 659 | default: | ||
| 660 | return 0; | ||
| 661 | } | ||
| 662 | } | ||
| 663 | |||
| 645 | static inline unsigned int core_ticks_per_usec(const struct adapter *adap) | 664 | static inline unsigned int core_ticks_per_usec(const struct adapter *adap) |
| 646 | { | 665 | { |
| 647 | return adap->params.vpd.cclk / 1000; | 666 | return adap->params.vpd.cclk / 1000; |
diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c index 604f4f87f550..0df1284df497 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c +++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c | |||
| @@ -3416,16 +3416,6 @@ static int adap_init0_config(struct adapter *adapter, int reset) | |||
| 3416 | finicsum, cfcsum); | 3416 | finicsum, cfcsum); |
| 3417 | 3417 | ||
| 3418 | /* | 3418 | /* |
| 3419 | * If we're a pure NIC driver then disable all offloading facilities. | ||
| 3420 | * This will allow the firmware to optimize aspects of the hardware | ||
| 3421 | * configuration which will result in improved performance. | ||
| 3422 | */ | ||
| 3423 | caps_cmd.ofldcaps = 0; | ||
| 3424 | caps_cmd.iscsicaps = 0; | ||
| 3425 | caps_cmd.rdmacaps = 0; | ||
| 3426 | caps_cmd.fcoecaps = 0; | ||
| 3427 | |||
| 3428 | /* | ||
| 3429 | * And now tell the firmware to use the configuration we just loaded. | 3419 | * And now tell the firmware to use the configuration we just loaded. |
| 3430 | */ | 3420 | */ |
| 3431 | caps_cmd.op_to_write = | 3421 | caps_cmd.op_to_write = |
| @@ -3513,18 +3503,6 @@ static int adap_init0_no_config(struct adapter *adapter, int reset) | |||
| 3513 | if (ret < 0) | 3503 | if (ret < 0) |
| 3514 | goto bye; | 3504 | goto bye; |
| 3515 | 3505 | ||
| 3516 | #ifndef CONFIG_CHELSIO_T4_OFFLOAD | ||
| 3517 | /* | ||
| 3518 | * If we're a pure NIC driver then disable all offloading facilities. | ||
| 3519 | * This will allow the firmware to optimize aspects of the hardware | ||
| 3520 | * configuration which will result in improved performance. | ||
| 3521 | */ | ||
| 3522 | caps_cmd.ofldcaps = 0; | ||
| 3523 | caps_cmd.iscsicaps = 0; | ||
| 3524 | caps_cmd.rdmacaps = 0; | ||
| 3525 | caps_cmd.fcoecaps = 0; | ||
| 3526 | #endif | ||
| 3527 | |||
| 3528 | if (caps_cmd.niccaps & htons(FW_CAPS_CONFIG_NIC_VM)) { | 3506 | if (caps_cmd.niccaps & htons(FW_CAPS_CONFIG_NIC_VM)) { |
| 3529 | if (!vf_acls) | 3507 | if (!vf_acls) |
| 3530 | caps_cmd.niccaps ^= htons(FW_CAPS_CONFIG_NIC_VM); | 3508 | caps_cmd.niccaps ^= htons(FW_CAPS_CONFIG_NIC_VM); |
| @@ -3745,6 +3723,7 @@ static int adap_init0(struct adapter *adap) | |||
| 3745 | u32 v, port_vec; | 3723 | u32 v, port_vec; |
| 3746 | enum dev_state state; | 3724 | enum dev_state state; |
| 3747 | u32 params[7], val[7]; | 3725 | u32 params[7], val[7]; |
| 3726 | struct fw_caps_config_cmd caps_cmd; | ||
| 3748 | int reset = 1, j; | 3727 | int reset = 1, j; |
| 3749 | 3728 | ||
| 3750 | /* | 3729 | /* |
| @@ -3898,6 +3877,9 @@ static int adap_init0(struct adapter *adap) | |||
| 3898 | goto bye; | 3877 | goto bye; |
| 3899 | } | 3878 | } |
| 3900 | 3879 | ||
| 3880 | if (is_bypass_device(adap->pdev->device)) | ||
| 3881 | adap->params.bypass = 1; | ||
| 3882 | |||
| 3901 | /* | 3883 | /* |
| 3902 | * Grab some of our basic fundamental operating parameters. | 3884 | * Grab some of our basic fundamental operating parameters. |
| 3903 | */ | 3885 | */ |
| @@ -3940,13 +3922,12 @@ static int adap_init0(struct adapter *adap) | |||
| 3940 | adap->tids.aftid_end = val[1]; | 3922 | adap->tids.aftid_end = val[1]; |
| 3941 | } | 3923 | } |
| 3942 | 3924 | ||
| 3943 | #ifdef CONFIG_CHELSIO_T4_OFFLOAD | ||
| 3944 | /* | 3925 | /* |
| 3945 | * Get device capabilities so we can determine what resources we need | 3926 | * Get device capabilities so we can determine what resources we need |
| 3946 | * to manage. | 3927 | * to manage. |
| 3947 | */ | 3928 | */ |
| 3948 | memset(&caps_cmd, 0, sizeof(caps_cmd)); | 3929 | memset(&caps_cmd, 0, sizeof(caps_cmd)); |
| 3949 | caps_cmd.op_to_write = htonl(V_FW_CMD_OP(FW_CAPS_CONFIG_CMD) | | 3930 | caps_cmd.op_to_write = htonl(FW_CMD_OP(FW_CAPS_CONFIG_CMD) | |
| 3950 | FW_CMD_REQUEST | FW_CMD_READ); | 3931 | FW_CMD_REQUEST | FW_CMD_READ); |
| 3951 | caps_cmd.retval_len16 = htonl(FW_LEN16(caps_cmd)); | 3932 | caps_cmd.retval_len16 = htonl(FW_LEN16(caps_cmd)); |
| 3952 | ret = t4_wr_mbox(adap, adap->mbox, &caps_cmd, sizeof(caps_cmd), | 3933 | ret = t4_wr_mbox(adap, adap->mbox, &caps_cmd, sizeof(caps_cmd), |
| @@ -3991,15 +3972,6 @@ static int adap_init0(struct adapter *adap) | |||
| 3991 | adap->vres.ddp.size = val[4] - val[3] + 1; | 3972 | adap->vres.ddp.size = val[4] - val[3] + 1; |
| 3992 | adap->params.ofldq_wr_cred = val[5]; | 3973 | adap->params.ofldq_wr_cred = val[5]; |
| 3993 | 3974 | ||
| 3994 | params[0] = FW_PARAM_PFVF(ETHOFLD_START); | ||
| 3995 | params[1] = FW_PARAM_PFVF(ETHOFLD_END); | ||
| 3996 | ret = t4_query_params(adap, adap->mbox, adap->fn, 0, 2, | ||
| 3997 | params, val); | ||
| 3998 | if ((val[0] != val[1]) && (ret >= 0)) { | ||
| 3999 | adap->tids.uotid_base = val[0]; | ||
| 4000 | adap->tids.nuotids = val[1] - val[0] + 1; | ||
| 4001 | } | ||
| 4002 | |||
| 4003 | adap->params.offload = 1; | 3975 | adap->params.offload = 1; |
| 4004 | } | 3976 | } |
| 4005 | if (caps_cmd.rdmacaps) { | 3977 | if (caps_cmd.rdmacaps) { |
| @@ -4048,7 +4020,6 @@ static int adap_init0(struct adapter *adap) | |||
| 4048 | } | 4020 | } |
| 4049 | #undef FW_PARAM_PFVF | 4021 | #undef FW_PARAM_PFVF |
| 4050 | #undef FW_PARAM_DEV | 4022 | #undef FW_PARAM_DEV |
| 4051 | #endif /* CONFIG_CHELSIO_T4_OFFLOAD */ | ||
| 4052 | 4023 | ||
| 4053 | /* | 4024 | /* |
| 4054 | * These are finalized by FW initialization, load their values now. | 4025 | * These are finalized by FW initialization, load their values now. |
diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_uld.h b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_uld.h index 1b899fea1a91..39bec73ff87c 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_uld.h +++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_uld.h | |||
| @@ -102,6 +102,9 @@ struct tid_info { | |||
| 102 | unsigned int ftid_base; | 102 | unsigned int ftid_base; |
| 103 | unsigned int aftid_base; | 103 | unsigned int aftid_base; |
| 104 | unsigned int aftid_end; | 104 | unsigned int aftid_end; |
| 105 | /* Server filter region */ | ||
| 106 | unsigned int sftid_base; | ||
| 107 | unsigned int nsftids; | ||
| 105 | 108 | ||
| 106 | spinlock_t atid_lock ____cacheline_aligned_in_smp; | 109 | spinlock_t atid_lock ____cacheline_aligned_in_smp; |
| 107 | union aopen_entry *afree; | 110 | union aopen_entry *afree; |
diff --git a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c index 32eec15fe4c2..730ae2cfa49e 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c +++ b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c | |||
| @@ -2519,6 +2519,7 @@ int t4_fw_bye(struct adapter *adap, unsigned int mbox) | |||
| 2519 | { | 2519 | { |
| 2520 | struct fw_bye_cmd c; | 2520 | struct fw_bye_cmd c; |
| 2521 | 2521 | ||
| 2522 | memset(&c, 0, sizeof(c)); | ||
| 2522 | INIT_CMD(c, BYE, WRITE); | 2523 | INIT_CMD(c, BYE, WRITE); |
| 2523 | return t4_wr_mbox(adap, mbox, &c, sizeof(c), NULL); | 2524 | return t4_wr_mbox(adap, mbox, &c, sizeof(c), NULL); |
| 2524 | } | 2525 | } |
| @@ -2535,6 +2536,7 @@ int t4_early_init(struct adapter *adap, unsigned int mbox) | |||
| 2535 | { | 2536 | { |
| 2536 | struct fw_initialize_cmd c; | 2537 | struct fw_initialize_cmd c; |
| 2537 | 2538 | ||
| 2539 | memset(&c, 0, sizeof(c)); | ||
| 2538 | INIT_CMD(c, INITIALIZE, WRITE); | 2540 | INIT_CMD(c, INITIALIZE, WRITE); |
| 2539 | return t4_wr_mbox(adap, mbox, &c, sizeof(c), NULL); | 2541 | return t4_wr_mbox(adap, mbox, &c, sizeof(c), NULL); |
| 2540 | } | 2542 | } |
| @@ -2551,6 +2553,7 @@ int t4_fw_reset(struct adapter *adap, unsigned int mbox, int reset) | |||
| 2551 | { | 2553 | { |
| 2552 | struct fw_reset_cmd c; | 2554 | struct fw_reset_cmd c; |
| 2553 | 2555 | ||
| 2556 | memset(&c, 0, sizeof(c)); | ||
| 2554 | INIT_CMD(c, RESET, WRITE); | 2557 | INIT_CMD(c, RESET, WRITE); |
| 2555 | c.val = htonl(reset); | 2558 | c.val = htonl(reset); |
| 2556 | return t4_wr_mbox(adap, mbox, &c, sizeof(c), NULL); | 2559 | return t4_wr_mbox(adap, mbox, &c, sizeof(c), NULL); |
| @@ -2828,7 +2831,7 @@ int t4_fixup_host_params(struct adapter *adap, unsigned int page_size, | |||
| 2828 | HOSTPAGESIZEPF7(sge_hps)); | 2831 | HOSTPAGESIZEPF7(sge_hps)); |
| 2829 | 2832 | ||
| 2830 | t4_set_reg_field(adap, SGE_CONTROL, | 2833 | t4_set_reg_field(adap, SGE_CONTROL, |
| 2831 | INGPADBOUNDARY(INGPADBOUNDARY_MASK) | | 2834 | INGPADBOUNDARY_MASK | |
| 2832 | EGRSTATUSPAGESIZE_MASK, | 2835 | EGRSTATUSPAGESIZE_MASK, |
| 2833 | INGPADBOUNDARY(fl_align_log - 5) | | 2836 | INGPADBOUNDARY(fl_align_log - 5) | |
| 2834 | EGRSTATUSPAGESIZE(stat_len != 64)); | 2837 | EGRSTATUSPAGESIZE(stat_len != 64)); |
| @@ -3278,6 +3281,7 @@ int t4_identify_port(struct adapter *adap, unsigned int mbox, unsigned int viid, | |||
| 3278 | { | 3281 | { |
| 3279 | struct fw_vi_enable_cmd c; | 3282 | struct fw_vi_enable_cmd c; |
| 3280 | 3283 | ||
| 3284 | memset(&c, 0, sizeof(c)); | ||
| 3281 | c.op_to_viid = htonl(FW_CMD_OP(FW_VI_ENABLE_CMD) | FW_CMD_REQUEST | | 3285 | c.op_to_viid = htonl(FW_CMD_OP(FW_VI_ENABLE_CMD) | FW_CMD_REQUEST | |
| 3282 | FW_CMD_EXEC | FW_VI_ENABLE_CMD_VIID(viid)); | 3286 | FW_CMD_EXEC | FW_VI_ENABLE_CMD_VIID(viid)); |
| 3283 | c.ien_to_len16 = htonl(FW_VI_ENABLE_CMD_LED | FW_LEN16(c)); | 3287 | c.ien_to_len16 = htonl(FW_VI_ENABLE_CMD_LED | FW_LEN16(c)); |
diff --git a/drivers/net/ethernet/freescale/gianfar.c b/drivers/net/ethernet/freescale/gianfar.c index 1d03dcdd5e56..19ac096cb07b 100644 --- a/drivers/net/ethernet/freescale/gianfar.c +++ b/drivers/net/ethernet/freescale/gianfar.c | |||
| @@ -1353,8 +1353,11 @@ static int gfar_restore(struct device *dev) | |||
| 1353 | struct gfar_private *priv = dev_get_drvdata(dev); | 1353 | struct gfar_private *priv = dev_get_drvdata(dev); |
| 1354 | struct net_device *ndev = priv->ndev; | 1354 | struct net_device *ndev = priv->ndev; |
| 1355 | 1355 | ||
| 1356 | if (!netif_running(ndev)) | 1356 | if (!netif_running(ndev)) { |
| 1357 | netif_device_attach(ndev); | ||
| 1358 | |||
| 1357 | return 0; | 1359 | return 0; |
| 1360 | } | ||
| 1358 | 1361 | ||
| 1359 | gfar_init_bds(ndev); | 1362 | gfar_init_bds(ndev); |
| 1360 | init_registers(ndev); | 1363 | init_registers(ndev); |
diff --git a/drivers/net/ethernet/freescale/gianfar_ptp.c b/drivers/net/ethernet/freescale/gianfar_ptp.c index b9db0e040563..2e5daee0438a 100644 --- a/drivers/net/ethernet/freescale/gianfar_ptp.c +++ b/drivers/net/ethernet/freescale/gianfar_ptp.c | |||
| @@ -478,7 +478,7 @@ static int gianfar_ptp_probe(struct platform_device *dev) | |||
| 478 | pr_err("no resource\n"); | 478 | pr_err("no resource\n"); |
| 479 | goto no_resource; | 479 | goto no_resource; |
| 480 | } | 480 | } |
| 481 | if (request_resource(&ioport_resource, etsects->rsrc)) { | 481 | if (request_resource(&iomem_resource, etsects->rsrc)) { |
| 482 | pr_err("resource busy\n"); | 482 | pr_err("resource busy\n"); |
| 483 | goto no_resource; | 483 | goto no_resource; |
| 484 | } | 484 | } |
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c index 56b20d17d0e4..116f0e901bee 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c | |||
| @@ -2673,6 +2673,9 @@ static int ixgbe_get_ts_info(struct net_device *dev, | |||
| 2673 | case ixgbe_mac_X540: | 2673 | case ixgbe_mac_X540: |
| 2674 | case ixgbe_mac_82599EB: | 2674 | case ixgbe_mac_82599EB: |
| 2675 | info->so_timestamping = | 2675 | info->so_timestamping = |
| 2676 | SOF_TIMESTAMPING_TX_SOFTWARE | | ||
| 2677 | SOF_TIMESTAMPING_RX_SOFTWARE | | ||
| 2678 | SOF_TIMESTAMPING_SOFTWARE | | ||
| 2676 | SOF_TIMESTAMPING_TX_HARDWARE | | 2679 | SOF_TIMESTAMPING_TX_HARDWARE | |
| 2677 | SOF_TIMESTAMPING_RX_HARDWARE | | 2680 | SOF_TIMESTAMPING_RX_HARDWARE | |
| 2678 | SOF_TIMESTAMPING_RAW_HARDWARE; | 2681 | SOF_TIMESTAMPING_RAW_HARDWARE; |
diff --git a/drivers/net/ethernet/jme.c b/drivers/net/ethernet/jme.c index f8064df10cc4..60ac46f4ac08 100644 --- a/drivers/net/ethernet/jme.c +++ b/drivers/net/ethernet/jme.c | |||
| @@ -1860,10 +1860,14 @@ jme_open(struct net_device *netdev) | |||
| 1860 | jme_clear_pm(jme); | 1860 | jme_clear_pm(jme); |
| 1861 | JME_NAPI_ENABLE(jme); | 1861 | JME_NAPI_ENABLE(jme); |
| 1862 | 1862 | ||
| 1863 | tasklet_enable(&jme->linkch_task); | 1863 | tasklet_init(&jme->linkch_task, jme_link_change_tasklet, |
| 1864 | tasklet_enable(&jme->txclean_task); | 1864 | (unsigned long) jme); |
| 1865 | tasklet_hi_enable(&jme->rxclean_task); | 1865 | tasklet_init(&jme->txclean_task, jme_tx_clean_tasklet, |
| 1866 | tasklet_hi_enable(&jme->rxempty_task); | 1866 | (unsigned long) jme); |
| 1867 | tasklet_init(&jme->rxclean_task, jme_rx_clean_tasklet, | ||
| 1868 | (unsigned long) jme); | ||
| 1869 | tasklet_init(&jme->rxempty_task, jme_rx_empty_tasklet, | ||
| 1870 | (unsigned long) jme); | ||
| 1867 | 1871 | ||
| 1868 | rc = jme_request_irq(jme); | 1872 | rc = jme_request_irq(jme); |
| 1869 | if (rc) | 1873 | if (rc) |
| @@ -1948,10 +1952,10 @@ jme_close(struct net_device *netdev) | |||
| 1948 | 1952 | ||
| 1949 | JME_NAPI_DISABLE(jme); | 1953 | JME_NAPI_DISABLE(jme); |
| 1950 | 1954 | ||
| 1951 | tasklet_disable(&jme->linkch_task); | 1955 | tasklet_kill(&jme->linkch_task); |
| 1952 | tasklet_disable(&jme->txclean_task); | 1956 | tasklet_kill(&jme->txclean_task); |
| 1953 | tasklet_disable(&jme->rxclean_task); | 1957 | tasklet_kill(&jme->rxclean_task); |
| 1954 | tasklet_disable(&jme->rxempty_task); | 1958 | tasklet_kill(&jme->rxempty_task); |
| 1955 | 1959 | ||
| 1956 | jme_disable_rx_engine(jme); | 1960 | jme_disable_rx_engine(jme); |
| 1957 | jme_disable_tx_engine(jme); | 1961 | jme_disable_tx_engine(jme); |
| @@ -3079,22 +3083,6 @@ jme_init_one(struct pci_dev *pdev, | |||
| 3079 | tasklet_init(&jme->pcc_task, | 3083 | tasklet_init(&jme->pcc_task, |
| 3080 | jme_pcc_tasklet, | 3084 | jme_pcc_tasklet, |
| 3081 | (unsigned long) jme); | 3085 | (unsigned long) jme); |
| 3082 | tasklet_init(&jme->linkch_task, | ||
| 3083 | jme_link_change_tasklet, | ||
| 3084 | (unsigned long) jme); | ||
| 3085 | tasklet_init(&jme->txclean_task, | ||
| 3086 | jme_tx_clean_tasklet, | ||
| 3087 | (unsigned long) jme); | ||
| 3088 | tasklet_init(&jme->rxclean_task, | ||
| 3089 | jme_rx_clean_tasklet, | ||
| 3090 | (unsigned long) jme); | ||
| 3091 | tasklet_init(&jme->rxempty_task, | ||
| 3092 | jme_rx_empty_tasklet, | ||
| 3093 | (unsigned long) jme); | ||
| 3094 | tasklet_disable_nosync(&jme->linkch_task); | ||
| 3095 | tasklet_disable_nosync(&jme->txclean_task); | ||
| 3096 | tasklet_disable_nosync(&jme->rxclean_task); | ||
| 3097 | tasklet_disable_nosync(&jme->rxempty_task); | ||
| 3098 | jme->dpi.cur = PCC_P1; | 3086 | jme->dpi.cur = PCC_P1; |
| 3099 | 3087 | ||
| 3100 | jme->reg_ghc = 0; | 3088 | jme->reg_ghc = 0; |
diff --git a/drivers/net/ethernet/marvell/skge.c b/drivers/net/ethernet/marvell/skge.c index 9b9c2ac5c4c2..d19a143aa5a8 100644 --- a/drivers/net/ethernet/marvell/skge.c +++ b/drivers/net/ethernet/marvell/skge.c | |||
| @@ -4026,7 +4026,7 @@ static void __devexit skge_remove(struct pci_dev *pdev) | |||
| 4026 | dev0 = hw->dev[0]; | 4026 | dev0 = hw->dev[0]; |
| 4027 | unregister_netdev(dev0); | 4027 | unregister_netdev(dev0); |
| 4028 | 4028 | ||
| 4029 | tasklet_disable(&hw->phy_task); | 4029 | tasklet_kill(&hw->phy_task); |
| 4030 | 4030 | ||
| 4031 | spin_lock_irq(&hw->hw_lock); | 4031 | spin_lock_irq(&hw->hw_lock); |
| 4032 | hw->intr_mask = 0; | 4032 | hw->intr_mask = 0; |
diff --git a/drivers/net/ethernet/mellanox/mlx4/en_dcb_nl.c b/drivers/net/ethernet/mellanox/mlx4/en_dcb_nl.c index 5d36795877cb..b799ab12a291 100644 --- a/drivers/net/ethernet/mellanox/mlx4/en_dcb_nl.c +++ b/drivers/net/ethernet/mellanox/mlx4/en_dcb_nl.c | |||
| @@ -237,7 +237,7 @@ static int mlx4_en_dcbnl_ieee_setmaxrate(struct net_device *dev, | |||
| 237 | if (err) | 237 | if (err) |
| 238 | return err; | 238 | return err; |
| 239 | 239 | ||
| 240 | memcpy(priv->maxrate, tmp, sizeof(*priv->maxrate)); | 240 | memcpy(priv->maxrate, tmp, sizeof(priv->maxrate)); |
| 241 | 241 | ||
| 242 | return 0; | 242 | return 0; |
| 243 | } | 243 | } |
diff --git a/drivers/net/ethernet/mellanox/mlx4/en_tx.c b/drivers/net/ethernet/mellanox/mlx4/en_tx.c index c10e3a6de09f..b35094c590ba 100644 --- a/drivers/net/ethernet/mellanox/mlx4/en_tx.c +++ b/drivers/net/ethernet/mellanox/mlx4/en_tx.c | |||
| @@ -143,7 +143,6 @@ void mlx4_en_destroy_tx_ring(struct mlx4_en_priv *priv, | |||
| 143 | mlx4_bf_free(mdev->dev, &ring->bf); | 143 | mlx4_bf_free(mdev->dev, &ring->bf); |
| 144 | mlx4_qp_remove(mdev->dev, &ring->qp); | 144 | mlx4_qp_remove(mdev->dev, &ring->qp); |
| 145 | mlx4_qp_free(mdev->dev, &ring->qp); | 145 | mlx4_qp_free(mdev->dev, &ring->qp); |
| 146 | mlx4_qp_release_range(mdev->dev, ring->qpn, 1); | ||
| 147 | mlx4_en_unmap_buffer(&ring->wqres.buf); | 146 | mlx4_en_unmap_buffer(&ring->wqres.buf); |
| 148 | mlx4_free_hwq_res(mdev->dev, &ring->wqres, ring->buf_size); | 147 | mlx4_free_hwq_res(mdev->dev, &ring->wqres, ring->buf_size); |
| 149 | kfree(ring->bounce_buf); | 148 | kfree(ring->bounce_buf); |
| @@ -712,7 +711,7 @@ netdev_tx_t mlx4_en_xmit(struct sk_buff *skb, struct net_device *dev) | |||
| 712 | if (bounce) | 711 | if (bounce) |
| 713 | tx_desc = mlx4_en_bounce_to_desc(priv, ring, index, desc_size); | 712 | tx_desc = mlx4_en_bounce_to_desc(priv, ring, index, desc_size); |
| 714 | 713 | ||
| 715 | if (ring->bf_enabled && desc_size <= MAX_BF && !bounce && !vlan_tag) { | 714 | if (ring->bf_enabled && desc_size <= MAX_BF && !bounce && !vlan_tx_tag_present(skb)) { |
| 716 | *(__be32 *) (&tx_desc->ctrl.vlan_tag) |= cpu_to_be32(ring->doorbell_qpn); | 715 | *(__be32 *) (&tx_desc->ctrl.vlan_tag) |= cpu_to_be32(ring->doorbell_qpn); |
| 717 | op_own |= htonl((bf_index & 0xffff) << 8); | 716 | op_own |= htonl((bf_index & 0xffff) << 8); |
| 718 | /* Ensure new descirptor hits memory | 717 | /* Ensure new descirptor hits memory |
diff --git a/drivers/net/ethernet/mellanox/mlx4/eq.c b/drivers/net/ethernet/mellanox/mlx4/eq.c index 51c764901ad2..b84a88bc44dc 100644 --- a/drivers/net/ethernet/mellanox/mlx4/eq.c +++ b/drivers/net/ethernet/mellanox/mlx4/eq.c | |||
| @@ -329,9 +329,6 @@ int set_and_calc_slave_port_state(struct mlx4_dev *dev, int slave, | |||
| 329 | ctx = &priv->mfunc.master.slave_state[slave]; | 329 | ctx = &priv->mfunc.master.slave_state[slave]; |
| 330 | spin_lock_irqsave(&ctx->lock, flags); | 330 | spin_lock_irqsave(&ctx->lock, flags); |
| 331 | 331 | ||
| 332 | mlx4_dbg(dev, "%s: slave: %d, current state: %d new event :%d\n", | ||
| 333 | __func__, slave, cur_state, event); | ||
| 334 | |||
| 335 | switch (cur_state) { | 332 | switch (cur_state) { |
| 336 | case SLAVE_PORT_DOWN: | 333 | case SLAVE_PORT_DOWN: |
| 337 | if (MLX4_PORT_STATE_DEV_EVENT_PORT_UP == event) | 334 | if (MLX4_PORT_STATE_DEV_EVENT_PORT_UP == event) |
| @@ -366,9 +363,6 @@ int set_and_calc_slave_port_state(struct mlx4_dev *dev, int slave, | |||
| 366 | goto out; | 363 | goto out; |
| 367 | } | 364 | } |
| 368 | ret = mlx4_get_slave_port_state(dev, slave, port); | 365 | ret = mlx4_get_slave_port_state(dev, slave, port); |
| 369 | mlx4_dbg(dev, "%s: slave: %d, current state: %d new event" | ||
| 370 | " :%d gen_event: %d\n", | ||
| 371 | __func__, slave, cur_state, event, *gen_event); | ||
| 372 | 366 | ||
| 373 | out: | 367 | out: |
| 374 | spin_unlock_irqrestore(&ctx->lock, flags); | 368 | spin_unlock_irqrestore(&ctx->lock, flags); |
| @@ -843,6 +837,18 @@ static void __iomem *mlx4_get_eq_uar(struct mlx4_dev *dev, struct mlx4_eq *eq) | |||
| 843 | return priv->eq_table.uar_map[index] + 0x800 + 8 * (eq->eqn % 4); | 837 | return priv->eq_table.uar_map[index] + 0x800 + 8 * (eq->eqn % 4); |
| 844 | } | 838 | } |
| 845 | 839 | ||
| 840 | static void mlx4_unmap_uar(struct mlx4_dev *dev) | ||
| 841 | { | ||
| 842 | struct mlx4_priv *priv = mlx4_priv(dev); | ||
| 843 | int i; | ||
| 844 | |||
| 845 | for (i = 0; i < mlx4_num_eq_uar(dev); ++i) | ||
| 846 | if (priv->eq_table.uar_map[i]) { | ||
| 847 | iounmap(priv->eq_table.uar_map[i]); | ||
| 848 | priv->eq_table.uar_map[i] = NULL; | ||
| 849 | } | ||
| 850 | } | ||
| 851 | |||
| 846 | static int mlx4_create_eq(struct mlx4_dev *dev, int nent, | 852 | static int mlx4_create_eq(struct mlx4_dev *dev, int nent, |
| 847 | u8 intr, struct mlx4_eq *eq) | 853 | u8 intr, struct mlx4_eq *eq) |
| 848 | { | 854 | { |
| @@ -1207,6 +1213,7 @@ err_out_unmap: | |||
| 1207 | mlx4_free_irqs(dev); | 1213 | mlx4_free_irqs(dev); |
| 1208 | 1214 | ||
| 1209 | err_out_bitmap: | 1215 | err_out_bitmap: |
| 1216 | mlx4_unmap_uar(dev); | ||
| 1210 | mlx4_bitmap_cleanup(&priv->eq_table.bitmap); | 1217 | mlx4_bitmap_cleanup(&priv->eq_table.bitmap); |
| 1211 | 1218 | ||
| 1212 | err_out_free: | 1219 | err_out_free: |
| @@ -1231,10 +1238,7 @@ void mlx4_cleanup_eq_table(struct mlx4_dev *dev) | |||
| 1231 | if (!mlx4_is_slave(dev)) | 1238 | if (!mlx4_is_slave(dev)) |
| 1232 | mlx4_unmap_clr_int(dev); | 1239 | mlx4_unmap_clr_int(dev); |
| 1233 | 1240 | ||
| 1234 | for (i = 0; i < mlx4_num_eq_uar(dev); ++i) | 1241 | mlx4_unmap_uar(dev); |
| 1235 | if (priv->eq_table.uar_map[i]) | ||
| 1236 | iounmap(priv->eq_table.uar_map[i]); | ||
| 1237 | |||
| 1238 | mlx4_bitmap_cleanup(&priv->eq_table.bitmap); | 1242 | mlx4_bitmap_cleanup(&priv->eq_table.bitmap); |
| 1239 | 1243 | ||
| 1240 | kfree(priv->eq_table.uar_map); | 1244 | kfree(priv->eq_table.uar_map); |
diff --git a/drivers/net/ethernet/mellanox/mlx4/main.c b/drivers/net/ethernet/mellanox/mlx4/main.c index 80df2ab0177c..2aa80afd98d2 100644 --- a/drivers/net/ethernet/mellanox/mlx4/main.c +++ b/drivers/net/ethernet/mellanox/mlx4/main.c | |||
| @@ -1405,7 +1405,10 @@ unmap_bf: | |||
| 1405 | unmap_bf_area(dev); | 1405 | unmap_bf_area(dev); |
| 1406 | 1406 | ||
| 1407 | err_close: | 1407 | err_close: |
| 1408 | mlx4_close_hca(dev); | 1408 | if (mlx4_is_slave(dev)) |
| 1409 | mlx4_slave_exit(dev); | ||
| 1410 | else | ||
| 1411 | mlx4_CLOSE_HCA(dev, 0); | ||
| 1409 | 1412 | ||
| 1410 | err_free_icm: | 1413 | err_free_icm: |
| 1411 | if (!mlx4_is_slave(dev)) | 1414 | if (!mlx4_is_slave(dev)) |
diff --git a/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c b/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c index 926c911c0ac4..b05705f50f0f 100644 --- a/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c +++ b/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c | |||
| @@ -330,9 +330,6 @@ static void update_pkey_index(struct mlx4_dev *dev, int slave, | |||
| 330 | 330 | ||
| 331 | new_index = priv->virt2phys_pkey[slave][port - 1][orig_index]; | 331 | new_index = priv->virt2phys_pkey[slave][port - 1][orig_index]; |
| 332 | *(u8 *)(inbox->buf + 35) = new_index; | 332 | *(u8 *)(inbox->buf + 35) = new_index; |
| 333 | |||
| 334 | mlx4_dbg(dev, "port = %d, orig pkey index = %d, " | ||
| 335 | "new pkey index = %d\n", port, orig_index, new_index); | ||
| 336 | } | 333 | } |
| 337 | 334 | ||
| 338 | static void update_gid(struct mlx4_dev *dev, struct mlx4_cmd_mailbox *inbox, | 335 | static void update_gid(struct mlx4_dev *dev, struct mlx4_cmd_mailbox *inbox, |
| @@ -351,9 +348,6 @@ static void update_gid(struct mlx4_dev *dev, struct mlx4_cmd_mailbox *inbox, | |||
| 351 | if (optpar & MLX4_QP_OPTPAR_ALT_ADDR_PATH) | 348 | if (optpar & MLX4_QP_OPTPAR_ALT_ADDR_PATH) |
| 352 | qp_ctx->alt_path.mgid_index = slave & 0x7F; | 349 | qp_ctx->alt_path.mgid_index = slave & 0x7F; |
| 353 | } | 350 | } |
| 354 | |||
| 355 | mlx4_dbg(dev, "slave %d, new gid index: 0x%x ", | ||
| 356 | slave, qp_ctx->pri_path.mgid_index); | ||
| 357 | } | 351 | } |
| 358 | 352 | ||
| 359 | static int mpt_mask(struct mlx4_dev *dev) | 353 | static int mpt_mask(struct mlx4_dev *dev) |
diff --git a/drivers/net/ethernet/micrel/ksz884x.c b/drivers/net/ethernet/micrel/ksz884x.c index 318fee91c79d..69e01977a1dd 100644 --- a/drivers/net/ethernet/micrel/ksz884x.c +++ b/drivers/net/ethernet/micrel/ksz884x.c | |||
| @@ -5407,8 +5407,8 @@ static int netdev_close(struct net_device *dev) | |||
| 5407 | /* Delay for receive task to stop scheduling itself. */ | 5407 | /* Delay for receive task to stop scheduling itself. */ |
| 5408 | msleep(2000 / HZ); | 5408 | msleep(2000 / HZ); |
| 5409 | 5409 | ||
| 5410 | tasklet_disable(&hw_priv->rx_tasklet); | 5410 | tasklet_kill(&hw_priv->rx_tasklet); |
| 5411 | tasklet_disable(&hw_priv->tx_tasklet); | 5411 | tasklet_kill(&hw_priv->tx_tasklet); |
| 5412 | free_irq(dev->irq, hw_priv->dev); | 5412 | free_irq(dev->irq, hw_priv->dev); |
| 5413 | 5413 | ||
| 5414 | transmit_cleanup(hw_priv, 0); | 5414 | transmit_cleanup(hw_priv, 0); |
| @@ -5459,8 +5459,10 @@ static int prepare_hardware(struct net_device *dev) | |||
| 5459 | rc = request_irq(dev->irq, netdev_intr, IRQF_SHARED, dev->name, dev); | 5459 | rc = request_irq(dev->irq, netdev_intr, IRQF_SHARED, dev->name, dev); |
| 5460 | if (rc) | 5460 | if (rc) |
| 5461 | return rc; | 5461 | return rc; |
| 5462 | tasklet_enable(&hw_priv->rx_tasklet); | 5462 | tasklet_init(&hw_priv->rx_tasklet, rx_proc_task, |
| 5463 | tasklet_enable(&hw_priv->tx_tasklet); | 5463 | (unsigned long) hw_priv); |
| 5464 | tasklet_init(&hw_priv->tx_tasklet, tx_proc_task, | ||
| 5465 | (unsigned long) hw_priv); | ||
| 5464 | 5466 | ||
| 5465 | hw->promiscuous = 0; | 5467 | hw->promiscuous = 0; |
| 5466 | hw->all_multi = 0; | 5468 | hw->all_multi = 0; |
| @@ -7033,16 +7035,6 @@ static int __devinit pcidev_init(struct pci_dev *pdev, | |||
| 7033 | spin_lock_init(&hw_priv->hwlock); | 7035 | spin_lock_init(&hw_priv->hwlock); |
| 7034 | mutex_init(&hw_priv->lock); | 7036 | mutex_init(&hw_priv->lock); |
| 7035 | 7037 | ||
| 7036 | /* tasklet is enabled. */ | ||
| 7037 | tasklet_init(&hw_priv->rx_tasklet, rx_proc_task, | ||
| 7038 | (unsigned long) hw_priv); | ||
| 7039 | tasklet_init(&hw_priv->tx_tasklet, tx_proc_task, | ||
| 7040 | (unsigned long) hw_priv); | ||
| 7041 | |||
| 7042 | /* tasklet_enable will decrement the atomic counter. */ | ||
| 7043 | tasklet_disable(&hw_priv->rx_tasklet); | ||
| 7044 | tasklet_disable(&hw_priv->tx_tasklet); | ||
| 7045 | |||
| 7046 | for (i = 0; i < TOTAL_PORT_NUM; i++) | 7038 | for (i = 0; i < TOTAL_PORT_NUM; i++) |
| 7047 | init_waitqueue_head(&hw_priv->counter[i].counter); | 7039 | init_waitqueue_head(&hw_priv->counter[i].counter); |
| 7048 | 7040 | ||
diff --git a/drivers/net/ethernet/nxp/lpc_eth.c b/drivers/net/ethernet/nxp/lpc_eth.c index 53743f7a2ca9..af8b4142088c 100644 --- a/drivers/net/ethernet/nxp/lpc_eth.c +++ b/drivers/net/ethernet/nxp/lpc_eth.c | |||
| @@ -1524,6 +1524,7 @@ static int lpc_eth_drv_remove(struct platform_device *pdev) | |||
| 1524 | pldat->dma_buff_base_p); | 1524 | pldat->dma_buff_base_p); |
| 1525 | free_irq(ndev->irq, ndev); | 1525 | free_irq(ndev->irq, ndev); |
| 1526 | iounmap(pldat->net_base); | 1526 | iounmap(pldat->net_base); |
| 1527 | mdiobus_unregister(pldat->mii_bus); | ||
| 1527 | mdiobus_free(pldat->mii_bus); | 1528 | mdiobus_free(pldat->mii_bus); |
| 1528 | clk_disable(pldat->clk); | 1529 | clk_disable(pldat->clk); |
| 1529 | clk_put(pldat->clk); | 1530 | clk_put(pldat->clk); |
diff --git a/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c b/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c index b2a94d02a521..4c4fe5b1a29a 100644 --- a/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c +++ b/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c | |||
| @@ -339,26 +339,6 @@ static void pch_gbe_wait_clr_bit(void *reg, u32 bit) | |||
| 339 | } | 339 | } |
| 340 | 340 | ||
| 341 | /** | 341 | /** |
| 342 | * pch_gbe_wait_clr_bit_irq - Wait to clear a bit for interrupt context | ||
| 343 | * @reg: Pointer of register | ||
| 344 | * @busy: Busy bit | ||
| 345 | */ | ||
| 346 | static int pch_gbe_wait_clr_bit_irq(void *reg, u32 bit) | ||
| 347 | { | ||
| 348 | u32 tmp; | ||
| 349 | int ret = -1; | ||
| 350 | /* wait busy */ | ||
| 351 | tmp = 20; | ||
| 352 | while ((ioread32(reg) & bit) && --tmp) | ||
| 353 | udelay(5); | ||
| 354 | if (!tmp) | ||
| 355 | pr_err("Error: busy bit is not cleared\n"); | ||
| 356 | else | ||
| 357 | ret = 0; | ||
| 358 | return ret; | ||
| 359 | } | ||
| 360 | |||
| 361 | /** | ||
| 362 | * pch_gbe_mac_mar_set - Set MAC address register | 342 | * pch_gbe_mac_mar_set - Set MAC address register |
| 363 | * @hw: Pointer to the HW structure | 343 | * @hw: Pointer to the HW structure |
| 364 | * @addr: Pointer to the MAC address | 344 | * @addr: Pointer to the MAC address |
| @@ -409,15 +389,20 @@ static void pch_gbe_mac_reset_hw(struct pch_gbe_hw *hw) | |||
| 409 | return; | 389 | return; |
| 410 | } | 390 | } |
| 411 | 391 | ||
| 412 | static void pch_gbe_mac_reset_rx(struct pch_gbe_hw *hw) | 392 | static void pch_gbe_disable_mac_rx(struct pch_gbe_hw *hw) |
| 413 | { | 393 | { |
| 414 | /* Read the MAC addresses. and store to the private data */ | 394 | u32 rctl; |
| 415 | pch_gbe_mac_read_mac_addr(hw); | 395 | /* Disables Receive MAC */ |
| 416 | iowrite32(PCH_GBE_RX_RST, &hw->reg->RESET); | 396 | rctl = ioread32(&hw->reg->MAC_RX_EN); |
| 417 | pch_gbe_wait_clr_bit_irq(&hw->reg->RESET, PCH_GBE_RX_RST); | 397 | iowrite32((rctl & ~PCH_GBE_MRE_MAC_RX_EN), &hw->reg->MAC_RX_EN); |
| 418 | /* Setup the MAC addresses */ | 398 | } |
| 419 | pch_gbe_mac_mar_set(hw, hw->mac.addr, 0); | 399 | |
| 420 | return; | 400 | static void pch_gbe_enable_mac_rx(struct pch_gbe_hw *hw) |
| 401 | { | ||
| 402 | u32 rctl; | ||
| 403 | /* Enables Receive MAC */ | ||
| 404 | rctl = ioread32(&hw->reg->MAC_RX_EN); | ||
| 405 | iowrite32((rctl | PCH_GBE_MRE_MAC_RX_EN), &hw->reg->MAC_RX_EN); | ||
| 421 | } | 406 | } |
| 422 | 407 | ||
| 423 | /** | 408 | /** |
| @@ -913,7 +898,7 @@ static void pch_gbe_setup_rctl(struct pch_gbe_adapter *adapter) | |||
| 913 | static void pch_gbe_configure_rx(struct pch_gbe_adapter *adapter) | 898 | static void pch_gbe_configure_rx(struct pch_gbe_adapter *adapter) |
| 914 | { | 899 | { |
| 915 | struct pch_gbe_hw *hw = &adapter->hw; | 900 | struct pch_gbe_hw *hw = &adapter->hw; |
| 916 | u32 rdba, rdlen, rctl, rxdma; | 901 | u32 rdba, rdlen, rxdma; |
| 917 | 902 | ||
| 918 | pr_debug("dma adr = 0x%08llx size = 0x%08x\n", | 903 | pr_debug("dma adr = 0x%08llx size = 0x%08x\n", |
| 919 | (unsigned long long)adapter->rx_ring->dma, | 904 | (unsigned long long)adapter->rx_ring->dma, |
| @@ -921,9 +906,7 @@ static void pch_gbe_configure_rx(struct pch_gbe_adapter *adapter) | |||
| 921 | 906 | ||
| 922 | pch_gbe_mac_force_mac_fc(hw); | 907 | pch_gbe_mac_force_mac_fc(hw); |
| 923 | 908 | ||
| 924 | /* Disables Receive MAC */ | 909 | pch_gbe_disable_mac_rx(hw); |
| 925 | rctl = ioread32(&hw->reg->MAC_RX_EN); | ||
| 926 | iowrite32((rctl & ~PCH_GBE_MRE_MAC_RX_EN), &hw->reg->MAC_RX_EN); | ||
| 927 | 910 | ||
| 928 | /* Disables Receive DMA */ | 911 | /* Disables Receive DMA */ |
| 929 | rxdma = ioread32(&hw->reg->DMA_CTRL); | 912 | rxdma = ioread32(&hw->reg->DMA_CTRL); |
| @@ -1316,38 +1299,17 @@ void pch_gbe_update_stats(struct pch_gbe_adapter *adapter) | |||
| 1316 | spin_unlock_irqrestore(&adapter->stats_lock, flags); | 1299 | spin_unlock_irqrestore(&adapter->stats_lock, flags); |
| 1317 | } | 1300 | } |
| 1318 | 1301 | ||
| 1319 | static void pch_gbe_stop_receive(struct pch_gbe_adapter *adapter) | 1302 | static void pch_gbe_disable_dma_rx(struct pch_gbe_hw *hw) |
| 1320 | { | 1303 | { |
| 1321 | struct pch_gbe_hw *hw = &adapter->hw; | ||
| 1322 | u32 rxdma; | 1304 | u32 rxdma; |
| 1323 | u16 value; | ||
| 1324 | int ret; | ||
| 1325 | 1305 | ||
| 1326 | /* Disable Receive DMA */ | 1306 | /* Disable Receive DMA */ |
| 1327 | rxdma = ioread32(&hw->reg->DMA_CTRL); | 1307 | rxdma = ioread32(&hw->reg->DMA_CTRL); |
| 1328 | rxdma &= ~PCH_GBE_RX_DMA_EN; | 1308 | rxdma &= ~PCH_GBE_RX_DMA_EN; |
| 1329 | iowrite32(rxdma, &hw->reg->DMA_CTRL); | 1309 | iowrite32(rxdma, &hw->reg->DMA_CTRL); |
| 1330 | /* Wait Rx DMA BUS is IDLE */ | ||
| 1331 | ret = pch_gbe_wait_clr_bit_irq(&hw->reg->RX_DMA_ST, PCH_GBE_IDLE_CHECK); | ||
| 1332 | if (ret) { | ||
| 1333 | /* Disable Bus master */ | ||
| 1334 | pci_read_config_word(adapter->pdev, PCI_COMMAND, &value); | ||
| 1335 | value &= ~PCI_COMMAND_MASTER; | ||
| 1336 | pci_write_config_word(adapter->pdev, PCI_COMMAND, value); | ||
| 1337 | /* Stop Receive */ | ||
| 1338 | pch_gbe_mac_reset_rx(hw); | ||
| 1339 | /* Enable Bus master */ | ||
| 1340 | value |= PCI_COMMAND_MASTER; | ||
| 1341 | pci_write_config_word(adapter->pdev, PCI_COMMAND, value); | ||
| 1342 | } else { | ||
| 1343 | /* Stop Receive */ | ||
| 1344 | pch_gbe_mac_reset_rx(hw); | ||
| 1345 | } | ||
| 1346 | /* reprogram multicast address register after reset */ | ||
| 1347 | pch_gbe_set_multi(adapter->netdev); | ||
| 1348 | } | 1310 | } |
| 1349 | 1311 | ||
| 1350 | static void pch_gbe_start_receive(struct pch_gbe_hw *hw) | 1312 | static void pch_gbe_enable_dma_rx(struct pch_gbe_hw *hw) |
| 1351 | { | 1313 | { |
| 1352 | u32 rxdma; | 1314 | u32 rxdma; |
| 1353 | 1315 | ||
| @@ -1355,9 +1317,6 @@ static void pch_gbe_start_receive(struct pch_gbe_hw *hw) | |||
| 1355 | rxdma = ioread32(&hw->reg->DMA_CTRL); | 1317 | rxdma = ioread32(&hw->reg->DMA_CTRL); |
| 1356 | rxdma |= PCH_GBE_RX_DMA_EN; | 1318 | rxdma |= PCH_GBE_RX_DMA_EN; |
| 1357 | iowrite32(rxdma, &hw->reg->DMA_CTRL); | 1319 | iowrite32(rxdma, &hw->reg->DMA_CTRL); |
| 1358 | /* Enables Receive */ | ||
| 1359 | iowrite32(PCH_GBE_MRE_MAC_RX_EN, &hw->reg->MAC_RX_EN); | ||
| 1360 | return; | ||
| 1361 | } | 1320 | } |
| 1362 | 1321 | ||
| 1363 | /** | 1322 | /** |
| @@ -1393,7 +1352,7 @@ static irqreturn_t pch_gbe_intr(int irq, void *data) | |||
| 1393 | int_en = ioread32(&hw->reg->INT_EN); | 1352 | int_en = ioread32(&hw->reg->INT_EN); |
| 1394 | iowrite32((int_en & ~PCH_GBE_INT_RX_FIFO_ERR), | 1353 | iowrite32((int_en & ~PCH_GBE_INT_RX_FIFO_ERR), |
| 1395 | &hw->reg->INT_EN); | 1354 | &hw->reg->INT_EN); |
| 1396 | pch_gbe_stop_receive(adapter); | 1355 | pch_gbe_disable_dma_rx(&adapter->hw); |
| 1397 | int_st |= ioread32(&hw->reg->INT_ST); | 1356 | int_st |= ioread32(&hw->reg->INT_ST); |
| 1398 | int_st = int_st & ioread32(&hw->reg->INT_EN); | 1357 | int_st = int_st & ioread32(&hw->reg->INT_EN); |
| 1399 | } | 1358 | } |
| @@ -1971,12 +1930,12 @@ int pch_gbe_up(struct pch_gbe_adapter *adapter) | |||
| 1971 | struct net_device *netdev = adapter->netdev; | 1930 | struct net_device *netdev = adapter->netdev; |
| 1972 | struct pch_gbe_tx_ring *tx_ring = adapter->tx_ring; | 1931 | struct pch_gbe_tx_ring *tx_ring = adapter->tx_ring; |
| 1973 | struct pch_gbe_rx_ring *rx_ring = adapter->rx_ring; | 1932 | struct pch_gbe_rx_ring *rx_ring = adapter->rx_ring; |
| 1974 | int err; | 1933 | int err = -EINVAL; |
| 1975 | 1934 | ||
| 1976 | /* Ensure we have a valid MAC */ | 1935 | /* Ensure we have a valid MAC */ |
| 1977 | if (!is_valid_ether_addr(adapter->hw.mac.addr)) { | 1936 | if (!is_valid_ether_addr(adapter->hw.mac.addr)) { |
| 1978 | pr_err("Error: Invalid MAC address\n"); | 1937 | pr_err("Error: Invalid MAC address\n"); |
| 1979 | return -EINVAL; | 1938 | goto out; |
| 1980 | } | 1939 | } |
| 1981 | 1940 | ||
| 1982 | /* hardware has been reset, we need to reload some things */ | 1941 | /* hardware has been reset, we need to reload some things */ |
| @@ -1989,18 +1948,19 @@ int pch_gbe_up(struct pch_gbe_adapter *adapter) | |||
| 1989 | 1948 | ||
| 1990 | err = pch_gbe_request_irq(adapter); | 1949 | err = pch_gbe_request_irq(adapter); |
| 1991 | if (err) { | 1950 | if (err) { |
| 1992 | pr_err("Error: can't bring device up\n"); | 1951 | pr_err("Error: can't bring device up - irq request failed\n"); |
| 1993 | return err; | 1952 | goto out; |
| 1994 | } | 1953 | } |
| 1995 | err = pch_gbe_alloc_rx_buffers_pool(adapter, rx_ring, rx_ring->count); | 1954 | err = pch_gbe_alloc_rx_buffers_pool(adapter, rx_ring, rx_ring->count); |
| 1996 | if (err) { | 1955 | if (err) { |
| 1997 | pr_err("Error: can't bring device up\n"); | 1956 | pr_err("Error: can't bring device up - alloc rx buffers pool failed\n"); |
| 1998 | return err; | 1957 | goto freeirq; |
| 1999 | } | 1958 | } |
| 2000 | pch_gbe_alloc_tx_buffers(adapter, tx_ring); | 1959 | pch_gbe_alloc_tx_buffers(adapter, tx_ring); |
| 2001 | pch_gbe_alloc_rx_buffers(adapter, rx_ring, rx_ring->count); | 1960 | pch_gbe_alloc_rx_buffers(adapter, rx_ring, rx_ring->count); |
| 2002 | adapter->tx_queue_len = netdev->tx_queue_len; | 1961 | adapter->tx_queue_len = netdev->tx_queue_len; |
| 2003 | pch_gbe_start_receive(&adapter->hw); | 1962 | pch_gbe_enable_dma_rx(&adapter->hw); |
| 1963 | pch_gbe_enable_mac_rx(&adapter->hw); | ||
| 2004 | 1964 | ||
| 2005 | mod_timer(&adapter->watchdog_timer, jiffies); | 1965 | mod_timer(&adapter->watchdog_timer, jiffies); |
| 2006 | 1966 | ||
| @@ -2009,6 +1969,11 @@ int pch_gbe_up(struct pch_gbe_adapter *adapter) | |||
| 2009 | netif_start_queue(adapter->netdev); | 1969 | netif_start_queue(adapter->netdev); |
| 2010 | 1970 | ||
| 2011 | return 0; | 1971 | return 0; |
| 1972 | |||
| 1973 | freeirq: | ||
| 1974 | pch_gbe_free_irq(adapter); | ||
| 1975 | out: | ||
| 1976 | return err; | ||
| 2012 | } | 1977 | } |
| 2013 | 1978 | ||
| 2014 | /** | 1979 | /** |
| @@ -2405,7 +2370,6 @@ static int pch_gbe_napi_poll(struct napi_struct *napi, int budget) | |||
| 2405 | int work_done = 0; | 2370 | int work_done = 0; |
| 2406 | bool poll_end_flag = false; | 2371 | bool poll_end_flag = false; |
| 2407 | bool cleaned = false; | 2372 | bool cleaned = false; |
| 2408 | u32 int_en; | ||
| 2409 | 2373 | ||
| 2410 | pr_debug("budget : %d\n", budget); | 2374 | pr_debug("budget : %d\n", budget); |
| 2411 | 2375 | ||
| @@ -2422,19 +2386,13 @@ static int pch_gbe_napi_poll(struct napi_struct *napi, int budget) | |||
| 2422 | 2386 | ||
| 2423 | if (poll_end_flag) { | 2387 | if (poll_end_flag) { |
| 2424 | napi_complete(napi); | 2388 | napi_complete(napi); |
| 2425 | if (adapter->rx_stop_flag) { | ||
| 2426 | adapter->rx_stop_flag = false; | ||
| 2427 | pch_gbe_start_receive(&adapter->hw); | ||
| 2428 | } | ||
| 2429 | pch_gbe_irq_enable(adapter); | 2389 | pch_gbe_irq_enable(adapter); |
| 2430 | } else | 2390 | } |
| 2431 | if (adapter->rx_stop_flag) { | 2391 | |
| 2432 | adapter->rx_stop_flag = false; | 2392 | if (adapter->rx_stop_flag) { |
| 2433 | pch_gbe_start_receive(&adapter->hw); | 2393 | adapter->rx_stop_flag = false; |
| 2434 | int_en = ioread32(&adapter->hw.reg->INT_EN); | 2394 | pch_gbe_enable_dma_rx(&adapter->hw); |
| 2435 | iowrite32((int_en | PCH_GBE_INT_RX_FIFO_ERR), | 2395 | } |
| 2436 | &adapter->hw.reg->INT_EN); | ||
| 2437 | } | ||
| 2438 | 2396 | ||
| 2439 | pr_debug("poll_end_flag : %d work_done : %d budget : %d\n", | 2397 | pr_debug("poll_end_flag : %d work_done : %d budget : %d\n", |
| 2440 | poll_end_flag, work_done, budget); | 2398 | poll_end_flag, work_done, budget); |
diff --git a/drivers/net/ethernet/qlogic/qla3xxx.c b/drivers/net/ethernet/qlogic/qla3xxx.c index df09b1cb742f..6407d0d77e81 100644 --- a/drivers/net/ethernet/qlogic/qla3xxx.c +++ b/drivers/net/ethernet/qlogic/qla3xxx.c | |||
| @@ -2525,6 +2525,13 @@ static int ql_alloc_net_req_rsp_queues(struct ql3_adapter *qdev) | |||
| 2525 | qdev->req_q_size = | 2525 | qdev->req_q_size = |
| 2526 | (u32) (NUM_REQ_Q_ENTRIES * sizeof(struct ob_mac_iocb_req)); | 2526 | (u32) (NUM_REQ_Q_ENTRIES * sizeof(struct ob_mac_iocb_req)); |
| 2527 | 2527 | ||
| 2528 | qdev->rsp_q_size = NUM_RSP_Q_ENTRIES * sizeof(struct net_rsp_iocb); | ||
| 2529 | |||
| 2530 | /* The barrier is required to ensure request and response queue | ||
| 2531 | * addr writes to the registers. | ||
| 2532 | */ | ||
| 2533 | wmb(); | ||
| 2534 | |||
| 2528 | qdev->req_q_virt_addr = | 2535 | qdev->req_q_virt_addr = |
| 2529 | pci_alloc_consistent(qdev->pdev, | 2536 | pci_alloc_consistent(qdev->pdev, |
| 2530 | (size_t) qdev->req_q_size, | 2537 | (size_t) qdev->req_q_size, |
| @@ -2536,8 +2543,6 @@ static int ql_alloc_net_req_rsp_queues(struct ql3_adapter *qdev) | |||
| 2536 | return -ENOMEM; | 2543 | return -ENOMEM; |
| 2537 | } | 2544 | } |
| 2538 | 2545 | ||
| 2539 | qdev->rsp_q_size = NUM_RSP_Q_ENTRIES * sizeof(struct net_rsp_iocb); | ||
| 2540 | |||
| 2541 | qdev->rsp_q_virt_addr = | 2546 | qdev->rsp_q_virt_addr = |
| 2542 | pci_alloc_consistent(qdev->pdev, | 2547 | pci_alloc_consistent(qdev->pdev, |
| 2543 | (size_t) qdev->rsp_q_size, | 2548 | (size_t) qdev->rsp_q_size, |
diff --git a/drivers/net/ethernet/realtek/8139cp.c b/drivers/net/ethernet/realtek/8139cp.c index 1c818254b7be..609125a249d9 100644 --- a/drivers/net/ethernet/realtek/8139cp.c +++ b/drivers/net/ethernet/realtek/8139cp.c | |||
| @@ -979,17 +979,6 @@ static void cp_init_hw (struct cp_private *cp) | |||
| 979 | cpw32_f (MAC0 + 0, le32_to_cpu (*(__le32 *) (dev->dev_addr + 0))); | 979 | cpw32_f (MAC0 + 0, le32_to_cpu (*(__le32 *) (dev->dev_addr + 0))); |
| 980 | cpw32_f (MAC0 + 4, le32_to_cpu (*(__le32 *) (dev->dev_addr + 4))); | 980 | cpw32_f (MAC0 + 4, le32_to_cpu (*(__le32 *) (dev->dev_addr + 4))); |
| 981 | 981 | ||
| 982 | cpw32_f(HiTxRingAddr, 0); | ||
| 983 | cpw32_f(HiTxRingAddr + 4, 0); | ||
| 984 | |||
| 985 | ring_dma = cp->ring_dma; | ||
| 986 | cpw32_f(RxRingAddr, ring_dma & 0xffffffff); | ||
| 987 | cpw32_f(RxRingAddr + 4, (ring_dma >> 16) >> 16); | ||
| 988 | |||
| 989 | ring_dma += sizeof(struct cp_desc) * CP_RX_RING_SIZE; | ||
| 990 | cpw32_f(TxRingAddr, ring_dma & 0xffffffff); | ||
| 991 | cpw32_f(TxRingAddr + 4, (ring_dma >> 16) >> 16); | ||
| 992 | |||
| 993 | cp_start_hw(cp); | 982 | cp_start_hw(cp); |
| 994 | cpw8(TxThresh, 0x06); /* XXX convert magic num to a constant */ | 983 | cpw8(TxThresh, 0x06); /* XXX convert magic num to a constant */ |
| 995 | 984 | ||
| @@ -1003,6 +992,17 @@ static void cp_init_hw (struct cp_private *cp) | |||
| 1003 | 992 | ||
| 1004 | cpw8(Config5, cpr8(Config5) & PMEStatus); | 993 | cpw8(Config5, cpr8(Config5) & PMEStatus); |
| 1005 | 994 | ||
| 995 | cpw32_f(HiTxRingAddr, 0); | ||
| 996 | cpw32_f(HiTxRingAddr + 4, 0); | ||
| 997 | |||
| 998 | ring_dma = cp->ring_dma; | ||
| 999 | cpw32_f(RxRingAddr, ring_dma & 0xffffffff); | ||
| 1000 | cpw32_f(RxRingAddr + 4, (ring_dma >> 16) >> 16); | ||
| 1001 | |||
| 1002 | ring_dma += sizeof(struct cp_desc) * CP_RX_RING_SIZE; | ||
| 1003 | cpw32_f(TxRingAddr, ring_dma & 0xffffffff); | ||
| 1004 | cpw32_f(TxRingAddr + 4, (ring_dma >> 16) >> 16); | ||
| 1005 | |||
| 1006 | cpw16(MultiIntr, 0); | 1006 | cpw16(MultiIntr, 0); |
| 1007 | 1007 | ||
| 1008 | cpw8_f(Cfg9346, Cfg9346_Lock); | 1008 | cpw8_f(Cfg9346, Cfg9346_Lock); |
| @@ -1060,17 +1060,22 @@ static int cp_init_rings (struct cp_private *cp) | |||
| 1060 | 1060 | ||
| 1061 | static int cp_alloc_rings (struct cp_private *cp) | 1061 | static int cp_alloc_rings (struct cp_private *cp) |
| 1062 | { | 1062 | { |
| 1063 | struct device *d = &cp->pdev->dev; | ||
| 1063 | void *mem; | 1064 | void *mem; |
| 1065 | int rc; | ||
| 1064 | 1066 | ||
| 1065 | mem = dma_alloc_coherent(&cp->pdev->dev, CP_RING_BYTES, | 1067 | mem = dma_alloc_coherent(d, CP_RING_BYTES, &cp->ring_dma, GFP_KERNEL); |
| 1066 | &cp->ring_dma, GFP_KERNEL); | ||
| 1067 | if (!mem) | 1068 | if (!mem) |
| 1068 | return -ENOMEM; | 1069 | return -ENOMEM; |
| 1069 | 1070 | ||
| 1070 | cp->rx_ring = mem; | 1071 | cp->rx_ring = mem; |
| 1071 | cp->tx_ring = &cp->rx_ring[CP_RX_RING_SIZE]; | 1072 | cp->tx_ring = &cp->rx_ring[CP_RX_RING_SIZE]; |
| 1072 | 1073 | ||
| 1073 | return cp_init_rings(cp); | 1074 | rc = cp_init_rings(cp); |
| 1075 | if (rc < 0) | ||
| 1076 | dma_free_coherent(d, CP_RING_BYTES, cp->rx_ring, cp->ring_dma); | ||
| 1077 | |||
| 1078 | return rc; | ||
| 1074 | } | 1079 | } |
| 1075 | 1080 | ||
| 1076 | static void cp_clean_rings (struct cp_private *cp) | 1081 | static void cp_clean_rings (struct cp_private *cp) |
diff --git a/drivers/net/ethernet/realtek/r8169.c b/drivers/net/ethernet/realtek/r8169.c index e7ff886e8047..927aa33d4349 100644 --- a/drivers/net/ethernet/realtek/r8169.c +++ b/drivers/net/ethernet/realtek/r8169.c | |||
| @@ -3827,6 +3827,8 @@ static void rtl_wol_suspend_quirk(struct rtl8169_private *tp) | |||
| 3827 | void __iomem *ioaddr = tp->mmio_addr; | 3827 | void __iomem *ioaddr = tp->mmio_addr; |
| 3828 | 3828 | ||
| 3829 | switch (tp->mac_version) { | 3829 | switch (tp->mac_version) { |
| 3830 | case RTL_GIGA_MAC_VER_25: | ||
| 3831 | case RTL_GIGA_MAC_VER_26: | ||
| 3830 | case RTL_GIGA_MAC_VER_29: | 3832 | case RTL_GIGA_MAC_VER_29: |
| 3831 | case RTL_GIGA_MAC_VER_30: | 3833 | case RTL_GIGA_MAC_VER_30: |
| 3832 | case RTL_GIGA_MAC_VER_32: | 3834 | case RTL_GIGA_MAC_VER_32: |
| @@ -4519,6 +4521,9 @@ static void rtl_set_rx_mode(struct net_device *dev) | |||
| 4519 | mc_filter[1] = swab32(data); | 4521 | mc_filter[1] = swab32(data); |
| 4520 | } | 4522 | } |
| 4521 | 4523 | ||
| 4524 | if (tp->mac_version == RTL_GIGA_MAC_VER_35) | ||
| 4525 | mc_filter[1] = mc_filter[0] = 0xffffffff; | ||
| 4526 | |||
| 4522 | RTL_W32(MAR0 + 4, mc_filter[1]); | 4527 | RTL_W32(MAR0 + 4, mc_filter[1]); |
| 4523 | RTL_W32(MAR0 + 0, mc_filter[0]); | 4528 | RTL_W32(MAR0 + 0, mc_filter[0]); |
| 4524 | 4529 | ||
diff --git a/drivers/net/ethernet/sis/sis900.c b/drivers/net/ethernet/sis/sis900.c index fb9f6b38511f..edf5edb13140 100644 --- a/drivers/net/ethernet/sis/sis900.c +++ b/drivers/net/ethernet/sis/sis900.c | |||
| @@ -2479,7 +2479,7 @@ static int sis900_resume(struct pci_dev *pci_dev) | |||
| 2479 | netif_start_queue(net_dev); | 2479 | netif_start_queue(net_dev); |
| 2480 | 2480 | ||
| 2481 | /* Workaround for EDB */ | 2481 | /* Workaround for EDB */ |
| 2482 | sis900_set_mode(ioaddr, HW_SPEED_10_MBPS, FDX_CAPABLE_HALF_SELECTED); | 2482 | sis900_set_mode(sis_priv, HW_SPEED_10_MBPS, FDX_CAPABLE_HALF_SELECTED); |
| 2483 | 2483 | ||
| 2484 | /* Enable all known interrupts by setting the interrupt mask. */ | 2484 | /* Enable all known interrupts by setting the interrupt mask. */ |
| 2485 | sw32(imr, RxSOVR | RxORN | RxERR | RxOK | TxURN | TxERR | TxIDLE); | 2485 | sw32(imr, RxSOVR | RxORN | RxERR | RxOK | TxURN | TxERR | TxIDLE); |
diff --git a/drivers/net/ethernet/smsc/smsc911x.c b/drivers/net/ethernet/smsc/smsc911x.c index 62d1baf111ea..c53c0f4e2ce3 100644 --- a/drivers/net/ethernet/smsc/smsc911x.c +++ b/drivers/net/ethernet/smsc/smsc911x.c | |||
| @@ -2110,7 +2110,7 @@ static void __devinit smsc911x_read_mac_address(struct net_device *dev) | |||
| 2110 | static int __devinit smsc911x_init(struct net_device *dev) | 2110 | static int __devinit smsc911x_init(struct net_device *dev) |
| 2111 | { | 2111 | { |
| 2112 | struct smsc911x_data *pdata = netdev_priv(dev); | 2112 | struct smsc911x_data *pdata = netdev_priv(dev); |
| 2113 | unsigned int byte_test; | 2113 | unsigned int byte_test, mask; |
| 2114 | unsigned int to = 100; | 2114 | unsigned int to = 100; |
| 2115 | 2115 | ||
| 2116 | SMSC_TRACE(pdata, probe, "Driver Parameters:"); | 2116 | SMSC_TRACE(pdata, probe, "Driver Parameters:"); |
| @@ -2130,9 +2130,22 @@ static int __devinit smsc911x_init(struct net_device *dev) | |||
| 2130 | /* | 2130 | /* |
| 2131 | * poll the READY bit in PMT_CTRL. Any other access to the device is | 2131 | * poll the READY bit in PMT_CTRL. Any other access to the device is |
| 2132 | * forbidden while this bit isn't set. Try for 100ms | 2132 | * forbidden while this bit isn't set. Try for 100ms |
| 2133 | * | ||
| 2134 | * Note that this test is done before the WORD_SWAP register is | ||
| 2135 | * programmed. So in some configurations the READY bit is at 16 before | ||
| 2136 | * WORD_SWAP is written to. This issue is worked around by waiting | ||
| 2137 | * until either bit 0 or bit 16 gets set in PMT_CTRL. | ||
| 2138 | * | ||
| 2139 | * SMSC has confirmed that checking bit 16 (marked as reserved in | ||
| 2140 | * the datasheet) is fine since these bits "will either never be set | ||
| 2141 | * or can only go high after READY does (so also indicate the device | ||
| 2142 | * is ready)". | ||
| 2133 | */ | 2143 | */ |
| 2134 | while (!(smsc911x_reg_read(pdata, PMT_CTRL) & PMT_CTRL_READY_) && --to) | 2144 | |
| 2145 | mask = PMT_CTRL_READY_ | swahw32(PMT_CTRL_READY_); | ||
| 2146 | while (!(smsc911x_reg_read(pdata, PMT_CTRL) & mask) && --to) | ||
| 2135 | udelay(1000); | 2147 | udelay(1000); |
| 2148 | |||
| 2136 | if (to == 0) { | 2149 | if (to == 0) { |
| 2137 | pr_err("Device not READY in 100ms aborting\n"); | 2150 | pr_err("Device not READY in 100ms aborting\n"); |
| 2138 | return -ENODEV; | 2151 | return -ENODEV; |
diff --git a/drivers/net/ethernet/ti/Kconfig b/drivers/net/ethernet/ti/Kconfig index b26cbda5efa9..2c41894d5472 100644 --- a/drivers/net/ethernet/ti/Kconfig +++ b/drivers/net/ethernet/ti/Kconfig | |||
| @@ -5,7 +5,7 @@ | |||
| 5 | config NET_VENDOR_TI | 5 | config NET_VENDOR_TI |
| 6 | bool "Texas Instruments (TI) devices" | 6 | bool "Texas Instruments (TI) devices" |
| 7 | default y | 7 | default y |
| 8 | depends on PCI || EISA || AR7 || (ARM && (ARCH_DAVINCI || ARCH_OMAP3)) | 8 | depends on PCI || EISA || AR7 || (ARM && (ARCH_DAVINCI || ARCH_OMAP3 || SOC_AM33XX)) |
| 9 | ---help--- | 9 | ---help--- |
| 10 | If you have a network (Ethernet) card belonging to this class, say Y | 10 | If you have a network (Ethernet) card belonging to this class, say Y |
| 11 | and read the Ethernet-HOWTO, available from | 11 | and read the Ethernet-HOWTO, available from |
diff --git a/drivers/net/ethernet/tile/tilegx.c b/drivers/net/ethernet/tile/tilegx.c index 4e2a1628484d..66e025ad5df1 100644 --- a/drivers/net/ethernet/tile/tilegx.c +++ b/drivers/net/ethernet/tile/tilegx.c | |||
| @@ -917,7 +917,7 @@ static int tile_net_setup_interrupts(struct net_device *dev) | |||
| 917 | ingress_irq = rc; | 917 | ingress_irq = rc; |
| 918 | tile_irq_activate(ingress_irq, TILE_IRQ_PERCPU); | 918 | tile_irq_activate(ingress_irq, TILE_IRQ_PERCPU); |
| 919 | rc = request_irq(ingress_irq, tile_net_handle_ingress_irq, | 919 | rc = request_irq(ingress_irq, tile_net_handle_ingress_irq, |
| 920 | 0, NULL, NULL); | 920 | 0, "tile_net", NULL); |
| 921 | if (rc != 0) { | 921 | if (rc != 0) { |
| 922 | netdev_err(dev, "request_irq failed: %d\n", rc); | 922 | netdev_err(dev, "request_irq failed: %d\n", rc); |
| 923 | destroy_irq(ingress_irq); | 923 | destroy_irq(ingress_irq); |
| @@ -1334,11 +1334,11 @@ static int tso_count_edescs(struct sk_buff *skb) | |||
| 1334 | { | 1334 | { |
| 1335 | struct skb_shared_info *sh = skb_shinfo(skb); | 1335 | struct skb_shared_info *sh = skb_shinfo(skb); |
| 1336 | unsigned int sh_len = skb_transport_offset(skb) + tcp_hdrlen(skb); | 1336 | unsigned int sh_len = skb_transport_offset(skb) + tcp_hdrlen(skb); |
| 1337 | unsigned int data_len = skb->data_len + skb->hdr_len - sh_len; | 1337 | unsigned int data_len = skb->len - sh_len; |
| 1338 | unsigned int p_len = sh->gso_size; | 1338 | unsigned int p_len = sh->gso_size; |
| 1339 | long f_id = -1; /* id of the current fragment */ | 1339 | long f_id = -1; /* id of the current fragment */ |
| 1340 | long f_size = skb->hdr_len; /* size of the current fragment */ | 1340 | long f_size = skb_headlen(skb) - sh_len; /* current fragment size */ |
| 1341 | long f_used = sh_len; /* bytes used from the current fragment */ | 1341 | long f_used = 0; /* bytes used from the current fragment */ |
| 1342 | long n; /* size of the current piece of payload */ | 1342 | long n; /* size of the current piece of payload */ |
| 1343 | int num_edescs = 0; | 1343 | int num_edescs = 0; |
| 1344 | int segment; | 1344 | int segment; |
| @@ -1353,7 +1353,7 @@ static int tso_count_edescs(struct sk_buff *skb) | |||
| 1353 | /* Advance as needed. */ | 1353 | /* Advance as needed. */ |
| 1354 | while (f_used >= f_size) { | 1354 | while (f_used >= f_size) { |
| 1355 | f_id++; | 1355 | f_id++; |
| 1356 | f_size = sh->frags[f_id].size; | 1356 | f_size = skb_frag_size(&sh->frags[f_id]); |
| 1357 | f_used = 0; | 1357 | f_used = 0; |
| 1358 | } | 1358 | } |
| 1359 | 1359 | ||
| @@ -1384,13 +1384,13 @@ static void tso_headers_prepare(struct sk_buff *skb, unsigned char *headers, | |||
| 1384 | struct iphdr *ih; | 1384 | struct iphdr *ih; |
| 1385 | struct tcphdr *th; | 1385 | struct tcphdr *th; |
| 1386 | unsigned int sh_len = skb_transport_offset(skb) + tcp_hdrlen(skb); | 1386 | unsigned int sh_len = skb_transport_offset(skb) + tcp_hdrlen(skb); |
| 1387 | unsigned int data_len = skb->data_len + skb->hdr_len - sh_len; | 1387 | unsigned int data_len = skb->len - sh_len; |
| 1388 | unsigned char *data = skb->data; | 1388 | unsigned char *data = skb->data; |
| 1389 | unsigned int ih_off, th_off, p_len; | 1389 | unsigned int ih_off, th_off, p_len; |
| 1390 | unsigned int isum_seed, tsum_seed, id, seq; | 1390 | unsigned int isum_seed, tsum_seed, id, seq; |
| 1391 | long f_id = -1; /* id of the current fragment */ | 1391 | long f_id = -1; /* id of the current fragment */ |
| 1392 | long f_size = skb->hdr_len; /* size of the current fragment */ | 1392 | long f_size = skb_headlen(skb) - sh_len; /* current fragment size */ |
| 1393 | long f_used = sh_len; /* bytes used from the current fragment */ | 1393 | long f_used = 0; /* bytes used from the current fragment */ |
| 1394 | long n; /* size of the current piece of payload */ | 1394 | long n; /* size of the current piece of payload */ |
| 1395 | int segment; | 1395 | int segment; |
| 1396 | 1396 | ||
| @@ -1405,7 +1405,7 @@ static void tso_headers_prepare(struct sk_buff *skb, unsigned char *headers, | |||
| 1405 | isum_seed = ((0xFFFF - ih->check) + | 1405 | isum_seed = ((0xFFFF - ih->check) + |
| 1406 | (0xFFFF - ih->tot_len) + | 1406 | (0xFFFF - ih->tot_len) + |
| 1407 | (0xFFFF - ih->id)); | 1407 | (0xFFFF - ih->id)); |
| 1408 | tsum_seed = th->check + (0xFFFF ^ htons(sh_len + data_len)); | 1408 | tsum_seed = th->check + (0xFFFF ^ htons(skb->len)); |
| 1409 | id = ntohs(ih->id); | 1409 | id = ntohs(ih->id); |
| 1410 | seq = ntohl(th->seq); | 1410 | seq = ntohl(th->seq); |
| 1411 | 1411 | ||
| @@ -1444,7 +1444,7 @@ static void tso_headers_prepare(struct sk_buff *skb, unsigned char *headers, | |||
| 1444 | /* Advance as needed. */ | 1444 | /* Advance as needed. */ |
| 1445 | while (f_used >= f_size) { | 1445 | while (f_used >= f_size) { |
| 1446 | f_id++; | 1446 | f_id++; |
| 1447 | f_size = sh->frags[f_id].size; | 1447 | f_size = skb_frag_size(&sh->frags[f_id]); |
| 1448 | f_used = 0; | 1448 | f_used = 0; |
| 1449 | } | 1449 | } |
| 1450 | 1450 | ||
| @@ -1478,14 +1478,14 @@ static void tso_egress(struct net_device *dev, gxio_mpipe_equeue_t *equeue, | |||
| 1478 | struct tile_net_priv *priv = netdev_priv(dev); | 1478 | struct tile_net_priv *priv = netdev_priv(dev); |
| 1479 | struct skb_shared_info *sh = skb_shinfo(skb); | 1479 | struct skb_shared_info *sh = skb_shinfo(skb); |
| 1480 | unsigned int sh_len = skb_transport_offset(skb) + tcp_hdrlen(skb); | 1480 | unsigned int sh_len = skb_transport_offset(skb) + tcp_hdrlen(skb); |
| 1481 | unsigned int data_len = skb->data_len + skb->hdr_len - sh_len; | 1481 | unsigned int data_len = skb->len - sh_len; |
| 1482 | unsigned int p_len = sh->gso_size; | 1482 | unsigned int p_len = sh->gso_size; |
| 1483 | gxio_mpipe_edesc_t edesc_head = { { 0 } }; | 1483 | gxio_mpipe_edesc_t edesc_head = { { 0 } }; |
| 1484 | gxio_mpipe_edesc_t edesc_body = { { 0 } }; | 1484 | gxio_mpipe_edesc_t edesc_body = { { 0 } }; |
| 1485 | long f_id = -1; /* id of the current fragment */ | 1485 | long f_id = -1; /* id of the current fragment */ |
| 1486 | long f_size = skb->hdr_len; /* size of the current fragment */ | 1486 | long f_size = skb_headlen(skb) - sh_len; /* current fragment size */ |
| 1487 | long f_used = sh_len; /* bytes used from the current fragment */ | 1487 | long f_used = 0; /* bytes used from the current fragment */ |
| 1488 | void *f_data = skb->data; | 1488 | void *f_data = skb->data + sh_len; |
| 1489 | long n; /* size of the current piece of payload */ | 1489 | long n; /* size of the current piece of payload */ |
| 1490 | unsigned long tx_packets = 0, tx_bytes = 0; | 1490 | unsigned long tx_packets = 0, tx_bytes = 0; |
| 1491 | unsigned int csum_start; | 1491 | unsigned int csum_start; |
| @@ -1516,15 +1516,18 @@ static void tso_egress(struct net_device *dev, gxio_mpipe_equeue_t *equeue, | |||
| 1516 | 1516 | ||
| 1517 | /* Egress the payload. */ | 1517 | /* Egress the payload. */ |
| 1518 | while (p_used < p_len) { | 1518 | while (p_used < p_len) { |
| 1519 | void *va; | ||
| 1519 | 1520 | ||
| 1520 | /* Advance as needed. */ | 1521 | /* Advance as needed. */ |
| 1521 | while (f_used >= f_size) { | 1522 | while (f_used >= f_size) { |
| 1522 | f_id++; | 1523 | f_id++; |
| 1523 | f_size = sh->frags[f_id].size; | 1524 | f_size = skb_frag_size(&sh->frags[f_id]); |
| 1524 | f_used = 0; | ||
| 1525 | f_data = tile_net_frag_buf(&sh->frags[f_id]); | 1525 | f_data = tile_net_frag_buf(&sh->frags[f_id]); |
| 1526 | f_used = 0; | ||
| 1526 | } | 1527 | } |
| 1527 | 1528 | ||
| 1529 | va = f_data + f_used; | ||
| 1530 | |||
| 1528 | /* Use bytes from the current fragment. */ | 1531 | /* Use bytes from the current fragment. */ |
| 1529 | n = p_len - p_used; | 1532 | n = p_len - p_used; |
| 1530 | if (n > f_size - f_used) | 1533 | if (n > f_size - f_used) |
| @@ -1533,7 +1536,7 @@ static void tso_egress(struct net_device *dev, gxio_mpipe_equeue_t *equeue, | |||
| 1533 | p_used += n; | 1536 | p_used += n; |
| 1534 | 1537 | ||
| 1535 | /* Egress a piece of the payload. */ | 1538 | /* Egress a piece of the payload. */ |
| 1536 | edesc_body.va = va_to_tile_io_addr(f_data) + f_used; | 1539 | edesc_body.va = va_to_tile_io_addr(va); |
| 1537 | edesc_body.xfer_size = n; | 1540 | edesc_body.xfer_size = n; |
| 1538 | edesc_body.bound = !(p_used < p_len); | 1541 | edesc_body.bound = !(p_used < p_len); |
| 1539 | gxio_mpipe_equeue_put_at(equeue, edesc_body, slot); | 1542 | gxio_mpipe_equeue_put_at(equeue, edesc_body, slot); |
diff --git a/drivers/net/ethernet/xilinx/xilinx_axienet_main.c b/drivers/net/ethernet/xilinx/xilinx_axienet_main.c index 0793299bd39e..a788501e978e 100644 --- a/drivers/net/ethernet/xilinx/xilinx_axienet_main.c +++ b/drivers/net/ethernet/xilinx/xilinx_axienet_main.c | |||
| @@ -894,6 +894,8 @@ out: | |||
| 894 | return IRQ_HANDLED; | 894 | return IRQ_HANDLED; |
| 895 | } | 895 | } |
| 896 | 896 | ||
| 897 | static void axienet_dma_err_handler(unsigned long data); | ||
| 898 | |||
| 897 | /** | 899 | /** |
| 898 | * axienet_open - Driver open routine. | 900 | * axienet_open - Driver open routine. |
| 899 | * @ndev: Pointer to net_device structure | 901 | * @ndev: Pointer to net_device structure |
| @@ -942,6 +944,10 @@ static int axienet_open(struct net_device *ndev) | |||
| 942 | phy_start(lp->phy_dev); | 944 | phy_start(lp->phy_dev); |
| 943 | } | 945 | } |
| 944 | 946 | ||
| 947 | /* Enable tasklets for Axi DMA error handling */ | ||
| 948 | tasklet_init(&lp->dma_err_tasklet, axienet_dma_err_handler, | ||
| 949 | (unsigned long) lp); | ||
| 950 | |||
| 945 | /* Enable interrupts for Axi DMA Tx */ | 951 | /* Enable interrupts for Axi DMA Tx */ |
| 946 | ret = request_irq(lp->tx_irq, axienet_tx_irq, 0, ndev->name, ndev); | 952 | ret = request_irq(lp->tx_irq, axienet_tx_irq, 0, ndev->name, ndev); |
| 947 | if (ret) | 953 | if (ret) |
| @@ -950,8 +956,7 @@ static int axienet_open(struct net_device *ndev) | |||
| 950 | ret = request_irq(lp->rx_irq, axienet_rx_irq, 0, ndev->name, ndev); | 956 | ret = request_irq(lp->rx_irq, axienet_rx_irq, 0, ndev->name, ndev); |
| 951 | if (ret) | 957 | if (ret) |
| 952 | goto err_rx_irq; | 958 | goto err_rx_irq; |
| 953 | /* Enable tasklets for Axi DMA error handling */ | 959 | |
| 954 | tasklet_enable(&lp->dma_err_tasklet); | ||
| 955 | return 0; | 960 | return 0; |
| 956 | 961 | ||
| 957 | err_rx_irq: | 962 | err_rx_irq: |
| @@ -960,6 +965,7 @@ err_tx_irq: | |||
| 960 | if (lp->phy_dev) | 965 | if (lp->phy_dev) |
| 961 | phy_disconnect(lp->phy_dev); | 966 | phy_disconnect(lp->phy_dev); |
| 962 | lp->phy_dev = NULL; | 967 | lp->phy_dev = NULL; |
| 968 | tasklet_kill(&lp->dma_err_tasklet); | ||
| 963 | dev_err(lp->dev, "request_irq() failed\n"); | 969 | dev_err(lp->dev, "request_irq() failed\n"); |
| 964 | return ret; | 970 | return ret; |
| 965 | } | 971 | } |
| @@ -990,7 +996,7 @@ static int axienet_stop(struct net_device *ndev) | |||
| 990 | axienet_setoptions(ndev, lp->options & | 996 | axienet_setoptions(ndev, lp->options & |
| 991 | ~(XAE_OPTION_TXEN | XAE_OPTION_RXEN)); | 997 | ~(XAE_OPTION_TXEN | XAE_OPTION_RXEN)); |
| 992 | 998 | ||
| 993 | tasklet_disable(&lp->dma_err_tasklet); | 999 | tasklet_kill(&lp->dma_err_tasklet); |
| 994 | 1000 | ||
| 995 | free_irq(lp->tx_irq, ndev); | 1001 | free_irq(lp->tx_irq, ndev); |
| 996 | free_irq(lp->rx_irq, ndev); | 1002 | free_irq(lp->rx_irq, ndev); |
| @@ -1613,10 +1619,6 @@ static int __devinit axienet_of_probe(struct platform_device *op) | |||
| 1613 | goto err_iounmap_2; | 1619 | goto err_iounmap_2; |
| 1614 | } | 1620 | } |
| 1615 | 1621 | ||
| 1616 | tasklet_init(&lp->dma_err_tasklet, axienet_dma_err_handler, | ||
| 1617 | (unsigned long) lp); | ||
| 1618 | tasklet_disable(&lp->dma_err_tasklet); | ||
| 1619 | |||
| 1620 | return 0; | 1622 | return 0; |
| 1621 | 1623 | ||
| 1622 | err_iounmap_2: | 1624 | err_iounmap_2: |
diff --git a/drivers/net/ethernet/xscale/ixp4xx_eth.c b/drivers/net/ethernet/xscale/ixp4xx_eth.c index 98934bdf6acf..477d6729b17f 100644 --- a/drivers/net/ethernet/xscale/ixp4xx_eth.c +++ b/drivers/net/ethernet/xscale/ixp4xx_eth.c | |||
| @@ -1102,10 +1102,12 @@ static int init_queues(struct port *port) | |||
| 1102 | { | 1102 | { |
| 1103 | int i; | 1103 | int i; |
| 1104 | 1104 | ||
| 1105 | if (!ports_open) | 1105 | if (!ports_open) { |
| 1106 | if (!(dma_pool = dma_pool_create(DRV_NAME, NULL, | 1106 | dma_pool = dma_pool_create(DRV_NAME, &port->netdev->dev, |
| 1107 | POOL_ALLOC_SIZE, 32, 0))) | 1107 | POOL_ALLOC_SIZE, 32, 0); |
| 1108 | if (!dma_pool) | ||
| 1108 | return -ENOMEM; | 1109 | return -ENOMEM; |
| 1110 | } | ||
| 1109 | 1111 | ||
| 1110 | if (!(port->desc_tab = dma_pool_alloc(dma_pool, GFP_KERNEL, | 1112 | if (!(port->desc_tab = dma_pool_alloc(dma_pool, GFP_KERNEL, |
| 1111 | &port->desc_tab_phys))) | 1113 | &port->desc_tab_phys))) |
diff --git a/drivers/net/irda/sir_dev.c b/drivers/net/irda/sir_dev.c index 5039f08f5a5b..43e9ab4f4d7e 100644 --- a/drivers/net/irda/sir_dev.c +++ b/drivers/net/irda/sir_dev.c | |||
| @@ -222,7 +222,7 @@ static void sirdev_config_fsm(struct work_struct *work) | |||
| 222 | break; | 222 | break; |
| 223 | 223 | ||
| 224 | case SIRDEV_STATE_DONGLE_SPEED: | 224 | case SIRDEV_STATE_DONGLE_SPEED: |
| 225 | if (dev->dongle_drv->reset) { | 225 | if (dev->dongle_drv->set_speed) { |
| 226 | ret = dev->dongle_drv->set_speed(dev, fsm->param); | 226 | ret = dev->dongle_drv->set_speed(dev, fsm->param); |
| 227 | if (ret < 0) { | 227 | if (ret < 0) { |
| 228 | fsm->result = ret; | 228 | fsm->result = ret; |
diff --git a/drivers/net/phy/Kconfig b/drivers/net/phy/Kconfig index 983bbf4d5ef6..961f0b293913 100644 --- a/drivers/net/phy/Kconfig +++ b/drivers/net/phy/Kconfig | |||
| @@ -15,6 +15,11 @@ if PHYLIB | |||
| 15 | 15 | ||
| 16 | comment "MII PHY device drivers" | 16 | comment "MII PHY device drivers" |
| 17 | 17 | ||
| 18 | config AT803X_PHY | ||
| 19 | tristate "Drivers for Atheros AT803X PHYs" | ||
| 20 | ---help--- | ||
| 21 | Currently supports the AT8030 and AT8035 model | ||
| 22 | |||
| 18 | config AMD_PHY | 23 | config AMD_PHY |
| 19 | tristate "Drivers for the AMD PHYs" | 24 | tristate "Drivers for the AMD PHYs" |
| 20 | ---help--- | 25 | ---help--- |
diff --git a/drivers/net/phy/Makefile b/drivers/net/phy/Makefile index 426674debae4..9645e389a58d 100644 --- a/drivers/net/phy/Makefile +++ b/drivers/net/phy/Makefile | |||
| @@ -25,6 +25,7 @@ obj-$(CONFIG_STE10XP) += ste10Xp.o | |||
| 25 | obj-$(CONFIG_MICREL_PHY) += micrel.o | 25 | obj-$(CONFIG_MICREL_PHY) += micrel.o |
| 26 | obj-$(CONFIG_MDIO_OCTEON) += mdio-octeon.o | 26 | obj-$(CONFIG_MDIO_OCTEON) += mdio-octeon.o |
| 27 | obj-$(CONFIG_MICREL_KS8995MA) += spi_ks8995.o | 27 | obj-$(CONFIG_MICREL_KS8995MA) += spi_ks8995.o |
| 28 | obj-$(CONFIG_AT803X_PHY) += at803x.o | ||
| 28 | obj-$(CONFIG_AMD_PHY) += amd.o | 29 | obj-$(CONFIG_AMD_PHY) += amd.o |
| 29 | obj-$(CONFIG_MDIO_BUS_MUX) += mdio-mux.o | 30 | obj-$(CONFIG_MDIO_BUS_MUX) += mdio-mux.o |
| 30 | obj-$(CONFIG_MDIO_BUS_MUX_GPIO) += mdio-mux-gpio.o | 31 | obj-$(CONFIG_MDIO_BUS_MUX_GPIO) += mdio-mux-gpio.o |
diff --git a/drivers/net/phy/at803x.c b/drivers/net/phy/at803x.c new file mode 100644 index 000000000000..45cbc10de01c --- /dev/null +++ b/drivers/net/phy/at803x.c | |||
| @@ -0,0 +1,176 @@ | |||
| 1 | /* | ||
| 2 | * drivers/net/phy/at803x.c | ||
| 3 | * | ||
| 4 | * Driver for Atheros 803x PHY | ||
| 5 | * | ||
| 6 | * Author: Matus Ujhelyi <ujhelyi.m@gmail.com> | ||
| 7 | * | ||
| 8 | * This program is free software; you can redistribute it and/or modify it | ||
| 9 | * under the terms of the GNU General Public License as published by the | ||
| 10 | * Free Software Foundation; either version 2 of the License, or (at your | ||
| 11 | * option) any later version. | ||
| 12 | */ | ||
| 13 | |||
| 14 | #include <linux/phy.h> | ||
| 15 | #include <linux/module.h> | ||
| 16 | #include <linux/string.h> | ||
| 17 | #include <linux/netdevice.h> | ||
| 18 | #include <linux/etherdevice.h> | ||
| 19 | |||
| 20 | #define AT803X_INTR_ENABLE 0x12 | ||
| 21 | #define AT803X_INTR_STATUS 0x13 | ||
| 22 | #define AT803X_WOL_ENABLE 0x01 | ||
| 23 | #define AT803X_DEVICE_ADDR 0x03 | ||
| 24 | #define AT803X_LOC_MAC_ADDR_0_15_OFFSET 0x804C | ||
| 25 | #define AT803X_LOC_MAC_ADDR_16_31_OFFSET 0x804B | ||
| 26 | #define AT803X_LOC_MAC_ADDR_32_47_OFFSET 0x804A | ||
| 27 | #define AT803X_MMD_ACCESS_CONTROL 0x0D | ||
| 28 | #define AT803X_MMD_ACCESS_CONTROL_DATA 0x0E | ||
| 29 | #define AT803X_FUNC_DATA 0x4003 | ||
| 30 | |||
| 31 | MODULE_DESCRIPTION("Atheros 803x PHY driver"); | ||
| 32 | MODULE_AUTHOR("Matus Ujhelyi"); | ||
| 33 | MODULE_LICENSE("GPL"); | ||
| 34 | |||
| 35 | static void at803x_set_wol_mac_addr(struct phy_device *phydev) | ||
| 36 | { | ||
| 37 | struct net_device *ndev = phydev->attached_dev; | ||
| 38 | const u8 *mac; | ||
| 39 | unsigned int i, offsets[] = { | ||
| 40 | AT803X_LOC_MAC_ADDR_32_47_OFFSET, | ||
| 41 | AT803X_LOC_MAC_ADDR_16_31_OFFSET, | ||
| 42 | AT803X_LOC_MAC_ADDR_0_15_OFFSET, | ||
| 43 | }; | ||
| 44 | |||
| 45 | if (!ndev) | ||
| 46 | return; | ||
| 47 | |||
| 48 | mac = (const u8 *) ndev->dev_addr; | ||
| 49 | |||
| 50 | if (!is_valid_ether_addr(mac)) | ||
| 51 | return; | ||
| 52 | |||
| 53 | for (i = 0; i < 3; i++) { | ||
| 54 | phy_write(phydev, AT803X_MMD_ACCESS_CONTROL, | ||
| 55 | AT803X_DEVICE_ADDR); | ||
| 56 | phy_write(phydev, AT803X_MMD_ACCESS_CONTROL_DATA, | ||
| 57 | offsets[i]); | ||
| 58 | phy_write(phydev, AT803X_MMD_ACCESS_CONTROL, | ||
| 59 | AT803X_FUNC_DATA); | ||
| 60 | phy_write(phydev, AT803X_MMD_ACCESS_CONTROL_DATA, | ||
| 61 | mac[(i * 2) + 1] | (mac[(i * 2)] << 8)); | ||
| 62 | } | ||
| 63 | } | ||
| 64 | |||
| 65 | static int at803x_config_init(struct phy_device *phydev) | ||
| 66 | { | ||
| 67 | int val; | ||
| 68 | u32 features; | ||
| 69 | int status; | ||
| 70 | |||
| 71 | features = SUPPORTED_TP | SUPPORTED_MII | SUPPORTED_AUI | | ||
| 72 | SUPPORTED_FIBRE | SUPPORTED_BNC; | ||
| 73 | |||
| 74 | val = phy_read(phydev, MII_BMSR); | ||
| 75 | if (val < 0) | ||
| 76 | return val; | ||
| 77 | |||
| 78 | if (val & BMSR_ANEGCAPABLE) | ||
| 79 | features |= SUPPORTED_Autoneg; | ||
| 80 | if (val & BMSR_100FULL) | ||
| 81 | features |= SUPPORTED_100baseT_Full; | ||
| 82 | if (val & BMSR_100HALF) | ||
| 83 | features |= SUPPORTED_100baseT_Half; | ||
| 84 | if (val & BMSR_10FULL) | ||
| 85 | features |= SUPPORTED_10baseT_Full; | ||
| 86 | if (val & BMSR_10HALF) | ||
| 87 | features |= SUPPORTED_10baseT_Half; | ||
| 88 | |||
| 89 | if (val & BMSR_ESTATEN) { | ||
| 90 | val = phy_read(phydev, MII_ESTATUS); | ||
| 91 | if (val < 0) | ||
| 92 | return val; | ||
| 93 | |||
| 94 | if (val & ESTATUS_1000_TFULL) | ||
| 95 | features |= SUPPORTED_1000baseT_Full; | ||
| 96 | if (val & ESTATUS_1000_THALF) | ||
| 97 | features |= SUPPORTED_1000baseT_Half; | ||
| 98 | } | ||
| 99 | |||
| 100 | phydev->supported = features; | ||
| 101 | phydev->advertising = features; | ||
| 102 | |||
| 103 | /* enable WOL */ | ||
| 104 | at803x_set_wol_mac_addr(phydev); | ||
| 105 | status = phy_write(phydev, AT803X_INTR_ENABLE, AT803X_WOL_ENABLE); | ||
| 106 | status = phy_read(phydev, AT803X_INTR_STATUS); | ||
| 107 | |||
| 108 | return 0; | ||
| 109 | } | ||
| 110 | |||
| 111 | /* ATHEROS 8035 */ | ||
| 112 | static struct phy_driver at8035_driver = { | ||
| 113 | .phy_id = 0x004dd072, | ||
| 114 | .name = "Atheros 8035 ethernet", | ||
| 115 | .phy_id_mask = 0xffffffef, | ||
| 116 | .config_init = at803x_config_init, | ||
| 117 | .features = PHY_GBIT_FEATURES, | ||
| 118 | .flags = PHY_HAS_INTERRUPT, | ||
| 119 | .config_aneg = &genphy_config_aneg, | ||
| 120 | .read_status = &genphy_read_status, | ||
| 121 | .driver = { | ||
| 122 | .owner = THIS_MODULE, | ||
| 123 | }, | ||
| 124 | }; | ||
| 125 | |||
| 126 | /* ATHEROS 8030 */ | ||
| 127 | static struct phy_driver at8030_driver = { | ||
| 128 | .phy_id = 0x004dd076, | ||
| 129 | .name = "Atheros 8030 ethernet", | ||
| 130 | .phy_id_mask = 0xffffffef, | ||
| 131 | .config_init = at803x_config_init, | ||
| 132 | .features = PHY_GBIT_FEATURES, | ||
| 133 | .flags = PHY_HAS_INTERRUPT, | ||
| 134 | .config_aneg = &genphy_config_aneg, | ||
| 135 | .read_status = &genphy_read_status, | ||
| 136 | .driver = { | ||
| 137 | .owner = THIS_MODULE, | ||
| 138 | }, | ||
| 139 | }; | ||
| 140 | |||
| 141 | static int __init atheros_init(void) | ||
| 142 | { | ||
| 143 | int ret; | ||
| 144 | |||
| 145 | ret = phy_driver_register(&at8035_driver); | ||
| 146 | if (ret) | ||
| 147 | goto err1; | ||
| 148 | |||
| 149 | ret = phy_driver_register(&at8030_driver); | ||
| 150 | if (ret) | ||
| 151 | goto err2; | ||
| 152 | |||
| 153 | return 0; | ||
| 154 | |||
| 155 | err2: | ||
| 156 | phy_driver_unregister(&at8035_driver); | ||
| 157 | err1: | ||
| 158 | return ret; | ||
| 159 | } | ||
| 160 | |||
| 161 | static void __exit atheros_exit(void) | ||
| 162 | { | ||
| 163 | phy_driver_unregister(&at8035_driver); | ||
| 164 | phy_driver_unregister(&at8030_driver); | ||
| 165 | } | ||
| 166 | |||
| 167 | module_init(atheros_init); | ||
| 168 | module_exit(atheros_exit); | ||
| 169 | |||
| 170 | static struct mdio_device_id __maybe_unused atheros_tbl[] = { | ||
| 171 | { 0x004dd076, 0xffffffef }, | ||
| 172 | { 0x004dd072, 0xffffffef }, | ||
| 173 | { } | ||
| 174 | }; | ||
| 175 | |||
| 176 | MODULE_DEVICE_TABLE(mdio, atheros_tbl); | ||
diff --git a/drivers/net/phy/mdio-gpio.c b/drivers/net/phy/mdio-gpio.c index 899274f2f9b1..2ed1140df3e9 100644 --- a/drivers/net/phy/mdio-gpio.c +++ b/drivers/net/phy/mdio-gpio.c | |||
| @@ -185,17 +185,20 @@ static int __devinit mdio_gpio_probe(struct platform_device *pdev) | |||
| 185 | { | 185 | { |
| 186 | struct mdio_gpio_platform_data *pdata; | 186 | struct mdio_gpio_platform_data *pdata; |
| 187 | struct mii_bus *new_bus; | 187 | struct mii_bus *new_bus; |
| 188 | int ret; | 188 | int ret, bus_id; |
| 189 | 189 | ||
| 190 | if (pdev->dev.of_node) | 190 | if (pdev->dev.of_node) { |
| 191 | pdata = mdio_gpio_of_get_data(pdev); | 191 | pdata = mdio_gpio_of_get_data(pdev); |
| 192 | else | 192 | bus_id = of_alias_get_id(pdev->dev.of_node, "mdio-gpio"); |
| 193 | } else { | ||
| 193 | pdata = pdev->dev.platform_data; | 194 | pdata = pdev->dev.platform_data; |
| 195 | bus_id = pdev->id; | ||
| 196 | } | ||
| 194 | 197 | ||
| 195 | if (!pdata) | 198 | if (!pdata) |
| 196 | return -ENODEV; | 199 | return -ENODEV; |
| 197 | 200 | ||
| 198 | new_bus = mdio_gpio_bus_init(&pdev->dev, pdata, pdev->id); | 201 | new_bus = mdio_gpio_bus_init(&pdev->dev, pdata, bus_id); |
| 199 | if (!new_bus) | 202 | if (!new_bus) |
| 200 | return -ENODEV; | 203 | return -ENODEV; |
| 201 | 204 | ||
diff --git a/drivers/net/team/team.c b/drivers/net/team/team.c index d44cca327588..ad86660fb8f9 100644 --- a/drivers/net/team/team.c +++ b/drivers/net/team/team.c | |||
| @@ -1794,10 +1794,12 @@ static void team_setup(struct net_device *dev) | |||
| 1794 | 1794 | ||
| 1795 | dev->features |= NETIF_F_LLTX; | 1795 | dev->features |= NETIF_F_LLTX; |
| 1796 | dev->features |= NETIF_F_GRO; | 1796 | dev->features |= NETIF_F_GRO; |
| 1797 | dev->hw_features = NETIF_F_HW_VLAN_TX | | 1797 | dev->hw_features = TEAM_VLAN_FEATURES | |
| 1798 | NETIF_F_HW_VLAN_TX | | ||
| 1798 | NETIF_F_HW_VLAN_RX | | 1799 | NETIF_F_HW_VLAN_RX | |
| 1799 | NETIF_F_HW_VLAN_FILTER; | 1800 | NETIF_F_HW_VLAN_FILTER; |
| 1800 | 1801 | ||
| 1802 | dev->hw_features &= ~(NETIF_F_ALL_CSUM & ~NETIF_F_HW_CSUM); | ||
| 1801 | dev->features |= dev->hw_features; | 1803 | dev->features |= dev->hw_features; |
| 1802 | } | 1804 | } |
| 1803 | 1805 | ||
diff --git a/drivers/net/team/team_mode_broadcast.c b/drivers/net/team/team_mode_broadcast.c index 9db0171e9366..c5db428e73fa 100644 --- a/drivers/net/team/team_mode_broadcast.c +++ b/drivers/net/team/team_mode_broadcast.c | |||
| @@ -29,8 +29,8 @@ static bool bc_transmit(struct team *team, struct sk_buff *skb) | |||
| 29 | if (last) { | 29 | if (last) { |
| 30 | skb2 = skb_clone(skb, GFP_ATOMIC); | 30 | skb2 = skb_clone(skb, GFP_ATOMIC); |
| 31 | if (skb2) { | 31 | if (skb2) { |
| 32 | ret = team_dev_queue_xmit(team, last, | 32 | ret = !team_dev_queue_xmit(team, last, |
| 33 | skb2); | 33 | skb2); |
| 34 | if (!sum_ret) | 34 | if (!sum_ret) |
| 35 | sum_ret = ret; | 35 | sum_ret = ret; |
| 36 | } | 36 | } |
| @@ -39,7 +39,7 @@ static bool bc_transmit(struct team *team, struct sk_buff *skb) | |||
| 39 | } | 39 | } |
| 40 | } | 40 | } |
| 41 | if (last) { | 41 | if (last) { |
| 42 | ret = team_dev_queue_xmit(team, last, skb); | 42 | ret = !team_dev_queue_xmit(team, last, skb); |
| 43 | if (!sum_ret) | 43 | if (!sum_ret) |
| 44 | sum_ret = ret; | 44 | sum_ret = ret; |
| 45 | } | 45 | } |
diff --git a/drivers/net/usb/cdc_eem.c b/drivers/net/usb/cdc_eem.c index c81e278629ff..08d55b6bf272 100644 --- a/drivers/net/usb/cdc_eem.c +++ b/drivers/net/usb/cdc_eem.c | |||
| @@ -31,6 +31,7 @@ | |||
| 31 | #include <linux/usb/cdc.h> | 31 | #include <linux/usb/cdc.h> |
| 32 | #include <linux/usb/usbnet.h> | 32 | #include <linux/usb/usbnet.h> |
| 33 | #include <linux/gfp.h> | 33 | #include <linux/gfp.h> |
| 34 | #include <linux/if_vlan.h> | ||
| 34 | 35 | ||
| 35 | 36 | ||
| 36 | /* | 37 | /* |
| @@ -92,7 +93,7 @@ static int eem_bind(struct usbnet *dev, struct usb_interface *intf) | |||
| 92 | 93 | ||
| 93 | /* no jumbogram (16K) support for now */ | 94 | /* no jumbogram (16K) support for now */ |
| 94 | 95 | ||
| 95 | dev->net->hard_header_len += EEM_HEAD + ETH_FCS_LEN; | 96 | dev->net->hard_header_len += EEM_HEAD + ETH_FCS_LEN + VLAN_HLEN; |
| 96 | dev->hard_mtu = dev->net->mtu + dev->net->hard_header_len; | 97 | dev->hard_mtu = dev->net->mtu + dev->net->hard_header_len; |
| 97 | 98 | ||
| 98 | return 0; | 99 | return 0; |
diff --git a/drivers/net/usb/cdc_ether.c b/drivers/net/usb/cdc_ether.c index a03de7197049..d0129827602b 100644 --- a/drivers/net/usb/cdc_ether.c +++ b/drivers/net/usb/cdc_ether.c | |||
| @@ -592,6 +592,32 @@ static const struct usb_device_id products [] = { | |||
| 592 | .driver_info = 0, | 592 | .driver_info = 0, |
| 593 | }, | 593 | }, |
| 594 | 594 | ||
| 595 | /* Novatel USB551L and MC551 - handled by qmi_wwan */ | ||
| 596 | { | ||
| 597 | .match_flags = USB_DEVICE_ID_MATCH_VENDOR | ||
| 598 | | USB_DEVICE_ID_MATCH_PRODUCT | ||
| 599 | | USB_DEVICE_ID_MATCH_INT_INFO, | ||
| 600 | .idVendor = NOVATEL_VENDOR_ID, | ||
| 601 | .idProduct = 0xB001, | ||
| 602 | .bInterfaceClass = USB_CLASS_COMM, | ||
| 603 | .bInterfaceSubClass = USB_CDC_SUBCLASS_ETHERNET, | ||
| 604 | .bInterfaceProtocol = USB_CDC_PROTO_NONE, | ||
| 605 | .driver_info = 0, | ||
| 606 | }, | ||
| 607 | |||
| 608 | /* Novatel E362 - handled by qmi_wwan */ | ||
| 609 | { | ||
| 610 | .match_flags = USB_DEVICE_ID_MATCH_VENDOR | ||
| 611 | | USB_DEVICE_ID_MATCH_PRODUCT | ||
| 612 | | USB_DEVICE_ID_MATCH_INT_INFO, | ||
| 613 | .idVendor = NOVATEL_VENDOR_ID, | ||
| 614 | .idProduct = 0x9010, | ||
| 615 | .bInterfaceClass = USB_CLASS_COMM, | ||
| 616 | .bInterfaceSubClass = USB_CDC_SUBCLASS_ETHERNET, | ||
| 617 | .bInterfaceProtocol = USB_CDC_PROTO_NONE, | ||
| 618 | .driver_info = 0, | ||
| 619 | }, | ||
| 620 | |||
| 595 | /* | 621 | /* |
| 596 | * WHITELIST!!! | 622 | * WHITELIST!!! |
| 597 | * | 623 | * |
| @@ -604,21 +630,6 @@ static const struct usb_device_id products [] = { | |||
| 604 | * because of bugs/quirks in a given product (like Zaurus, above). | 630 | * because of bugs/quirks in a given product (like Zaurus, above). |
| 605 | */ | 631 | */ |
| 606 | { | 632 | { |
| 607 | /* Novatel USB551L */ | ||
| 608 | /* This match must come *before* the generic CDC-ETHER match so that | ||
| 609 | * we get FLAG_WWAN set on the device, since it's descriptors are | ||
| 610 | * generic CDC-ETHER. | ||
| 611 | */ | ||
| 612 | .match_flags = USB_DEVICE_ID_MATCH_VENDOR | ||
| 613 | | USB_DEVICE_ID_MATCH_PRODUCT | ||
| 614 | | USB_DEVICE_ID_MATCH_INT_INFO, | ||
| 615 | .idVendor = NOVATEL_VENDOR_ID, | ||
| 616 | .idProduct = 0xB001, | ||
| 617 | .bInterfaceClass = USB_CLASS_COMM, | ||
| 618 | .bInterfaceSubClass = USB_CDC_SUBCLASS_ETHERNET, | ||
| 619 | .bInterfaceProtocol = USB_CDC_PROTO_NONE, | ||
| 620 | .driver_info = (unsigned long)&wwan_info, | ||
| 621 | }, { | ||
| 622 | /* ZTE (Vodafone) K3805-Z */ | 633 | /* ZTE (Vodafone) K3805-Z */ |
| 623 | .match_flags = USB_DEVICE_ID_MATCH_VENDOR | 634 | .match_flags = USB_DEVICE_ID_MATCH_VENDOR |
| 624 | | USB_DEVICE_ID_MATCH_PRODUCT | 635 | | USB_DEVICE_ID_MATCH_PRODUCT |
diff --git a/drivers/net/usb/cdc_ncm.c b/drivers/net/usb/cdc_ncm.c index 4cd582a4f625..74fab1a40156 100644 --- a/drivers/net/usb/cdc_ncm.c +++ b/drivers/net/usb/cdc_ncm.c | |||
| @@ -540,10 +540,12 @@ advance: | |||
| 540 | (ctx->ether_desc == NULL) || (ctx->control != intf)) | 540 | (ctx->ether_desc == NULL) || (ctx->control != intf)) |
| 541 | goto error; | 541 | goto error; |
| 542 | 542 | ||
| 543 | /* claim interfaces, if any */ | 543 | /* claim data interface, if different from control */ |
| 544 | temp = usb_driver_claim_interface(driver, ctx->data, dev); | 544 | if (ctx->data != ctx->control) { |
| 545 | if (temp) | 545 | temp = usb_driver_claim_interface(driver, ctx->data, dev); |
| 546 | goto error; | 546 | if (temp) |
| 547 | goto error; | ||
| 548 | } | ||
| 547 | 549 | ||
| 548 | iface_no = ctx->data->cur_altsetting->desc.bInterfaceNumber; | 550 | iface_no = ctx->data->cur_altsetting->desc.bInterfaceNumber; |
| 549 | 551 | ||
| @@ -623,6 +625,10 @@ static void cdc_ncm_unbind(struct usbnet *dev, struct usb_interface *intf) | |||
| 623 | 625 | ||
| 624 | tasklet_kill(&ctx->bh); | 626 | tasklet_kill(&ctx->bh); |
| 625 | 627 | ||
| 628 | /* handle devices with combined control and data interface */ | ||
| 629 | if (ctx->control == ctx->data) | ||
| 630 | ctx->data = NULL; | ||
| 631 | |||
| 626 | /* disconnect master --> disconnect slave */ | 632 | /* disconnect master --> disconnect slave */ |
| 627 | if (intf == ctx->control && ctx->data) { | 633 | if (intf == ctx->control && ctx->data) { |
| 628 | usb_set_intfdata(ctx->data, NULL); | 634 | usb_set_intfdata(ctx->data, NULL); |
| @@ -1245,6 +1251,14 @@ static const struct usb_device_id cdc_devs[] = { | |||
| 1245 | .driver_info = (unsigned long) &wwan_info, | 1251 | .driver_info = (unsigned long) &wwan_info, |
| 1246 | }, | 1252 | }, |
| 1247 | 1253 | ||
| 1254 | /* Huawei NCM devices disguised as vendor specific */ | ||
| 1255 | { USB_VENDOR_AND_INTERFACE_INFO(0x12d1, 0xff, 0x02, 0x16), | ||
| 1256 | .driver_info = (unsigned long)&wwan_info, | ||
| 1257 | }, | ||
| 1258 | { USB_VENDOR_AND_INTERFACE_INFO(0x12d1, 0xff, 0x02, 0x46), | ||
| 1259 | .driver_info = (unsigned long)&wwan_info, | ||
| 1260 | }, | ||
| 1261 | |||
| 1248 | /* Generic CDC-NCM devices */ | 1262 | /* Generic CDC-NCM devices */ |
| 1249 | { USB_INTERFACE_INFO(USB_CLASS_COMM, | 1263 | { USB_INTERFACE_INFO(USB_CLASS_COMM, |
| 1250 | USB_CDC_SUBCLASS_NCM, USB_CDC_PROTO_NONE), | 1264 | USB_CDC_SUBCLASS_NCM, USB_CDC_PROTO_NONE), |
diff --git a/drivers/net/usb/ipheth.c b/drivers/net/usb/ipheth.c index a28a983d465e..534d8becbbdc 100644 --- a/drivers/net/usb/ipheth.c +++ b/drivers/net/usb/ipheth.c | |||
| @@ -62,6 +62,7 @@ | |||
| 62 | #define USB_PRODUCT_IPAD 0x129a | 62 | #define USB_PRODUCT_IPAD 0x129a |
| 63 | #define USB_PRODUCT_IPHONE_4_VZW 0x129c | 63 | #define USB_PRODUCT_IPHONE_4_VZW 0x129c |
| 64 | #define USB_PRODUCT_IPHONE_4S 0x12a0 | 64 | #define USB_PRODUCT_IPHONE_4S 0x12a0 |
| 65 | #define USB_PRODUCT_IPHONE_5 0x12a8 | ||
| 65 | 66 | ||
| 66 | #define IPHETH_USBINTF_CLASS 255 | 67 | #define IPHETH_USBINTF_CLASS 255 |
| 67 | #define IPHETH_USBINTF_SUBCLASS 253 | 68 | #define IPHETH_USBINTF_SUBCLASS 253 |
| @@ -113,6 +114,10 @@ static struct usb_device_id ipheth_table[] = { | |||
| 113 | USB_VENDOR_APPLE, USB_PRODUCT_IPHONE_4S, | 114 | USB_VENDOR_APPLE, USB_PRODUCT_IPHONE_4S, |
| 114 | IPHETH_USBINTF_CLASS, IPHETH_USBINTF_SUBCLASS, | 115 | IPHETH_USBINTF_CLASS, IPHETH_USBINTF_SUBCLASS, |
| 115 | IPHETH_USBINTF_PROTO) }, | 116 | IPHETH_USBINTF_PROTO) }, |
| 117 | { USB_DEVICE_AND_INTERFACE_INFO( | ||
| 118 | USB_VENDOR_APPLE, USB_PRODUCT_IPHONE_5, | ||
| 119 | IPHETH_USBINTF_CLASS, IPHETH_USBINTF_SUBCLASS, | ||
| 120 | IPHETH_USBINTF_PROTO) }, | ||
| 116 | { } | 121 | { } |
| 117 | }; | 122 | }; |
| 118 | MODULE_DEVICE_TABLE(usb, ipheth_table); | 123 | MODULE_DEVICE_TABLE(usb, ipheth_table); |
diff --git a/drivers/net/usb/qmi_wwan.c b/drivers/net/usb/qmi_wwan.c index 6883c371c59f..1ea91f4237f0 100644 --- a/drivers/net/usb/qmi_wwan.c +++ b/drivers/net/usb/qmi_wwan.c | |||
| @@ -369,18 +369,74 @@ static const struct usb_device_id products[] = { | |||
| 369 | USB_VENDOR_AND_INTERFACE_INFO(0x106c, USB_CLASS_VENDOR_SPEC, 0xf1, 0xff), | 369 | USB_VENDOR_AND_INTERFACE_INFO(0x106c, USB_CLASS_VENDOR_SPEC, 0xf1, 0xff), |
| 370 | .driver_info = (unsigned long)&qmi_wwan_info, | 370 | .driver_info = (unsigned long)&qmi_wwan_info, |
| 371 | }, | 371 | }, |
| 372 | { /* Novatel USB551L and MC551 */ | ||
| 373 | USB_DEVICE_AND_INTERFACE_INFO(0x1410, 0xb001, | ||
| 374 | USB_CLASS_COMM, | ||
| 375 | USB_CDC_SUBCLASS_ETHERNET, | ||
| 376 | USB_CDC_PROTO_NONE), | ||
| 377 | .driver_info = (unsigned long)&qmi_wwan_info, | ||
| 378 | }, | ||
| 379 | { /* Novatel E362 */ | ||
| 380 | USB_DEVICE_AND_INTERFACE_INFO(0x1410, 0x9010, | ||
| 381 | USB_CLASS_COMM, | ||
| 382 | USB_CDC_SUBCLASS_ETHERNET, | ||
| 383 | USB_CDC_PROTO_NONE), | ||
| 384 | .driver_info = (unsigned long)&qmi_wwan_info, | ||
| 385 | }, | ||
| 372 | 386 | ||
| 373 | /* 3. Combined interface devices matching on interface number */ | 387 | /* 3. Combined interface devices matching on interface number */ |
| 388 | {QMI_FIXED_INTF(0x12d1, 0x140c, 1)}, /* Huawei E173 */ | ||
| 389 | {QMI_FIXED_INTF(0x19d2, 0x0002, 1)}, | ||
| 390 | {QMI_FIXED_INTF(0x19d2, 0x0012, 1)}, | ||
| 391 | {QMI_FIXED_INTF(0x19d2, 0x0017, 3)}, | ||
| 392 | {QMI_FIXED_INTF(0x19d2, 0x0021, 4)}, | ||
| 393 | {QMI_FIXED_INTF(0x19d2, 0x0025, 1)}, | ||
| 394 | {QMI_FIXED_INTF(0x19d2, 0x0031, 4)}, | ||
| 395 | {QMI_FIXED_INTF(0x19d2, 0x0042, 4)}, | ||
| 396 | {QMI_FIXED_INTF(0x19d2, 0x0049, 5)}, | ||
| 397 | {QMI_FIXED_INTF(0x19d2, 0x0052, 4)}, | ||
| 374 | {QMI_FIXED_INTF(0x19d2, 0x0055, 1)}, /* ZTE (Vodafone) K3520-Z */ | 398 | {QMI_FIXED_INTF(0x19d2, 0x0055, 1)}, /* ZTE (Vodafone) K3520-Z */ |
| 399 | {QMI_FIXED_INTF(0x19d2, 0x0058, 4)}, | ||
| 375 | {QMI_FIXED_INTF(0x19d2, 0x0063, 4)}, /* ZTE (Vodafone) K3565-Z */ | 400 | {QMI_FIXED_INTF(0x19d2, 0x0063, 4)}, /* ZTE (Vodafone) K3565-Z */ |
| 376 | {QMI_FIXED_INTF(0x19d2, 0x0104, 4)}, /* ZTE (Vodafone) K4505-Z */ | 401 | {QMI_FIXED_INTF(0x19d2, 0x0104, 4)}, /* ZTE (Vodafone) K4505-Z */ |
| 402 | {QMI_FIXED_INTF(0x19d2, 0x0113, 5)}, | ||
| 403 | {QMI_FIXED_INTF(0x19d2, 0x0118, 5)}, | ||
| 404 | {QMI_FIXED_INTF(0x19d2, 0x0121, 5)}, | ||
| 405 | {QMI_FIXED_INTF(0x19d2, 0x0123, 4)}, | ||
| 406 | {QMI_FIXED_INTF(0x19d2, 0x0124, 5)}, | ||
| 407 | {QMI_FIXED_INTF(0x19d2, 0x0125, 6)}, | ||
| 408 | {QMI_FIXED_INTF(0x19d2, 0x0126, 5)}, | ||
| 409 | {QMI_FIXED_INTF(0x19d2, 0x0130, 1)}, | ||
| 410 | {QMI_FIXED_INTF(0x19d2, 0x0133, 3)}, | ||
| 411 | {QMI_FIXED_INTF(0x19d2, 0x0141, 5)}, | ||
| 377 | {QMI_FIXED_INTF(0x19d2, 0x0157, 5)}, /* ZTE MF683 */ | 412 | {QMI_FIXED_INTF(0x19d2, 0x0157, 5)}, /* ZTE MF683 */ |
| 413 | {QMI_FIXED_INTF(0x19d2, 0x0158, 3)}, | ||
| 378 | {QMI_FIXED_INTF(0x19d2, 0x0167, 4)}, /* ZTE MF820D */ | 414 | {QMI_FIXED_INTF(0x19d2, 0x0167, 4)}, /* ZTE MF820D */ |
| 415 | {QMI_FIXED_INTF(0x19d2, 0x0168, 4)}, | ||
| 416 | {QMI_FIXED_INTF(0x19d2, 0x0176, 3)}, | ||
| 417 | {QMI_FIXED_INTF(0x19d2, 0x0178, 3)}, | ||
| 418 | {QMI_FIXED_INTF(0x19d2, 0x0191, 4)}, /* ZTE EuFi890 */ | ||
| 419 | {QMI_FIXED_INTF(0x19d2, 0x0199, 1)}, /* ZTE MF820S */ | ||
| 420 | {QMI_FIXED_INTF(0x19d2, 0x0200, 1)}, | ||
| 421 | {QMI_FIXED_INTF(0x19d2, 0x0257, 3)}, /* ZTE MF821 */ | ||
| 379 | {QMI_FIXED_INTF(0x19d2, 0x0326, 4)}, /* ZTE MF821D */ | 422 | {QMI_FIXED_INTF(0x19d2, 0x0326, 4)}, /* ZTE MF821D */ |
| 380 | {QMI_FIXED_INTF(0x19d2, 0x1008, 4)}, /* ZTE (Vodafone) K3570-Z */ | 423 | {QMI_FIXED_INTF(0x19d2, 0x1008, 4)}, /* ZTE (Vodafone) K3570-Z */ |
| 381 | {QMI_FIXED_INTF(0x19d2, 0x1010, 4)}, /* ZTE (Vodafone) K3571-Z */ | 424 | {QMI_FIXED_INTF(0x19d2, 0x1010, 4)}, /* ZTE (Vodafone) K3571-Z */ |
| 425 | {QMI_FIXED_INTF(0x19d2, 0x1012, 4)}, | ||
| 382 | {QMI_FIXED_INTF(0x19d2, 0x1018, 3)}, /* ZTE (Vodafone) K5006-Z */ | 426 | {QMI_FIXED_INTF(0x19d2, 0x1018, 3)}, /* ZTE (Vodafone) K5006-Z */ |
| 427 | {QMI_FIXED_INTF(0x19d2, 0x1021, 2)}, | ||
| 428 | {QMI_FIXED_INTF(0x19d2, 0x1245, 4)}, | ||
| 429 | {QMI_FIXED_INTF(0x19d2, 0x1247, 4)}, | ||
| 430 | {QMI_FIXED_INTF(0x19d2, 0x1252, 4)}, | ||
| 431 | {QMI_FIXED_INTF(0x19d2, 0x1254, 4)}, | ||
| 432 | {QMI_FIXED_INTF(0x19d2, 0x1255, 3)}, | ||
| 433 | {QMI_FIXED_INTF(0x19d2, 0x1255, 4)}, | ||
| 434 | {QMI_FIXED_INTF(0x19d2, 0x1256, 4)}, | ||
| 435 | {QMI_FIXED_INTF(0x19d2, 0x1401, 2)}, | ||
| 383 | {QMI_FIXED_INTF(0x19d2, 0x1402, 2)}, /* ZTE MF60 */ | 436 | {QMI_FIXED_INTF(0x19d2, 0x1402, 2)}, /* ZTE MF60 */ |
| 437 | {QMI_FIXED_INTF(0x19d2, 0x1424, 2)}, | ||
| 438 | {QMI_FIXED_INTF(0x19d2, 0x1425, 2)}, | ||
| 439 | {QMI_FIXED_INTF(0x19d2, 0x1426, 2)}, /* ZTE MF91 */ | ||
| 384 | {QMI_FIXED_INTF(0x19d2, 0x2002, 4)}, /* ZTE (Vodafone) K3765-Z */ | 440 | {QMI_FIXED_INTF(0x19d2, 0x2002, 4)}, /* ZTE (Vodafone) K3765-Z */ |
| 385 | {QMI_FIXED_INTF(0x0f3d, 0x68a2, 8)}, /* Sierra Wireless MC7700 */ | 441 | {QMI_FIXED_INTF(0x0f3d, 0x68a2, 8)}, /* Sierra Wireless MC7700 */ |
| 386 | {QMI_FIXED_INTF(0x114f, 0x68a2, 8)}, /* Sierra Wireless MC7750 */ | 442 | {QMI_FIXED_INTF(0x114f, 0x68a2, 8)}, /* Sierra Wireless MC7750 */ |
diff --git a/drivers/net/usb/smsc95xx.c b/drivers/net/usb/smsc95xx.c index 7479a5761d0d..362cb8cfeb92 100644 --- a/drivers/net/usb/smsc95xx.c +++ b/drivers/net/usb/smsc95xx.c | |||
| @@ -184,7 +184,7 @@ static int smsc95xx_mdio_read(struct net_device *netdev, int phy_id, int idx) | |||
| 184 | /* set the address, index & direction (read from PHY) */ | 184 | /* set the address, index & direction (read from PHY) */ |
| 185 | phy_id &= dev->mii.phy_id_mask; | 185 | phy_id &= dev->mii.phy_id_mask; |
| 186 | idx &= dev->mii.reg_num_mask; | 186 | idx &= dev->mii.reg_num_mask; |
| 187 | addr = (phy_id << 11) | (idx << 6) | MII_READ_; | 187 | addr = (phy_id << 11) | (idx << 6) | MII_READ_ | MII_BUSY_; |
| 188 | ret = smsc95xx_write_reg(dev, MII_ADDR, addr); | 188 | ret = smsc95xx_write_reg(dev, MII_ADDR, addr); |
| 189 | check_warn_goto_done(ret, "Error writing MII_ADDR"); | 189 | check_warn_goto_done(ret, "Error writing MII_ADDR"); |
| 190 | 190 | ||
| @@ -221,7 +221,7 @@ static void smsc95xx_mdio_write(struct net_device *netdev, int phy_id, int idx, | |||
| 221 | /* set the address, index & direction (write to PHY) */ | 221 | /* set the address, index & direction (write to PHY) */ |
| 222 | phy_id &= dev->mii.phy_id_mask; | 222 | phy_id &= dev->mii.phy_id_mask; |
| 223 | idx &= dev->mii.reg_num_mask; | 223 | idx &= dev->mii.reg_num_mask; |
| 224 | addr = (phy_id << 11) | (idx << 6) | MII_WRITE_; | 224 | addr = (phy_id << 11) | (idx << 6) | MII_WRITE_ | MII_BUSY_; |
| 225 | ret = smsc95xx_write_reg(dev, MII_ADDR, addr); | 225 | ret = smsc95xx_write_reg(dev, MII_ADDR, addr); |
| 226 | check_warn_goto_done(ret, "Error writing MII_ADDR"); | 226 | check_warn_goto_done(ret, "Error writing MII_ADDR"); |
| 227 | 227 | ||
| @@ -1344,6 +1344,7 @@ static struct sk_buff *smsc95xx_tx_fixup(struct usbnet *dev, | |||
| 1344 | } else { | 1344 | } else { |
| 1345 | u32 csum_preamble = smsc95xx_calc_csum_preamble(skb); | 1345 | u32 csum_preamble = smsc95xx_calc_csum_preamble(skb); |
| 1346 | skb_push(skb, 4); | 1346 | skb_push(skb, 4); |
| 1347 | cpu_to_le32s(&csum_preamble); | ||
| 1347 | memcpy(skb->data, &csum_preamble, 4); | 1348 | memcpy(skb->data, &csum_preamble, 4); |
| 1348 | } | 1349 | } |
| 1349 | } | 1350 | } |
diff --git a/drivers/net/usb/usbnet.c b/drivers/net/usb/usbnet.c index f9819d10b1f9..edb81ed06950 100644 --- a/drivers/net/usb/usbnet.c +++ b/drivers/net/usb/usbnet.c | |||
| @@ -359,10 +359,12 @@ static enum skb_state defer_bh(struct usbnet *dev, struct sk_buff *skb, | |||
| 359 | void usbnet_defer_kevent (struct usbnet *dev, int work) | 359 | void usbnet_defer_kevent (struct usbnet *dev, int work) |
| 360 | { | 360 | { |
| 361 | set_bit (work, &dev->flags); | 361 | set_bit (work, &dev->flags); |
| 362 | if (!schedule_work (&dev->kevent)) | 362 | if (!schedule_work (&dev->kevent)) { |
| 363 | netdev_err(dev->net, "kevent %d may have been dropped\n", work); | 363 | if (net_ratelimit()) |
| 364 | else | 364 | netdev_err(dev->net, "kevent %d may have been dropped\n", work); |
| 365 | } else { | ||
| 365 | netdev_dbg(dev->net, "kevent %d scheduled\n", work); | 366 | netdev_dbg(dev->net, "kevent %d scheduled\n", work); |
| 367 | } | ||
| 366 | } | 368 | } |
| 367 | EXPORT_SYMBOL_GPL(usbnet_defer_kevent); | 369 | EXPORT_SYMBOL_GPL(usbnet_defer_kevent); |
| 368 | 370 | ||
| @@ -1158,6 +1160,7 @@ netdev_tx_t usbnet_start_xmit (struct sk_buff *skb, | |||
| 1158 | usb_anchor_urb(urb, &dev->deferred); | 1160 | usb_anchor_urb(urb, &dev->deferred); |
| 1159 | /* no use to process more packets */ | 1161 | /* no use to process more packets */ |
| 1160 | netif_stop_queue(net); | 1162 | netif_stop_queue(net); |
| 1163 | usb_put_urb(urb); | ||
| 1161 | spin_unlock_irqrestore(&dev->txq.lock, flags); | 1164 | spin_unlock_irqrestore(&dev->txq.lock, flags); |
| 1162 | netdev_dbg(dev->net, "Delaying transmission for resumption\n"); | 1165 | netdev_dbg(dev->net, "Delaying transmission for resumption\n"); |
| 1163 | goto deferred; | 1166 | goto deferred; |
| @@ -1310,6 +1313,8 @@ void usbnet_disconnect (struct usb_interface *intf) | |||
| 1310 | 1313 | ||
| 1311 | cancel_work_sync(&dev->kevent); | 1314 | cancel_work_sync(&dev->kevent); |
| 1312 | 1315 | ||
| 1316 | usb_scuttle_anchored_urbs(&dev->deferred); | ||
| 1317 | |||
| 1313 | if (dev->driver_info->unbind) | 1318 | if (dev->driver_info->unbind) |
| 1314 | dev->driver_info->unbind (dev, intf); | 1319 | dev->driver_info->unbind (dev, intf); |
| 1315 | 1320 | ||
diff --git a/drivers/net/vmxnet3/vmxnet3_drv.c b/drivers/net/vmxnet3/vmxnet3_drv.c index ce9d4f2c9776..0ae1bcc6da73 100644 --- a/drivers/net/vmxnet3/vmxnet3_drv.c +++ b/drivers/net/vmxnet3/vmxnet3_drv.c | |||
| @@ -744,28 +744,43 @@ vmxnet3_map_pkt(struct sk_buff *skb, struct vmxnet3_tx_ctx *ctx, | |||
| 744 | 744 | ||
| 745 | for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { | 745 | for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { |
| 746 | const struct skb_frag_struct *frag = &skb_shinfo(skb)->frags[i]; | 746 | const struct skb_frag_struct *frag = &skb_shinfo(skb)->frags[i]; |
| 747 | u32 buf_size; | ||
| 747 | 748 | ||
| 748 | tbi = tq->buf_info + tq->tx_ring.next2fill; | 749 | buf_offset = 0; |
| 749 | tbi->map_type = VMXNET3_MAP_PAGE; | 750 | len = skb_frag_size(frag); |
| 750 | tbi->dma_addr = skb_frag_dma_map(&adapter->pdev->dev, frag, | 751 | while (len) { |
| 751 | 0, skb_frag_size(frag), | 752 | tbi = tq->buf_info + tq->tx_ring.next2fill; |
| 752 | DMA_TO_DEVICE); | 753 | if (len < VMXNET3_MAX_TX_BUF_SIZE) { |
| 754 | buf_size = len; | ||
| 755 | dw2 |= len; | ||
| 756 | } else { | ||
| 757 | buf_size = VMXNET3_MAX_TX_BUF_SIZE; | ||
| 758 | /* spec says that for TxDesc.len, 0 == 2^14 */ | ||
| 759 | } | ||
| 760 | tbi->map_type = VMXNET3_MAP_PAGE; | ||
| 761 | tbi->dma_addr = skb_frag_dma_map(&adapter->pdev->dev, frag, | ||
| 762 | buf_offset, buf_size, | ||
| 763 | DMA_TO_DEVICE); | ||
| 753 | 764 | ||
| 754 | tbi->len = skb_frag_size(frag); | 765 | tbi->len = buf_size; |
| 755 | 766 | ||
| 756 | gdesc = tq->tx_ring.base + tq->tx_ring.next2fill; | 767 | gdesc = tq->tx_ring.base + tq->tx_ring.next2fill; |
| 757 | BUG_ON(gdesc->txd.gen == tq->tx_ring.gen); | 768 | BUG_ON(gdesc->txd.gen == tq->tx_ring.gen); |
| 758 | 769 | ||
| 759 | gdesc->txd.addr = cpu_to_le64(tbi->dma_addr); | 770 | gdesc->txd.addr = cpu_to_le64(tbi->dma_addr); |
| 760 | gdesc->dword[2] = cpu_to_le32(dw2 | skb_frag_size(frag)); | 771 | gdesc->dword[2] = cpu_to_le32(dw2); |
| 761 | gdesc->dword[3] = 0; | 772 | gdesc->dword[3] = 0; |
| 762 | 773 | ||
| 763 | dev_dbg(&adapter->netdev->dev, | 774 | dev_dbg(&adapter->netdev->dev, |
| 764 | "txd[%u]: 0x%llu %u %u\n", | 775 | "txd[%u]: 0x%llu %u %u\n", |
| 765 | tq->tx_ring.next2fill, le64_to_cpu(gdesc->txd.addr), | 776 | tq->tx_ring.next2fill, le64_to_cpu(gdesc->txd.addr), |
| 766 | le32_to_cpu(gdesc->dword[2]), gdesc->dword[3]); | 777 | le32_to_cpu(gdesc->dword[2]), gdesc->dword[3]); |
| 767 | vmxnet3_cmd_ring_adv_next2fill(&tq->tx_ring); | 778 | vmxnet3_cmd_ring_adv_next2fill(&tq->tx_ring); |
| 768 | dw2 = tq->tx_ring.gen << VMXNET3_TXD_GEN_SHIFT; | 779 | dw2 = tq->tx_ring.gen << VMXNET3_TXD_GEN_SHIFT; |
| 780 | |||
| 781 | len -= buf_size; | ||
| 782 | buf_offset += buf_size; | ||
| 783 | } | ||
| 769 | } | 784 | } |
| 770 | 785 | ||
| 771 | ctx->eop_txd = gdesc; | 786 | ctx->eop_txd = gdesc; |
| @@ -886,6 +901,18 @@ vmxnet3_prepare_tso(struct sk_buff *skb, | |||
| 886 | } | 901 | } |
| 887 | } | 902 | } |
| 888 | 903 | ||
| 904 | static int txd_estimate(const struct sk_buff *skb) | ||
| 905 | { | ||
| 906 | int count = VMXNET3_TXD_NEEDED(skb_headlen(skb)) + 1; | ||
| 907 | int i; | ||
| 908 | |||
| 909 | for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { | ||
| 910 | const struct skb_frag_struct *frag = &skb_shinfo(skb)->frags[i]; | ||
| 911 | |||
| 912 | count += VMXNET3_TXD_NEEDED(skb_frag_size(frag)); | ||
| 913 | } | ||
| 914 | return count; | ||
| 915 | } | ||
| 889 | 916 | ||
| 890 | /* | 917 | /* |
| 891 | * Transmits a pkt thru a given tq | 918 | * Transmits a pkt thru a given tq |
| @@ -914,9 +941,7 @@ vmxnet3_tq_xmit(struct sk_buff *skb, struct vmxnet3_tx_queue *tq, | |||
| 914 | union Vmxnet3_GenericDesc tempTxDesc; | 941 | union Vmxnet3_GenericDesc tempTxDesc; |
| 915 | #endif | 942 | #endif |
| 916 | 943 | ||
| 917 | /* conservatively estimate # of descriptors to use */ | 944 | count = txd_estimate(skb); |
| 918 | count = VMXNET3_TXD_NEEDED(skb_headlen(skb)) + | ||
| 919 | skb_shinfo(skb)->nr_frags + 1; | ||
| 920 | 945 | ||
| 921 | ctx.ipv4 = (vlan_get_protocol(skb) == cpu_to_be16(ETH_P_IP)); | 946 | ctx.ipv4 = (vlan_get_protocol(skb) == cpu_to_be16(ETH_P_IP)); |
| 922 | 947 | ||
diff --git a/drivers/net/vxlan.c b/drivers/net/vxlan.c index 607976c00162..8b5c61917076 100644 --- a/drivers/net/vxlan.c +++ b/drivers/net/vxlan.c | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * VXLAN: Virtual eXtensiable Local Area Network | 2 | * VXLAN: Virtual eXtensible Local Area Network |
| 3 | * | 3 | * |
| 4 | * Copyright (c) 2012 Vyatta Inc. | 4 | * Copyright (c) 2012 Vyatta Inc. |
| 5 | * | 5 | * |
| @@ -50,8 +50,8 @@ | |||
| 50 | 50 | ||
| 51 | #define VXLAN_N_VID (1u << 24) | 51 | #define VXLAN_N_VID (1u << 24) |
| 52 | #define VXLAN_VID_MASK (VXLAN_N_VID - 1) | 52 | #define VXLAN_VID_MASK (VXLAN_N_VID - 1) |
| 53 | /* VLAN + IP header + UDP + VXLAN */ | 53 | /* IP header + UDP + VXLAN + Ethernet header */ |
| 54 | #define VXLAN_HEADROOM (4 + 20 + 8 + 8) | 54 | #define VXLAN_HEADROOM (20 + 8 + 8 + 14) |
| 55 | 55 | ||
| 56 | #define VXLAN_FLAGS 0x08000000 /* struct vxlanhdr.vx_flags required value. */ | 56 | #define VXLAN_FLAGS 0x08000000 /* struct vxlanhdr.vx_flags required value. */ |
| 57 | 57 | ||
| @@ -816,7 +816,7 @@ static void vxlan_cleanup(unsigned long arg) | |||
| 816 | = container_of(p, struct vxlan_fdb, hlist); | 816 | = container_of(p, struct vxlan_fdb, hlist); |
| 817 | unsigned long timeout; | 817 | unsigned long timeout; |
| 818 | 818 | ||
| 819 | if (f->state == NUD_PERMANENT) | 819 | if (f->state & NUD_PERMANENT) |
| 820 | continue; | 820 | continue; |
| 821 | 821 | ||
| 822 | timeout = f->used + vxlan->age_interval * HZ; | 822 | timeout = f->used + vxlan->age_interval * HZ; |
| @@ -1102,6 +1102,10 @@ static int vxlan_newlink(struct net *net, struct net_device *dev, | |||
| 1102 | 1102 | ||
| 1103 | if (!tb[IFLA_MTU]) | 1103 | if (!tb[IFLA_MTU]) |
| 1104 | dev->mtu = lowerdev->mtu - VXLAN_HEADROOM; | 1104 | dev->mtu = lowerdev->mtu - VXLAN_HEADROOM; |
| 1105 | |||
| 1106 | /* update header length based on lower device */ | ||
| 1107 | dev->hard_header_len = lowerdev->hard_header_len + | ||
| 1108 | VXLAN_HEADROOM; | ||
| 1105 | } | 1109 | } |
| 1106 | 1110 | ||
| 1107 | if (data[IFLA_VXLAN_TOS]) | 1111 | if (data[IFLA_VXLAN_TOS]) |
diff --git a/drivers/net/wan/ixp4xx_hss.c b/drivers/net/wan/ixp4xx_hss.c index 3f575afd8cfc..760776b3d66c 100644 --- a/drivers/net/wan/ixp4xx_hss.c +++ b/drivers/net/wan/ixp4xx_hss.c | |||
| @@ -969,10 +969,12 @@ static int init_hdlc_queues(struct port *port) | |||
| 969 | { | 969 | { |
| 970 | int i; | 970 | int i; |
| 971 | 971 | ||
| 972 | if (!ports_open) | 972 | if (!ports_open) { |
| 973 | if (!(dma_pool = dma_pool_create(DRV_NAME, NULL, | 973 | dma_pool = dma_pool_create(DRV_NAME, &port->netdev->dev, |
| 974 | POOL_ALLOC_SIZE, 32, 0))) | 974 | POOL_ALLOC_SIZE, 32, 0); |
| 975 | if (!dma_pool) | ||
| 975 | return -ENOMEM; | 976 | return -ENOMEM; |
| 977 | } | ||
| 976 | 978 | ||
| 977 | if (!(port->desc_tab = dma_pool_alloc(dma_pool, GFP_KERNEL, | 979 | if (!(port->desc_tab = dma_pool_alloc(dma_pool, GFP_KERNEL, |
| 978 | &port->desc_tab_phys))) | 980 | &port->desc_tab_phys))) |
| @@ -1363,7 +1365,7 @@ static int __devinit hss_init_one(struct platform_device *pdev) | |||
| 1363 | 1365 | ||
| 1364 | platform_set_drvdata(pdev, port); | 1366 | platform_set_drvdata(pdev, port); |
| 1365 | 1367 | ||
| 1366 | netdev_info(dev, "HSS-%i\n", port->id); | 1368 | netdev_info(dev, "initialized\n"); |
| 1367 | return 0; | 1369 | return 0; |
| 1368 | 1370 | ||
| 1369 | err_free_netdev: | 1371 | err_free_netdev: |
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h b/drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h index 89bf94d4d8a1..6f7cf49eff4d 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h +++ b/drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h | |||
| @@ -534,107 +534,107 @@ static const u32 ar9300_2p2_baseband_core[][2] = { | |||
| 534 | 534 | ||
| 535 | static const u32 ar9300Modes_high_power_tx_gain_table_2p2[][5] = { | 535 | static const u32 ar9300Modes_high_power_tx_gain_table_2p2[][5] = { |
| 536 | /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ | 536 | /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ |
| 537 | {0x0000a2dc, 0x000cfff0, 0x000cfff0, 0x03aaa352, 0x03aaa352}, | 537 | {0x0000a2dc, 0x00033800, 0x00033800, 0x03aaa352, 0x03aaa352}, |
| 538 | {0x0000a2e0, 0x000f0000, 0x000f0000, 0x03ccc584, 0x03ccc584}, | 538 | {0x0000a2e0, 0x0003c000, 0x0003c000, 0x03ccc584, 0x03ccc584}, |
| 539 | {0x0000a2e4, 0x03f00000, 0x03f00000, 0x03f0f800, 0x03f0f800}, | 539 | {0x0000a2e4, 0x03fc0000, 0x03fc0000, 0x03f0f800, 0x03f0f800}, |
| 540 | {0x0000a2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000}, | 540 | {0x0000a2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000}, |
| 541 | {0x0000a410, 0x000050d9, 0x000050d9, 0x000050d9, 0x000050d9}, | 541 | {0x0000a410, 0x000050d9, 0x000050d9, 0x000050d9, 0x000050d9}, |
| 542 | {0x0000a500, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | 542 | {0x0000a500, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, |
| 543 | {0x0000a504, 0x06000003, 0x06000003, 0x04000002, 0x04000002}, | 543 | {0x0000a504, 0x06000003, 0x06000003, 0x04000002, 0x04000002}, |
| 544 | {0x0000a508, 0x0a000020, 0x0a000020, 0x08000004, 0x08000004}, | 544 | {0x0000a508, 0x0a000020, 0x0a000020, 0x08000004, 0x08000004}, |
| 545 | {0x0000a50c, 0x10000023, 0x10000023, 0x0b000200, 0x0b000200}, | 545 | {0x0000a50c, 0x10000023, 0x10000023, 0x0b000200, 0x0b000200}, |
| 546 | {0x0000a510, 0x15000028, 0x15000028, 0x0f000202, 0x0f000202}, | 546 | {0x0000a510, 0x16000220, 0x16000220, 0x0f000202, 0x0f000202}, |
| 547 | {0x0000a514, 0x1b00002b, 0x1b00002b, 0x12000400, 0x12000400}, | 547 | {0x0000a514, 0x1c000223, 0x1c000223, 0x12000400, 0x12000400}, |
| 548 | {0x0000a518, 0x1f020028, 0x1f020028, 0x16000402, 0x16000402}, | 548 | {0x0000a518, 0x21002220, 0x21002220, 0x16000402, 0x16000402}, |
| 549 | {0x0000a51c, 0x2502002b, 0x2502002b, 0x19000404, 0x19000404}, | 549 | {0x0000a51c, 0x27002223, 0x27002223, 0x19000404, 0x19000404}, |
| 550 | {0x0000a520, 0x2a04002a, 0x2a04002a, 0x1c000603, 0x1c000603}, | 550 | {0x0000a520, 0x2b022220, 0x2b022220, 0x1c000603, 0x1c000603}, |
| 551 | {0x0000a524, 0x2e06002a, 0x2e06002a, 0x21000a02, 0x21000a02}, | 551 | {0x0000a524, 0x2f022222, 0x2f022222, 0x21000a02, 0x21000a02}, |
| 552 | {0x0000a528, 0x3302202d, 0x3302202d, 0x25000a04, 0x25000a04}, | 552 | {0x0000a528, 0x34022225, 0x34022225, 0x25000a04, 0x25000a04}, |
| 553 | {0x0000a52c, 0x3804202c, 0x3804202c, 0x28000a20, 0x28000a20}, | 553 | {0x0000a52c, 0x3a02222a, 0x3a02222a, 0x28000a20, 0x28000a20}, |
| 554 | {0x0000a530, 0x3c06202c, 0x3c06202c, 0x2c000e20, 0x2c000e20}, | 554 | {0x0000a530, 0x3e02222c, 0x3e02222c, 0x2c000e20, 0x2c000e20}, |
| 555 | {0x0000a534, 0x4108202d, 0x4108202d, 0x30000e22, 0x30000e22}, | 555 | {0x0000a534, 0x4202242a, 0x4202242a, 0x30000e22, 0x30000e22}, |
| 556 | {0x0000a538, 0x4506402d, 0x4506402d, 0x34000e24, 0x34000e24}, | 556 | {0x0000a538, 0x4702244a, 0x4702244a, 0x34000e24, 0x34000e24}, |
| 557 | {0x0000a53c, 0x4906222d, 0x4906222d, 0x38001640, 0x38001640}, | 557 | {0x0000a53c, 0x4b02244c, 0x4b02244c, 0x38001640, 0x38001640}, |
| 558 | {0x0000a540, 0x4d062231, 0x4d062231, 0x3c001660, 0x3c001660}, | 558 | {0x0000a540, 0x4e02246c, 0x4e02246c, 0x3c001660, 0x3c001660}, |
| 559 | {0x0000a544, 0x50082231, 0x50082231, 0x3f001861, 0x3f001861}, | 559 | {0x0000a544, 0x52022470, 0x52022470, 0x3f001861, 0x3f001861}, |
| 560 | {0x0000a548, 0x5608422e, 0x5608422e, 0x43001a81, 0x43001a81}, | 560 | {0x0000a548, 0x55022490, 0x55022490, 0x43001a81, 0x43001a81}, |
| 561 | {0x0000a54c, 0x5a08442e, 0x5a08442e, 0x47001a83, 0x47001a83}, | 561 | {0x0000a54c, 0x59022492, 0x59022492, 0x47001a83, 0x47001a83}, |
| 562 | {0x0000a550, 0x5e0a4431, 0x5e0a4431, 0x4a001c84, 0x4a001c84}, | 562 | {0x0000a550, 0x5d022692, 0x5d022692, 0x4a001c84, 0x4a001c84}, |
| 563 | {0x0000a554, 0x640a4432, 0x640a4432, 0x4e001ce3, 0x4e001ce3}, | 563 | {0x0000a554, 0x61022892, 0x61022892, 0x4e001ce3, 0x4e001ce3}, |
| 564 | {0x0000a558, 0x680a4434, 0x680a4434, 0x52001ce5, 0x52001ce5}, | 564 | {0x0000a558, 0x65024890, 0x65024890, 0x52001ce5, 0x52001ce5}, |
| 565 | {0x0000a55c, 0x6c0a6434, 0x6c0a6434, 0x56001ce9, 0x56001ce9}, | 565 | {0x0000a55c, 0x69024892, 0x69024892, 0x56001ce9, 0x56001ce9}, |
| 566 | {0x0000a560, 0x6f0a6633, 0x6f0a6633, 0x5a001ceb, 0x5a001ceb}, | 566 | {0x0000a560, 0x6e024c92, 0x6e024c92, 0x5a001ceb, 0x5a001ceb}, |
| 567 | {0x0000a564, 0x730c6634, 0x730c6634, 0x5d001eec, 0x5d001eec}, | 567 | {0x0000a564, 0x74026e92, 0x74026e92, 0x5d001eec, 0x5d001eec}, |
| 568 | {0x0000a568, 0x730c6634, 0x730c6634, 0x5d001eec, 0x5d001eec}, | 568 | {0x0000a568, 0x74026e92, 0x74026e92, 0x5d001eec, 0x5d001eec}, |
| 569 | {0x0000a56c, 0x730c6634, 0x730c6634, 0x5d001eec, 0x5d001eec}, | 569 | {0x0000a56c, 0x74026e92, 0x74026e92, 0x5d001eec, 0x5d001eec}, |
| 570 | {0x0000a570, 0x730c6634, 0x730c6634, 0x5d001eec, 0x5d001eec}, | 570 | {0x0000a570, 0x74026e92, 0x74026e92, 0x5d001eec, 0x5d001eec}, |
| 571 | {0x0000a574, 0x730c6634, 0x730c6634, 0x5d001eec, 0x5d001eec}, | 571 | {0x0000a574, 0x74026e92, 0x74026e92, 0x5d001eec, 0x5d001eec}, |
| 572 | {0x0000a578, 0x730c6634, 0x730c6634, 0x5d001eec, 0x5d001eec}, | 572 | {0x0000a578, 0x74026e92, 0x74026e92, 0x5d001eec, 0x5d001eec}, |
| 573 | {0x0000a57c, 0x730c6634, 0x730c6634, 0x5d001eec, 0x5d001eec}, | 573 | {0x0000a57c, 0x74026e92, 0x74026e92, 0x5d001eec, 0x5d001eec}, |
| 574 | {0x0000a580, 0x00800000, 0x00800000, 0x00800000, 0x00800000}, | 574 | {0x0000a580, 0x00800000, 0x00800000, 0x00800000, 0x00800000}, |
| 575 | {0x0000a584, 0x06800003, 0x06800003, 0x04800002, 0x04800002}, | 575 | {0x0000a584, 0x06800003, 0x06800003, 0x04800002, 0x04800002}, |
| 576 | {0x0000a588, 0x0a800020, 0x0a800020, 0x08800004, 0x08800004}, | 576 | {0x0000a588, 0x0a800020, 0x0a800020, 0x08800004, 0x08800004}, |
| 577 | {0x0000a58c, 0x10800023, 0x10800023, 0x0b800200, 0x0b800200}, | 577 | {0x0000a58c, 0x10800023, 0x10800023, 0x0b800200, 0x0b800200}, |
| 578 | {0x0000a590, 0x15800028, 0x15800028, 0x0f800202, 0x0f800202}, | 578 | {0x0000a590, 0x16800220, 0x16800220, 0x0f800202, 0x0f800202}, |
| 579 | {0x0000a594, 0x1b80002b, 0x1b80002b, 0x12800400, 0x12800400}, | 579 | {0x0000a594, 0x1c800223, 0x1c800223, 0x12800400, 0x12800400}, |
| 580 | {0x0000a598, 0x1f820028, 0x1f820028, 0x16800402, 0x16800402}, | 580 | {0x0000a598, 0x21802220, 0x21802220, 0x16800402, 0x16800402}, |
| 581 | {0x0000a59c, 0x2582002b, 0x2582002b, 0x19800404, 0x19800404}, | 581 | {0x0000a59c, 0x27802223, 0x27802223, 0x19800404, 0x19800404}, |
| 582 | {0x0000a5a0, 0x2a84002a, 0x2a84002a, 0x1c800603, 0x1c800603}, | 582 | {0x0000a5a0, 0x2b822220, 0x2b822220, 0x1c800603, 0x1c800603}, |
| 583 | {0x0000a5a4, 0x2e86002a, 0x2e86002a, 0x21800a02, 0x21800a02}, | 583 | {0x0000a5a4, 0x2f822222, 0x2f822222, 0x21800a02, 0x21800a02}, |
| 584 | {0x0000a5a8, 0x3382202d, 0x3382202d, 0x25800a04, 0x25800a04}, | 584 | {0x0000a5a8, 0x34822225, 0x34822225, 0x25800a04, 0x25800a04}, |
| 585 | {0x0000a5ac, 0x3884202c, 0x3884202c, 0x28800a20, 0x28800a20}, | 585 | {0x0000a5ac, 0x3a82222a, 0x3a82222a, 0x28800a20, 0x28800a20}, |
| 586 | {0x0000a5b0, 0x3c86202c, 0x3c86202c, 0x2c800e20, 0x2c800e20}, | 586 | {0x0000a5b0, 0x3e82222c, 0x3e82222c, 0x2c800e20, 0x2c800e20}, |
| 587 | {0x0000a5b4, 0x4188202d, 0x4188202d, 0x30800e22, 0x30800e22}, | 587 | {0x0000a5b4, 0x4282242a, 0x4282242a, 0x30800e22, 0x30800e22}, |
| 588 | {0x0000a5b8, 0x4586402d, 0x4586402d, 0x34800e24, 0x34800e24}, | 588 | {0x0000a5b8, 0x4782244a, 0x4782244a, 0x34800e24, 0x34800e24}, |
| 589 | {0x0000a5bc, 0x4986222d, 0x4986222d, 0x38801640, 0x38801640}, | 589 | {0x0000a5bc, 0x4b82244c, 0x4b82244c, 0x38801640, 0x38801640}, |
| 590 | {0x0000a5c0, 0x4d862231, 0x4d862231, 0x3c801660, 0x3c801660}, | 590 | {0x0000a5c0, 0x4e82246c, 0x4e82246c, 0x3c801660, 0x3c801660}, |
| 591 | {0x0000a5c4, 0x50882231, 0x50882231, 0x3f801861, 0x3f801861}, | 591 | {0x0000a5c4, 0x52822470, 0x52822470, 0x3f801861, 0x3f801861}, |
| 592 | {0x0000a5c8, 0x5688422e, 0x5688422e, 0x43801a81, 0x43801a81}, | 592 | {0x0000a5c8, 0x55822490, 0x55822490, 0x43801a81, 0x43801a81}, |
| 593 | {0x0000a5cc, 0x5a88442e, 0x5a88442e, 0x47801a83, 0x47801a83}, | 593 | {0x0000a5cc, 0x59822492, 0x59822492, 0x47801a83, 0x47801a83}, |
| 594 | {0x0000a5d0, 0x5e8a4431, 0x5e8a4431, 0x4a801c84, 0x4a801c84}, | 594 | {0x0000a5d0, 0x5d822692, 0x5d822692, 0x4a801c84, 0x4a801c84}, |
| 595 | {0x0000a5d4, 0x648a4432, 0x648a4432, 0x4e801ce3, 0x4e801ce3}, | 595 | {0x0000a5d4, 0x61822892, 0x61822892, 0x4e801ce3, 0x4e801ce3}, |
| 596 | {0x0000a5d8, 0x688a4434, 0x688a4434, 0x52801ce5, 0x52801ce5}, | 596 | {0x0000a5d8, 0x65824890, 0x65824890, 0x52801ce5, 0x52801ce5}, |
| 597 | {0x0000a5dc, 0x6c8a6434, 0x6c8a6434, 0x56801ce9, 0x56801ce9}, | 597 | {0x0000a5dc, 0x69824892, 0x69824892, 0x56801ce9, 0x56801ce9}, |
| 598 | {0x0000a5e0, 0x6f8a6633, 0x6f8a6633, 0x5a801ceb, 0x5a801ceb}, | 598 | {0x0000a5e0, 0x6e824c92, 0x6e824c92, 0x5a801ceb, 0x5a801ceb}, |
| 599 | {0x0000a5e4, 0x738c6634, 0x738c6634, 0x5d801eec, 0x5d801eec}, | 599 | {0x0000a5e4, 0x74826e92, 0x74826e92, 0x5d801eec, 0x5d801eec}, |
| 600 | {0x0000a5e8, 0x738c6634, 0x738c6634, 0x5d801eec, 0x5d801eec}, | 600 | {0x0000a5e8, 0x74826e92, 0x74826e92, 0x5d801eec, 0x5d801eec}, |
| 601 | {0x0000a5ec, 0x738c6634, 0x738c6634, 0x5d801eec, 0x5d801eec}, | 601 | {0x0000a5ec, 0x74826e92, 0x74826e92, 0x5d801eec, 0x5d801eec}, |
| 602 | {0x0000a5f0, 0x738c6634, 0x738c6634, 0x5d801eec, 0x5d801eec}, | 602 | {0x0000a5f0, 0x74826e92, 0x74826e92, 0x5d801eec, 0x5d801eec}, |
| 603 | {0x0000a5f4, 0x738c6634, 0x738c6634, 0x5d801eec, 0x5d801eec}, | 603 | {0x0000a5f4, 0x74826e92, 0x74826e92, 0x5d801eec, 0x5d801eec}, |
| 604 | {0x0000a5f8, 0x738c6634, 0x738c6634, 0x5d801eec, 0x5d801eec}, | 604 | {0x0000a5f8, 0x74826e92, 0x74826e92, 0x5d801eec, 0x5d801eec}, |
| 605 | {0x0000a5fc, 0x738c6634, 0x738c6634, 0x5d801eec, 0x5d801eec}, | 605 | {0x0000a5fc, 0x74826e92, 0x74826e92, 0x5d801eec, 0x5d801eec}, |
| 606 | {0x0000a600, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | 606 | {0x0000a600, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, |
| 607 | {0x0000a604, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | 607 | {0x0000a604, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, |
| 608 | {0x0000a608, 0x01804601, 0x01804601, 0x00000000, 0x00000000}, | 608 | {0x0000a608, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, |
| 609 | {0x0000a60c, 0x01804601, 0x01804601, 0x00000000, 0x00000000}, | 609 | {0x0000a60c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, |
| 610 | {0x0000a610, 0x01804601, 0x01804601, 0x00000000, 0x00000000}, | 610 | {0x0000a610, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, |
| 611 | {0x0000a614, 0x01804601, 0x01804601, 0x01404000, 0x01404000}, | 611 | {0x0000a614, 0x02004000, 0x02004000, 0x01404000, 0x01404000}, |
| 612 | {0x0000a618, 0x01804601, 0x01804601, 0x01404501, 0x01404501}, | 612 | {0x0000a618, 0x02004801, 0x02004801, 0x01404501, 0x01404501}, |
| 613 | {0x0000a61c, 0x01804601, 0x01804601, 0x02008501, 0x02008501}, | 613 | {0x0000a61c, 0x02808a02, 0x02808a02, 0x02008501, 0x02008501}, |
| 614 | {0x0000a620, 0x03408d02, 0x03408d02, 0x0280ca03, 0x0280ca03}, | 614 | {0x0000a620, 0x0380ce03, 0x0380ce03, 0x0280ca03, 0x0280ca03}, |
| 615 | {0x0000a624, 0x0300cc03, 0x0300cc03, 0x03010c04, 0x03010c04}, | 615 | {0x0000a624, 0x04411104, 0x04411104, 0x03010c04, 0x03010c04}, |
| 616 | {0x0000a628, 0x03410d04, 0x03410d04, 0x04014c04, 0x04014c04}, | 616 | {0x0000a628, 0x04411104, 0x04411104, 0x04014c04, 0x04014c04}, |
| 617 | {0x0000a62c, 0x03410d04, 0x03410d04, 0x04015005, 0x04015005}, | 617 | {0x0000a62c, 0x04411104, 0x04411104, 0x04015005, 0x04015005}, |
| 618 | {0x0000a630, 0x03410d04, 0x03410d04, 0x04015005, 0x04015005}, | 618 | {0x0000a630, 0x04411104, 0x04411104, 0x04015005, 0x04015005}, |
| 619 | {0x0000a634, 0x03410d04, 0x03410d04, 0x04015005, 0x04015005}, | 619 | {0x0000a634, 0x04411104, 0x04411104, 0x04015005, 0x04015005}, |
| 620 | {0x0000a638, 0x03410d04, 0x03410d04, 0x04015005, 0x04015005}, | 620 | {0x0000a638, 0x04411104, 0x04411104, 0x04015005, 0x04015005}, |
| 621 | {0x0000a63c, 0x03410d04, 0x03410d04, 0x04015005, 0x04015005}, | 621 | {0x0000a63c, 0x04411104, 0x04411104, 0x04015005, 0x04015005}, |
| 622 | {0x0000b2dc, 0x000cfff0, 0x000cfff0, 0x03aaa352, 0x03aaa352}, | 622 | {0x0000b2dc, 0x00033800, 0x00033800, 0x03aaa352, 0x03aaa352}, |
| 623 | {0x0000b2e0, 0x000f0000, 0x000f0000, 0x03ccc584, 0x03ccc584}, | 623 | {0x0000b2e0, 0x0003c000, 0x0003c000, 0x03ccc584, 0x03ccc584}, |
| 624 | {0x0000b2e4, 0x03f00000, 0x03f00000, 0x03f0f800, 0x03f0f800}, | 624 | {0x0000b2e4, 0x03fc0000, 0x03fc0000, 0x03f0f800, 0x03f0f800}, |
| 625 | {0x0000b2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000}, | 625 | {0x0000b2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000}, |
| 626 | {0x0000c2dc, 0x000cfff0, 0x000cfff0, 0x03aaa352, 0x03aaa352}, | 626 | {0x0000c2dc, 0x00033800, 0x00033800, 0x03aaa352, 0x03aaa352}, |
| 627 | {0x0000c2e0, 0x000f0000, 0x000f0000, 0x03ccc584, 0x03ccc584}, | 627 | {0x0000c2e0, 0x0003c000, 0x0003c000, 0x03ccc584, 0x03ccc584}, |
| 628 | {0x0000c2e4, 0x03f00000, 0x03f00000, 0x03f0f800, 0x03f0f800}, | 628 | {0x0000c2e4, 0x03fc0000, 0x03fc0000, 0x03f0f800, 0x03f0f800}, |
| 629 | {0x0000c2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000}, | 629 | {0x0000c2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000}, |
| 630 | {0x00016044, 0x012492d4, 0x012492d4, 0x012492d4, 0x012492d4}, | 630 | {0x00016044, 0x012492d4, 0x012492d4, 0x012492d4, 0x012492d4}, |
| 631 | {0x00016048, 0x61200001, 0x61200001, 0x66480001, 0x66480001}, | 631 | {0x00016048, 0x66480001, 0x66480001, 0x66480001, 0x66480001}, |
| 632 | {0x00016068, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c}, | 632 | {0x00016068, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c}, |
| 633 | {0x00016444, 0x012492d4, 0x012492d4, 0x012492d4, 0x012492d4}, | 633 | {0x00016444, 0x012492d4, 0x012492d4, 0x012492d4, 0x012492d4}, |
| 634 | {0x00016448, 0x61200001, 0x61200001, 0x66480001, 0x66480001}, | 634 | {0x00016448, 0x66480001, 0x66480001, 0x66480001, 0x66480001}, |
| 635 | {0x00016468, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c}, | 635 | {0x00016468, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c}, |
| 636 | {0x00016844, 0x012492d4, 0x012492d4, 0x012492d4, 0x012492d4}, | 636 | {0x00016844, 0x012492d4, 0x012492d4, 0x012492d4, 0x012492d4}, |
| 637 | {0x00016848, 0x61200001, 0x61200001, 0x66480001, 0x66480001}, | 637 | {0x00016848, 0x66480001, 0x66480001, 0x66480001, 0x66480001}, |
| 638 | {0x00016868, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c}, | 638 | {0x00016868, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c}, |
| 639 | }; | 639 | }; |
| 640 | 640 | ||
diff --git a/drivers/net/wireless/ath/ath9k/hif_usb.c b/drivers/net/wireless/ath/ath9k/hif_usb.c index 924c4616c3d9..f5dda84176c3 100644 --- a/drivers/net/wireless/ath/ath9k/hif_usb.c +++ b/drivers/net/wireless/ath/ath9k/hif_usb.c | |||
| @@ -38,6 +38,7 @@ static struct usb_device_id ath9k_hif_usb_ids[] = { | |||
| 38 | { USB_DEVICE(0x04CA, 0x4605) }, /* Liteon */ | 38 | { USB_DEVICE(0x04CA, 0x4605) }, /* Liteon */ |
| 39 | { USB_DEVICE(0x040D, 0x3801) }, /* VIA */ | 39 | { USB_DEVICE(0x040D, 0x3801) }, /* VIA */ |
| 40 | { USB_DEVICE(0x0cf3, 0xb003) }, /* Ubiquiti WifiStation Ext */ | 40 | { USB_DEVICE(0x0cf3, 0xb003) }, /* Ubiquiti WifiStation Ext */ |
| 41 | { USB_DEVICE(0x0cf3, 0xb002) }, /* Ubiquiti WifiStation */ | ||
| 41 | { USB_DEVICE(0x057c, 0x8403) }, /* AVM FRITZ!WLAN 11N v2 USB */ | 42 | { USB_DEVICE(0x057c, 0x8403) }, /* AVM FRITZ!WLAN 11N v2 USB */ |
| 42 | 43 | ||
| 43 | { USB_DEVICE(0x0cf3, 0x7015), | 44 | { USB_DEVICE(0x0cf3, 0x7015), |
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c index 8e1559aba495..1829b445d0b0 100644 --- a/drivers/net/wireless/ath/ath9k/hw.c +++ b/drivers/net/wireless/ath/ath9k/hw.c | |||
| @@ -1456,7 +1456,7 @@ static bool ath9k_hw_set_reset_reg(struct ath_hw *ah, u32 type) | |||
| 1456 | switch (type) { | 1456 | switch (type) { |
| 1457 | case ATH9K_RESET_POWER_ON: | 1457 | case ATH9K_RESET_POWER_ON: |
| 1458 | ret = ath9k_hw_set_reset_power_on(ah); | 1458 | ret = ath9k_hw_set_reset_power_on(ah); |
| 1459 | if (!ret) | 1459 | if (ret) |
| 1460 | ah->reset_power_on = true; | 1460 | ah->reset_power_on = true; |
| 1461 | break; | 1461 | break; |
| 1462 | case ATH9K_RESET_WARM: | 1462 | case ATH9K_RESET_WARM: |
diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c index 378bd70256b2..741918a2027b 100644 --- a/drivers/net/wireless/ath/ath9k/xmit.c +++ b/drivers/net/wireless/ath/ath9k/xmit.c | |||
| @@ -312,6 +312,7 @@ static struct ath_buf *ath_tx_get_buffer(struct ath_softc *sc) | |||
| 312 | } | 312 | } |
| 313 | 313 | ||
| 314 | bf = list_first_entry(&sc->tx.txbuf, struct ath_buf, list); | 314 | bf = list_first_entry(&sc->tx.txbuf, struct ath_buf, list); |
| 315 | bf->bf_next = NULL; | ||
| 315 | list_del(&bf->list); | 316 | list_del(&bf->list); |
| 316 | 317 | ||
| 317 | spin_unlock_bh(&sc->tx.txbuflock); | 318 | spin_unlock_bh(&sc->tx.txbuflock); |
| @@ -393,7 +394,7 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq, | |||
| 393 | u16 seq_st = 0, acked_cnt = 0, txfail_cnt = 0, seq_first; | 394 | u16 seq_st = 0, acked_cnt = 0, txfail_cnt = 0, seq_first; |
| 394 | u32 ba[WME_BA_BMP_SIZE >> 5]; | 395 | u32 ba[WME_BA_BMP_SIZE >> 5]; |
| 395 | int isaggr, txfail, txpending, sendbar = 0, needreset = 0, nbad = 0; | 396 | int isaggr, txfail, txpending, sendbar = 0, needreset = 0, nbad = 0; |
| 396 | bool rc_update = true; | 397 | bool rc_update = true, isba; |
| 397 | struct ieee80211_tx_rate rates[4]; | 398 | struct ieee80211_tx_rate rates[4]; |
| 398 | struct ath_frame_info *fi; | 399 | struct ath_frame_info *fi; |
| 399 | int nframes; | 400 | int nframes; |
| @@ -437,13 +438,17 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq, | |||
| 437 | tidno = ieee80211_get_qos_ctl(hdr)[0] & IEEE80211_QOS_CTL_TID_MASK; | 438 | tidno = ieee80211_get_qos_ctl(hdr)[0] & IEEE80211_QOS_CTL_TID_MASK; |
| 438 | tid = ATH_AN_2_TID(an, tidno); | 439 | tid = ATH_AN_2_TID(an, tidno); |
| 439 | seq_first = tid->seq_start; | 440 | seq_first = tid->seq_start; |
| 441 | isba = ts->ts_flags & ATH9K_TX_BA; | ||
| 440 | 442 | ||
| 441 | /* | 443 | /* |
| 442 | * The hardware occasionally sends a tx status for the wrong TID. | 444 | * The hardware occasionally sends a tx status for the wrong TID. |
| 443 | * In this case, the BA status cannot be considered valid and all | 445 | * In this case, the BA status cannot be considered valid and all |
| 444 | * subframes need to be retransmitted | 446 | * subframes need to be retransmitted |
| 447 | * | ||
| 448 | * Only BlockAcks have a TID and therefore normal Acks cannot be | ||
| 449 | * checked | ||
| 445 | */ | 450 | */ |
| 446 | if (tidno != ts->tid) | 451 | if (isba && tidno != ts->tid) |
| 447 | txok = false; | 452 | txok = false; |
| 448 | 453 | ||
| 449 | isaggr = bf_isaggr(bf); | 454 | isaggr = bf_isaggr(bf); |
| @@ -1774,6 +1779,7 @@ static void ath_tx_send_normal(struct ath_softc *sc, struct ath_txq *txq, | |||
| 1774 | list_add_tail(&bf->list, &bf_head); | 1779 | list_add_tail(&bf->list, &bf_head); |
| 1775 | bf->bf_state.bf_type = 0; | 1780 | bf->bf_state.bf_type = 0; |
| 1776 | 1781 | ||
| 1782 | bf->bf_next = NULL; | ||
| 1777 | bf->bf_lastbf = bf; | 1783 | bf->bf_lastbf = bf; |
| 1778 | ath_tx_fill_desc(sc, bf, txq, fi->framelen); | 1784 | ath_tx_fill_desc(sc, bf, txq, fi->framelen); |
| 1779 | ath_tx_txqaddbuf(sc, txq, &bf_head, false); | 1785 | ath_tx_txqaddbuf(sc, txq, &bf_head, false); |
diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c index 73730e94e0ac..c5a99c8c8168 100644 --- a/drivers/net/wireless/b43/main.c +++ b/drivers/net/wireless/b43/main.c | |||
| @@ -5404,6 +5404,8 @@ static void b43_bcma_remove(struct bcma_device *core) | |||
| 5404 | cancel_work_sync(&wldev->restart_work); | 5404 | cancel_work_sync(&wldev->restart_work); |
| 5405 | 5405 | ||
| 5406 | B43_WARN_ON(!wl); | 5406 | B43_WARN_ON(!wl); |
| 5407 | if (!wldev->fw.ucode.data) | ||
| 5408 | return; /* NULL if firmware never loaded */ | ||
| 5407 | if (wl->current_dev == wldev && wl->hw_registred) { | 5409 | if (wl->current_dev == wldev && wl->hw_registred) { |
| 5408 | b43_leds_stop(wldev); | 5410 | b43_leds_stop(wldev); |
| 5409 | ieee80211_unregister_hw(wl->hw); | 5411 | ieee80211_unregister_hw(wl->hw); |
| @@ -5478,6 +5480,8 @@ static void b43_ssb_remove(struct ssb_device *sdev) | |||
| 5478 | cancel_work_sync(&wldev->restart_work); | 5480 | cancel_work_sync(&wldev->restart_work); |
| 5479 | 5481 | ||
| 5480 | B43_WARN_ON(!wl); | 5482 | B43_WARN_ON(!wl); |
| 5483 | if (!wldev->fw.ucode.data) | ||
| 5484 | return; /* NULL if firmware never loaded */ | ||
| 5481 | if (wl->current_dev == wldev && wl->hw_registred) { | 5485 | if (wl->current_dev == wldev && wl->hw_registred) { |
| 5482 | b43_leds_stop(wldev); | 5486 | b43_leds_stop(wldev); |
| 5483 | ieee80211_unregister_hw(wl->hw); | 5487 | ieee80211_unregister_hw(wl->hw); |
diff --git a/drivers/net/wireless/b43legacy/pio.c b/drivers/net/wireless/b43legacy/pio.c index 192251adf986..282eedec675e 100644 --- a/drivers/net/wireless/b43legacy/pio.c +++ b/drivers/net/wireless/b43legacy/pio.c | |||
| @@ -382,7 +382,7 @@ static void cancel_transfers(struct b43legacy_pioqueue *queue) | |||
| 382 | { | 382 | { |
| 383 | struct b43legacy_pio_txpacket *packet, *tmp_packet; | 383 | struct b43legacy_pio_txpacket *packet, *tmp_packet; |
| 384 | 384 | ||
| 385 | tasklet_disable(&queue->txtask); | 385 | tasklet_kill(&queue->txtask); |
| 386 | 386 | ||
| 387 | list_for_each_entry_safe(packet, tmp_packet, &queue->txrunning, list) | 387 | list_for_each_entry_safe(packet, tmp_packet, &queue->txrunning, list) |
| 388 | free_txpacket(packet, 0); | 388 | free_txpacket(packet, 0); |
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/usb.c b/drivers/net/wireless/brcm80211/brcmfmac/usb.c index a2b4b1e71017..7a6dfdc67b6c 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/usb.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/usb.c | |||
| @@ -1339,7 +1339,7 @@ static int brcmf_usb_probe_cb(struct brcmf_usbdev_info *devinfo, | |||
| 1339 | } | 1339 | } |
| 1340 | 1340 | ||
| 1341 | ret = brcmf_bus_start(dev); | 1341 | ret = brcmf_bus_start(dev); |
| 1342 | if (ret == -ENOLINK) { | 1342 | if (ret) { |
| 1343 | brcmf_dbg(ERROR, "dongle is not responding\n"); | 1343 | brcmf_dbg(ERROR, "dongle is not responding\n"); |
| 1344 | brcmf_detach(dev); | 1344 | brcmf_detach(dev); |
| 1345 | goto fail; | 1345 | goto fail; |
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c index c1abaa6db59e..481345c23ded 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c | |||
| @@ -3569,7 +3569,7 @@ brcmf_cfg80211_sched_scan_start(struct wiphy *wiphy, | |||
| 3569 | 3569 | ||
| 3570 | if (!request || !request->n_ssids || !request->n_match_sets) { | 3570 | if (!request || !request->n_ssids || !request->n_match_sets) { |
| 3571 | WL_ERR("Invalid sched scan req!! n_ssids:%d\n", | 3571 | WL_ERR("Invalid sched scan req!! n_ssids:%d\n", |
| 3572 | request->n_ssids); | 3572 | request ? request->n_ssids : 0); |
| 3573 | return -EINVAL; | 3573 | return -EINVAL; |
| 3574 | } | 3574 | } |
| 3575 | 3575 | ||
| @@ -3972,7 +3972,7 @@ brcmf_set_management_ie(struct brcmf_cfg80211_info *cfg, | |||
| 3972 | u8 *iovar_ie_buf; | 3972 | u8 *iovar_ie_buf; |
| 3973 | u8 *curr_ie_buf; | 3973 | u8 *curr_ie_buf; |
| 3974 | u8 *mgmt_ie_buf = NULL; | 3974 | u8 *mgmt_ie_buf = NULL; |
| 3975 | u32 mgmt_ie_buf_len = 0; | 3975 | int mgmt_ie_buf_len; |
| 3976 | u32 *mgmt_ie_len = 0; | 3976 | u32 *mgmt_ie_len = 0; |
| 3977 | u32 del_add_ie_buf_len = 0; | 3977 | u32 del_add_ie_buf_len = 0; |
| 3978 | u32 total_ie_buf_len = 0; | 3978 | u32 total_ie_buf_len = 0; |
| @@ -3982,7 +3982,7 @@ brcmf_set_management_ie(struct brcmf_cfg80211_info *cfg, | |||
| 3982 | struct parsed_vndr_ie_info *vndrie_info; | 3982 | struct parsed_vndr_ie_info *vndrie_info; |
| 3983 | s32 i; | 3983 | s32 i; |
| 3984 | u8 *ptr; | 3984 | u8 *ptr; |
| 3985 | u32 remained_buf_len; | 3985 | int remained_buf_len; |
| 3986 | 3986 | ||
| 3987 | WL_TRACE("bssidx %d, pktflag : 0x%02X\n", bssidx, pktflag); | 3987 | WL_TRACE("bssidx %d, pktflag : 0x%02X\n", bssidx, pktflag); |
| 3988 | iovar_ie_buf = kzalloc(WL_EXTRA_BUF_MAX, GFP_KERNEL); | 3988 | iovar_ie_buf = kzalloc(WL_EXTRA_BUF_MAX, GFP_KERNEL); |
| @@ -4401,7 +4401,7 @@ static s32 brcmf_mode_to_nl80211_iftype(s32 mode) | |||
| 4401 | 4401 | ||
| 4402 | static void brcmf_wiphy_pno_params(struct wiphy *wiphy) | 4402 | static void brcmf_wiphy_pno_params(struct wiphy *wiphy) |
| 4403 | { | 4403 | { |
| 4404 | #ifndef CONFIG_BRCMFISCAN | 4404 | #ifndef CONFIG_BRCMISCAN |
| 4405 | /* scheduled scan settings */ | 4405 | /* scheduled scan settings */ |
| 4406 | wiphy->max_sched_scan_ssids = BRCMF_PNO_MAX_PFN_COUNT; | 4406 | wiphy->max_sched_scan_ssids = BRCMF_PNO_MAX_PFN_COUNT; |
| 4407 | wiphy->max_match_sets = BRCMF_PNO_MAX_PFN_COUNT; | 4407 | wiphy->max_match_sets = BRCMF_PNO_MAX_PFN_COUNT; |
| @@ -4606,12 +4606,13 @@ brcmf_bss_roaming_done(struct brcmf_cfg80211_info *cfg, | |||
| 4606 | struct brcmf_cfg80211_profile *profile = cfg->profile; | 4606 | struct brcmf_cfg80211_profile *profile = cfg->profile; |
| 4607 | struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg); | 4607 | struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg); |
| 4608 | struct wiphy *wiphy = cfg_to_wiphy(cfg); | 4608 | struct wiphy *wiphy = cfg_to_wiphy(cfg); |
| 4609 | struct brcmf_channel_info_le channel_le; | 4609 | struct ieee80211_channel *notify_channel = NULL; |
| 4610 | struct ieee80211_channel *notify_channel; | ||
| 4611 | struct ieee80211_supported_band *band; | 4610 | struct ieee80211_supported_band *band; |
| 4611 | struct brcmf_bss_info_le *bi; | ||
| 4612 | u32 freq; | 4612 | u32 freq; |
| 4613 | s32 err = 0; | 4613 | s32 err = 0; |
| 4614 | u32 target_channel; | 4614 | u32 target_channel; |
| 4615 | u8 *buf; | ||
| 4615 | 4616 | ||
| 4616 | WL_TRACE("Enter\n"); | 4617 | WL_TRACE("Enter\n"); |
| 4617 | 4618 | ||
| @@ -4619,11 +4620,22 @@ brcmf_bss_roaming_done(struct brcmf_cfg80211_info *cfg, | |||
| 4619 | memcpy(profile->bssid, e->addr, ETH_ALEN); | 4620 | memcpy(profile->bssid, e->addr, ETH_ALEN); |
| 4620 | brcmf_update_bss_info(cfg); | 4621 | brcmf_update_bss_info(cfg); |
| 4621 | 4622 | ||
| 4622 | brcmf_exec_dcmd(ndev, BRCMF_C_GET_CHANNEL, &channel_le, | 4623 | buf = kzalloc(WL_BSS_INFO_MAX, GFP_KERNEL); |
| 4623 | sizeof(channel_le)); | 4624 | if (buf == NULL) { |
| 4625 | err = -ENOMEM; | ||
| 4626 | goto done; | ||
| 4627 | } | ||
| 4624 | 4628 | ||
| 4625 | target_channel = le32_to_cpu(channel_le.target_channel); | 4629 | /* data sent to dongle has to be little endian */ |
| 4626 | WL_CONN("Roamed to channel %d\n", target_channel); | 4630 | *(__le32 *)buf = cpu_to_le32(WL_BSS_INFO_MAX); |
| 4631 | err = brcmf_exec_dcmd(ndev, BRCMF_C_GET_BSS_INFO, buf, WL_BSS_INFO_MAX); | ||
| 4632 | |||
| 4633 | if (err) | ||
| 4634 | goto done; | ||
| 4635 | |||
| 4636 | bi = (struct brcmf_bss_info_le *)(buf + 4); | ||
| 4637 | target_channel = bi->ctl_ch ? bi->ctl_ch : | ||
| 4638 | CHSPEC_CHANNEL(le16_to_cpu(bi->chanspec)); | ||
| 4627 | 4639 | ||
| 4628 | if (target_channel <= CH_MAX_2G_CHANNEL) | 4640 | if (target_channel <= CH_MAX_2G_CHANNEL) |
| 4629 | band = wiphy->bands[IEEE80211_BAND_2GHZ]; | 4641 | band = wiphy->bands[IEEE80211_BAND_2GHZ]; |
| @@ -4633,6 +4645,8 @@ brcmf_bss_roaming_done(struct brcmf_cfg80211_info *cfg, | |||
| 4633 | freq = ieee80211_channel_to_frequency(target_channel, band->band); | 4645 | freq = ieee80211_channel_to_frequency(target_channel, band->band); |
| 4634 | notify_channel = ieee80211_get_channel(wiphy, freq); | 4646 | notify_channel = ieee80211_get_channel(wiphy, freq); |
| 4635 | 4647 | ||
| 4648 | done: | ||
| 4649 | kfree(buf); | ||
| 4636 | cfg80211_roamed(ndev, notify_channel, (u8 *)profile->bssid, | 4650 | cfg80211_roamed(ndev, notify_channel, (u8 *)profile->bssid, |
| 4637 | conn_info->req_ie, conn_info->req_ie_len, | 4651 | conn_info->req_ie, conn_info->req_ie_len, |
| 4638 | conn_info->resp_ie, conn_info->resp_ie_len, GFP_KERNEL); | 4652 | conn_info->resp_ie, conn_info->resp_ie_len, GFP_KERNEL); |
| @@ -5186,41 +5200,6 @@ brcmf_cfg80211_event(struct net_device *ndev, | |||
| 5186 | schedule_work(&cfg->event_work); | 5200 | schedule_work(&cfg->event_work); |
| 5187 | } | 5201 | } |
| 5188 | 5202 | ||
| 5189 | static s32 brcmf_dongle_mode(struct net_device *ndev, s32 iftype) | ||
| 5190 | { | ||
| 5191 | s32 infra = 0; | ||
| 5192 | s32 err = 0; | ||
| 5193 | |||
| 5194 | switch (iftype) { | ||
| 5195 | case NL80211_IFTYPE_MONITOR: | ||
| 5196 | case NL80211_IFTYPE_WDS: | ||
| 5197 | WL_ERR("type (%d) : currently we do not support this mode\n", | ||
| 5198 | iftype); | ||
| 5199 | err = -EINVAL; | ||
| 5200 | return err; | ||
| 5201 | case NL80211_IFTYPE_ADHOC: | ||
| 5202 | infra = 0; | ||
| 5203 | break; | ||
| 5204 | case NL80211_IFTYPE_STATION: | ||
| 5205 | infra = 1; | ||
| 5206 | break; | ||
| 5207 | case NL80211_IFTYPE_AP: | ||
| 5208 | infra = 1; | ||
| 5209 | break; | ||
| 5210 | default: | ||
| 5211 | err = -EINVAL; | ||
| 5212 | WL_ERR("invalid type (%d)\n", iftype); | ||
| 5213 | return err; | ||
| 5214 | } | ||
| 5215 | err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_SET_INFRA, &infra); | ||
| 5216 | if (err) { | ||
| 5217 | WL_ERR("WLC_SET_INFRA error (%d)\n", err); | ||
| 5218 | return err; | ||
| 5219 | } | ||
| 5220 | |||
| 5221 | return 0; | ||
| 5222 | } | ||
| 5223 | |||
| 5224 | static s32 brcmf_dongle_eventmsg(struct net_device *ndev) | 5203 | static s32 brcmf_dongle_eventmsg(struct net_device *ndev) |
| 5225 | { | 5204 | { |
| 5226 | /* Room for "event_msgs" + '\0' + bitvec */ | 5205 | /* Room for "event_msgs" + '\0' + bitvec */ |
| @@ -5439,7 +5418,8 @@ static s32 brcmf_config_dongle(struct brcmf_cfg80211_info *cfg) | |||
| 5439 | WL_BEACON_TIMEOUT); | 5418 | WL_BEACON_TIMEOUT); |
| 5440 | if (err) | 5419 | if (err) |
| 5441 | goto default_conf_out; | 5420 | goto default_conf_out; |
| 5442 | err = brcmf_dongle_mode(ndev, wdev->iftype); | 5421 | err = brcmf_cfg80211_change_iface(wdev->wiphy, ndev, wdev->iftype, |
| 5422 | NULL, NULL); | ||
| 5443 | if (err && err != -EINPROGRESS) | 5423 | if (err && err != -EINPROGRESS) |
| 5444 | goto default_conf_out; | 5424 | goto default_conf_out; |
| 5445 | err = brcmf_dongle_probecap(cfg); | 5425 | err = brcmf_dongle_probecap(cfg); |
diff --git a/drivers/net/wireless/ipw2x00/ipw2200.c b/drivers/net/wireless/ipw2x00/ipw2200.c index 935120fc8c93..768bf612533e 100644 --- a/drivers/net/wireless/ipw2x00/ipw2200.c +++ b/drivers/net/wireless/ipw2x00/ipw2200.c | |||
| @@ -10472,7 +10472,7 @@ static void ipw_handle_promiscuous_tx(struct ipw_priv *priv, | |||
| 10472 | } else | 10472 | } else |
| 10473 | len = src->len; | 10473 | len = src->len; |
| 10474 | 10474 | ||
| 10475 | dst = alloc_skb(len + sizeof(*rt_hdr), GFP_ATOMIC); | 10475 | dst = alloc_skb(len + sizeof(*rt_hdr) + sizeof(u16)*2, GFP_ATOMIC); |
| 10476 | if (!dst) | 10476 | if (!dst) |
| 10477 | continue; | 10477 | continue; |
| 10478 | 10478 | ||
diff --git a/drivers/net/wireless/iwlwifi/dvm/devices.c b/drivers/net/wireless/iwlwifi/dvm/devices.c index 349c205d5f62..da5862064195 100644 --- a/drivers/net/wireless/iwlwifi/dvm/devices.c +++ b/drivers/net/wireless/iwlwifi/dvm/devices.c | |||
| @@ -518,7 +518,7 @@ static int iwl6000_hw_channel_switch(struct iwl_priv *priv, | |||
| 518 | * See iwlagn_mac_channel_switch. | 518 | * See iwlagn_mac_channel_switch. |
| 519 | */ | 519 | */ |
| 520 | struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; | 520 | struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; |
| 521 | struct iwl6000_channel_switch_cmd cmd; | 521 | struct iwl6000_channel_switch_cmd *cmd; |
| 522 | u32 switch_time_in_usec, ucode_switch_time; | 522 | u32 switch_time_in_usec, ucode_switch_time; |
| 523 | u16 ch; | 523 | u16 ch; |
| 524 | u32 tsf_low; | 524 | u32 tsf_low; |
| @@ -527,18 +527,25 @@ static int iwl6000_hw_channel_switch(struct iwl_priv *priv, | |||
| 527 | struct ieee80211_vif *vif = ctx->vif; | 527 | struct ieee80211_vif *vif = ctx->vif; |
| 528 | struct iwl_host_cmd hcmd = { | 528 | struct iwl_host_cmd hcmd = { |
| 529 | .id = REPLY_CHANNEL_SWITCH, | 529 | .id = REPLY_CHANNEL_SWITCH, |
| 530 | .len = { sizeof(cmd), }, | 530 | .len = { sizeof(*cmd), }, |
| 531 | .flags = CMD_SYNC, | 531 | .flags = CMD_SYNC, |
| 532 | .data = { &cmd, }, | 532 | .dataflags[0] = IWL_HCMD_DFL_NOCOPY, |
| 533 | }; | 533 | }; |
| 534 | int err; | ||
| 534 | 535 | ||
| 535 | cmd.band = priv->band == IEEE80211_BAND_2GHZ; | 536 | cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); |
| 537 | if (!cmd) | ||
| 538 | return -ENOMEM; | ||
| 539 | |||
| 540 | hcmd.data[0] = cmd; | ||
| 541 | |||
| 542 | cmd->band = priv->band == IEEE80211_BAND_2GHZ; | ||
| 536 | ch = ch_switch->channel->hw_value; | 543 | ch = ch_switch->channel->hw_value; |
| 537 | IWL_DEBUG_11H(priv, "channel switch from %u to %u\n", | 544 | IWL_DEBUG_11H(priv, "channel switch from %u to %u\n", |
| 538 | ctx->active.channel, ch); | 545 | ctx->active.channel, ch); |
| 539 | cmd.channel = cpu_to_le16(ch); | 546 | cmd->channel = cpu_to_le16(ch); |
| 540 | cmd.rxon_flags = ctx->staging.flags; | 547 | cmd->rxon_flags = ctx->staging.flags; |
| 541 | cmd.rxon_filter_flags = ctx->staging.filter_flags; | 548 | cmd->rxon_filter_flags = ctx->staging.filter_flags; |
| 542 | switch_count = ch_switch->count; | 549 | switch_count = ch_switch->count; |
| 543 | tsf_low = ch_switch->timestamp & 0x0ffffffff; | 550 | tsf_low = ch_switch->timestamp & 0x0ffffffff; |
| 544 | /* | 551 | /* |
| @@ -554,23 +561,25 @@ static int iwl6000_hw_channel_switch(struct iwl_priv *priv, | |||
| 554 | switch_count = 0; | 561 | switch_count = 0; |
| 555 | } | 562 | } |
| 556 | if (switch_count <= 1) | 563 | if (switch_count <= 1) |
| 557 | cmd.switch_time = cpu_to_le32(priv->ucode_beacon_time); | 564 | cmd->switch_time = cpu_to_le32(priv->ucode_beacon_time); |
| 558 | else { | 565 | else { |
| 559 | switch_time_in_usec = | 566 | switch_time_in_usec = |
| 560 | vif->bss_conf.beacon_int * switch_count * TIME_UNIT; | 567 | vif->bss_conf.beacon_int * switch_count * TIME_UNIT; |
| 561 | ucode_switch_time = iwl_usecs_to_beacons(priv, | 568 | ucode_switch_time = iwl_usecs_to_beacons(priv, |
| 562 | switch_time_in_usec, | 569 | switch_time_in_usec, |
| 563 | beacon_interval); | 570 | beacon_interval); |
| 564 | cmd.switch_time = iwl_add_beacon_time(priv, | 571 | cmd->switch_time = iwl_add_beacon_time(priv, |
| 565 | priv->ucode_beacon_time, | 572 | priv->ucode_beacon_time, |
| 566 | ucode_switch_time, | 573 | ucode_switch_time, |
| 567 | beacon_interval); | 574 | beacon_interval); |
| 568 | } | 575 | } |
| 569 | IWL_DEBUG_11H(priv, "uCode time for the switch is 0x%x\n", | 576 | IWL_DEBUG_11H(priv, "uCode time for the switch is 0x%x\n", |
| 570 | cmd.switch_time); | 577 | cmd->switch_time); |
| 571 | cmd.expect_beacon = ch_switch->channel->flags & IEEE80211_CHAN_RADAR; | 578 | cmd->expect_beacon = ch_switch->channel->flags & IEEE80211_CHAN_RADAR; |
| 572 | 579 | ||
| 573 | return iwl_dvm_send_cmd(priv, &hcmd); | 580 | err = iwl_dvm_send_cmd(priv, &hcmd); |
| 581 | kfree(cmd); | ||
| 582 | return err; | ||
| 574 | } | 583 | } |
| 575 | 584 | ||
| 576 | struct iwl_lib_ops iwl6000_lib = { | 585 | struct iwl_lib_ops iwl6000_lib = { |
diff --git a/drivers/net/wireless/iwlwifi/dvm/mac80211.c b/drivers/net/wireless/iwlwifi/dvm/mac80211.c index ff8162d4c454..2d9eee93c743 100644 --- a/drivers/net/wireless/iwlwifi/dvm/mac80211.c +++ b/drivers/net/wireless/iwlwifi/dvm/mac80211.c | |||
| @@ -521,7 +521,7 @@ static void iwlagn_mac_tx(struct ieee80211_hw *hw, | |||
| 521 | ieee80211_get_tx_rate(hw, IEEE80211_SKB_CB(skb))->bitrate); | 521 | ieee80211_get_tx_rate(hw, IEEE80211_SKB_CB(skb))->bitrate); |
| 522 | 522 | ||
| 523 | if (iwlagn_tx_skb(priv, control->sta, skb)) | 523 | if (iwlagn_tx_skb(priv, control->sta, skb)) |
| 524 | dev_kfree_skb_any(skb); | 524 | ieee80211_free_txskb(hw, skb); |
| 525 | } | 525 | } |
| 526 | 526 | ||
| 527 | static void iwlagn_mac_update_tkip_key(struct ieee80211_hw *hw, | 527 | static void iwlagn_mac_update_tkip_key(struct ieee80211_hw *hw, |
| @@ -1354,6 +1354,20 @@ static int iwlagn_mac_add_interface(struct ieee80211_hw *hw, | |||
| 1354 | vif_priv->ctx = ctx; | 1354 | vif_priv->ctx = ctx; |
| 1355 | ctx->vif = vif; | 1355 | ctx->vif = vif; |
| 1356 | 1356 | ||
| 1357 | /* | ||
| 1358 | * In SNIFFER device type, the firmware reports the FCS to | ||
| 1359 | * the host, rather than snipping it off. Unfortunately, | ||
| 1360 | * mac80211 doesn't (yet) provide a per-packet flag for | ||
| 1361 | * this, so that we have to set the hardware flag based | ||
| 1362 | * on the interfaces added. As the monitor interface can | ||
| 1363 | * only be present by itself, and will be removed before | ||
| 1364 | * other interfaces are added, this is safe. | ||
| 1365 | */ | ||
| 1366 | if (vif->type == NL80211_IFTYPE_MONITOR) | ||
| 1367 | priv->hw->flags |= IEEE80211_HW_RX_INCLUDES_FCS; | ||
| 1368 | else | ||
| 1369 | priv->hw->flags &= ~IEEE80211_HW_RX_INCLUDES_FCS; | ||
| 1370 | |||
| 1357 | err = iwl_setup_interface(priv, ctx); | 1371 | err = iwl_setup_interface(priv, ctx); |
| 1358 | if (!err || reset) | 1372 | if (!err || reset) |
| 1359 | goto out; | 1373 | goto out; |
diff --git a/drivers/net/wireless/iwlwifi/dvm/main.c b/drivers/net/wireless/iwlwifi/dvm/main.c index 7ff3f1430678..408132cf83c1 100644 --- a/drivers/net/wireless/iwlwifi/dvm/main.c +++ b/drivers/net/wireless/iwlwifi/dvm/main.c | |||
| @@ -2114,7 +2114,7 @@ static void iwl_free_skb(struct iwl_op_mode *op_mode, struct sk_buff *skb) | |||
| 2114 | 2114 | ||
| 2115 | info = IEEE80211_SKB_CB(skb); | 2115 | info = IEEE80211_SKB_CB(skb); |
| 2116 | iwl_trans_free_tx_cmd(priv->trans, info->driver_data[1]); | 2116 | iwl_trans_free_tx_cmd(priv->trans, info->driver_data[1]); |
| 2117 | dev_kfree_skb_any(skb); | 2117 | ieee80211_free_txskb(priv->hw, skb); |
| 2118 | } | 2118 | } |
| 2119 | 2119 | ||
| 2120 | static void iwl_set_hw_rfkill_state(struct iwl_op_mode *op_mode, bool state) | 2120 | static void iwl_set_hw_rfkill_state(struct iwl_op_mode *op_mode, bool state) |
diff --git a/drivers/net/wireless/iwlwifi/dvm/rxon.c b/drivers/net/wireless/iwlwifi/dvm/rxon.c index 10896393e5a0..2830ea290502 100644 --- a/drivers/net/wireless/iwlwifi/dvm/rxon.c +++ b/drivers/net/wireless/iwlwifi/dvm/rxon.c | |||
| @@ -1012,12 +1012,12 @@ static void iwl_calc_basic_rates(struct iwl_priv *priv, | |||
| 1012 | * As a consequence, it's not as complicated as it sounds, just add | 1012 | * As a consequence, it's not as complicated as it sounds, just add |
| 1013 | * any lower rates to the ACK rate bitmap. | 1013 | * any lower rates to the ACK rate bitmap. |
| 1014 | */ | 1014 | */ |
| 1015 | if (IWL_RATE_11M_INDEX < lowest_present_ofdm) | 1015 | if (IWL_RATE_11M_INDEX < lowest_present_cck) |
| 1016 | ofdm |= IWL_RATE_11M_MASK >> IWL_FIRST_CCK_RATE; | 1016 | cck |= IWL_RATE_11M_MASK >> IWL_FIRST_CCK_RATE; |
| 1017 | if (IWL_RATE_5M_INDEX < lowest_present_ofdm) | 1017 | if (IWL_RATE_5M_INDEX < lowest_present_cck) |
| 1018 | ofdm |= IWL_RATE_5M_MASK >> IWL_FIRST_CCK_RATE; | 1018 | cck |= IWL_RATE_5M_MASK >> IWL_FIRST_CCK_RATE; |
| 1019 | if (IWL_RATE_2M_INDEX < lowest_present_ofdm) | 1019 | if (IWL_RATE_2M_INDEX < lowest_present_cck) |
| 1020 | ofdm |= IWL_RATE_2M_MASK >> IWL_FIRST_CCK_RATE; | 1020 | cck |= IWL_RATE_2M_MASK >> IWL_FIRST_CCK_RATE; |
| 1021 | /* 1M already there or needed so always add */ | 1021 | /* 1M already there or needed so always add */ |
| 1022 | cck |= IWL_RATE_1M_MASK >> IWL_FIRST_CCK_RATE; | 1022 | cck |= IWL_RATE_1M_MASK >> IWL_FIRST_CCK_RATE; |
| 1023 | 1023 | ||
diff --git a/drivers/net/wireless/iwlwifi/pcie/rx.c b/drivers/net/wireless/iwlwifi/pcie/rx.c index 17c8e5d82681..bb69f8f90b3b 100644 --- a/drivers/net/wireless/iwlwifi/pcie/rx.c +++ b/drivers/net/wireless/iwlwifi/pcie/rx.c | |||
| @@ -321,6 +321,14 @@ static void iwl_rx_allocate(struct iwl_trans *trans, gfp_t priority) | |||
| 321 | dma_map_page(trans->dev, page, 0, | 321 | dma_map_page(trans->dev, page, 0, |
| 322 | PAGE_SIZE << trans_pcie->rx_page_order, | 322 | PAGE_SIZE << trans_pcie->rx_page_order, |
| 323 | DMA_FROM_DEVICE); | 323 | DMA_FROM_DEVICE); |
| 324 | if (dma_mapping_error(trans->dev, rxb->page_dma)) { | ||
| 325 | rxb->page = NULL; | ||
| 326 | spin_lock_irqsave(&rxq->lock, flags); | ||
| 327 | list_add(&rxb->list, &rxq->rx_used); | ||
| 328 | spin_unlock_irqrestore(&rxq->lock, flags); | ||
| 329 | __free_pages(page, trans_pcie->rx_page_order); | ||
| 330 | return; | ||
| 331 | } | ||
| 324 | /* dma address must be no more than 36 bits */ | 332 | /* dma address must be no more than 36 bits */ |
| 325 | BUG_ON(rxb->page_dma & ~DMA_BIT_MASK(36)); | 333 | BUG_ON(rxb->page_dma & ~DMA_BIT_MASK(36)); |
| 326 | /* and also 256 byte aligned! */ | 334 | /* and also 256 byte aligned! */ |
| @@ -488,8 +496,19 @@ static void iwl_rx_handle_rxbuf(struct iwl_trans *trans, | |||
| 488 | dma_map_page(trans->dev, rxb->page, 0, | 496 | dma_map_page(trans->dev, rxb->page, 0, |
| 489 | PAGE_SIZE << trans_pcie->rx_page_order, | 497 | PAGE_SIZE << trans_pcie->rx_page_order, |
| 490 | DMA_FROM_DEVICE); | 498 | DMA_FROM_DEVICE); |
| 491 | list_add_tail(&rxb->list, &rxq->rx_free); | 499 | if (dma_mapping_error(trans->dev, rxb->page_dma)) { |
| 492 | rxq->free_count++; | 500 | /* |
| 501 | * free the page(s) as well to not break | ||
| 502 | * the invariant that the items on the used | ||
| 503 | * list have no page(s) | ||
| 504 | */ | ||
| 505 | __free_pages(rxb->page, trans_pcie->rx_page_order); | ||
| 506 | rxb->page = NULL; | ||
| 507 | list_add_tail(&rxb->list, &rxq->rx_used); | ||
| 508 | } else { | ||
| 509 | list_add_tail(&rxb->list, &rxq->rx_free); | ||
| 510 | rxq->free_count++; | ||
| 511 | } | ||
| 493 | } else | 512 | } else |
| 494 | list_add_tail(&rxb->list, &rxq->rx_used); | 513 | list_add_tail(&rxb->list, &rxq->rx_used); |
| 495 | spin_unlock_irqrestore(&rxq->lock, flags); | 514 | spin_unlock_irqrestore(&rxq->lock, flags); |
diff --git a/drivers/net/wireless/iwlwifi/pcie/tx.c b/drivers/net/wireless/iwlwifi/pcie/tx.c index 105e3af3c621..79a4ddc002d3 100644 --- a/drivers/net/wireless/iwlwifi/pcie/tx.c +++ b/drivers/net/wireless/iwlwifi/pcie/tx.c | |||
| @@ -480,20 +480,12 @@ void iwl_trans_pcie_txq_enable(struct iwl_trans *trans, int txq_id, int fifo, | |||
| 480 | void iwl_trans_pcie_txq_disable(struct iwl_trans *trans, int txq_id) | 480 | void iwl_trans_pcie_txq_disable(struct iwl_trans *trans, int txq_id) |
| 481 | { | 481 | { |
| 482 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); | 482 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); |
| 483 | u16 rd_ptr, wr_ptr; | ||
| 484 | int n_bd = trans_pcie->txq[txq_id].q.n_bd; | ||
| 485 | 483 | ||
| 486 | if (!test_and_clear_bit(txq_id, trans_pcie->queue_used)) { | 484 | if (!test_and_clear_bit(txq_id, trans_pcie->queue_used)) { |
| 487 | WARN_ONCE(1, "queue %d not used", txq_id); | 485 | WARN_ONCE(1, "queue %d not used", txq_id); |
| 488 | return; | 486 | return; |
| 489 | } | 487 | } |
| 490 | 488 | ||
| 491 | rd_ptr = iwl_read_prph(trans, SCD_QUEUE_RDPTR(txq_id)) & (n_bd - 1); | ||
| 492 | wr_ptr = iwl_read_prph(trans, SCD_QUEUE_WRPTR(txq_id)); | ||
| 493 | |||
| 494 | WARN_ONCE(rd_ptr != wr_ptr, "queue %d isn't empty: [%d,%d]", | ||
| 495 | txq_id, rd_ptr, wr_ptr); | ||
| 496 | |||
| 497 | iwl_txq_set_inactive(trans, txq_id); | 489 | iwl_txq_set_inactive(trans, txq_id); |
| 498 | IWL_DEBUG_TX_QUEUES(trans, "Deactivate queue %d\n", txq_id); | 490 | IWL_DEBUG_TX_QUEUES(trans, "Deactivate queue %d\n", txq_id); |
| 499 | } | 491 | } |
diff --git a/drivers/net/wireless/mwifiex/cfg80211.c b/drivers/net/wireless/mwifiex/cfg80211.c index 0679458a1bac..780d3e168297 100644 --- a/drivers/net/wireless/mwifiex/cfg80211.c +++ b/drivers/net/wireless/mwifiex/cfg80211.c | |||
| @@ -1825,8 +1825,6 @@ mwifiex_cfg80211_scan(struct wiphy *wiphy, | |||
| 1825 | return -EBUSY; | 1825 | return -EBUSY; |
| 1826 | } | 1826 | } |
| 1827 | 1827 | ||
| 1828 | priv->scan_request = request; | ||
| 1829 | |||
| 1830 | priv->user_scan_cfg = kzalloc(sizeof(struct mwifiex_user_scan_cfg), | 1828 | priv->user_scan_cfg = kzalloc(sizeof(struct mwifiex_user_scan_cfg), |
| 1831 | GFP_KERNEL); | 1829 | GFP_KERNEL); |
| 1832 | if (!priv->user_scan_cfg) { | 1830 | if (!priv->user_scan_cfg) { |
| @@ -1834,6 +1832,8 @@ mwifiex_cfg80211_scan(struct wiphy *wiphy, | |||
| 1834 | return -ENOMEM; | 1832 | return -ENOMEM; |
| 1835 | } | 1833 | } |
| 1836 | 1834 | ||
| 1835 | priv->scan_request = request; | ||
| 1836 | |||
| 1837 | priv->user_scan_cfg->num_ssids = request->n_ssids; | 1837 | priv->user_scan_cfg->num_ssids = request->n_ssids; |
| 1838 | priv->user_scan_cfg->ssid_list = request->ssids; | 1838 | priv->user_scan_cfg->ssid_list = request->ssids; |
| 1839 | 1839 | ||
| @@ -1870,6 +1870,9 @@ mwifiex_cfg80211_scan(struct wiphy *wiphy, | |||
| 1870 | ret = mwifiex_scan_networks(priv, priv->user_scan_cfg); | 1870 | ret = mwifiex_scan_networks(priv, priv->user_scan_cfg); |
| 1871 | if (ret) { | 1871 | if (ret) { |
| 1872 | dev_err(priv->adapter->dev, "scan failed: %d\n", ret); | 1872 | dev_err(priv->adapter->dev, "scan failed: %d\n", ret); |
| 1873 | priv->scan_request = NULL; | ||
| 1874 | kfree(priv->user_scan_cfg); | ||
| 1875 | priv->user_scan_cfg = NULL; | ||
| 1873 | return ret; | 1876 | return ret; |
| 1874 | } | 1877 | } |
| 1875 | 1878 | ||
diff --git a/drivers/net/wireless/mwifiex/cmdevt.c b/drivers/net/wireless/mwifiex/cmdevt.c index 8d465107f52b..ae9010ed58de 100644 --- a/drivers/net/wireless/mwifiex/cmdevt.c +++ b/drivers/net/wireless/mwifiex/cmdevt.c | |||
| @@ -890,9 +890,6 @@ mwifiex_cmd_timeout_func(unsigned long function_context) | |||
| 890 | return; | 890 | return; |
| 891 | } | 891 | } |
| 892 | cmd_node = adapter->curr_cmd; | 892 | cmd_node = adapter->curr_cmd; |
| 893 | if (cmd_node->wait_q_enabled) | ||
| 894 | adapter->cmd_wait_q.status = -ETIMEDOUT; | ||
| 895 | |||
| 896 | if (cmd_node) { | 893 | if (cmd_node) { |
| 897 | adapter->dbg.timeout_cmd_id = | 894 | adapter->dbg.timeout_cmd_id = |
| 898 | adapter->dbg.last_cmd_id[adapter->dbg.last_cmd_index]; | 895 | adapter->dbg.last_cmd_id[adapter->dbg.last_cmd_index]; |
| @@ -938,6 +935,14 @@ mwifiex_cmd_timeout_func(unsigned long function_context) | |||
| 938 | 935 | ||
| 939 | dev_err(adapter->dev, "ps_mode=%d ps_state=%d\n", | 936 | dev_err(adapter->dev, "ps_mode=%d ps_state=%d\n", |
| 940 | adapter->ps_mode, adapter->ps_state); | 937 | adapter->ps_mode, adapter->ps_state); |
| 938 | |||
| 939 | if (cmd_node->wait_q_enabled) { | ||
| 940 | adapter->cmd_wait_q.status = -ETIMEDOUT; | ||
| 941 | wake_up_interruptible(&adapter->cmd_wait_q.wait); | ||
| 942 | mwifiex_cancel_pending_ioctl(adapter); | ||
| 943 | /* reset cmd_sent flag to unblock new commands */ | ||
| 944 | adapter->cmd_sent = false; | ||
| 945 | } | ||
| 941 | } | 946 | } |
| 942 | if (adapter->hw_status == MWIFIEX_HW_STATUS_INITIALIZING) | 947 | if (adapter->hw_status == MWIFIEX_HW_STATUS_INITIALIZING) |
| 943 | mwifiex_init_fw_complete(adapter); | 948 | mwifiex_init_fw_complete(adapter); |
diff --git a/drivers/net/wireless/mwifiex/scan.c b/drivers/net/wireless/mwifiex/scan.c index 00b658d3b6ec..9171aaedbccd 100644 --- a/drivers/net/wireless/mwifiex/scan.c +++ b/drivers/net/wireless/mwifiex/scan.c | |||
| @@ -1843,21 +1843,18 @@ static int mwifiex_scan_specific_ssid(struct mwifiex_private *priv, | |||
| 1843 | struct cfg80211_ssid *req_ssid) | 1843 | struct cfg80211_ssid *req_ssid) |
| 1844 | { | 1844 | { |
| 1845 | struct mwifiex_adapter *adapter = priv->adapter; | 1845 | struct mwifiex_adapter *adapter = priv->adapter; |
| 1846 | int ret = 0; | 1846 | int ret; |
| 1847 | struct mwifiex_user_scan_cfg *scan_cfg; | 1847 | struct mwifiex_user_scan_cfg *scan_cfg; |
| 1848 | 1848 | ||
| 1849 | if (!req_ssid) | ||
| 1850 | return -1; | ||
| 1851 | |||
| 1852 | if (adapter->scan_processing) { | 1849 | if (adapter->scan_processing) { |
| 1853 | dev_dbg(adapter->dev, "cmd: Scan already in process...\n"); | 1850 | dev_err(adapter->dev, "cmd: Scan already in process...\n"); |
| 1854 | return ret; | 1851 | return -EBUSY; |
| 1855 | } | 1852 | } |
| 1856 | 1853 | ||
| 1857 | if (priv->scan_block) { | 1854 | if (priv->scan_block) { |
| 1858 | dev_dbg(adapter->dev, | 1855 | dev_err(adapter->dev, |
| 1859 | "cmd: Scan is blocked during association...\n"); | 1856 | "cmd: Scan is blocked during association...\n"); |
| 1860 | return ret; | 1857 | return -EBUSY; |
| 1861 | } | 1858 | } |
| 1862 | 1859 | ||
| 1863 | scan_cfg = kzalloc(sizeof(struct mwifiex_user_scan_cfg), GFP_KERNEL); | 1860 | scan_cfg = kzalloc(sizeof(struct mwifiex_user_scan_cfg), GFP_KERNEL); |
diff --git a/drivers/net/wireless/mwifiex/sdio.c b/drivers/net/wireless/mwifiex/sdio.c index fc8a9bfa1248..82cf0fa2d9f6 100644 --- a/drivers/net/wireless/mwifiex/sdio.c +++ b/drivers/net/wireless/mwifiex/sdio.c | |||
| @@ -161,7 +161,6 @@ static int mwifiex_sdio_suspend(struct device *dev) | |||
| 161 | struct sdio_mmc_card *card; | 161 | struct sdio_mmc_card *card; |
| 162 | struct mwifiex_adapter *adapter; | 162 | struct mwifiex_adapter *adapter; |
| 163 | mmc_pm_flag_t pm_flag = 0; | 163 | mmc_pm_flag_t pm_flag = 0; |
| 164 | int hs_actived = 0; | ||
| 165 | int i; | 164 | int i; |
| 166 | int ret = 0; | 165 | int ret = 0; |
| 167 | 166 | ||
| @@ -188,12 +187,14 @@ static int mwifiex_sdio_suspend(struct device *dev) | |||
| 188 | adapter = card->adapter; | 187 | adapter = card->adapter; |
| 189 | 188 | ||
| 190 | /* Enable the Host Sleep */ | 189 | /* Enable the Host Sleep */ |
| 191 | hs_actived = mwifiex_enable_hs(adapter); | 190 | if (!mwifiex_enable_hs(adapter)) { |
| 192 | if (hs_actived) { | 191 | dev_err(adapter->dev, "cmd: failed to suspend\n"); |
| 193 | pr_debug("cmd: suspend with MMC_PM_KEEP_POWER\n"); | 192 | return -EFAULT; |
| 194 | ret = sdio_set_host_pm_flags(func, MMC_PM_KEEP_POWER); | ||
| 195 | } | 193 | } |
| 196 | 194 | ||
| 195 | dev_dbg(adapter->dev, "cmd: suspend with MMC_PM_KEEP_POWER\n"); | ||
| 196 | ret = sdio_set_host_pm_flags(func, MMC_PM_KEEP_POWER); | ||
| 197 | |||
| 197 | /* Indicate device suspended */ | 198 | /* Indicate device suspended */ |
| 198 | adapter->is_suspended = true; | 199 | adapter->is_suspended = true; |
| 199 | 200 | ||
diff --git a/drivers/net/wireless/rt2x00/rt2500usb.c b/drivers/net/wireless/rt2x00/rt2500usb.c index a12e84f892be..6b2e1e431dd2 100644 --- a/drivers/net/wireless/rt2x00/rt2500usb.c +++ b/drivers/net/wireless/rt2x00/rt2500usb.c | |||
| @@ -1988,6 +1988,7 @@ static struct usb_driver rt2500usb_driver = { | |||
| 1988 | .disconnect = rt2x00usb_disconnect, | 1988 | .disconnect = rt2x00usb_disconnect, |
| 1989 | .suspend = rt2x00usb_suspend, | 1989 | .suspend = rt2x00usb_suspend, |
| 1990 | .resume = rt2x00usb_resume, | 1990 | .resume = rt2x00usb_resume, |
| 1991 | .reset_resume = rt2x00usb_resume, | ||
| 1991 | .disable_hub_initiated_lpm = 1, | 1992 | .disable_hub_initiated_lpm = 1, |
| 1992 | }; | 1993 | }; |
| 1993 | 1994 | ||
diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c index 01dc8891070c..59474ae0aec0 100644 --- a/drivers/net/wireless/rt2x00/rt2800lib.c +++ b/drivers/net/wireless/rt2x00/rt2800lib.c | |||
| @@ -2449,7 +2449,7 @@ static int rt2800_get_gain_calibration_delta(struct rt2x00_dev *rt2x00dev) | |||
| 2449 | /* | 2449 | /* |
| 2450 | * Check if temperature compensation is supported. | 2450 | * Check if temperature compensation is supported. |
| 2451 | */ | 2451 | */ |
| 2452 | if (tssi_bounds[4] == 0xff) | 2452 | if (tssi_bounds[4] == 0xff || step == 0xff) |
| 2453 | return 0; | 2453 | return 0; |
| 2454 | 2454 | ||
| 2455 | /* | 2455 | /* |
diff --git a/drivers/net/wireless/rt2x00/rt2800usb.c b/drivers/net/wireless/rt2x00/rt2800usb.c index c9e9370eb789..3b8fb5a603f2 100644 --- a/drivers/net/wireless/rt2x00/rt2800usb.c +++ b/drivers/net/wireless/rt2x00/rt2800usb.c | |||
| @@ -1282,6 +1282,7 @@ static struct usb_driver rt2800usb_driver = { | |||
| 1282 | .disconnect = rt2x00usb_disconnect, | 1282 | .disconnect = rt2x00usb_disconnect, |
| 1283 | .suspend = rt2x00usb_suspend, | 1283 | .suspend = rt2x00usb_suspend, |
| 1284 | .resume = rt2x00usb_resume, | 1284 | .resume = rt2x00usb_resume, |
| 1285 | .reset_resume = rt2x00usb_resume, | ||
| 1285 | .disable_hub_initiated_lpm = 1, | 1286 | .disable_hub_initiated_lpm = 1, |
| 1286 | }; | 1287 | }; |
| 1287 | 1288 | ||
diff --git a/drivers/net/wireless/rt2x00/rt73usb.c b/drivers/net/wireless/rt2x00/rt73usb.c index e5eb43b3eee7..24eec66e9fd2 100644 --- a/drivers/net/wireless/rt2x00/rt73usb.c +++ b/drivers/net/wireless/rt2x00/rt73usb.c | |||
| @@ -2535,6 +2535,7 @@ static struct usb_driver rt73usb_driver = { | |||
| 2535 | .disconnect = rt2x00usb_disconnect, | 2535 | .disconnect = rt2x00usb_disconnect, |
| 2536 | .suspend = rt2x00usb_suspend, | 2536 | .suspend = rt2x00usb_suspend, |
| 2537 | .resume = rt2x00usb_resume, | 2537 | .resume = rt2x00usb_resume, |
| 2538 | .reset_resume = rt2x00usb_resume, | ||
| 2538 | .disable_hub_initiated_lpm = 1, | 2539 | .disable_hub_initiated_lpm = 1, |
| 2539 | }; | 2540 | }; |
| 2540 | 2541 | ||
diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c b/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c index 9970c2b1b199..b7e6607e6b6d 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c | |||
| @@ -297,6 +297,7 @@ static struct usb_device_id rtl8192c_usb_ids[] = { | |||
| 297 | /*=== Customer ID ===*/ | 297 | /*=== Customer ID ===*/ |
| 298 | /****** 8188CU ********/ | 298 | /****** 8188CU ********/ |
| 299 | {RTL_USB_DEVICE(0x050d, 0x1102, rtl92cu_hal_cfg)}, /*Belkin - Edimax*/ | 299 | {RTL_USB_DEVICE(0x050d, 0x1102, rtl92cu_hal_cfg)}, /*Belkin - Edimax*/ |
| 300 | {RTL_USB_DEVICE(0x050d, 0x11f2, rtl92cu_hal_cfg)}, /*Belkin - ISY*/ | ||
| 300 | {RTL_USB_DEVICE(0x06f8, 0xe033, rtl92cu_hal_cfg)}, /*Hercules - Edimax*/ | 301 | {RTL_USB_DEVICE(0x06f8, 0xe033, rtl92cu_hal_cfg)}, /*Hercules - Edimax*/ |
| 301 | {RTL_USB_DEVICE(0x07b8, 0x8188, rtl92cu_hal_cfg)}, /*Abocom - Abocom*/ | 302 | {RTL_USB_DEVICE(0x07b8, 0x8188, rtl92cu_hal_cfg)}, /*Abocom - Abocom*/ |
| 302 | {RTL_USB_DEVICE(0x07b8, 0x8189, rtl92cu_hal_cfg)}, /*Funai - Abocom*/ | 303 | {RTL_USB_DEVICE(0x07b8, 0x8189, rtl92cu_hal_cfg)}, /*Funai - Abocom*/ |
diff --git a/drivers/net/wireless/rtlwifi/usb.c b/drivers/net/wireless/rtlwifi/usb.c index 030beb45d8b0..e3ea4b346889 100644 --- a/drivers/net/wireless/rtlwifi/usb.c +++ b/drivers/net/wireless/rtlwifi/usb.c | |||
| @@ -673,7 +673,7 @@ static int rtl_usb_start(struct ieee80211_hw *hw) | |||
| 673 | set_hal_start(rtlhal); | 673 | set_hal_start(rtlhal); |
| 674 | 674 | ||
| 675 | /* Start bulk IN */ | 675 | /* Start bulk IN */ |
| 676 | _rtl_usb_receive(hw); | 676 | err = _rtl_usb_receive(hw); |
| 677 | } | 677 | } |
| 678 | 678 | ||
| 679 | return err; | 679 | return err; |
diff --git a/drivers/net/xen-netfront.c b/drivers/net/xen-netfront.c index caa011008cd0..fc24eb9b3948 100644 --- a/drivers/net/xen-netfront.c +++ b/drivers/net/xen-netfront.c | |||
| @@ -452,29 +452,85 @@ static void xennet_make_frags(struct sk_buff *skb, struct net_device *dev, | |||
| 452 | /* Grant backend access to each skb fragment page. */ | 452 | /* Grant backend access to each skb fragment page. */ |
| 453 | for (i = 0; i < frags; i++) { | 453 | for (i = 0; i < frags; i++) { |
| 454 | skb_frag_t *frag = skb_shinfo(skb)->frags + i; | 454 | skb_frag_t *frag = skb_shinfo(skb)->frags + i; |
| 455 | struct page *page = skb_frag_page(frag); | ||
| 455 | 456 | ||
| 456 | tx->flags |= XEN_NETTXF_more_data; | 457 | len = skb_frag_size(frag); |
| 458 | offset = frag->page_offset; | ||
| 457 | 459 | ||
| 458 | id = get_id_from_freelist(&np->tx_skb_freelist, np->tx_skbs); | 460 | /* Data must not cross a page boundary. */ |
| 459 | np->tx_skbs[id].skb = skb_get(skb); | 461 | BUG_ON(len + offset > PAGE_SIZE<<compound_order(page)); |
| 460 | tx = RING_GET_REQUEST(&np->tx, prod++); | ||
| 461 | tx->id = id; | ||
| 462 | ref = gnttab_claim_grant_reference(&np->gref_tx_head); | ||
| 463 | BUG_ON((signed short)ref < 0); | ||
| 464 | 462 | ||
| 465 | mfn = pfn_to_mfn(page_to_pfn(skb_frag_page(frag))); | 463 | /* Skip unused frames from start of page */ |
| 466 | gnttab_grant_foreign_access_ref(ref, np->xbdev->otherend_id, | 464 | page += offset >> PAGE_SHIFT; |
| 467 | mfn, GNTMAP_readonly); | 465 | offset &= ~PAGE_MASK; |
| 468 | 466 | ||
| 469 | tx->gref = np->grant_tx_ref[id] = ref; | 467 | while (len > 0) { |
| 470 | tx->offset = frag->page_offset; | 468 | unsigned long bytes; |
| 471 | tx->size = skb_frag_size(frag); | 469 | |
| 472 | tx->flags = 0; | 470 | BUG_ON(offset >= PAGE_SIZE); |
| 471 | |||
| 472 | bytes = PAGE_SIZE - offset; | ||
| 473 | if (bytes > len) | ||
| 474 | bytes = len; | ||
| 475 | |||
| 476 | tx->flags |= XEN_NETTXF_more_data; | ||
| 477 | |||
| 478 | id = get_id_from_freelist(&np->tx_skb_freelist, | ||
| 479 | np->tx_skbs); | ||
| 480 | np->tx_skbs[id].skb = skb_get(skb); | ||
| 481 | tx = RING_GET_REQUEST(&np->tx, prod++); | ||
| 482 | tx->id = id; | ||
| 483 | ref = gnttab_claim_grant_reference(&np->gref_tx_head); | ||
| 484 | BUG_ON((signed short)ref < 0); | ||
| 485 | |||
| 486 | mfn = pfn_to_mfn(page_to_pfn(page)); | ||
| 487 | gnttab_grant_foreign_access_ref(ref, | ||
| 488 | np->xbdev->otherend_id, | ||
| 489 | mfn, GNTMAP_readonly); | ||
| 490 | |||
| 491 | tx->gref = np->grant_tx_ref[id] = ref; | ||
| 492 | tx->offset = offset; | ||
| 493 | tx->size = bytes; | ||
| 494 | tx->flags = 0; | ||
| 495 | |||
| 496 | offset += bytes; | ||
| 497 | len -= bytes; | ||
| 498 | |||
| 499 | /* Next frame */ | ||
| 500 | if (offset == PAGE_SIZE && len) { | ||
| 501 | BUG_ON(!PageCompound(page)); | ||
| 502 | page++; | ||
| 503 | offset = 0; | ||
| 504 | } | ||
| 505 | } | ||
| 473 | } | 506 | } |
| 474 | 507 | ||
| 475 | np->tx.req_prod_pvt = prod; | 508 | np->tx.req_prod_pvt = prod; |
| 476 | } | 509 | } |
| 477 | 510 | ||
| 511 | /* | ||
| 512 | * Count how many ring slots are required to send the frags of this | ||
| 513 | * skb. Each frag might be a compound page. | ||
| 514 | */ | ||
| 515 | static int xennet_count_skb_frag_slots(struct sk_buff *skb) | ||
| 516 | { | ||
| 517 | int i, frags = skb_shinfo(skb)->nr_frags; | ||
| 518 | int pages = 0; | ||
| 519 | |||
| 520 | for (i = 0; i < frags; i++) { | ||
| 521 | skb_frag_t *frag = skb_shinfo(skb)->frags + i; | ||
| 522 | unsigned long size = skb_frag_size(frag); | ||
| 523 | unsigned long offset = frag->page_offset; | ||
| 524 | |||
| 525 | /* Skip unused frames from start of page */ | ||
| 526 | offset &= ~PAGE_MASK; | ||
| 527 | |||
| 528 | pages += PFN_UP(offset + size); | ||
| 529 | } | ||
| 530 | |||
| 531 | return pages; | ||
| 532 | } | ||
| 533 | |||
| 478 | static int xennet_start_xmit(struct sk_buff *skb, struct net_device *dev) | 534 | static int xennet_start_xmit(struct sk_buff *skb, struct net_device *dev) |
| 479 | { | 535 | { |
| 480 | unsigned short id; | 536 | unsigned short id; |
| @@ -487,23 +543,23 @@ static int xennet_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
| 487 | grant_ref_t ref; | 543 | grant_ref_t ref; |
| 488 | unsigned long mfn; | 544 | unsigned long mfn; |
| 489 | int notify; | 545 | int notify; |
| 490 | int frags = skb_shinfo(skb)->nr_frags; | 546 | int slots; |
| 491 | unsigned int offset = offset_in_page(data); | 547 | unsigned int offset = offset_in_page(data); |
| 492 | unsigned int len = skb_headlen(skb); | 548 | unsigned int len = skb_headlen(skb); |
| 493 | unsigned long flags; | 549 | unsigned long flags; |
| 494 | 550 | ||
| 495 | frags += DIV_ROUND_UP(offset + len, PAGE_SIZE); | 551 | slots = DIV_ROUND_UP(offset + len, PAGE_SIZE) + |
| 496 | if (unlikely(frags > MAX_SKB_FRAGS + 1)) { | 552 | xennet_count_skb_frag_slots(skb); |
| 497 | printk(KERN_ALERT "xennet: skb rides the rocket: %d frags\n", | 553 | if (unlikely(slots > MAX_SKB_FRAGS + 1)) { |
| 498 | frags); | 554 | net_alert_ratelimited( |
| 499 | dump_stack(); | 555 | "xennet: skb rides the rocket: %d slots\n", slots); |
| 500 | goto drop; | 556 | goto drop; |
| 501 | } | 557 | } |
| 502 | 558 | ||
| 503 | spin_lock_irqsave(&np->tx_lock, flags); | 559 | spin_lock_irqsave(&np->tx_lock, flags); |
| 504 | 560 | ||
| 505 | if (unlikely(!netif_carrier_ok(dev) || | 561 | if (unlikely(!netif_carrier_ok(dev) || |
| 506 | (frags > 1 && !xennet_can_sg(dev)) || | 562 | (slots > 1 && !xennet_can_sg(dev)) || |
| 507 | netif_needs_gso(skb, netif_skb_features(skb)))) { | 563 | netif_needs_gso(skb, netif_skb_features(skb)))) { |
| 508 | spin_unlock_irqrestore(&np->tx_lock, flags); | 564 | spin_unlock_irqrestore(&np->tx_lock, flags); |
| 509 | goto drop; | 565 | goto drop; |
diff --git a/drivers/nfc/pn533.c b/drivers/nfc/pn533.c index 97c440a8cd61..30ae18a03a9c 100644 --- a/drivers/nfc/pn533.c +++ b/drivers/nfc/pn533.c | |||
| @@ -698,13 +698,14 @@ static void pn533_wq_cmd(struct work_struct *work) | |||
| 698 | 698 | ||
| 699 | cmd = list_first_entry(&dev->cmd_queue, struct pn533_cmd, queue); | 699 | cmd = list_first_entry(&dev->cmd_queue, struct pn533_cmd, queue); |
| 700 | 700 | ||
| 701 | list_del(&cmd->queue); | ||
| 702 | |||
| 701 | mutex_unlock(&dev->cmd_lock); | 703 | mutex_unlock(&dev->cmd_lock); |
| 702 | 704 | ||
| 703 | __pn533_send_cmd_frame_async(dev, cmd->out_frame, cmd->in_frame, | 705 | __pn533_send_cmd_frame_async(dev, cmd->out_frame, cmd->in_frame, |
| 704 | cmd->in_frame_len, cmd->cmd_complete, | 706 | cmd->in_frame_len, cmd->cmd_complete, |
| 705 | cmd->arg, cmd->flags); | 707 | cmd->arg, cmd->flags); |
| 706 | 708 | ||
| 707 | list_del(&cmd->queue); | ||
| 708 | kfree(cmd); | 709 | kfree(cmd); |
| 709 | } | 710 | } |
| 710 | 711 | ||
| @@ -1678,11 +1679,14 @@ static void pn533_deactivate_target(struct nfc_dev *nfc_dev, | |||
| 1678 | static int pn533_in_dep_link_up_complete(struct pn533 *dev, void *arg, | 1679 | static int pn533_in_dep_link_up_complete(struct pn533 *dev, void *arg, |
| 1679 | u8 *params, int params_len) | 1680 | u8 *params, int params_len) |
| 1680 | { | 1681 | { |
| 1681 | struct pn533_cmd_jump_dep *cmd; | ||
| 1682 | struct pn533_cmd_jump_dep_response *resp; | 1682 | struct pn533_cmd_jump_dep_response *resp; |
| 1683 | struct nfc_target nfc_target; | 1683 | struct nfc_target nfc_target; |
| 1684 | u8 target_gt_len; | 1684 | u8 target_gt_len; |
| 1685 | int rc; | 1685 | int rc; |
| 1686 | struct pn533_cmd_jump_dep *cmd = (struct pn533_cmd_jump_dep *)arg; | ||
| 1687 | u8 active = cmd->active; | ||
| 1688 | |||
| 1689 | kfree(arg); | ||
| 1686 | 1690 | ||
| 1687 | if (params_len == -ENOENT) { | 1691 | if (params_len == -ENOENT) { |
| 1688 | nfc_dev_dbg(&dev->interface->dev, ""); | 1692 | nfc_dev_dbg(&dev->interface->dev, ""); |
| @@ -1704,7 +1708,6 @@ static int pn533_in_dep_link_up_complete(struct pn533 *dev, void *arg, | |||
| 1704 | } | 1708 | } |
| 1705 | 1709 | ||
| 1706 | resp = (struct pn533_cmd_jump_dep_response *) params; | 1710 | resp = (struct pn533_cmd_jump_dep_response *) params; |
| 1707 | cmd = (struct pn533_cmd_jump_dep *) arg; | ||
| 1708 | rc = resp->status & PN533_CMD_RET_MASK; | 1711 | rc = resp->status & PN533_CMD_RET_MASK; |
| 1709 | if (rc != PN533_CMD_RET_SUCCESS) { | 1712 | if (rc != PN533_CMD_RET_SUCCESS) { |
| 1710 | nfc_dev_err(&dev->interface->dev, | 1713 | nfc_dev_err(&dev->interface->dev, |
| @@ -1734,7 +1737,7 @@ static int pn533_in_dep_link_up_complete(struct pn533 *dev, void *arg, | |||
| 1734 | if (rc == 0) | 1737 | if (rc == 0) |
| 1735 | rc = nfc_dep_link_is_up(dev->nfc_dev, | 1738 | rc = nfc_dep_link_is_up(dev->nfc_dev, |
| 1736 | dev->nfc_dev->targets[0].idx, | 1739 | dev->nfc_dev->targets[0].idx, |
| 1737 | !cmd->active, NFC_RF_INITIATOR); | 1740 | !active, NFC_RF_INITIATOR); |
| 1738 | 1741 | ||
| 1739 | return 0; | 1742 | return 0; |
| 1740 | } | 1743 | } |
| @@ -1819,12 +1822,8 @@ static int pn533_dep_link_up(struct nfc_dev *nfc_dev, struct nfc_target *target, | |||
| 1819 | rc = pn533_send_cmd_frame_async(dev, dev->out_frame, dev->in_frame, | 1822 | rc = pn533_send_cmd_frame_async(dev, dev->out_frame, dev->in_frame, |
| 1820 | dev->in_maxlen, pn533_in_dep_link_up_complete, | 1823 | dev->in_maxlen, pn533_in_dep_link_up_complete, |
| 1821 | cmd, GFP_KERNEL); | 1824 | cmd, GFP_KERNEL); |
| 1822 | if (rc) | 1825 | if (rc < 0) |
| 1823 | goto out; | 1826 | kfree(cmd); |
| 1824 | |||
| 1825 | |||
| 1826 | out: | ||
| 1827 | kfree(cmd); | ||
| 1828 | 1827 | ||
| 1829 | return rc; | 1828 | return rc; |
| 1830 | } | 1829 | } |
| @@ -2078,8 +2077,12 @@ error: | |||
| 2078 | static int pn533_tm_send_complete(struct pn533 *dev, void *arg, | 2077 | static int pn533_tm_send_complete(struct pn533 *dev, void *arg, |
| 2079 | u8 *params, int params_len) | 2078 | u8 *params, int params_len) |
| 2080 | { | 2079 | { |
| 2080 | struct sk_buff *skb_out = arg; | ||
| 2081 | |||
| 2081 | nfc_dev_dbg(&dev->interface->dev, "%s", __func__); | 2082 | nfc_dev_dbg(&dev->interface->dev, "%s", __func__); |
| 2082 | 2083 | ||
| 2084 | dev_kfree_skb(skb_out); | ||
| 2085 | |||
| 2083 | if (params_len < 0) { | 2086 | if (params_len < 0) { |
| 2084 | nfc_dev_err(&dev->interface->dev, | 2087 | nfc_dev_err(&dev->interface->dev, |
| 2085 | "Error %d when sending data", | 2088 | "Error %d when sending data", |
| @@ -2117,7 +2120,7 @@ static int pn533_tm_send(struct nfc_dev *nfc_dev, struct sk_buff *skb) | |||
| 2117 | 2120 | ||
| 2118 | rc = pn533_send_cmd_frame_async(dev, out_frame, dev->in_frame, | 2121 | rc = pn533_send_cmd_frame_async(dev, out_frame, dev->in_frame, |
| 2119 | dev->in_maxlen, pn533_tm_send_complete, | 2122 | dev->in_maxlen, pn533_tm_send_complete, |
| 2120 | NULL, GFP_KERNEL); | 2123 | skb, GFP_KERNEL); |
| 2121 | if (rc) { | 2124 | if (rc) { |
| 2122 | nfc_dev_err(&dev->interface->dev, | 2125 | nfc_dev_err(&dev->interface->dev, |
| 2123 | "Error %d when trying to send data", rc); | 2126 | "Error %d when trying to send data", rc); |
diff --git a/drivers/of/address.c b/drivers/of/address.c index 72e496f1e9b0..0125524c08c4 100644 --- a/drivers/of/address.c +++ b/drivers/of/address.c | |||
| @@ -37,9 +37,9 @@ struct of_bus { | |||
| 37 | int (*match)(struct device_node *parent); | 37 | int (*match)(struct device_node *parent); |
| 38 | void (*count_cells)(struct device_node *child, | 38 | void (*count_cells)(struct device_node *child, |
| 39 | int *addrc, int *sizec); | 39 | int *addrc, int *sizec); |
| 40 | u64 (*map)(u32 *addr, const __be32 *range, | 40 | u64 (*map)(__be32 *addr, const __be32 *range, |
| 41 | int na, int ns, int pna); | 41 | int na, int ns, int pna); |
| 42 | int (*translate)(u32 *addr, u64 offset, int na); | 42 | int (*translate)(__be32 *addr, u64 offset, int na); |
| 43 | unsigned int (*get_flags)(const __be32 *addr); | 43 | unsigned int (*get_flags)(const __be32 *addr); |
| 44 | }; | 44 | }; |
| 45 | 45 | ||
| @@ -56,7 +56,7 @@ static void of_bus_default_count_cells(struct device_node *dev, | |||
| 56 | *sizec = of_n_size_cells(dev); | 56 | *sizec = of_n_size_cells(dev); |
| 57 | } | 57 | } |
| 58 | 58 | ||
| 59 | static u64 of_bus_default_map(u32 *addr, const __be32 *range, | 59 | static u64 of_bus_default_map(__be32 *addr, const __be32 *range, |
| 60 | int na, int ns, int pna) | 60 | int na, int ns, int pna) |
| 61 | { | 61 | { |
| 62 | u64 cp, s, da; | 62 | u64 cp, s, da; |
| @@ -82,7 +82,7 @@ static u64 of_bus_default_map(u32 *addr, const __be32 *range, | |||
| 82 | return da - cp; | 82 | return da - cp; |
| 83 | } | 83 | } |
| 84 | 84 | ||
| 85 | static int of_bus_default_translate(u32 *addr, u64 offset, int na) | 85 | static int of_bus_default_translate(__be32 *addr, u64 offset, int na) |
| 86 | { | 86 | { |
| 87 | u64 a = of_read_number(addr, na); | 87 | u64 a = of_read_number(addr, na); |
| 88 | memset(addr, 0, na * 4); | 88 | memset(addr, 0, na * 4); |
| @@ -138,7 +138,7 @@ static unsigned int of_bus_pci_get_flags(const __be32 *addr) | |||
| 138 | return flags; | 138 | return flags; |
| 139 | } | 139 | } |
| 140 | 140 | ||
| 141 | static u64 of_bus_pci_map(u32 *addr, const __be32 *range, int na, int ns, | 141 | static u64 of_bus_pci_map(__be32 *addr, const __be32 *range, int na, int ns, |
| 142 | int pna) | 142 | int pna) |
| 143 | { | 143 | { |
| 144 | u64 cp, s, da; | 144 | u64 cp, s, da; |
| @@ -165,7 +165,7 @@ static u64 of_bus_pci_map(u32 *addr, const __be32 *range, int na, int ns, | |||
| 165 | return da - cp; | 165 | return da - cp; |
| 166 | } | 166 | } |
| 167 | 167 | ||
| 168 | static int of_bus_pci_translate(u32 *addr, u64 offset, int na) | 168 | static int of_bus_pci_translate(__be32 *addr, u64 offset, int na) |
| 169 | { | 169 | { |
| 170 | return of_bus_default_translate(addr + 1, offset, na - 1); | 170 | return of_bus_default_translate(addr + 1, offset, na - 1); |
| 171 | } | 171 | } |
| @@ -247,7 +247,7 @@ static void of_bus_isa_count_cells(struct device_node *child, | |||
| 247 | *sizec = 1; | 247 | *sizec = 1; |
| 248 | } | 248 | } |
| 249 | 249 | ||
| 250 | static u64 of_bus_isa_map(u32 *addr, const __be32 *range, int na, int ns, | 250 | static u64 of_bus_isa_map(__be32 *addr, const __be32 *range, int na, int ns, |
| 251 | int pna) | 251 | int pna) |
| 252 | { | 252 | { |
| 253 | u64 cp, s, da; | 253 | u64 cp, s, da; |
| @@ -270,7 +270,7 @@ static u64 of_bus_isa_map(u32 *addr, const __be32 *range, int na, int ns, | |||
| 270 | return da - cp; | 270 | return da - cp; |
| 271 | } | 271 | } |
| 272 | 272 | ||
| 273 | static int of_bus_isa_translate(u32 *addr, u64 offset, int na) | 273 | static int of_bus_isa_translate(__be32 *addr, u64 offset, int na) |
| 274 | { | 274 | { |
| 275 | return of_bus_default_translate(addr + 1, offset, na - 1); | 275 | return of_bus_default_translate(addr + 1, offset, na - 1); |
| 276 | } | 276 | } |
| @@ -338,7 +338,7 @@ static struct of_bus *of_match_bus(struct device_node *np) | |||
| 338 | } | 338 | } |
| 339 | 339 | ||
| 340 | static int of_translate_one(struct device_node *parent, struct of_bus *bus, | 340 | static int of_translate_one(struct device_node *parent, struct of_bus *bus, |
| 341 | struct of_bus *pbus, u32 *addr, | 341 | struct of_bus *pbus, __be32 *addr, |
| 342 | int na, int ns, int pna, const char *rprop) | 342 | int na, int ns, int pna, const char *rprop) |
| 343 | { | 343 | { |
| 344 | const __be32 *ranges; | 344 | const __be32 *ranges; |
| @@ -409,12 +409,12 @@ static int of_translate_one(struct device_node *parent, struct of_bus *bus, | |||
| 409 | * that can be mapped to a cpu physical address). This is not really specified | 409 | * that can be mapped to a cpu physical address). This is not really specified |
| 410 | * that way, but this is traditionally the way IBM at least do things | 410 | * that way, but this is traditionally the way IBM at least do things |
| 411 | */ | 411 | */ |
| 412 | u64 __of_translate_address(struct device_node *dev, const __be32 *in_addr, | 412 | static u64 __of_translate_address(struct device_node *dev, |
| 413 | const char *rprop) | 413 | const __be32 *in_addr, const char *rprop) |
| 414 | { | 414 | { |
| 415 | struct device_node *parent = NULL; | 415 | struct device_node *parent = NULL; |
| 416 | struct of_bus *bus, *pbus; | 416 | struct of_bus *bus, *pbus; |
| 417 | u32 addr[OF_MAX_ADDR_CELLS]; | 417 | __be32 addr[OF_MAX_ADDR_CELLS]; |
| 418 | int na, ns, pna, pns; | 418 | int na, ns, pna, pns; |
| 419 | u64 result = OF_BAD_ADDR; | 419 | u64 result = OF_BAD_ADDR; |
| 420 | 420 | ||
diff --git a/drivers/of/irq.c b/drivers/of/irq.c index a23ec7779997..a3c1c5aae6a9 100644 --- a/drivers/of/irq.c +++ b/drivers/of/irq.c | |||
| @@ -192,11 +192,13 @@ int of_irq_map_raw(struct device_node *parent, const __be32 *intspec, | |||
| 192 | /* Compare specifiers */ | 192 | /* Compare specifiers */ |
| 193 | match = 1; | 193 | match = 1; |
| 194 | for (i = 0; i < addrsize && match; ++i) { | 194 | for (i = 0; i < addrsize && match; ++i) { |
| 195 | u32 mask = imask ? imask[i] : 0xffffffffu; | 195 | __be32 mask = imask ? imask[i] |
| 196 | : cpu_to_be32(0xffffffffu); | ||
| 196 | match = ((addr[i] ^ imap[i]) & mask) == 0; | 197 | match = ((addr[i] ^ imap[i]) & mask) == 0; |
| 197 | } | 198 | } |
| 198 | for (; i < (addrsize + intsize) && match; ++i) { | 199 | for (; i < (addrsize + intsize) && match; ++i) { |
| 199 | u32 mask = imask ? imask[i] : 0xffffffffu; | 200 | __be32 mask = imask ? imask[i] |
| 201 | : cpu_to_be32(0xffffffffu); | ||
| 200 | match = | 202 | match = |
| 201 | ((intspec[i-addrsize] ^ imap[i]) & mask) == 0; | 203 | ((intspec[i-addrsize] ^ imap[i]) & mask) == 0; |
| 202 | } | 204 | } |
| @@ -465,7 +467,7 @@ void __init of_irq_init(const struct of_device_id *matches) | |||
| 465 | pr_debug("of_irq_init: init %s @ %p, parent %p\n", | 467 | pr_debug("of_irq_init: init %s @ %p, parent %p\n", |
| 466 | match->compatible, | 468 | match->compatible, |
| 467 | desc->dev, desc->interrupt_parent); | 469 | desc->dev, desc->interrupt_parent); |
| 468 | irq_init_cb = match->data; | 470 | irq_init_cb = (of_irq_init_cb_t)match->data; |
| 469 | ret = irq_init_cb(desc->dev, desc->interrupt_parent); | 471 | ret = irq_init_cb(desc->dev, desc->interrupt_parent); |
| 470 | if (ret) { | 472 | if (ret) { |
| 471 | kfree(desc); | 473 | kfree(desc); |
diff --git a/drivers/of/platform.c b/drivers/of/platform.c index 9bdeaf30b17d..b80891b43816 100644 --- a/drivers/of/platform.c +++ b/drivers/of/platform.c | |||
| @@ -76,7 +76,7 @@ void of_device_make_bus_id(struct device *dev) | |||
| 76 | { | 76 | { |
| 77 | static atomic_t bus_no_reg_magic; | 77 | static atomic_t bus_no_reg_magic; |
| 78 | struct device_node *node = dev->of_node; | 78 | struct device_node *node = dev->of_node; |
| 79 | const u32 *reg; | 79 | const __be32 *reg; |
| 80 | u64 addr; | 80 | u64 addr; |
| 81 | const __be32 *addrp; | 81 | const __be32 *addrp; |
| 82 | int magic; | 82 | int magic; |
diff --git a/drivers/pci/bus.c b/drivers/pci/bus.c index 6241fd05bd41..a543746fb354 100644 --- a/drivers/pci/bus.c +++ b/drivers/pci/bus.c | |||
| @@ -320,10 +320,7 @@ void pci_walk_bus(struct pci_bus *top, int (*cb)(struct pci_dev *, void *), | |||
| 320 | } else | 320 | } else |
| 321 | next = dev->bus_list.next; | 321 | next = dev->bus_list.next; |
| 322 | 322 | ||
| 323 | /* Run device routines with the device locked */ | ||
| 324 | device_lock(&dev->dev); | ||
| 325 | retval = cb(dev, userdata); | 323 | retval = cb(dev, userdata); |
| 326 | device_unlock(&dev->dev); | ||
| 327 | if (retval) | 324 | if (retval) |
| 328 | break; | 325 | break; |
| 329 | } | 326 | } |
diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c index 94c6e2aa03d6..6c94fc9489e7 100644 --- a/drivers/pci/pci-driver.c +++ b/drivers/pci/pci-driver.c | |||
| @@ -398,6 +398,8 @@ static void pci_device_shutdown(struct device *dev) | |||
| 398 | struct pci_dev *pci_dev = to_pci_dev(dev); | 398 | struct pci_dev *pci_dev = to_pci_dev(dev); |
| 399 | struct pci_driver *drv = pci_dev->driver; | 399 | struct pci_driver *drv = pci_dev->driver; |
| 400 | 400 | ||
| 401 | pm_runtime_resume(dev); | ||
| 402 | |||
| 401 | if (drv && drv->shutdown) | 403 | if (drv && drv->shutdown) |
| 402 | drv->shutdown(pci_dev); | 404 | drv->shutdown(pci_dev); |
| 403 | pci_msi_shutdown(pci_dev); | 405 | pci_msi_shutdown(pci_dev); |
| @@ -408,16 +410,6 @@ static void pci_device_shutdown(struct device *dev) | |||
| 408 | * continue to do DMA | 410 | * continue to do DMA |
| 409 | */ | 411 | */ |
| 410 | pci_disable_device(pci_dev); | 412 | pci_disable_device(pci_dev); |
| 411 | |||
| 412 | /* | ||
| 413 | * Devices may be enabled to wake up by runtime PM, but they need not | ||
| 414 | * be supposed to wake up the system from its "power off" state (e.g. | ||
| 415 | * ACPI S5). Therefore disable wakeup for all devices that aren't | ||
| 416 | * supposed to wake up the system at this point. The state argument | ||
| 417 | * will be ignored by pci_enable_wake(). | ||
| 418 | */ | ||
| 419 | if (!device_may_wakeup(dev)) | ||
| 420 | pci_enable_wake(pci_dev, PCI_UNKNOWN, false); | ||
| 421 | } | 413 | } |
| 422 | 414 | ||
| 423 | #ifdef CONFIG_PM | 415 | #ifdef CONFIG_PM |
diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c index 02d107b15281..f39378d9da15 100644 --- a/drivers/pci/pci-sysfs.c +++ b/drivers/pci/pci-sysfs.c | |||
| @@ -458,40 +458,6 @@ boot_vga_show(struct device *dev, struct device_attribute *attr, char *buf) | |||
| 458 | } | 458 | } |
| 459 | struct device_attribute vga_attr = __ATTR_RO(boot_vga); | 459 | struct device_attribute vga_attr = __ATTR_RO(boot_vga); |
| 460 | 460 | ||
| 461 | static void | ||
| 462 | pci_config_pm_runtime_get(struct pci_dev *pdev) | ||
| 463 | { | ||
| 464 | struct device *dev = &pdev->dev; | ||
| 465 | struct device *parent = dev->parent; | ||
| 466 | |||
| 467 | if (parent) | ||
| 468 | pm_runtime_get_sync(parent); | ||
| 469 | pm_runtime_get_noresume(dev); | ||
| 470 | /* | ||
| 471 | * pdev->current_state is set to PCI_D3cold during suspending, | ||
| 472 | * so wait until suspending completes | ||
| 473 | */ | ||
| 474 | pm_runtime_barrier(dev); | ||
| 475 | /* | ||
| 476 | * Only need to resume devices in D3cold, because config | ||
| 477 | * registers are still accessible for devices suspended but | ||
| 478 | * not in D3cold. | ||
| 479 | */ | ||
| 480 | if (pdev->current_state == PCI_D3cold) | ||
| 481 | pm_runtime_resume(dev); | ||
| 482 | } | ||
| 483 | |||
| 484 | static void | ||
| 485 | pci_config_pm_runtime_put(struct pci_dev *pdev) | ||
| 486 | { | ||
| 487 | struct device *dev = &pdev->dev; | ||
| 488 | struct device *parent = dev->parent; | ||
| 489 | |||
| 490 | pm_runtime_put(dev); | ||
| 491 | if (parent) | ||
| 492 | pm_runtime_put_sync(parent); | ||
| 493 | } | ||
| 494 | |||
| 495 | static ssize_t | 461 | static ssize_t |
| 496 | pci_read_config(struct file *filp, struct kobject *kobj, | 462 | pci_read_config(struct file *filp, struct kobject *kobj, |
| 497 | struct bin_attribute *bin_attr, | 463 | struct bin_attribute *bin_attr, |
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 54858838f098..aabf64798bda 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c | |||
| @@ -1858,6 +1858,38 @@ bool pci_dev_run_wake(struct pci_dev *dev) | |||
| 1858 | } | 1858 | } |
| 1859 | EXPORT_SYMBOL_GPL(pci_dev_run_wake); | 1859 | EXPORT_SYMBOL_GPL(pci_dev_run_wake); |
| 1860 | 1860 | ||
| 1861 | void pci_config_pm_runtime_get(struct pci_dev *pdev) | ||
| 1862 | { | ||
| 1863 | struct device *dev = &pdev->dev; | ||
| 1864 | struct device *parent = dev->parent; | ||
| 1865 | |||
| 1866 | if (parent) | ||
| 1867 | pm_runtime_get_sync(parent); | ||
| 1868 | pm_runtime_get_noresume(dev); | ||
| 1869 | /* | ||
| 1870 | * pdev->current_state is set to PCI_D3cold during suspending, | ||
| 1871 | * so wait until suspending completes | ||
| 1872 | */ | ||
| 1873 | pm_runtime_barrier(dev); | ||
| 1874 | /* | ||
| 1875 | * Only need to resume devices in D3cold, because config | ||
| 1876 | * registers are still accessible for devices suspended but | ||
| 1877 | * not in D3cold. | ||
| 1878 | */ | ||
| 1879 | if (pdev->current_state == PCI_D3cold) | ||
| 1880 | pm_runtime_resume(dev); | ||
| 1881 | } | ||
| 1882 | |||
| 1883 | void pci_config_pm_runtime_put(struct pci_dev *pdev) | ||
| 1884 | { | ||
| 1885 | struct device *dev = &pdev->dev; | ||
| 1886 | struct device *parent = dev->parent; | ||
| 1887 | |||
| 1888 | pm_runtime_put(dev); | ||
| 1889 | if (parent) | ||
| 1890 | pm_runtime_put_sync(parent); | ||
| 1891 | } | ||
| 1892 | |||
| 1861 | /** | 1893 | /** |
| 1862 | * pci_pm_init - Initialize PM functions of given PCI device | 1894 | * pci_pm_init - Initialize PM functions of given PCI device |
| 1863 | * @dev: PCI device to handle. | 1895 | * @dev: PCI device to handle. |
diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h index bacbcba69cf3..fd92aab9904b 100644 --- a/drivers/pci/pci.h +++ b/drivers/pci/pci.h | |||
| @@ -72,6 +72,8 @@ extern void pci_disable_enabled_device(struct pci_dev *dev); | |||
| 72 | extern int pci_finish_runtime_suspend(struct pci_dev *dev); | 72 | extern int pci_finish_runtime_suspend(struct pci_dev *dev); |
| 73 | extern int __pci_pme_wakeup(struct pci_dev *dev, void *ign); | 73 | extern int __pci_pme_wakeup(struct pci_dev *dev, void *ign); |
| 74 | extern void pci_wakeup_bus(struct pci_bus *bus); | 74 | extern void pci_wakeup_bus(struct pci_bus *bus); |
| 75 | extern void pci_config_pm_runtime_get(struct pci_dev *dev); | ||
| 76 | extern void pci_config_pm_runtime_put(struct pci_dev *dev); | ||
| 75 | extern void pci_pm_init(struct pci_dev *dev); | 77 | extern void pci_pm_init(struct pci_dev *dev); |
| 76 | extern void platform_pci_wakeup_init(struct pci_dev *dev); | 78 | extern void platform_pci_wakeup_init(struct pci_dev *dev); |
| 77 | extern void pci_allocate_cap_save_buffers(struct pci_dev *dev); | 79 | extern void pci_allocate_cap_save_buffers(struct pci_dev *dev); |
diff --git a/drivers/pci/pcie/aer/aerdrv_core.c b/drivers/pci/pcie/aer/aerdrv_core.c index 06bad96af415..af4e31cd3a3b 100644 --- a/drivers/pci/pcie/aer/aerdrv_core.c +++ b/drivers/pci/pcie/aer/aerdrv_core.c | |||
| @@ -213,6 +213,7 @@ static int report_error_detected(struct pci_dev *dev, void *data) | |||
| 213 | struct aer_broadcast_data *result_data; | 213 | struct aer_broadcast_data *result_data; |
| 214 | result_data = (struct aer_broadcast_data *) data; | 214 | result_data = (struct aer_broadcast_data *) data; |
| 215 | 215 | ||
| 216 | device_lock(&dev->dev); | ||
| 216 | dev->error_state = result_data->state; | 217 | dev->error_state = result_data->state; |
| 217 | 218 | ||
| 218 | if (!dev->driver || | 219 | if (!dev->driver || |
| @@ -231,12 +232,14 @@ static int report_error_detected(struct pci_dev *dev, void *data) | |||
| 231 | dev->driver ? | 232 | dev->driver ? |
| 232 | "no AER-aware driver" : "no driver"); | 233 | "no AER-aware driver" : "no driver"); |
| 233 | } | 234 | } |
| 234 | return 0; | 235 | goto out; |
| 235 | } | 236 | } |
| 236 | 237 | ||
| 237 | err_handler = dev->driver->err_handler; | 238 | err_handler = dev->driver->err_handler; |
| 238 | vote = err_handler->error_detected(dev, result_data->state); | 239 | vote = err_handler->error_detected(dev, result_data->state); |
| 239 | result_data->result = merge_result(result_data->result, vote); | 240 | result_data->result = merge_result(result_data->result, vote); |
| 241 | out: | ||
| 242 | device_unlock(&dev->dev); | ||
| 240 | return 0; | 243 | return 0; |
| 241 | } | 244 | } |
| 242 | 245 | ||
| @@ -247,14 +250,17 @@ static int report_mmio_enabled(struct pci_dev *dev, void *data) | |||
| 247 | struct aer_broadcast_data *result_data; | 250 | struct aer_broadcast_data *result_data; |
| 248 | result_data = (struct aer_broadcast_data *) data; | 251 | result_data = (struct aer_broadcast_data *) data; |
| 249 | 252 | ||
| 253 | device_lock(&dev->dev); | ||
| 250 | if (!dev->driver || | 254 | if (!dev->driver || |
| 251 | !dev->driver->err_handler || | 255 | !dev->driver->err_handler || |
| 252 | !dev->driver->err_handler->mmio_enabled) | 256 | !dev->driver->err_handler->mmio_enabled) |
| 253 | return 0; | 257 | goto out; |
| 254 | 258 | ||
| 255 | err_handler = dev->driver->err_handler; | 259 | err_handler = dev->driver->err_handler; |
| 256 | vote = err_handler->mmio_enabled(dev); | 260 | vote = err_handler->mmio_enabled(dev); |
| 257 | result_data->result = merge_result(result_data->result, vote); | 261 | result_data->result = merge_result(result_data->result, vote); |
| 262 | out: | ||
| 263 | device_unlock(&dev->dev); | ||
| 258 | return 0; | 264 | return 0; |
| 259 | } | 265 | } |
| 260 | 266 | ||
| @@ -265,14 +271,17 @@ static int report_slot_reset(struct pci_dev *dev, void *data) | |||
| 265 | struct aer_broadcast_data *result_data; | 271 | struct aer_broadcast_data *result_data; |
| 266 | result_data = (struct aer_broadcast_data *) data; | 272 | result_data = (struct aer_broadcast_data *) data; |
| 267 | 273 | ||
| 274 | device_lock(&dev->dev); | ||
| 268 | if (!dev->driver || | 275 | if (!dev->driver || |
| 269 | !dev->driver->err_handler || | 276 | !dev->driver->err_handler || |
| 270 | !dev->driver->err_handler->slot_reset) | 277 | !dev->driver->err_handler->slot_reset) |
| 271 | return 0; | 278 | goto out; |
| 272 | 279 | ||
| 273 | err_handler = dev->driver->err_handler; | 280 | err_handler = dev->driver->err_handler; |
| 274 | vote = err_handler->slot_reset(dev); | 281 | vote = err_handler->slot_reset(dev); |
| 275 | result_data->result = merge_result(result_data->result, vote); | 282 | result_data->result = merge_result(result_data->result, vote); |
| 283 | out: | ||
| 284 | device_unlock(&dev->dev); | ||
| 276 | return 0; | 285 | return 0; |
| 277 | } | 286 | } |
| 278 | 287 | ||
| @@ -280,15 +289,18 @@ static int report_resume(struct pci_dev *dev, void *data) | |||
| 280 | { | 289 | { |
| 281 | const struct pci_error_handlers *err_handler; | 290 | const struct pci_error_handlers *err_handler; |
| 282 | 291 | ||
| 292 | device_lock(&dev->dev); | ||
| 283 | dev->error_state = pci_channel_io_normal; | 293 | dev->error_state = pci_channel_io_normal; |
| 284 | 294 | ||
| 285 | if (!dev->driver || | 295 | if (!dev->driver || |
| 286 | !dev->driver->err_handler || | 296 | !dev->driver->err_handler || |
| 287 | !dev->driver->err_handler->resume) | 297 | !dev->driver->err_handler->resume) |
| 288 | return 0; | 298 | goto out; |
| 289 | 299 | ||
| 290 | err_handler = dev->driver->err_handler; | 300 | err_handler = dev->driver->err_handler; |
| 291 | err_handler->resume(dev); | 301 | err_handler->resume(dev); |
| 302 | out: | ||
| 303 | device_unlock(&dev->dev); | ||
| 292 | return 0; | 304 | return 0; |
| 293 | } | 305 | } |
| 294 | 306 | ||
diff --git a/drivers/pci/pcie/portdrv_core.c b/drivers/pci/pcie/portdrv_core.c index d03a7a39b2d8..ed129b414624 100644 --- a/drivers/pci/pcie/portdrv_core.c +++ b/drivers/pci/pcie/portdrv_core.c | |||
| @@ -272,7 +272,8 @@ static int get_port_device_capability(struct pci_dev *dev) | |||
| 272 | } | 272 | } |
| 273 | 273 | ||
| 274 | /* Hot-Plug Capable */ | 274 | /* Hot-Plug Capable */ |
| 275 | if (cap_mask & PCIE_PORT_SERVICE_HP) { | 275 | if ((cap_mask & PCIE_PORT_SERVICE_HP) && |
| 276 | dev->pcie_flags_reg & PCI_EXP_FLAGS_SLOT) { | ||
| 276 | pcie_capability_read_dword(dev, PCI_EXP_SLTCAP, ®32); | 277 | pcie_capability_read_dword(dev, PCI_EXP_SLTCAP, ®32); |
| 277 | if (reg32 & PCI_EXP_SLTCAP_HPC) { | 278 | if (reg32 & PCI_EXP_SLTCAP_HPC) { |
| 278 | services |= PCIE_PORT_SERVICE_HP; | 279 | services |= PCIE_PORT_SERVICE_HP; |
diff --git a/drivers/pci/proc.c b/drivers/pci/proc.c index eb907a8faf2a..9b8505ccc56d 100644 --- a/drivers/pci/proc.c +++ b/drivers/pci/proc.c | |||
| @@ -76,6 +76,8 @@ proc_bus_pci_read(struct file *file, char __user *buf, size_t nbytes, loff_t *pp | |||
| 76 | if (!access_ok(VERIFY_WRITE, buf, cnt)) | 76 | if (!access_ok(VERIFY_WRITE, buf, cnt)) |
| 77 | return -EINVAL; | 77 | return -EINVAL; |
| 78 | 78 | ||
| 79 | pci_config_pm_runtime_get(dev); | ||
| 80 | |||
| 79 | if ((pos & 1) && cnt) { | 81 | if ((pos & 1) && cnt) { |
| 80 | unsigned char val; | 82 | unsigned char val; |
| 81 | pci_user_read_config_byte(dev, pos, &val); | 83 | pci_user_read_config_byte(dev, pos, &val); |
| @@ -121,6 +123,8 @@ proc_bus_pci_read(struct file *file, char __user *buf, size_t nbytes, loff_t *pp | |||
| 121 | cnt--; | 123 | cnt--; |
| 122 | } | 124 | } |
| 123 | 125 | ||
| 126 | pci_config_pm_runtime_put(dev); | ||
| 127 | |||
| 124 | *ppos = pos; | 128 | *ppos = pos; |
| 125 | return nbytes; | 129 | return nbytes; |
| 126 | } | 130 | } |
| @@ -146,6 +150,8 @@ proc_bus_pci_write(struct file *file, const char __user *buf, size_t nbytes, lof | |||
| 146 | if (!access_ok(VERIFY_READ, buf, cnt)) | 150 | if (!access_ok(VERIFY_READ, buf, cnt)) |
| 147 | return -EINVAL; | 151 | return -EINVAL; |
| 148 | 152 | ||
| 153 | pci_config_pm_runtime_get(dev); | ||
| 154 | |||
| 149 | if ((pos & 1) && cnt) { | 155 | if ((pos & 1) && cnt) { |
| 150 | unsigned char val; | 156 | unsigned char val; |
| 151 | __get_user(val, buf); | 157 | __get_user(val, buf); |
| @@ -191,6 +197,8 @@ proc_bus_pci_write(struct file *file, const char __user *buf, size_t nbytes, lof | |||
| 191 | cnt--; | 197 | cnt--; |
| 192 | } | 198 | } |
| 193 | 199 | ||
| 200 | pci_config_pm_runtime_put(dev); | ||
| 201 | |||
| 194 | *ppos = pos; | 202 | *ppos = pos; |
| 195 | i_size_write(ino, dp->size); | 203 | i_size_write(ino, dp->size); |
| 196 | return nbytes; | 204 | return nbytes; |
diff --git a/drivers/pcmcia/pxa2xx_sharpsl.c b/drivers/pcmcia/pxa2xx_sharpsl.c index b066273b6b4f..7dd879ce514d 100644 --- a/drivers/pcmcia/pxa2xx_sharpsl.c +++ b/drivers/pcmcia/pxa2xx_sharpsl.c | |||
| @@ -194,7 +194,7 @@ static void sharpsl_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt) | |||
| 194 | sharpsl_pcmcia_init_reset(skt); | 194 | sharpsl_pcmcia_init_reset(skt); |
| 195 | } | 195 | } |
| 196 | 196 | ||
| 197 | static struct pcmcia_low_level sharpsl_pcmcia_ops __initdata = { | 197 | static struct pcmcia_low_level sharpsl_pcmcia_ops = { |
| 198 | .owner = THIS_MODULE, | 198 | .owner = THIS_MODULE, |
| 199 | .hw_init = sharpsl_pcmcia_hw_init, | 199 | .hw_init = sharpsl_pcmcia_hw_init, |
| 200 | .socket_state = sharpsl_pcmcia_socket_state, | 200 | .socket_state = sharpsl_pcmcia_socket_state, |
diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig index 7bf914df6e91..aeecf0f72cad 100644 --- a/drivers/pinctrl/Kconfig +++ b/drivers/pinctrl/Kconfig | |||
| @@ -178,12 +178,14 @@ config PINCTRL_COH901 | |||
| 178 | ports of 8 GPIO pins each. | 178 | ports of 8 GPIO pins each. |
| 179 | 179 | ||
| 180 | config PINCTRL_SAMSUNG | 180 | config PINCTRL_SAMSUNG |
| 181 | bool "Samsung pinctrl driver" | 181 | bool |
| 182 | depends on OF && GPIOLIB | ||
| 182 | select PINMUX | 183 | select PINMUX |
| 183 | select PINCONF | 184 | select PINCONF |
| 184 | 185 | ||
| 185 | config PINCTRL_EXYNOS4 | 186 | config PINCTRL_EXYNOS4 |
| 186 | bool "Pinctrl driver data for Exynos4 SoC" | 187 | bool "Pinctrl driver data for Exynos4 SoC" |
| 188 | depends on OF && GPIOLIB | ||
| 187 | select PINCTRL_SAMSUNG | 189 | select PINCTRL_SAMSUNG |
| 188 | 190 | ||
| 189 | config PINCTRL_MVEBU | 191 | config PINCTRL_MVEBU |
diff --git a/drivers/pinctrl/core.c b/drivers/pinctrl/core.c index 0f1ec9e8ff14..2e39c04fc16b 100644 --- a/drivers/pinctrl/core.c +++ b/drivers/pinctrl/core.c | |||
| @@ -1061,8 +1061,10 @@ static int pinctrl_groups_show(struct seq_file *s, void *what) | |||
| 1061 | seq_printf(s, "group: %s\n", gname); | 1061 | seq_printf(s, "group: %s\n", gname); |
| 1062 | for (i = 0; i < num_pins; i++) { | 1062 | for (i = 0; i < num_pins; i++) { |
| 1063 | pname = pin_get_name(pctldev, pins[i]); | 1063 | pname = pin_get_name(pctldev, pins[i]); |
| 1064 | if (WARN_ON(!pname)) | 1064 | if (WARN_ON(!pname)) { |
| 1065 | mutex_unlock(&pinctrl_mutex); | ||
| 1065 | return -EINVAL; | 1066 | return -EINVAL; |
| 1067 | } | ||
| 1066 | seq_printf(s, "pin %d (%s)\n", pins[i], pname); | 1068 | seq_printf(s, "pin %d (%s)\n", pins[i], pname); |
| 1067 | } | 1069 | } |
| 1068 | seq_puts(s, "\n"); | 1070 | seq_puts(s, "\n"); |
diff --git a/drivers/pinctrl/pinconf.c b/drivers/pinctrl/pinconf.c index 43f474cdc110..baee2cc46a17 100644 --- a/drivers/pinctrl/pinconf.c +++ b/drivers/pinctrl/pinconf.c | |||
| @@ -537,8 +537,6 @@ static int pinconf_groups_show(struct seq_file *s, void *what) | |||
| 537 | seq_puts(s, "Pin config settings per pin group\n"); | 537 | seq_puts(s, "Pin config settings per pin group\n"); |
| 538 | seq_puts(s, "Format: group (name): configs\n"); | 538 | seq_puts(s, "Format: group (name): configs\n"); |
| 539 | 539 | ||
| 540 | mutex_lock(&pinctrl_mutex); | ||
| 541 | |||
| 542 | while (selector < ngroups) { | 540 | while (selector < ngroups) { |
| 543 | const char *gname = pctlops->get_group_name(pctldev, selector); | 541 | const char *gname = pctlops->get_group_name(pctldev, selector); |
| 544 | 542 | ||
| @@ -549,8 +547,6 @@ static int pinconf_groups_show(struct seq_file *s, void *what) | |||
| 549 | selector++; | 547 | selector++; |
| 550 | } | 548 | } |
| 551 | 549 | ||
| 552 | mutex_unlock(&pinctrl_mutex); | ||
| 553 | |||
| 554 | return 0; | 550 | return 0; |
| 555 | } | 551 | } |
| 556 | 552 | ||
diff --git a/drivers/pinctrl/pinctrl-bcm2835.c b/drivers/pinctrl/pinctrl-bcm2835.c index a4adee633fa9..7e9be18ec2d2 100644 --- a/drivers/pinctrl/pinctrl-bcm2835.c +++ b/drivers/pinctrl/pinctrl-bcm2835.c | |||
| @@ -29,7 +29,6 @@ | |||
| 29 | #include <linux/irq.h> | 29 | #include <linux/irq.h> |
| 30 | #include <linux/irqdesc.h> | 30 | #include <linux/irqdesc.h> |
| 31 | #include <linux/irqdomain.h> | 31 | #include <linux/irqdomain.h> |
| 32 | #include <linux/irq.h> | ||
| 33 | #include <linux/module.h> | 32 | #include <linux/module.h> |
| 34 | #include <linux/of_address.h> | 33 | #include <linux/of_address.h> |
| 35 | #include <linux/of.h> | 34 | #include <linux/of.h> |
| @@ -960,7 +959,7 @@ static int __devinit bcm2835_pinctrl_probe(struct platform_device *pdev) | |||
| 960 | return err; | 959 | return err; |
| 961 | } | 960 | } |
| 962 | 961 | ||
| 963 | pc->base = devm_request_and_ioremap(&pdev->dev, &iomem); | 962 | pc->base = devm_request_and_ioremap(dev, &iomem); |
| 964 | if (!pc->base) | 963 | if (!pc->base) |
| 965 | return -EADDRNOTAVAIL; | 964 | return -EADDRNOTAVAIL; |
| 966 | 965 | ||
| @@ -1032,7 +1031,7 @@ static int __devinit bcm2835_pinctrl_probe(struct platform_device *pdev) | |||
| 1032 | pc->pctl_dev = pinctrl_register(&bcm2835_pinctrl_desc, dev, pc); | 1031 | pc->pctl_dev = pinctrl_register(&bcm2835_pinctrl_desc, dev, pc); |
| 1033 | if (!pc->pctl_dev) { | 1032 | if (!pc->pctl_dev) { |
| 1034 | gpiochip_remove(&pc->gpio_chip); | 1033 | gpiochip_remove(&pc->gpio_chip); |
| 1035 | return PTR_ERR(pc->pctl_dev); | 1034 | return -EINVAL; |
| 1036 | } | 1035 | } |
| 1037 | 1036 | ||
| 1038 | pc->gpio_range = bcm2835_pinctrl_gpio_range; | 1037 | pc->gpio_range = bcm2835_pinctrl_gpio_range; |
diff --git a/drivers/pinctrl/pinctrl-nomadik.c b/drivers/pinctrl/pinctrl-nomadik.c index fec9c30133d4..cf82d9ce4dee 100644 --- a/drivers/pinctrl/pinctrl-nomadik.c +++ b/drivers/pinctrl/pinctrl-nomadik.c | |||
| @@ -30,7 +30,20 @@ | |||
| 30 | #include <linux/pinctrl/pinconf.h> | 30 | #include <linux/pinctrl/pinconf.h> |
| 31 | /* Since we request GPIOs from ourself */ | 31 | /* Since we request GPIOs from ourself */ |
| 32 | #include <linux/pinctrl/consumer.h> | 32 | #include <linux/pinctrl/consumer.h> |
| 33 | /* | ||
| 34 | * For the U8500 archs, use the PRCMU register interface, for the older | ||
| 35 | * Nomadik, provide some stubs. The functions using these will only be | ||
| 36 | * called on the U8500 series. | ||
| 37 | */ | ||
| 38 | #ifdef CONFIG_ARCH_U8500 | ||
| 33 | #include <linux/mfd/dbx500-prcmu.h> | 39 | #include <linux/mfd/dbx500-prcmu.h> |
| 40 | #else | ||
| 41 | static inline u32 prcmu_read(unsigned int reg) { | ||
| 42 | return 0; | ||
| 43 | } | ||
| 44 | static inline void prcmu_write(unsigned int reg, u32 value) {} | ||
| 45 | static inline void prcmu_write_masked(unsigned int reg, u32 mask, u32 value) {} | ||
| 46 | #endif | ||
| 34 | 47 | ||
| 35 | #include <asm/mach/irq.h> | 48 | #include <asm/mach/irq.h> |
| 36 | 49 | ||
| @@ -1043,7 +1056,7 @@ static int nmk_gpio_to_irq(struct gpio_chip *chip, unsigned offset) | |||
| 1043 | struct nmk_gpio_chip *nmk_chip = | 1056 | struct nmk_gpio_chip *nmk_chip = |
| 1044 | container_of(chip, struct nmk_gpio_chip, chip); | 1057 | container_of(chip, struct nmk_gpio_chip, chip); |
| 1045 | 1058 | ||
| 1046 | return irq_find_mapping(nmk_chip->domain, offset); | 1059 | return irq_create_mapping(nmk_chip->domain, offset); |
| 1047 | } | 1060 | } |
| 1048 | 1061 | ||
| 1049 | #ifdef CONFIG_DEBUG_FS | 1062 | #ifdef CONFIG_DEBUG_FS |
| @@ -1268,6 +1281,7 @@ static int __devinit nmk_gpio_probe(struct platform_device *dev) | |||
| 1268 | struct clk *clk; | 1281 | struct clk *clk; |
| 1269 | int secondary_irq; | 1282 | int secondary_irq; |
| 1270 | void __iomem *base; | 1283 | void __iomem *base; |
| 1284 | int irq_start = 0; | ||
| 1271 | int irq; | 1285 | int irq; |
| 1272 | int ret; | 1286 | int ret; |
| 1273 | 1287 | ||
| @@ -1371,19 +1385,11 @@ static int __devinit nmk_gpio_probe(struct platform_device *dev) | |||
| 1371 | 1385 | ||
| 1372 | platform_set_drvdata(dev, nmk_chip); | 1386 | platform_set_drvdata(dev, nmk_chip); |
| 1373 | 1387 | ||
| 1374 | if (np) { | 1388 | if (!np) |
| 1375 | /* The DT case will just grab a set of IRQ numbers */ | ||
| 1376 | nmk_chip->domain = irq_domain_add_linear(np, NMK_GPIO_PER_CHIP, | ||
| 1377 | &nmk_gpio_irq_simple_ops, nmk_chip); | ||
| 1378 | } else { | ||
| 1379 | /* Non-DT legacy mode, use hardwired IRQ numbers */ | ||
| 1380 | int irq_start; | ||
| 1381 | |||
| 1382 | irq_start = NOMADIK_GPIO_TO_IRQ(pdata->first_gpio); | 1389 | irq_start = NOMADIK_GPIO_TO_IRQ(pdata->first_gpio); |
| 1383 | nmk_chip->domain = irq_domain_add_simple(NULL, | 1390 | nmk_chip->domain = irq_domain_add_simple(np, |
| 1384 | NMK_GPIO_PER_CHIP, irq_start, | 1391 | NMK_GPIO_PER_CHIP, irq_start, |
| 1385 | &nmk_gpio_irq_simple_ops, nmk_chip); | 1392 | &nmk_gpio_irq_simple_ops, nmk_chip); |
| 1386 | } | ||
| 1387 | if (!nmk_chip->domain) { | 1393 | if (!nmk_chip->domain) { |
| 1388 | dev_err(&dev->dev, "failed to create irqdomain\n"); | 1394 | dev_err(&dev->dev, "failed to create irqdomain\n"); |
| 1389 | ret = -ENOSYS; | 1395 | ret = -ENOSYS; |
diff --git a/drivers/pinctrl/pinctrl-samsung.c b/drivers/pinctrl/pinctrl-samsung.c index dd108a94acf9..861cd5f04d5e 100644 --- a/drivers/pinctrl/pinctrl-samsung.c +++ b/drivers/pinctrl/pinctrl-samsung.c | |||
| @@ -513,7 +513,7 @@ static int samsung_gpio_direction_output(struct gpio_chip *gc, unsigned offset, | |||
| 513 | * Parse the pin names listed in the 'samsung,pins' property and convert it | 513 | * Parse the pin names listed in the 'samsung,pins' property and convert it |
| 514 | * into a list of gpio numbers are create a pin group from it. | 514 | * into a list of gpio numbers are create a pin group from it. |
| 515 | */ | 515 | */ |
| 516 | static int __init samsung_pinctrl_parse_dt_pins(struct platform_device *pdev, | 516 | static int __devinit samsung_pinctrl_parse_dt_pins(struct platform_device *pdev, |
| 517 | struct device_node *cfg_np, struct pinctrl_desc *pctl, | 517 | struct device_node *cfg_np, struct pinctrl_desc *pctl, |
| 518 | unsigned int **pin_list, unsigned int *npins) | 518 | unsigned int **pin_list, unsigned int *npins) |
| 519 | { | 519 | { |
| @@ -560,7 +560,7 @@ static int __init samsung_pinctrl_parse_dt_pins(struct platform_device *pdev, | |||
| 560 | * from device node of the pin-controller. A pin group is formed with all | 560 | * from device node of the pin-controller. A pin group is formed with all |
| 561 | * the pins listed in the "samsung,pins" property. | 561 | * the pins listed in the "samsung,pins" property. |
| 562 | */ | 562 | */ |
| 563 | static int __init samsung_pinctrl_parse_dt(struct platform_device *pdev, | 563 | static int __devinit samsung_pinctrl_parse_dt(struct platform_device *pdev, |
| 564 | struct samsung_pinctrl_drv_data *drvdata) | 564 | struct samsung_pinctrl_drv_data *drvdata) |
| 565 | { | 565 | { |
| 566 | struct device *dev = &pdev->dev; | 566 | struct device *dev = &pdev->dev; |
| @@ -655,7 +655,7 @@ static int __init samsung_pinctrl_parse_dt(struct platform_device *pdev, | |||
| 655 | } | 655 | } |
| 656 | 656 | ||
| 657 | /* register the pinctrl interface with the pinctrl subsystem */ | 657 | /* register the pinctrl interface with the pinctrl subsystem */ |
| 658 | static int __init samsung_pinctrl_register(struct platform_device *pdev, | 658 | static int __devinit samsung_pinctrl_register(struct platform_device *pdev, |
| 659 | struct samsung_pinctrl_drv_data *drvdata) | 659 | struct samsung_pinctrl_drv_data *drvdata) |
| 660 | { | 660 | { |
| 661 | struct pinctrl_desc *ctrldesc = &drvdata->pctl; | 661 | struct pinctrl_desc *ctrldesc = &drvdata->pctl; |
| @@ -729,7 +729,7 @@ static int __init samsung_pinctrl_register(struct platform_device *pdev, | |||
| 729 | } | 729 | } |
| 730 | 730 | ||
| 731 | /* register the gpiolib interface with the gpiolib subsystem */ | 731 | /* register the gpiolib interface with the gpiolib subsystem */ |
| 732 | static int __init samsung_gpiolib_register(struct platform_device *pdev, | 732 | static int __devinit samsung_gpiolib_register(struct platform_device *pdev, |
| 733 | struct samsung_pinctrl_drv_data *drvdata) | 733 | struct samsung_pinctrl_drv_data *drvdata) |
| 734 | { | 734 | { |
| 735 | struct gpio_chip *gc; | 735 | struct gpio_chip *gc; |
| @@ -762,7 +762,7 @@ static int __init samsung_gpiolib_register(struct platform_device *pdev, | |||
| 762 | } | 762 | } |
| 763 | 763 | ||
| 764 | /* unregister the gpiolib interface with the gpiolib subsystem */ | 764 | /* unregister the gpiolib interface with the gpiolib subsystem */ |
| 765 | static int __init samsung_gpiolib_unregister(struct platform_device *pdev, | 765 | static int __devinit samsung_gpiolib_unregister(struct platform_device *pdev, |
| 766 | struct samsung_pinctrl_drv_data *drvdata) | 766 | struct samsung_pinctrl_drv_data *drvdata) |
| 767 | { | 767 | { |
| 768 | int ret = gpiochip_remove(drvdata->gc); | 768 | int ret = gpiochip_remove(drvdata->gc); |
diff --git a/drivers/pinctrl/pinctrl-sirf.c b/drivers/pinctrl/pinctrl-sirf.c index 675497c15149..9ecacf3d0a75 100644 --- a/drivers/pinctrl/pinctrl-sirf.c +++ b/drivers/pinctrl/pinctrl-sirf.c | |||
| @@ -1323,41 +1323,6 @@ static inline struct sirfsoc_gpio_bank *sirfsoc_gpio_to_bank(unsigned int gpio) | |||
| 1323 | return &sgpio_bank[gpio / SIRFSOC_GPIO_BANK_SIZE]; | 1323 | return &sgpio_bank[gpio / SIRFSOC_GPIO_BANK_SIZE]; |
| 1324 | } | 1324 | } |
| 1325 | 1325 | ||
| 1326 | void sirfsoc_gpio_set_pull(unsigned gpio, unsigned mode) | ||
| 1327 | { | ||
| 1328 | struct sirfsoc_gpio_bank *bank = sirfsoc_gpio_to_bank(gpio); | ||
| 1329 | int idx = sirfsoc_gpio_to_offset(gpio); | ||
| 1330 | u32 val, offset; | ||
| 1331 | unsigned long flags; | ||
| 1332 | |||
| 1333 | offset = SIRFSOC_GPIO_CTRL(bank->id, idx); | ||
| 1334 | |||
| 1335 | spin_lock_irqsave(&sgpio_lock, flags); | ||
| 1336 | |||
| 1337 | val = readl(bank->chip.regs + offset); | ||
| 1338 | |||
| 1339 | switch (mode) { | ||
| 1340 | case SIRFSOC_GPIO_PULL_NONE: | ||
| 1341 | val &= ~SIRFSOC_GPIO_CTL_PULL_MASK; | ||
| 1342 | break; | ||
| 1343 | case SIRFSOC_GPIO_PULL_UP: | ||
| 1344 | val |= SIRFSOC_GPIO_CTL_PULL_MASK; | ||
| 1345 | val |= SIRFSOC_GPIO_CTL_PULL_HIGH; | ||
| 1346 | break; | ||
| 1347 | case SIRFSOC_GPIO_PULL_DOWN: | ||
| 1348 | val |= SIRFSOC_GPIO_CTL_PULL_MASK; | ||
| 1349 | val &= ~SIRFSOC_GPIO_CTL_PULL_HIGH; | ||
| 1350 | break; | ||
| 1351 | default: | ||
| 1352 | break; | ||
| 1353 | } | ||
| 1354 | |||
| 1355 | writel(val, bank->chip.regs + offset); | ||
| 1356 | |||
| 1357 | spin_unlock_irqrestore(&sgpio_lock, flags); | ||
| 1358 | } | ||
| 1359 | EXPORT_SYMBOL(sirfsoc_gpio_set_pull); | ||
| 1360 | |||
| 1361 | static inline struct sirfsoc_gpio_bank *sirfsoc_irqchip_to_bank(struct gpio_chip *chip) | 1326 | static inline struct sirfsoc_gpio_bank *sirfsoc_irqchip_to_bank(struct gpio_chip *chip) |
| 1362 | { | 1327 | { |
| 1363 | return container_of(to_of_mm_gpio_chip(chip), struct sirfsoc_gpio_bank, chip); | 1328 | return container_of(to_of_mm_gpio_chip(chip), struct sirfsoc_gpio_bank, chip); |
diff --git a/drivers/pinctrl/pinctrl-tegra.c b/drivers/pinctrl/pinctrl-tegra.c index 729b686c3ad2..7da0b371fd65 100644 --- a/drivers/pinctrl/pinctrl-tegra.c +++ b/drivers/pinctrl/pinctrl-tegra.c | |||
| @@ -464,7 +464,7 @@ static int tegra_pinconf_reg(struct tegra_pmx *pmx, | |||
| 464 | *bank = g->drv_bank; | 464 | *bank = g->drv_bank; |
| 465 | *reg = g->drv_reg; | 465 | *reg = g->drv_reg; |
| 466 | *bit = g->lpmd_bit; | 466 | *bit = g->lpmd_bit; |
| 467 | *width = 1; | 467 | *width = 2; |
| 468 | break; | 468 | break; |
| 469 | case TEGRA_PINCONF_PARAM_DRIVE_DOWN_STRENGTH: | 469 | case TEGRA_PINCONF_PARAM_DRIVE_DOWN_STRENGTH: |
| 470 | *bank = g->drv_bank; | 470 | *bank = g->drv_bank; |
diff --git a/drivers/pinctrl/pinctrl-tegra30.c b/drivers/pinctrl/pinctrl-tegra30.c index 0386fdf0da16..7894f14c7059 100644 --- a/drivers/pinctrl/pinctrl-tegra30.c +++ b/drivers/pinctrl/pinctrl-tegra30.c | |||
| @@ -3345,10 +3345,10 @@ static const struct tegra_function tegra30_functions[] = { | |||
| 3345 | FUNCTION(vi_alt3), | 3345 | FUNCTION(vi_alt3), |
| 3346 | }; | 3346 | }; |
| 3347 | 3347 | ||
| 3348 | #define MUXCTL_REG_A 0x3000 | 3348 | #define DRV_PINGROUP_REG_A 0x868 /* bank 0 */ |
| 3349 | #define PINGROUP_REG_A 0x868 | 3349 | #define PINGROUP_REG_A 0x3000 /* bank 1 */ |
| 3350 | 3350 | ||
| 3351 | #define PINGROUP_REG_Y(r) ((r) - MUXCTL_REG_A) | 3351 | #define PINGROUP_REG_Y(r) ((r) - PINGROUP_REG_A) |
| 3352 | #define PINGROUP_REG_N(r) -1 | 3352 | #define PINGROUP_REG_N(r) -1 |
| 3353 | 3353 | ||
| 3354 | #define PINGROUP(pg_name, f0, f1, f2, f3, f_safe, r, od, ior) \ | 3354 | #define PINGROUP(pg_name, f0, f1, f2, f3, f_safe, r, od, ior) \ |
| @@ -3364,25 +3364,25 @@ static const struct tegra_function tegra30_functions[] = { | |||
| 3364 | }, \ | 3364 | }, \ |
| 3365 | .func_safe = TEGRA_MUX_ ## f_safe, \ | 3365 | .func_safe = TEGRA_MUX_ ## f_safe, \ |
| 3366 | .mux_reg = PINGROUP_REG_Y(r), \ | 3366 | .mux_reg = PINGROUP_REG_Y(r), \ |
| 3367 | .mux_bank = 0, \ | 3367 | .mux_bank = 1, \ |
| 3368 | .mux_bit = 0, \ | 3368 | .mux_bit = 0, \ |
| 3369 | .pupd_reg = PINGROUP_REG_Y(r), \ | 3369 | .pupd_reg = PINGROUP_REG_Y(r), \ |
| 3370 | .pupd_bank = 0, \ | 3370 | .pupd_bank = 1, \ |
| 3371 | .pupd_bit = 2, \ | 3371 | .pupd_bit = 2, \ |
| 3372 | .tri_reg = PINGROUP_REG_Y(r), \ | 3372 | .tri_reg = PINGROUP_REG_Y(r), \ |
| 3373 | .tri_bank = 0, \ | 3373 | .tri_bank = 1, \ |
| 3374 | .tri_bit = 4, \ | 3374 | .tri_bit = 4, \ |
| 3375 | .einput_reg = PINGROUP_REG_Y(r), \ | 3375 | .einput_reg = PINGROUP_REG_Y(r), \ |
| 3376 | .einput_bank = 0, \ | 3376 | .einput_bank = 1, \ |
| 3377 | .einput_bit = 5, \ | 3377 | .einput_bit = 5, \ |
| 3378 | .odrain_reg = PINGROUP_REG_##od(r), \ | 3378 | .odrain_reg = PINGROUP_REG_##od(r), \ |
| 3379 | .odrain_bank = 0, \ | 3379 | .odrain_bank = 1, \ |
| 3380 | .odrain_bit = 6, \ | 3380 | .odrain_bit = 6, \ |
| 3381 | .lock_reg = PINGROUP_REG_Y(r), \ | 3381 | .lock_reg = PINGROUP_REG_Y(r), \ |
| 3382 | .lock_bank = 0, \ | 3382 | .lock_bank = 1, \ |
| 3383 | .lock_bit = 7, \ | 3383 | .lock_bit = 7, \ |
| 3384 | .ioreset_reg = PINGROUP_REG_##ior(r), \ | 3384 | .ioreset_reg = PINGROUP_REG_##ior(r), \ |
| 3385 | .ioreset_bank = 0, \ | 3385 | .ioreset_bank = 1, \ |
| 3386 | .ioreset_bit = 8, \ | 3386 | .ioreset_bit = 8, \ |
| 3387 | .drv_reg = -1, \ | 3387 | .drv_reg = -1, \ |
| 3388 | } | 3388 | } |
| @@ -3401,8 +3401,8 @@ static const struct tegra_function tegra30_functions[] = { | |||
| 3401 | .odrain_reg = -1, \ | 3401 | .odrain_reg = -1, \ |
| 3402 | .lock_reg = -1, \ | 3402 | .lock_reg = -1, \ |
| 3403 | .ioreset_reg = -1, \ | 3403 | .ioreset_reg = -1, \ |
| 3404 | .drv_reg = ((r) - PINGROUP_REG_A), \ | 3404 | .drv_reg = ((r) - DRV_PINGROUP_REG_A), \ |
| 3405 | .drv_bank = 1, \ | 3405 | .drv_bank = 0, \ |
| 3406 | .hsm_bit = hsm_b, \ | 3406 | .hsm_bit = hsm_b, \ |
| 3407 | .schmitt_bit = schmitt_b, \ | 3407 | .schmitt_bit = schmitt_b, \ |
| 3408 | .lpmd_bit = lpmd_b, \ | 3408 | .lpmd_bit = lpmd_b, \ |
diff --git a/drivers/pinctrl/pinctrl-xway.c b/drivers/pinctrl/pinctrl-xway.c index f8d917d40c92..b9bcaec66223 100644 --- a/drivers/pinctrl/pinctrl-xway.c +++ b/drivers/pinctrl/pinctrl-xway.c | |||
| @@ -17,8 +17,6 @@ | |||
| 17 | #include <linux/ioport.h> | 17 | #include <linux/ioport.h> |
| 18 | #include <linux/io.h> | 18 | #include <linux/io.h> |
| 19 | #include <linux/device.h> | 19 | #include <linux/device.h> |
| 20 | #include <linux/module.h> | ||
| 21 | #include <linux/io.h> | ||
| 22 | #include <linux/platform_device.h> | 20 | #include <linux/platform_device.h> |
| 23 | 21 | ||
| 24 | #include "pinctrl-lantiq.h" | 22 | #include "pinctrl-lantiq.h" |
diff --git a/drivers/pinctrl/spear/pinctrl-spear.c b/drivers/pinctrl/spear/pinctrl-spear.c index 5d4f44f462f0..b1fd6ee33c6c 100644 --- a/drivers/pinctrl/spear/pinctrl-spear.c +++ b/drivers/pinctrl/spear/pinctrl-spear.c | |||
| @@ -244,7 +244,7 @@ static int spear_pinctrl_endisable(struct pinctrl_dev *pctldev, | |||
| 244 | else | 244 | else |
| 245 | temp = ~muxreg->val; | 245 | temp = ~muxreg->val; |
| 246 | 246 | ||
| 247 | val |= temp; | 247 | val |= muxreg->mask & temp; |
| 248 | pmx_writel(pmx, val, muxreg->reg); | 248 | pmx_writel(pmx, val, muxreg->reg); |
| 249 | } | 249 | } |
| 250 | } | 250 | } |
diff --git a/drivers/pinctrl/spear/pinctrl-spear1310.c b/drivers/pinctrl/spear/pinctrl-spear1310.c index d6cca8c81b92..0436fc7895d6 100644 --- a/drivers/pinctrl/spear/pinctrl-spear1310.c +++ b/drivers/pinctrl/spear/pinctrl-spear1310.c | |||
| @@ -25,8 +25,8 @@ static const struct pinctrl_pin_desc spear1310_pins[] = { | |||
| 25 | }; | 25 | }; |
| 26 | 26 | ||
| 27 | /* registers */ | 27 | /* registers */ |
| 28 | #define PERIP_CFG 0x32C | 28 | #define PERIP_CFG 0x3B0 |
| 29 | #define MCIF_SEL_SHIFT 3 | 29 | #define MCIF_SEL_SHIFT 5 |
| 30 | #define MCIF_SEL_SD (0x1 << MCIF_SEL_SHIFT) | 30 | #define MCIF_SEL_SD (0x1 << MCIF_SEL_SHIFT) |
| 31 | #define MCIF_SEL_CF (0x2 << MCIF_SEL_SHIFT) | 31 | #define MCIF_SEL_CF (0x2 << MCIF_SEL_SHIFT) |
| 32 | #define MCIF_SEL_XD (0x3 << MCIF_SEL_SHIFT) | 32 | #define MCIF_SEL_XD (0x3 << MCIF_SEL_SHIFT) |
| @@ -164,6 +164,10 @@ static const struct pinctrl_pin_desc spear1310_pins[] = { | |||
| 164 | #define PMX_SSP0_CS0_MASK (1 << 29) | 164 | #define PMX_SSP0_CS0_MASK (1 << 29) |
| 165 | #define PMX_SSP0_CS1_2_MASK (1 << 30) | 165 | #define PMX_SSP0_CS1_2_MASK (1 << 30) |
| 166 | 166 | ||
| 167 | #define PAD_DIRECTION_SEL_0 0x65C | ||
| 168 | #define PAD_DIRECTION_SEL_1 0x660 | ||
| 169 | #define PAD_DIRECTION_SEL_2 0x664 | ||
| 170 | |||
| 167 | /* combined macros */ | 171 | /* combined macros */ |
| 168 | #define PMX_GMII_MASK (PMX_GMIICLK_MASK | \ | 172 | #define PMX_GMII_MASK (PMX_GMIICLK_MASK | \ |
| 169 | PMX_GMIICOL_CRS_XFERER_MIITXCLK_MASK | \ | 173 | PMX_GMIICOL_CRS_XFERER_MIITXCLK_MASK | \ |
| @@ -237,6 +241,10 @@ static struct spear_muxreg i2c0_muxreg[] = { | |||
| 237 | .reg = PAD_FUNCTION_EN_0, | 241 | .reg = PAD_FUNCTION_EN_0, |
| 238 | .mask = PMX_I2C0_MASK, | 242 | .mask = PMX_I2C0_MASK, |
| 239 | .val = PMX_I2C0_MASK, | 243 | .val = PMX_I2C0_MASK, |
| 244 | }, { | ||
| 245 | .reg = PAD_DIRECTION_SEL_0, | ||
| 246 | .mask = PMX_I2C0_MASK, | ||
| 247 | .val = PMX_I2C0_MASK, | ||
| 240 | }, | 248 | }, |
| 241 | }; | 249 | }; |
| 242 | 250 | ||
| @@ -269,6 +277,10 @@ static struct spear_muxreg ssp0_muxreg[] = { | |||
| 269 | .reg = PAD_FUNCTION_EN_0, | 277 | .reg = PAD_FUNCTION_EN_0, |
| 270 | .mask = PMX_SSP0_MASK, | 278 | .mask = PMX_SSP0_MASK, |
| 271 | .val = PMX_SSP0_MASK, | 279 | .val = PMX_SSP0_MASK, |
| 280 | }, { | ||
| 281 | .reg = PAD_DIRECTION_SEL_0, | ||
| 282 | .mask = PMX_SSP0_MASK, | ||
| 283 | .val = PMX_SSP0_MASK, | ||
| 272 | }, | 284 | }, |
| 273 | }; | 285 | }; |
| 274 | 286 | ||
| @@ -294,6 +306,10 @@ static struct spear_muxreg ssp0_cs0_muxreg[] = { | |||
| 294 | .reg = PAD_FUNCTION_EN_2, | 306 | .reg = PAD_FUNCTION_EN_2, |
| 295 | .mask = PMX_SSP0_CS0_MASK, | 307 | .mask = PMX_SSP0_CS0_MASK, |
| 296 | .val = PMX_SSP0_CS0_MASK, | 308 | .val = PMX_SSP0_CS0_MASK, |
| 309 | }, { | ||
| 310 | .reg = PAD_DIRECTION_SEL_2, | ||
| 311 | .mask = PMX_SSP0_CS0_MASK, | ||
| 312 | .val = PMX_SSP0_CS0_MASK, | ||
| 297 | }, | 313 | }, |
| 298 | }; | 314 | }; |
| 299 | 315 | ||
| @@ -319,6 +335,10 @@ static struct spear_muxreg ssp0_cs1_2_muxreg[] = { | |||
| 319 | .reg = PAD_FUNCTION_EN_2, | 335 | .reg = PAD_FUNCTION_EN_2, |
| 320 | .mask = PMX_SSP0_CS1_2_MASK, | 336 | .mask = PMX_SSP0_CS1_2_MASK, |
| 321 | .val = PMX_SSP0_CS1_2_MASK, | 337 | .val = PMX_SSP0_CS1_2_MASK, |
| 338 | }, { | ||
| 339 | .reg = PAD_DIRECTION_SEL_2, | ||
| 340 | .mask = PMX_SSP0_CS1_2_MASK, | ||
| 341 | .val = PMX_SSP0_CS1_2_MASK, | ||
| 322 | }, | 342 | }, |
| 323 | }; | 343 | }; |
| 324 | 344 | ||
| @@ -352,6 +372,10 @@ static struct spear_muxreg i2s0_muxreg[] = { | |||
| 352 | .reg = PAD_FUNCTION_EN_0, | 372 | .reg = PAD_FUNCTION_EN_0, |
| 353 | .mask = PMX_I2S0_MASK, | 373 | .mask = PMX_I2S0_MASK, |
| 354 | .val = PMX_I2S0_MASK, | 374 | .val = PMX_I2S0_MASK, |
| 375 | }, { | ||
| 376 | .reg = PAD_DIRECTION_SEL_0, | ||
| 377 | .mask = PMX_I2S0_MASK, | ||
| 378 | .val = PMX_I2S0_MASK, | ||
| 355 | }, | 379 | }, |
| 356 | }; | 380 | }; |
| 357 | 381 | ||
| @@ -384,6 +408,10 @@ static struct spear_muxreg i2s1_muxreg[] = { | |||
| 384 | .reg = PAD_FUNCTION_EN_1, | 408 | .reg = PAD_FUNCTION_EN_1, |
| 385 | .mask = PMX_I2S1_MASK, | 409 | .mask = PMX_I2S1_MASK, |
| 386 | .val = PMX_I2S1_MASK, | 410 | .val = PMX_I2S1_MASK, |
| 411 | }, { | ||
| 412 | .reg = PAD_DIRECTION_SEL_1, | ||
| 413 | .mask = PMX_I2S1_MASK, | ||
| 414 | .val = PMX_I2S1_MASK, | ||
| 387 | }, | 415 | }, |
| 388 | }; | 416 | }; |
| 389 | 417 | ||
| @@ -418,6 +446,10 @@ static struct spear_muxreg clcd_muxreg[] = { | |||
| 418 | .reg = PAD_FUNCTION_EN_0, | 446 | .reg = PAD_FUNCTION_EN_0, |
| 419 | .mask = PMX_CLCD1_MASK, | 447 | .mask = PMX_CLCD1_MASK, |
| 420 | .val = PMX_CLCD1_MASK, | 448 | .val = PMX_CLCD1_MASK, |
| 449 | }, { | ||
| 450 | .reg = PAD_DIRECTION_SEL_0, | ||
| 451 | .mask = PMX_CLCD1_MASK, | ||
| 452 | .val = PMX_CLCD1_MASK, | ||
| 421 | }, | 453 | }, |
| 422 | }; | 454 | }; |
| 423 | 455 | ||
| @@ -443,6 +475,10 @@ static struct spear_muxreg clcd_high_res_muxreg[] = { | |||
| 443 | .reg = PAD_FUNCTION_EN_1, | 475 | .reg = PAD_FUNCTION_EN_1, |
| 444 | .mask = PMX_CLCD2_MASK, | 476 | .mask = PMX_CLCD2_MASK, |
| 445 | .val = PMX_CLCD2_MASK, | 477 | .val = PMX_CLCD2_MASK, |
| 478 | }, { | ||
| 479 | .reg = PAD_DIRECTION_SEL_1, | ||
| 480 | .mask = PMX_CLCD2_MASK, | ||
| 481 | .val = PMX_CLCD2_MASK, | ||
| 446 | }, | 482 | }, |
| 447 | }; | 483 | }; |
| 448 | 484 | ||
| @@ -461,7 +497,7 @@ static struct spear_pingroup clcd_high_res_pingroup = { | |||
| 461 | .nmodemuxs = ARRAY_SIZE(clcd_high_res_modemux), | 497 | .nmodemuxs = ARRAY_SIZE(clcd_high_res_modemux), |
| 462 | }; | 498 | }; |
| 463 | 499 | ||
| 464 | static const char *const clcd_grps[] = { "clcd_grp", "clcd_high_res" }; | 500 | static const char *const clcd_grps[] = { "clcd_grp", "clcd_high_res_grp" }; |
| 465 | static struct spear_function clcd_function = { | 501 | static struct spear_function clcd_function = { |
| 466 | .name = "clcd", | 502 | .name = "clcd", |
| 467 | .groups = clcd_grps, | 503 | .groups = clcd_grps, |
| @@ -479,6 +515,14 @@ static struct spear_muxreg arm_gpio_muxreg[] = { | |||
| 479 | .reg = PAD_FUNCTION_EN_1, | 515 | .reg = PAD_FUNCTION_EN_1, |
| 480 | .mask = PMX_EGPIO_1_GRP_MASK, | 516 | .mask = PMX_EGPIO_1_GRP_MASK, |
| 481 | .val = PMX_EGPIO_1_GRP_MASK, | 517 | .val = PMX_EGPIO_1_GRP_MASK, |
| 518 | }, { | ||
| 519 | .reg = PAD_DIRECTION_SEL_0, | ||
| 520 | .mask = PMX_EGPIO_0_GRP_MASK, | ||
| 521 | .val = PMX_EGPIO_0_GRP_MASK, | ||
| 522 | }, { | ||
| 523 | .reg = PAD_DIRECTION_SEL_1, | ||
| 524 | .mask = PMX_EGPIO_1_GRP_MASK, | ||
| 525 | .val = PMX_EGPIO_1_GRP_MASK, | ||
| 482 | }, | 526 | }, |
| 483 | }; | 527 | }; |
| 484 | 528 | ||
| @@ -511,6 +555,10 @@ static struct spear_muxreg smi_2_chips_muxreg[] = { | |||
| 511 | .reg = PAD_FUNCTION_EN_0, | 555 | .reg = PAD_FUNCTION_EN_0, |
| 512 | .mask = PMX_SMI_MASK, | 556 | .mask = PMX_SMI_MASK, |
| 513 | .val = PMX_SMI_MASK, | 557 | .val = PMX_SMI_MASK, |
| 558 | }, { | ||
| 559 | .reg = PAD_DIRECTION_SEL_0, | ||
| 560 | .mask = PMX_SMI_MASK, | ||
| 561 | .val = PMX_SMI_MASK, | ||
| 514 | }, | 562 | }, |
| 515 | }; | 563 | }; |
| 516 | 564 | ||
| @@ -539,6 +587,14 @@ static struct spear_muxreg smi_4_chips_muxreg[] = { | |||
| 539 | .reg = PAD_FUNCTION_EN_1, | 587 | .reg = PAD_FUNCTION_EN_1, |
| 540 | .mask = PMX_SMINCS2_MASK | PMX_SMINCS3_MASK, | 588 | .mask = PMX_SMINCS2_MASK | PMX_SMINCS3_MASK, |
| 541 | .val = PMX_SMINCS2_MASK | PMX_SMINCS3_MASK, | 589 | .val = PMX_SMINCS2_MASK | PMX_SMINCS3_MASK, |
| 590 | }, { | ||
| 591 | .reg = PAD_DIRECTION_SEL_0, | ||
| 592 | .mask = PMX_SMI_MASK, | ||
| 593 | .val = PMX_SMI_MASK, | ||
| 594 | }, { | ||
| 595 | .reg = PAD_DIRECTION_SEL_1, | ||
| 596 | .mask = PMX_SMINCS2_MASK | PMX_SMINCS3_MASK, | ||
| 597 | .val = PMX_SMINCS2_MASK | PMX_SMINCS3_MASK, | ||
| 542 | }, | 598 | }, |
| 543 | }; | 599 | }; |
| 544 | 600 | ||
| @@ -573,6 +629,10 @@ static struct spear_muxreg gmii_muxreg[] = { | |||
| 573 | .reg = PAD_FUNCTION_EN_0, | 629 | .reg = PAD_FUNCTION_EN_0, |
| 574 | .mask = PMX_GMII_MASK, | 630 | .mask = PMX_GMII_MASK, |
| 575 | .val = PMX_GMII_MASK, | 631 | .val = PMX_GMII_MASK, |
| 632 | }, { | ||
| 633 | .reg = PAD_DIRECTION_SEL_0, | ||
| 634 | .mask = PMX_GMII_MASK, | ||
| 635 | .val = PMX_GMII_MASK, | ||
| 576 | }, | 636 | }, |
| 577 | }; | 637 | }; |
| 578 | 638 | ||
| @@ -615,6 +675,18 @@ static struct spear_muxreg rgmii_muxreg[] = { | |||
| 615 | .reg = PAD_FUNCTION_EN_2, | 675 | .reg = PAD_FUNCTION_EN_2, |
| 616 | .mask = PMX_RGMII_REG2_MASK, | 676 | .mask = PMX_RGMII_REG2_MASK, |
| 617 | .val = 0, | 677 | .val = 0, |
| 678 | }, { | ||
| 679 | .reg = PAD_DIRECTION_SEL_0, | ||
| 680 | .mask = PMX_RGMII_REG0_MASK, | ||
| 681 | .val = PMX_RGMII_REG0_MASK, | ||
| 682 | }, { | ||
| 683 | .reg = PAD_DIRECTION_SEL_1, | ||
| 684 | .mask = PMX_RGMII_REG1_MASK, | ||
| 685 | .val = PMX_RGMII_REG1_MASK, | ||
| 686 | }, { | ||
| 687 | .reg = PAD_DIRECTION_SEL_2, | ||
| 688 | .mask = PMX_RGMII_REG2_MASK, | ||
| 689 | .val = PMX_RGMII_REG2_MASK, | ||
| 618 | }, | 690 | }, |
| 619 | }; | 691 | }; |
| 620 | 692 | ||
| @@ -649,6 +721,10 @@ static struct spear_muxreg smii_0_1_2_muxreg[] = { | |||
| 649 | .reg = PAD_FUNCTION_EN_1, | 721 | .reg = PAD_FUNCTION_EN_1, |
| 650 | .mask = PMX_SMII_0_1_2_MASK, | 722 | .mask = PMX_SMII_0_1_2_MASK, |
| 651 | .val = 0, | 723 | .val = 0, |
| 724 | }, { | ||
| 725 | .reg = PAD_DIRECTION_SEL_1, | ||
| 726 | .mask = PMX_SMII_0_1_2_MASK, | ||
| 727 | .val = PMX_SMII_0_1_2_MASK, | ||
| 652 | }, | 728 | }, |
| 653 | }; | 729 | }; |
| 654 | 730 | ||
| @@ -681,6 +757,10 @@ static struct spear_muxreg ras_mii_txclk_muxreg[] = { | |||
| 681 | .reg = PAD_FUNCTION_EN_1, | 757 | .reg = PAD_FUNCTION_EN_1, |
| 682 | .mask = PMX_NFCE2_MASK, | 758 | .mask = PMX_NFCE2_MASK, |
| 683 | .val = 0, | 759 | .val = 0, |
| 760 | }, { | ||
| 761 | .reg = PAD_DIRECTION_SEL_1, | ||
| 762 | .mask = PMX_NFCE2_MASK, | ||
| 763 | .val = PMX_NFCE2_MASK, | ||
| 684 | }, | 764 | }, |
| 685 | }; | 765 | }; |
| 686 | 766 | ||
| @@ -721,6 +801,14 @@ static struct spear_muxreg nand_8bit_muxreg[] = { | |||
| 721 | .reg = PAD_FUNCTION_EN_1, | 801 | .reg = PAD_FUNCTION_EN_1, |
| 722 | .mask = PMX_NAND8BIT_1_MASK, | 802 | .mask = PMX_NAND8BIT_1_MASK, |
| 723 | .val = PMX_NAND8BIT_1_MASK, | 803 | .val = PMX_NAND8BIT_1_MASK, |
| 804 | }, { | ||
| 805 | .reg = PAD_DIRECTION_SEL_0, | ||
| 806 | .mask = PMX_NAND8BIT_0_MASK, | ||
| 807 | .val = PMX_NAND8BIT_0_MASK, | ||
| 808 | }, { | ||
| 809 | .reg = PAD_DIRECTION_SEL_1, | ||
| 810 | .mask = PMX_NAND8BIT_1_MASK, | ||
| 811 | .val = PMX_NAND8BIT_1_MASK, | ||
| 724 | }, | 812 | }, |
| 725 | }; | 813 | }; |
| 726 | 814 | ||
| @@ -747,6 +835,10 @@ static struct spear_muxreg nand_16bit_muxreg[] = { | |||
| 747 | .reg = PAD_FUNCTION_EN_1, | 835 | .reg = PAD_FUNCTION_EN_1, |
| 748 | .mask = PMX_NAND16BIT_1_MASK, | 836 | .mask = PMX_NAND16BIT_1_MASK, |
| 749 | .val = PMX_NAND16BIT_1_MASK, | 837 | .val = PMX_NAND16BIT_1_MASK, |
| 838 | }, { | ||
| 839 | .reg = PAD_DIRECTION_SEL_1, | ||
| 840 | .mask = PMX_NAND16BIT_1_MASK, | ||
| 841 | .val = PMX_NAND16BIT_1_MASK, | ||
| 750 | }, | 842 | }, |
| 751 | }; | 843 | }; |
| 752 | 844 | ||
| @@ -772,6 +864,10 @@ static struct spear_muxreg nand_4_chips_muxreg[] = { | |||
| 772 | .reg = PAD_FUNCTION_EN_1, | 864 | .reg = PAD_FUNCTION_EN_1, |
| 773 | .mask = PMX_NAND_4CHIPS_MASK, | 865 | .mask = PMX_NAND_4CHIPS_MASK, |
| 774 | .val = PMX_NAND_4CHIPS_MASK, | 866 | .val = PMX_NAND_4CHIPS_MASK, |
| 867 | }, { | ||
| 868 | .reg = PAD_DIRECTION_SEL_1, | ||
| 869 | .mask = PMX_NAND_4CHIPS_MASK, | ||
| 870 | .val = PMX_NAND_4CHIPS_MASK, | ||
| 775 | }, | 871 | }, |
| 776 | }; | 872 | }; |
| 777 | 873 | ||
| @@ -833,6 +929,10 @@ static struct spear_muxreg keyboard_rowcol6_8_muxreg[] = { | |||
| 833 | .reg = PAD_FUNCTION_EN_1, | 929 | .reg = PAD_FUNCTION_EN_1, |
| 834 | .mask = PMX_KBD_ROWCOL68_MASK, | 930 | .mask = PMX_KBD_ROWCOL68_MASK, |
| 835 | .val = PMX_KBD_ROWCOL68_MASK, | 931 | .val = PMX_KBD_ROWCOL68_MASK, |
| 932 | }, { | ||
| 933 | .reg = PAD_DIRECTION_SEL_1, | ||
| 934 | .mask = PMX_KBD_ROWCOL68_MASK, | ||
| 935 | .val = PMX_KBD_ROWCOL68_MASK, | ||
| 836 | }, | 936 | }, |
| 837 | }; | 937 | }; |
| 838 | 938 | ||
| @@ -866,6 +966,10 @@ static struct spear_muxreg uart0_muxreg[] = { | |||
| 866 | .reg = PAD_FUNCTION_EN_0, | 966 | .reg = PAD_FUNCTION_EN_0, |
| 867 | .mask = PMX_UART0_MASK, | 967 | .mask = PMX_UART0_MASK, |
| 868 | .val = PMX_UART0_MASK, | 968 | .val = PMX_UART0_MASK, |
| 969 | }, { | ||
| 970 | .reg = PAD_DIRECTION_SEL_0, | ||
| 971 | .mask = PMX_UART0_MASK, | ||
| 972 | .val = PMX_UART0_MASK, | ||
| 869 | }, | 973 | }, |
| 870 | }; | 974 | }; |
| 871 | 975 | ||
| @@ -891,6 +995,10 @@ static struct spear_muxreg uart0_modem_muxreg[] = { | |||
| 891 | .reg = PAD_FUNCTION_EN_1, | 995 | .reg = PAD_FUNCTION_EN_1, |
| 892 | .mask = PMX_UART0_MODEM_MASK, | 996 | .mask = PMX_UART0_MODEM_MASK, |
| 893 | .val = PMX_UART0_MODEM_MASK, | 997 | .val = PMX_UART0_MODEM_MASK, |
| 998 | }, { | ||
| 999 | .reg = PAD_DIRECTION_SEL_1, | ||
| 1000 | .mask = PMX_UART0_MODEM_MASK, | ||
| 1001 | .val = PMX_UART0_MODEM_MASK, | ||
| 894 | }, | 1002 | }, |
| 895 | }; | 1003 | }; |
| 896 | 1004 | ||
| @@ -923,6 +1031,10 @@ static struct spear_muxreg gpt0_tmr0_muxreg[] = { | |||
| 923 | .reg = PAD_FUNCTION_EN_1, | 1031 | .reg = PAD_FUNCTION_EN_1, |
| 924 | .mask = PMX_GPT0_TMR0_MASK, | 1032 | .mask = PMX_GPT0_TMR0_MASK, |
| 925 | .val = PMX_GPT0_TMR0_MASK, | 1033 | .val = PMX_GPT0_TMR0_MASK, |
| 1034 | }, { | ||
| 1035 | .reg = PAD_DIRECTION_SEL_1, | ||
| 1036 | .mask = PMX_GPT0_TMR0_MASK, | ||
| 1037 | .val = PMX_GPT0_TMR0_MASK, | ||
| 926 | }, | 1038 | }, |
| 927 | }; | 1039 | }; |
| 928 | 1040 | ||
| @@ -948,6 +1060,10 @@ static struct spear_muxreg gpt0_tmr1_muxreg[] = { | |||
| 948 | .reg = PAD_FUNCTION_EN_1, | 1060 | .reg = PAD_FUNCTION_EN_1, |
| 949 | .mask = PMX_GPT0_TMR1_MASK, | 1061 | .mask = PMX_GPT0_TMR1_MASK, |
| 950 | .val = PMX_GPT0_TMR1_MASK, | 1062 | .val = PMX_GPT0_TMR1_MASK, |
| 1063 | }, { | ||
| 1064 | .reg = PAD_DIRECTION_SEL_1, | ||
| 1065 | .mask = PMX_GPT0_TMR1_MASK, | ||
| 1066 | .val = PMX_GPT0_TMR1_MASK, | ||
| 951 | }, | 1067 | }, |
| 952 | }; | 1068 | }; |
| 953 | 1069 | ||
| @@ -980,6 +1096,10 @@ static struct spear_muxreg gpt1_tmr0_muxreg[] = { | |||
| 980 | .reg = PAD_FUNCTION_EN_1, | 1096 | .reg = PAD_FUNCTION_EN_1, |
| 981 | .mask = PMX_GPT1_TMR0_MASK, | 1097 | .mask = PMX_GPT1_TMR0_MASK, |
| 982 | .val = PMX_GPT1_TMR0_MASK, | 1098 | .val = PMX_GPT1_TMR0_MASK, |
| 1099 | }, { | ||
| 1100 | .reg = PAD_DIRECTION_SEL_1, | ||
| 1101 | .mask = PMX_GPT1_TMR0_MASK, | ||
| 1102 | .val = PMX_GPT1_TMR0_MASK, | ||
| 983 | }, | 1103 | }, |
| 984 | }; | 1104 | }; |
| 985 | 1105 | ||
| @@ -1005,6 +1125,10 @@ static struct spear_muxreg gpt1_tmr1_muxreg[] = { | |||
| 1005 | .reg = PAD_FUNCTION_EN_1, | 1125 | .reg = PAD_FUNCTION_EN_1, |
| 1006 | .mask = PMX_GPT1_TMR1_MASK, | 1126 | .mask = PMX_GPT1_TMR1_MASK, |
| 1007 | .val = PMX_GPT1_TMR1_MASK, | 1127 | .val = PMX_GPT1_TMR1_MASK, |
| 1128 | }, { | ||
| 1129 | .reg = PAD_DIRECTION_SEL_1, | ||
| 1130 | .mask = PMX_GPT1_TMR1_MASK, | ||
| 1131 | .val = PMX_GPT1_TMR1_MASK, | ||
| 1008 | }, | 1132 | }, |
| 1009 | }; | 1133 | }; |
| 1010 | 1134 | ||
| @@ -1049,6 +1173,20 @@ static const unsigned mcif_pins[] = { 86, 87, 88, 89, 90, 91, 92, 93, 213, 214, | |||
| 1049 | .reg = PAD_FUNCTION_EN_2, \ | 1173 | .reg = PAD_FUNCTION_EN_2, \ |
| 1050 | .mask = PMX_MCIFALL_2_MASK, \ | 1174 | .mask = PMX_MCIFALL_2_MASK, \ |
| 1051 | .val = PMX_MCIFALL_2_MASK, \ | 1175 | .val = PMX_MCIFALL_2_MASK, \ |
| 1176 | }, { \ | ||
| 1177 | .reg = PAD_DIRECTION_SEL_0, \ | ||
| 1178 | .mask = PMX_MCI_DATA8_15_MASK, \ | ||
| 1179 | .val = PMX_MCI_DATA8_15_MASK, \ | ||
| 1180 | }, { \ | ||
| 1181 | .reg = PAD_DIRECTION_SEL_1, \ | ||
| 1182 | .mask = PMX_MCIFALL_1_MASK | PMX_NFWPRT1_MASK | \ | ||
| 1183 | PMX_NFWPRT2_MASK, \ | ||
| 1184 | .val = PMX_MCIFALL_1_MASK | PMX_NFWPRT1_MASK | \ | ||
| 1185 | PMX_NFWPRT2_MASK, \ | ||
| 1186 | }, { \ | ||
| 1187 | .reg = PAD_DIRECTION_SEL_2, \ | ||
| 1188 | .mask = PMX_MCIFALL_2_MASK, \ | ||
| 1189 | .val = PMX_MCIFALL_2_MASK, \ | ||
| 1052 | } | 1190 | } |
| 1053 | 1191 | ||
| 1054 | /* sdhci device */ | 1192 | /* sdhci device */ |
| @@ -1154,6 +1292,10 @@ static struct spear_muxreg touch_xy_muxreg[] = { | |||
| 1154 | .reg = PAD_FUNCTION_EN_2, | 1292 | .reg = PAD_FUNCTION_EN_2, |
| 1155 | .mask = PMX_TOUCH_XY_MASK, | 1293 | .mask = PMX_TOUCH_XY_MASK, |
| 1156 | .val = PMX_TOUCH_XY_MASK, | 1294 | .val = PMX_TOUCH_XY_MASK, |
| 1295 | }, { | ||
| 1296 | .reg = PAD_DIRECTION_SEL_2, | ||
| 1297 | .mask = PMX_TOUCH_XY_MASK, | ||
| 1298 | .val = PMX_TOUCH_XY_MASK, | ||
| 1157 | }, | 1299 | }, |
| 1158 | }; | 1300 | }; |
| 1159 | 1301 | ||
| @@ -1187,6 +1329,10 @@ static struct spear_muxreg uart1_dis_i2c_muxreg[] = { | |||
| 1187 | .reg = PAD_FUNCTION_EN_0, | 1329 | .reg = PAD_FUNCTION_EN_0, |
| 1188 | .mask = PMX_I2C0_MASK, | 1330 | .mask = PMX_I2C0_MASK, |
| 1189 | .val = 0, | 1331 | .val = 0, |
| 1332 | }, { | ||
| 1333 | .reg = PAD_DIRECTION_SEL_0, | ||
| 1334 | .mask = PMX_I2C0_MASK, | ||
| 1335 | .val = PMX_I2C0_MASK, | ||
| 1190 | }, | 1336 | }, |
| 1191 | }; | 1337 | }; |
| 1192 | 1338 | ||
| @@ -1213,6 +1359,12 @@ static struct spear_muxreg uart1_dis_sd_muxreg[] = { | |||
| 1213 | .mask = PMX_MCIDATA1_MASK | | 1359 | .mask = PMX_MCIDATA1_MASK | |
| 1214 | PMX_MCIDATA2_MASK, | 1360 | PMX_MCIDATA2_MASK, |
| 1215 | .val = 0, | 1361 | .val = 0, |
| 1362 | }, { | ||
| 1363 | .reg = PAD_DIRECTION_SEL_1, | ||
| 1364 | .mask = PMX_MCIDATA1_MASK | | ||
| 1365 | PMX_MCIDATA2_MASK, | ||
| 1366 | .val = PMX_MCIDATA1_MASK | | ||
| 1367 | PMX_MCIDATA2_MASK, | ||
| 1216 | }, | 1368 | }, |
| 1217 | }; | 1369 | }; |
| 1218 | 1370 | ||
| @@ -1246,6 +1398,10 @@ static struct spear_muxreg uart2_3_muxreg[] = { | |||
| 1246 | .reg = PAD_FUNCTION_EN_0, | 1398 | .reg = PAD_FUNCTION_EN_0, |
| 1247 | .mask = PMX_I2S0_MASK, | 1399 | .mask = PMX_I2S0_MASK, |
| 1248 | .val = 0, | 1400 | .val = 0, |
| 1401 | }, { | ||
| 1402 | .reg = PAD_DIRECTION_SEL_0, | ||
| 1403 | .mask = PMX_I2S0_MASK, | ||
| 1404 | .val = PMX_I2S0_MASK, | ||
| 1249 | }, | 1405 | }, |
| 1250 | }; | 1406 | }; |
| 1251 | 1407 | ||
| @@ -1278,6 +1434,10 @@ static struct spear_muxreg uart4_muxreg[] = { | |||
| 1278 | .reg = PAD_FUNCTION_EN_0, | 1434 | .reg = PAD_FUNCTION_EN_0, |
| 1279 | .mask = PMX_I2S0_MASK | PMX_CLCD1_MASK, | 1435 | .mask = PMX_I2S0_MASK | PMX_CLCD1_MASK, |
| 1280 | .val = 0, | 1436 | .val = 0, |
| 1437 | }, { | ||
| 1438 | .reg = PAD_DIRECTION_SEL_0, | ||
| 1439 | .mask = PMX_I2S0_MASK | PMX_CLCD1_MASK, | ||
| 1440 | .val = PMX_I2S0_MASK | PMX_CLCD1_MASK, | ||
| 1281 | }, | 1441 | }, |
| 1282 | }; | 1442 | }; |
| 1283 | 1443 | ||
| @@ -1310,6 +1470,10 @@ static struct spear_muxreg uart5_muxreg[] = { | |||
| 1310 | .reg = PAD_FUNCTION_EN_0, | 1470 | .reg = PAD_FUNCTION_EN_0, |
| 1311 | .mask = PMX_CLCD1_MASK, | 1471 | .mask = PMX_CLCD1_MASK, |
| 1312 | .val = 0, | 1472 | .val = 0, |
| 1473 | }, { | ||
| 1474 | .reg = PAD_DIRECTION_SEL_0, | ||
| 1475 | .mask = PMX_CLCD1_MASK, | ||
| 1476 | .val = PMX_CLCD1_MASK, | ||
| 1313 | }, | 1477 | }, |
| 1314 | }; | 1478 | }; |
| 1315 | 1479 | ||
| @@ -1344,6 +1508,10 @@ static struct spear_muxreg rs485_0_1_tdm_0_1_muxreg[] = { | |||
| 1344 | .reg = PAD_FUNCTION_EN_0, | 1508 | .reg = PAD_FUNCTION_EN_0, |
| 1345 | .mask = PMX_CLCD1_MASK, | 1509 | .mask = PMX_CLCD1_MASK, |
| 1346 | .val = 0, | 1510 | .val = 0, |
| 1511 | }, { | ||
| 1512 | .reg = PAD_DIRECTION_SEL_0, | ||
| 1513 | .mask = PMX_CLCD1_MASK, | ||
| 1514 | .val = PMX_CLCD1_MASK, | ||
| 1347 | }, | 1515 | }, |
| 1348 | }; | 1516 | }; |
| 1349 | 1517 | ||
| @@ -1376,6 +1544,10 @@ static struct spear_muxreg i2c_1_2_muxreg[] = { | |||
| 1376 | .reg = PAD_FUNCTION_EN_0, | 1544 | .reg = PAD_FUNCTION_EN_0, |
| 1377 | .mask = PMX_CLCD1_MASK, | 1545 | .mask = PMX_CLCD1_MASK, |
| 1378 | .val = 0, | 1546 | .val = 0, |
| 1547 | }, { | ||
| 1548 | .reg = PAD_DIRECTION_SEL_0, | ||
| 1549 | .mask = PMX_CLCD1_MASK, | ||
| 1550 | .val = PMX_CLCD1_MASK, | ||
| 1379 | }, | 1551 | }, |
| 1380 | }; | 1552 | }; |
| 1381 | 1553 | ||
| @@ -1409,6 +1581,10 @@ static struct spear_muxreg i2c3_dis_smi_clcd_muxreg[] = { | |||
| 1409 | .reg = PAD_FUNCTION_EN_0, | 1581 | .reg = PAD_FUNCTION_EN_0, |
| 1410 | .mask = PMX_CLCD1_MASK | PMX_SMI_MASK, | 1582 | .mask = PMX_CLCD1_MASK | PMX_SMI_MASK, |
| 1411 | .val = 0, | 1583 | .val = 0, |
| 1584 | }, { | ||
| 1585 | .reg = PAD_DIRECTION_SEL_0, | ||
| 1586 | .mask = PMX_CLCD1_MASK | PMX_SMI_MASK, | ||
| 1587 | .val = PMX_CLCD1_MASK | PMX_SMI_MASK, | ||
| 1412 | }, | 1588 | }, |
| 1413 | }; | 1589 | }; |
| 1414 | 1590 | ||
| @@ -1435,6 +1611,10 @@ static struct spear_muxreg i2c3_dis_sd_i2s0_muxreg[] = { | |||
| 1435 | .reg = PAD_FUNCTION_EN_1, | 1611 | .reg = PAD_FUNCTION_EN_1, |
| 1436 | .mask = PMX_I2S1_MASK | PMX_MCIDATA3_MASK, | 1612 | .mask = PMX_I2S1_MASK | PMX_MCIDATA3_MASK, |
| 1437 | .val = 0, | 1613 | .val = 0, |
| 1614 | }, { | ||
| 1615 | .reg = PAD_DIRECTION_SEL_1, | ||
| 1616 | .mask = PMX_I2S1_MASK | PMX_MCIDATA3_MASK, | ||
| 1617 | .val = PMX_I2S1_MASK | PMX_MCIDATA3_MASK, | ||
| 1438 | }, | 1618 | }, |
| 1439 | }; | 1619 | }; |
| 1440 | 1620 | ||
| @@ -1469,6 +1649,10 @@ static struct spear_muxreg i2c_4_5_dis_smi_muxreg[] = { | |||
| 1469 | .reg = PAD_FUNCTION_EN_0, | 1649 | .reg = PAD_FUNCTION_EN_0, |
| 1470 | .mask = PMX_SMI_MASK, | 1650 | .mask = PMX_SMI_MASK, |
| 1471 | .val = 0, | 1651 | .val = 0, |
| 1652 | }, { | ||
| 1653 | .reg = PAD_DIRECTION_SEL_0, | ||
| 1654 | .mask = PMX_SMI_MASK, | ||
| 1655 | .val = PMX_SMI_MASK, | ||
| 1472 | }, | 1656 | }, |
| 1473 | }; | 1657 | }; |
| 1474 | 1658 | ||
| @@ -1499,6 +1683,14 @@ static struct spear_muxreg i2c4_dis_sd_muxreg[] = { | |||
| 1499 | .reg = PAD_FUNCTION_EN_2, | 1683 | .reg = PAD_FUNCTION_EN_2, |
| 1500 | .mask = PMX_MCIDATA5_MASK, | 1684 | .mask = PMX_MCIDATA5_MASK, |
| 1501 | .val = 0, | 1685 | .val = 0, |
| 1686 | }, { | ||
| 1687 | .reg = PAD_DIRECTION_SEL_1, | ||
| 1688 | .mask = PMX_MCIDATA4_MASK, | ||
| 1689 | .val = PMX_MCIDATA4_MASK, | ||
| 1690 | }, { | ||
| 1691 | .reg = PAD_DIRECTION_SEL_2, | ||
| 1692 | .mask = PMX_MCIDATA5_MASK, | ||
| 1693 | .val = PMX_MCIDATA5_MASK, | ||
| 1502 | }, | 1694 | }, |
| 1503 | }; | 1695 | }; |
| 1504 | 1696 | ||
| @@ -1526,6 +1718,12 @@ static struct spear_muxreg i2c5_dis_sd_muxreg[] = { | |||
| 1526 | .mask = PMX_MCIDATA6_MASK | | 1718 | .mask = PMX_MCIDATA6_MASK | |
| 1527 | PMX_MCIDATA7_MASK, | 1719 | PMX_MCIDATA7_MASK, |
| 1528 | .val = 0, | 1720 | .val = 0, |
| 1721 | }, { | ||
| 1722 | .reg = PAD_DIRECTION_SEL_2, | ||
| 1723 | .mask = PMX_MCIDATA6_MASK | | ||
| 1724 | PMX_MCIDATA7_MASK, | ||
| 1725 | .val = PMX_MCIDATA6_MASK | | ||
| 1726 | PMX_MCIDATA7_MASK, | ||
| 1529 | }, | 1727 | }, |
| 1530 | }; | 1728 | }; |
| 1531 | 1729 | ||
| @@ -1560,6 +1758,10 @@ static struct spear_muxreg i2c_6_7_dis_kbd_muxreg[] = { | |||
| 1560 | .reg = PAD_FUNCTION_EN_1, | 1758 | .reg = PAD_FUNCTION_EN_1, |
| 1561 | .mask = PMX_KBD_ROWCOL25_MASK, | 1759 | .mask = PMX_KBD_ROWCOL25_MASK, |
| 1562 | .val = 0, | 1760 | .val = 0, |
| 1761 | }, { | ||
| 1762 | .reg = PAD_DIRECTION_SEL_1, | ||
| 1763 | .mask = PMX_KBD_ROWCOL25_MASK, | ||
| 1764 | .val = PMX_KBD_ROWCOL25_MASK, | ||
| 1563 | }, | 1765 | }, |
| 1564 | }; | 1766 | }; |
| 1565 | 1767 | ||
| @@ -1587,6 +1789,12 @@ static struct spear_muxreg i2c6_dis_sd_muxreg[] = { | |||
| 1587 | .mask = PMX_MCIIORDRE_MASK | | 1789 | .mask = PMX_MCIIORDRE_MASK | |
| 1588 | PMX_MCIIOWRWE_MASK, | 1790 | PMX_MCIIOWRWE_MASK, |
| 1589 | .val = 0, | 1791 | .val = 0, |
| 1792 | }, { | ||
| 1793 | .reg = PAD_DIRECTION_SEL_2, | ||
| 1794 | .mask = PMX_MCIIORDRE_MASK | | ||
| 1795 | PMX_MCIIOWRWE_MASK, | ||
| 1796 | .val = PMX_MCIIORDRE_MASK | | ||
| 1797 | PMX_MCIIOWRWE_MASK, | ||
| 1590 | }, | 1798 | }, |
| 1591 | }; | 1799 | }; |
| 1592 | 1800 | ||
| @@ -1613,6 +1821,12 @@ static struct spear_muxreg i2c7_dis_sd_muxreg[] = { | |||
| 1613 | .mask = PMX_MCIRESETCF_MASK | | 1821 | .mask = PMX_MCIRESETCF_MASK | |
| 1614 | PMX_MCICS0CE_MASK, | 1822 | PMX_MCICS0CE_MASK, |
| 1615 | .val = 0, | 1823 | .val = 0, |
| 1824 | }, { | ||
| 1825 | .reg = PAD_DIRECTION_SEL_2, | ||
| 1826 | .mask = PMX_MCIRESETCF_MASK | | ||
| 1827 | PMX_MCICS0CE_MASK, | ||
| 1828 | .val = PMX_MCIRESETCF_MASK | | ||
| 1829 | PMX_MCICS0CE_MASK, | ||
| 1616 | }, | 1830 | }, |
| 1617 | }; | 1831 | }; |
| 1618 | 1832 | ||
| @@ -1651,6 +1865,14 @@ static struct spear_muxreg can0_dis_nor_muxreg[] = { | |||
| 1651 | .reg = PAD_FUNCTION_EN_1, | 1865 | .reg = PAD_FUNCTION_EN_1, |
| 1652 | .mask = PMX_NFRSTPWDWN3_MASK, | 1866 | .mask = PMX_NFRSTPWDWN3_MASK, |
| 1653 | .val = 0, | 1867 | .val = 0, |
| 1868 | }, { | ||
| 1869 | .reg = PAD_DIRECTION_SEL_0, | ||
| 1870 | .mask = PMX_NFRSTPWDWN2_MASK, | ||
| 1871 | .val = PMX_NFRSTPWDWN2_MASK, | ||
| 1872 | }, { | ||
| 1873 | .reg = PAD_DIRECTION_SEL_1, | ||
| 1874 | .mask = PMX_NFRSTPWDWN3_MASK, | ||
| 1875 | .val = PMX_NFRSTPWDWN3_MASK, | ||
| 1654 | }, | 1876 | }, |
| 1655 | }; | 1877 | }; |
| 1656 | 1878 | ||
| @@ -1677,6 +1899,10 @@ static struct spear_muxreg can0_dis_sd_muxreg[] = { | |||
| 1677 | .reg = PAD_FUNCTION_EN_2, | 1899 | .reg = PAD_FUNCTION_EN_2, |
| 1678 | .mask = PMX_MCICFINTR_MASK | PMX_MCIIORDY_MASK, | 1900 | .mask = PMX_MCICFINTR_MASK | PMX_MCIIORDY_MASK, |
| 1679 | .val = 0, | 1901 | .val = 0, |
| 1902 | }, { | ||
| 1903 | .reg = PAD_DIRECTION_SEL_2, | ||
| 1904 | .mask = PMX_MCICFINTR_MASK | PMX_MCIIORDY_MASK, | ||
| 1905 | .val = PMX_MCICFINTR_MASK | PMX_MCIIORDY_MASK, | ||
| 1680 | }, | 1906 | }, |
| 1681 | }; | 1907 | }; |
| 1682 | 1908 | ||
| @@ -1711,6 +1937,10 @@ static struct spear_muxreg can1_dis_sd_muxreg[] = { | |||
| 1711 | .reg = PAD_FUNCTION_EN_2, | 1937 | .reg = PAD_FUNCTION_EN_2, |
| 1712 | .mask = PMX_MCICS1_MASK | PMX_MCIDMAACK_MASK, | 1938 | .mask = PMX_MCICS1_MASK | PMX_MCIDMAACK_MASK, |
| 1713 | .val = 0, | 1939 | .val = 0, |
| 1940 | }, { | ||
| 1941 | .reg = PAD_DIRECTION_SEL_2, | ||
| 1942 | .mask = PMX_MCICS1_MASK | PMX_MCIDMAACK_MASK, | ||
| 1943 | .val = PMX_MCICS1_MASK | PMX_MCIDMAACK_MASK, | ||
| 1714 | }, | 1944 | }, |
| 1715 | }; | 1945 | }; |
| 1716 | 1946 | ||
| @@ -1737,6 +1967,10 @@ static struct spear_muxreg can1_dis_kbd_muxreg[] = { | |||
| 1737 | .reg = PAD_FUNCTION_EN_1, | 1967 | .reg = PAD_FUNCTION_EN_1, |
| 1738 | .mask = PMX_KBD_ROWCOL25_MASK, | 1968 | .mask = PMX_KBD_ROWCOL25_MASK, |
| 1739 | .val = 0, | 1969 | .val = 0, |
| 1970 | }, { | ||
| 1971 | .reg = PAD_DIRECTION_SEL_1, | ||
| 1972 | .mask = PMX_KBD_ROWCOL25_MASK, | ||
| 1973 | .val = PMX_KBD_ROWCOL25_MASK, | ||
| 1740 | }, | 1974 | }, |
| 1741 | }; | 1975 | }; |
| 1742 | 1976 | ||
| @@ -1763,29 +1997,64 @@ static struct spear_function can1_function = { | |||
| 1763 | .ngroups = ARRAY_SIZE(can1_grps), | 1997 | .ngroups = ARRAY_SIZE(can1_grps), |
| 1764 | }; | 1998 | }; |
| 1765 | 1999 | ||
| 1766 | /* Pad multiplexing for pci device */ | 2000 | /* Pad multiplexing for (ras-ip) pci device */ |
| 1767 | static const unsigned pci_sata_pins[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 18, | 2001 | static const unsigned pci_pins[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 18, |
| 1768 | 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, | 2002 | 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, |
| 1769 | 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, | 2003 | 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, |
| 1770 | 55, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99 }; | 2004 | 55, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99 }; |
| 1771 | #define PCI_SATA_MUXREG \ | ||
| 1772 | { \ | ||
| 1773 | .reg = PAD_FUNCTION_EN_0, \ | ||
| 1774 | .mask = PMX_MCI_DATA8_15_MASK, \ | ||
| 1775 | .val = 0, \ | ||
| 1776 | }, { \ | ||
| 1777 | .reg = PAD_FUNCTION_EN_1, \ | ||
| 1778 | .mask = PMX_PCI_REG1_MASK, \ | ||
| 1779 | .val = 0, \ | ||
| 1780 | }, { \ | ||
| 1781 | .reg = PAD_FUNCTION_EN_2, \ | ||
| 1782 | .mask = PMX_PCI_REG2_MASK, \ | ||
| 1783 | .val = 0, \ | ||
| 1784 | } | ||
| 1785 | 2005 | ||
| 1786 | /* pad multiplexing for pcie0 device */ | 2006 | static struct spear_muxreg pci_muxreg[] = { |
| 2007 | { | ||
| 2008 | .reg = PAD_FUNCTION_EN_0, | ||
| 2009 | .mask = PMX_MCI_DATA8_15_MASK, | ||
| 2010 | .val = 0, | ||
| 2011 | }, { | ||
| 2012 | .reg = PAD_FUNCTION_EN_1, | ||
| 2013 | .mask = PMX_PCI_REG1_MASK, | ||
| 2014 | .val = 0, | ||
| 2015 | }, { | ||
| 2016 | .reg = PAD_FUNCTION_EN_2, | ||
| 2017 | .mask = PMX_PCI_REG2_MASK, | ||
| 2018 | .val = 0, | ||
| 2019 | }, { | ||
| 2020 | .reg = PAD_DIRECTION_SEL_0, | ||
| 2021 | .mask = PMX_MCI_DATA8_15_MASK, | ||
| 2022 | .val = PMX_MCI_DATA8_15_MASK, | ||
| 2023 | }, { | ||
| 2024 | .reg = PAD_DIRECTION_SEL_1, | ||
| 2025 | .mask = PMX_PCI_REG1_MASK, | ||
| 2026 | .val = PMX_PCI_REG1_MASK, | ||
| 2027 | }, { | ||
| 2028 | .reg = PAD_DIRECTION_SEL_2, | ||
| 2029 | .mask = PMX_PCI_REG2_MASK, | ||
| 2030 | .val = PMX_PCI_REG2_MASK, | ||
| 2031 | }, | ||
| 2032 | }; | ||
| 2033 | |||
| 2034 | static struct spear_modemux pci_modemux[] = { | ||
| 2035 | { | ||
| 2036 | .muxregs = pci_muxreg, | ||
| 2037 | .nmuxregs = ARRAY_SIZE(pci_muxreg), | ||
| 2038 | }, | ||
| 2039 | }; | ||
| 2040 | |||
| 2041 | static struct spear_pingroup pci_pingroup = { | ||
| 2042 | .name = "pci_grp", | ||
| 2043 | .pins = pci_pins, | ||
| 2044 | .npins = ARRAY_SIZE(pci_pins), | ||
| 2045 | .modemuxs = pci_modemux, | ||
| 2046 | .nmodemuxs = ARRAY_SIZE(pci_modemux), | ||
| 2047 | }; | ||
| 2048 | |||
| 2049 | static const char *const pci_grps[] = { "pci_grp" }; | ||
| 2050 | static struct spear_function pci_function = { | ||
| 2051 | .name = "pci", | ||
| 2052 | .groups = pci_grps, | ||
| 2053 | .ngroups = ARRAY_SIZE(pci_grps), | ||
| 2054 | }; | ||
| 2055 | |||
| 2056 | /* pad multiplexing for (fix-part) pcie0 device */ | ||
| 1787 | static struct spear_muxreg pcie0_muxreg[] = { | 2057 | static struct spear_muxreg pcie0_muxreg[] = { |
| 1788 | PCI_SATA_MUXREG, | ||
| 1789 | { | 2058 | { |
| 1790 | .reg = PCIE_SATA_CFG, | 2059 | .reg = PCIE_SATA_CFG, |
| 1791 | .mask = PCIE_CFG_VAL(0), | 2060 | .mask = PCIE_CFG_VAL(0), |
| @@ -1802,15 +2071,12 @@ static struct spear_modemux pcie0_modemux[] = { | |||
| 1802 | 2071 | ||
| 1803 | static struct spear_pingroup pcie0_pingroup = { | 2072 | static struct spear_pingroup pcie0_pingroup = { |
| 1804 | .name = "pcie0_grp", | 2073 | .name = "pcie0_grp", |
| 1805 | .pins = pci_sata_pins, | ||
| 1806 | .npins = ARRAY_SIZE(pci_sata_pins), | ||
| 1807 | .modemuxs = pcie0_modemux, | 2074 | .modemuxs = pcie0_modemux, |
| 1808 | .nmodemuxs = ARRAY_SIZE(pcie0_modemux), | 2075 | .nmodemuxs = ARRAY_SIZE(pcie0_modemux), |
| 1809 | }; | 2076 | }; |
| 1810 | 2077 | ||
| 1811 | /* pad multiplexing for pcie1 device */ | 2078 | /* pad multiplexing for (fix-part) pcie1 device */ |
| 1812 | static struct spear_muxreg pcie1_muxreg[] = { | 2079 | static struct spear_muxreg pcie1_muxreg[] = { |
| 1813 | PCI_SATA_MUXREG, | ||
| 1814 | { | 2080 | { |
| 1815 | .reg = PCIE_SATA_CFG, | 2081 | .reg = PCIE_SATA_CFG, |
| 1816 | .mask = PCIE_CFG_VAL(1), | 2082 | .mask = PCIE_CFG_VAL(1), |
| @@ -1827,15 +2093,12 @@ static struct spear_modemux pcie1_modemux[] = { | |||
| 1827 | 2093 | ||
| 1828 | static struct spear_pingroup pcie1_pingroup = { | 2094 | static struct spear_pingroup pcie1_pingroup = { |
| 1829 | .name = "pcie1_grp", | 2095 | .name = "pcie1_grp", |
| 1830 | .pins = pci_sata_pins, | ||
| 1831 | .npins = ARRAY_SIZE(pci_sata_pins), | ||
| 1832 | .modemuxs = pcie1_modemux, | 2096 | .modemuxs = pcie1_modemux, |
| 1833 | .nmodemuxs = ARRAY_SIZE(pcie1_modemux), | 2097 | .nmodemuxs = ARRAY_SIZE(pcie1_modemux), |
| 1834 | }; | 2098 | }; |
| 1835 | 2099 | ||
| 1836 | /* pad multiplexing for pcie2 device */ | 2100 | /* pad multiplexing for (fix-part) pcie2 device */ |
| 1837 | static struct spear_muxreg pcie2_muxreg[] = { | 2101 | static struct spear_muxreg pcie2_muxreg[] = { |
| 1838 | PCI_SATA_MUXREG, | ||
| 1839 | { | 2102 | { |
| 1840 | .reg = PCIE_SATA_CFG, | 2103 | .reg = PCIE_SATA_CFG, |
| 1841 | .mask = PCIE_CFG_VAL(2), | 2104 | .mask = PCIE_CFG_VAL(2), |
| @@ -1852,22 +2115,20 @@ static struct spear_modemux pcie2_modemux[] = { | |||
| 1852 | 2115 | ||
| 1853 | static struct spear_pingroup pcie2_pingroup = { | 2116 | static struct spear_pingroup pcie2_pingroup = { |
| 1854 | .name = "pcie2_grp", | 2117 | .name = "pcie2_grp", |
| 1855 | .pins = pci_sata_pins, | ||
| 1856 | .npins = ARRAY_SIZE(pci_sata_pins), | ||
| 1857 | .modemuxs = pcie2_modemux, | 2118 | .modemuxs = pcie2_modemux, |
| 1858 | .nmodemuxs = ARRAY_SIZE(pcie2_modemux), | 2119 | .nmodemuxs = ARRAY_SIZE(pcie2_modemux), |
| 1859 | }; | 2120 | }; |
| 1860 | 2121 | ||
| 1861 | static const char *const pci_grps[] = { "pcie0_grp", "pcie1_grp", "pcie2_grp" }; | 2122 | static const char *const pcie_grps[] = { "pcie0_grp", "pcie1_grp", "pcie2_grp" |
| 1862 | static struct spear_function pci_function = { | 2123 | }; |
| 1863 | .name = "pci", | 2124 | static struct spear_function pcie_function = { |
| 1864 | .groups = pci_grps, | 2125 | .name = "pci_express", |
| 1865 | .ngroups = ARRAY_SIZE(pci_grps), | 2126 | .groups = pcie_grps, |
| 2127 | .ngroups = ARRAY_SIZE(pcie_grps), | ||
| 1866 | }; | 2128 | }; |
| 1867 | 2129 | ||
| 1868 | /* pad multiplexing for sata0 device */ | 2130 | /* pad multiplexing for sata0 device */ |
| 1869 | static struct spear_muxreg sata0_muxreg[] = { | 2131 | static struct spear_muxreg sata0_muxreg[] = { |
| 1870 | PCI_SATA_MUXREG, | ||
| 1871 | { | 2132 | { |
| 1872 | .reg = PCIE_SATA_CFG, | 2133 | .reg = PCIE_SATA_CFG, |
| 1873 | .mask = SATA_CFG_VAL(0), | 2134 | .mask = SATA_CFG_VAL(0), |
| @@ -1884,15 +2145,12 @@ static struct spear_modemux sata0_modemux[] = { | |||
| 1884 | 2145 | ||
| 1885 | static struct spear_pingroup sata0_pingroup = { | 2146 | static struct spear_pingroup sata0_pingroup = { |
| 1886 | .name = "sata0_grp", | 2147 | .name = "sata0_grp", |
| 1887 | .pins = pci_sata_pins, | ||
| 1888 | .npins = ARRAY_SIZE(pci_sata_pins), | ||
| 1889 | .modemuxs = sata0_modemux, | 2148 | .modemuxs = sata0_modemux, |
| 1890 | .nmodemuxs = ARRAY_SIZE(sata0_modemux), | 2149 | .nmodemuxs = ARRAY_SIZE(sata0_modemux), |
| 1891 | }; | 2150 | }; |
| 1892 | 2151 | ||
| 1893 | /* pad multiplexing for sata1 device */ | 2152 | /* pad multiplexing for sata1 device */ |
| 1894 | static struct spear_muxreg sata1_muxreg[] = { | 2153 | static struct spear_muxreg sata1_muxreg[] = { |
| 1895 | PCI_SATA_MUXREG, | ||
| 1896 | { | 2154 | { |
| 1897 | .reg = PCIE_SATA_CFG, | 2155 | .reg = PCIE_SATA_CFG, |
| 1898 | .mask = SATA_CFG_VAL(1), | 2156 | .mask = SATA_CFG_VAL(1), |
| @@ -1909,15 +2167,12 @@ static struct spear_modemux sata1_modemux[] = { | |||
| 1909 | 2167 | ||
| 1910 | static struct spear_pingroup sata1_pingroup = { | 2168 | static struct spear_pingroup sata1_pingroup = { |
| 1911 | .name = "sata1_grp", | 2169 | .name = "sata1_grp", |
| 1912 | .pins = pci_sata_pins, | ||
| 1913 | .npins = ARRAY_SIZE(pci_sata_pins), | ||
| 1914 | .modemuxs = sata1_modemux, | 2170 | .modemuxs = sata1_modemux, |
| 1915 | .nmodemuxs = ARRAY_SIZE(sata1_modemux), | 2171 | .nmodemuxs = ARRAY_SIZE(sata1_modemux), |
| 1916 | }; | 2172 | }; |
| 1917 | 2173 | ||
| 1918 | /* pad multiplexing for sata2 device */ | 2174 | /* pad multiplexing for sata2 device */ |
| 1919 | static struct spear_muxreg sata2_muxreg[] = { | 2175 | static struct spear_muxreg sata2_muxreg[] = { |
| 1920 | PCI_SATA_MUXREG, | ||
| 1921 | { | 2176 | { |
| 1922 | .reg = PCIE_SATA_CFG, | 2177 | .reg = PCIE_SATA_CFG, |
| 1923 | .mask = SATA_CFG_VAL(2), | 2178 | .mask = SATA_CFG_VAL(2), |
| @@ -1934,8 +2189,6 @@ static struct spear_modemux sata2_modemux[] = { | |||
| 1934 | 2189 | ||
| 1935 | static struct spear_pingroup sata2_pingroup = { | 2190 | static struct spear_pingroup sata2_pingroup = { |
| 1936 | .name = "sata2_grp", | 2191 | .name = "sata2_grp", |
| 1937 | .pins = pci_sata_pins, | ||
| 1938 | .npins = ARRAY_SIZE(pci_sata_pins), | ||
| 1939 | .modemuxs = sata2_modemux, | 2192 | .modemuxs = sata2_modemux, |
| 1940 | .nmodemuxs = ARRAY_SIZE(sata2_modemux), | 2193 | .nmodemuxs = ARRAY_SIZE(sata2_modemux), |
| 1941 | }; | 2194 | }; |
| @@ -1957,6 +2210,14 @@ static struct spear_muxreg ssp1_dis_kbd_muxreg[] = { | |||
| 1957 | PMX_KBD_COL0_MASK | PMX_NFIO8_15_MASK | PMX_NFCE1_MASK | | 2210 | PMX_KBD_COL0_MASK | PMX_NFIO8_15_MASK | PMX_NFCE1_MASK | |
| 1958 | PMX_NFCE2_MASK, | 2211 | PMX_NFCE2_MASK, |
| 1959 | .val = 0, | 2212 | .val = 0, |
| 2213 | }, { | ||
| 2214 | .reg = PAD_DIRECTION_SEL_1, | ||
| 2215 | .mask = PMX_KBD_ROWCOL25_MASK | PMX_KBD_COL1_MASK | | ||
| 2216 | PMX_KBD_COL0_MASK | PMX_NFIO8_15_MASK | PMX_NFCE1_MASK | | ||
| 2217 | PMX_NFCE2_MASK, | ||
| 2218 | .val = PMX_KBD_ROWCOL25_MASK | PMX_KBD_COL1_MASK | | ||
| 2219 | PMX_KBD_COL0_MASK | PMX_NFIO8_15_MASK | PMX_NFCE1_MASK | | ||
| 2220 | PMX_NFCE2_MASK, | ||
| 1960 | }, | 2221 | }, |
| 1961 | }; | 2222 | }; |
| 1962 | 2223 | ||
| @@ -1983,6 +2244,12 @@ static struct spear_muxreg ssp1_dis_sd_muxreg[] = { | |||
| 1983 | .mask = PMX_MCIADDR0ALE_MASK | PMX_MCIADDR2_MASK | | 2244 | .mask = PMX_MCIADDR0ALE_MASK | PMX_MCIADDR2_MASK | |
| 1984 | PMX_MCICECF_MASK | PMX_MCICEXD_MASK, | 2245 | PMX_MCICECF_MASK | PMX_MCICEXD_MASK, |
| 1985 | .val = 0, | 2246 | .val = 0, |
| 2247 | }, { | ||
| 2248 | .reg = PAD_DIRECTION_SEL_2, | ||
| 2249 | .mask = PMX_MCIADDR0ALE_MASK | PMX_MCIADDR2_MASK | | ||
| 2250 | PMX_MCICECF_MASK | PMX_MCICEXD_MASK, | ||
| 2251 | .val = PMX_MCIADDR0ALE_MASK | PMX_MCIADDR2_MASK | | ||
| 2252 | PMX_MCICECF_MASK | PMX_MCICEXD_MASK, | ||
| 1986 | }, | 2253 | }, |
| 1987 | }; | 2254 | }; |
| 1988 | 2255 | ||
| @@ -2017,6 +2284,12 @@ static struct spear_muxreg gpt64_muxreg[] = { | |||
| 2017 | .mask = PMX_MCICDCF1_MASK | PMX_MCICDCF2_MASK | PMX_MCICDXD_MASK | 2284 | .mask = PMX_MCICDCF1_MASK | PMX_MCICDCF2_MASK | PMX_MCICDXD_MASK |
| 2018 | | PMX_MCILEDS_MASK, | 2285 | | PMX_MCILEDS_MASK, |
| 2019 | .val = 0, | 2286 | .val = 0, |
| 2287 | }, { | ||
| 2288 | .reg = PAD_DIRECTION_SEL_2, | ||
| 2289 | .mask = PMX_MCICDCF1_MASK | PMX_MCICDCF2_MASK | PMX_MCICDXD_MASK | ||
| 2290 | | PMX_MCILEDS_MASK, | ||
| 2291 | .val = PMX_MCICDCF1_MASK | PMX_MCICDCF2_MASK | PMX_MCICDXD_MASK | ||
| 2292 | | PMX_MCILEDS_MASK, | ||
| 2020 | }, | 2293 | }, |
| 2021 | }; | 2294 | }; |
| 2022 | 2295 | ||
| @@ -2093,6 +2366,7 @@ static struct spear_pingroup *spear1310_pingroups[] = { | |||
| 2093 | &can0_dis_sd_pingroup, | 2366 | &can0_dis_sd_pingroup, |
| 2094 | &can1_dis_sd_pingroup, | 2367 | &can1_dis_sd_pingroup, |
| 2095 | &can1_dis_kbd_pingroup, | 2368 | &can1_dis_kbd_pingroup, |
| 2369 | &pci_pingroup, | ||
| 2096 | &pcie0_pingroup, | 2370 | &pcie0_pingroup, |
| 2097 | &pcie1_pingroup, | 2371 | &pcie1_pingroup, |
| 2098 | &pcie2_pingroup, | 2372 | &pcie2_pingroup, |
| @@ -2138,6 +2412,7 @@ static struct spear_function *spear1310_functions[] = { | |||
| 2138 | &can0_function, | 2412 | &can0_function, |
| 2139 | &can1_function, | 2413 | &can1_function, |
| 2140 | &pci_function, | 2414 | &pci_function, |
| 2415 | &pcie_function, | ||
| 2141 | &sata_function, | 2416 | &sata_function, |
| 2142 | &ssp1_function, | 2417 | &ssp1_function, |
| 2143 | &gpt64_function, | 2418 | &gpt64_function, |
diff --git a/drivers/pinctrl/spear/pinctrl-spear1340.c b/drivers/pinctrl/spear/pinctrl-spear1340.c index a0eb057e55bd..0606b8cf3f2c 100644 --- a/drivers/pinctrl/spear/pinctrl-spear1340.c +++ b/drivers/pinctrl/spear/pinctrl-spear1340.c | |||
| @@ -213,7 +213,7 @@ static const struct pinctrl_pin_desc spear1340_pins[] = { | |||
| 213 | * Pad multiplexing for making all pads as gpio's. This is done to override the | 213 | * Pad multiplexing for making all pads as gpio's. This is done to override the |
| 214 | * values passed from bootloader and start from scratch. | 214 | * values passed from bootloader and start from scratch. |
| 215 | */ | 215 | */ |
| 216 | static const unsigned pads_as_gpio_pins[] = { 251 }; | 216 | static const unsigned pads_as_gpio_pins[] = { 12, 88, 89, 251 }; |
| 217 | static struct spear_muxreg pads_as_gpio_muxreg[] = { | 217 | static struct spear_muxreg pads_as_gpio_muxreg[] = { |
| 218 | { | 218 | { |
| 219 | .reg = PAD_FUNCTION_EN_1, | 219 | .reg = PAD_FUNCTION_EN_1, |
| @@ -1692,7 +1692,43 @@ static struct spear_pingroup clcd_pingroup = { | |||
| 1692 | .nmodemuxs = ARRAY_SIZE(clcd_modemux), | 1692 | .nmodemuxs = ARRAY_SIZE(clcd_modemux), |
| 1693 | }; | 1693 | }; |
| 1694 | 1694 | ||
| 1695 | static const char *const clcd_grps[] = { "clcd_grp" }; | 1695 | /* Disable cld runtime to save panel damage */ |
| 1696 | static struct spear_muxreg clcd_sleep_muxreg[] = { | ||
| 1697 | { | ||
| 1698 | .reg = PAD_SHARED_IP_EN_1, | ||
| 1699 | .mask = ARM_TRACE_MASK | MIPHY_DBG_MASK, | ||
| 1700 | .val = 0, | ||
| 1701 | }, { | ||
| 1702 | .reg = PAD_FUNCTION_EN_5, | ||
| 1703 | .mask = CLCD_REG4_MASK | CLCD_AND_ARM_TRACE_REG4_MASK, | ||
| 1704 | .val = 0x0, | ||
| 1705 | }, { | ||
| 1706 | .reg = PAD_FUNCTION_EN_6, | ||
| 1707 | .mask = CLCD_AND_ARM_TRACE_REG5_MASK, | ||
| 1708 | .val = 0x0, | ||
| 1709 | }, { | ||
| 1710 | .reg = PAD_FUNCTION_EN_7, | ||
| 1711 | .mask = CLCD_AND_ARM_TRACE_REG6_MASK, | ||
| 1712 | .val = 0x0, | ||
| 1713 | }, | ||
| 1714 | }; | ||
| 1715 | |||
| 1716 | static struct spear_modemux clcd_sleep_modemux[] = { | ||
| 1717 | { | ||
| 1718 | .muxregs = clcd_sleep_muxreg, | ||
| 1719 | .nmuxregs = ARRAY_SIZE(clcd_sleep_muxreg), | ||
| 1720 | }, | ||
| 1721 | }; | ||
| 1722 | |||
| 1723 | static struct spear_pingroup clcd_sleep_pingroup = { | ||
| 1724 | .name = "clcd_sleep_grp", | ||
| 1725 | .pins = clcd_pins, | ||
| 1726 | .npins = ARRAY_SIZE(clcd_pins), | ||
| 1727 | .modemuxs = clcd_sleep_modemux, | ||
| 1728 | .nmodemuxs = ARRAY_SIZE(clcd_sleep_modemux), | ||
| 1729 | }; | ||
| 1730 | |||
| 1731 | static const char *const clcd_grps[] = { "clcd_grp", "clcd_sleep_grp" }; | ||
| 1696 | static struct spear_function clcd_function = { | 1732 | static struct spear_function clcd_function = { |
| 1697 | .name = "clcd", | 1733 | .name = "clcd", |
| 1698 | .groups = clcd_grps, | 1734 | .groups = clcd_grps, |
| @@ -1893,6 +1929,7 @@ static struct spear_pingroup *spear1340_pingroups[] = { | |||
| 1893 | &sdhci_pingroup, | 1929 | &sdhci_pingroup, |
| 1894 | &cf_pingroup, | 1930 | &cf_pingroup, |
| 1895 | &xd_pingroup, | 1931 | &xd_pingroup, |
| 1932 | &clcd_sleep_pingroup, | ||
| 1896 | &clcd_pingroup, | 1933 | &clcd_pingroup, |
| 1897 | &arm_trace_pingroup, | 1934 | &arm_trace_pingroup, |
| 1898 | &miphy_dbg_pingroup, | 1935 | &miphy_dbg_pingroup, |
diff --git a/drivers/pinctrl/spear/pinctrl-spear320.c b/drivers/pinctrl/spear/pinctrl-spear320.c index 020b1e0bdb3e..ca47b0e50780 100644 --- a/drivers/pinctrl/spear/pinctrl-spear320.c +++ b/drivers/pinctrl/spear/pinctrl-spear320.c | |||
| @@ -2240,6 +2240,10 @@ static struct spear_muxreg pwm2_pin_34_muxreg[] = { | |||
| 2240 | .mask = PMX_SSP_CS_MASK, | 2240 | .mask = PMX_SSP_CS_MASK, |
| 2241 | .val = 0, | 2241 | .val = 0, |
| 2242 | }, { | 2242 | }, { |
| 2243 | .reg = MODE_CONFIG_REG, | ||
| 2244 | .mask = PMX_PWM_MASK, | ||
| 2245 | .val = PMX_PWM_MASK, | ||
| 2246 | }, { | ||
| 2243 | .reg = IP_SEL_PAD_30_39_REG, | 2247 | .reg = IP_SEL_PAD_30_39_REG, |
| 2244 | .mask = PMX_PL_34_MASK, | 2248 | .mask = PMX_PL_34_MASK, |
| 2245 | .val = PMX_PWM2_PL_34_VAL, | 2249 | .val = PMX_PWM2_PL_34_VAL, |
| @@ -2956,9 +2960,9 @@ static struct spear_function mii2_function = { | |||
| 2956 | }; | 2960 | }; |
| 2957 | 2961 | ||
| 2958 | /* Pad multiplexing for cadence mii 1_2 as smii or rmii device */ | 2962 | /* Pad multiplexing for cadence mii 1_2 as smii or rmii device */ |
| 2959 | static const unsigned smii0_1_pins[] = { 10, 11, 13, 14, 15, 16, 17, 18, 19, 20, | 2963 | static const unsigned rmii0_1_pins[] = { 10, 11, 13, 14, 15, 16, 17, 18, 19, 20, |
| 2960 | 21, 22, 23, 24, 25, 26, 27 }; | 2964 | 21, 22, 23, 24, 25, 26, 27 }; |
| 2961 | static const unsigned rmii0_1_pins[] = { 10, 11, 21, 22, 23, 24, 25, 26, 27 }; | 2965 | static const unsigned smii0_1_pins[] = { 10, 11, 21, 22, 23, 24, 25, 26, 27 }; |
| 2962 | static struct spear_muxreg mii0_1_muxreg[] = { | 2966 | static struct spear_muxreg mii0_1_muxreg[] = { |
| 2963 | { | 2967 | { |
| 2964 | .reg = PMX_CONFIG_REG, | 2968 | .reg = PMX_CONFIG_REG, |
diff --git a/drivers/pinctrl/spear/pinctrl-spear3xx.h b/drivers/pinctrl/spear/pinctrl-spear3xx.h index 31f44347f17c..7860b36053c4 100644 --- a/drivers/pinctrl/spear/pinctrl-spear3xx.h +++ b/drivers/pinctrl/spear/pinctrl-spear3xx.h | |||
| @@ -15,6 +15,7 @@ | |||
| 15 | #include "pinctrl-spear.h" | 15 | #include "pinctrl-spear.h" |
| 16 | 16 | ||
| 17 | /* pad mux declarations */ | 17 | /* pad mux declarations */ |
| 18 | #define PMX_PWM_MASK (1 << 16) | ||
| 18 | #define PMX_FIRDA_MASK (1 << 14) | 19 | #define PMX_FIRDA_MASK (1 << 14) |
| 19 | #define PMX_I2C_MASK (1 << 13) | 20 | #define PMX_I2C_MASK (1 << 13) |
| 20 | #define PMX_SSP_CS_MASK (1 << 12) | 21 | #define PMX_SSP_CS_MASK (1 << 12) |
diff --git a/drivers/rapidio/rio.c b/drivers/rapidio/rio.c index c17ae22567e0..0c6fcb461faf 100644 --- a/drivers/rapidio/rio.c +++ b/drivers/rapidio/rio.c | |||
| @@ -401,7 +401,7 @@ EXPORT_SYMBOL_GPL(rio_release_inb_pwrite); | |||
| 401 | /** | 401 | /** |
| 402 | * rio_map_inb_region -- Map inbound memory region. | 402 | * rio_map_inb_region -- Map inbound memory region. |
| 403 | * @mport: Master port. | 403 | * @mport: Master port. |
| 404 | * @lstart: physical address of memory region to be mapped | 404 | * @local: physical address of memory region to be mapped |
| 405 | * @rbase: RIO base address assigned to this window | 405 | * @rbase: RIO base address assigned to this window |
| 406 | * @size: Size of the memory region | 406 | * @size: Size of the memory region |
| 407 | * @rflags: Flags for mapping. | 407 | * @rflags: Flags for mapping. |
diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index 5c4829cba6a6..e872c8be080e 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c | |||
| @@ -1381,22 +1381,14 @@ struct regulator *regulator_get_exclusive(struct device *dev, const char *id) | |||
| 1381 | } | 1381 | } |
| 1382 | EXPORT_SYMBOL_GPL(regulator_get_exclusive); | 1382 | EXPORT_SYMBOL_GPL(regulator_get_exclusive); |
| 1383 | 1383 | ||
| 1384 | /** | 1384 | /* Locks held by regulator_put() */ |
| 1385 | * regulator_put - "free" the regulator source | 1385 | static void _regulator_put(struct regulator *regulator) |
| 1386 | * @regulator: regulator source | ||
| 1387 | * | ||
| 1388 | * Note: drivers must ensure that all regulator_enable calls made on this | ||
| 1389 | * regulator source are balanced by regulator_disable calls prior to calling | ||
| 1390 | * this function. | ||
| 1391 | */ | ||
| 1392 | void regulator_put(struct regulator *regulator) | ||
| 1393 | { | 1386 | { |
| 1394 | struct regulator_dev *rdev; | 1387 | struct regulator_dev *rdev; |
| 1395 | 1388 | ||
| 1396 | if (regulator == NULL || IS_ERR(regulator)) | 1389 | if (regulator == NULL || IS_ERR(regulator)) |
| 1397 | return; | 1390 | return; |
| 1398 | 1391 | ||
| 1399 | mutex_lock(®ulator_list_mutex); | ||
| 1400 | rdev = regulator->rdev; | 1392 | rdev = regulator->rdev; |
| 1401 | 1393 | ||
| 1402 | debugfs_remove_recursive(regulator->debugfs); | 1394 | debugfs_remove_recursive(regulator->debugfs); |
| @@ -1412,6 +1404,20 @@ void regulator_put(struct regulator *regulator) | |||
| 1412 | rdev->exclusive = 0; | 1404 | rdev->exclusive = 0; |
| 1413 | 1405 | ||
| 1414 | module_put(rdev->owner); | 1406 | module_put(rdev->owner); |
| 1407 | } | ||
| 1408 | |||
| 1409 | /** | ||
| 1410 | * regulator_put - "free" the regulator source | ||
| 1411 | * @regulator: regulator source | ||
| 1412 | * | ||
| 1413 | * Note: drivers must ensure that all regulator_enable calls made on this | ||
| 1414 | * regulator source are balanced by regulator_disable calls prior to calling | ||
| 1415 | * this function. | ||
| 1416 | */ | ||
| 1417 | void regulator_put(struct regulator *regulator) | ||
| 1418 | { | ||
| 1419 | mutex_lock(®ulator_list_mutex); | ||
| 1420 | _regulator_put(regulator); | ||
| 1415 | mutex_unlock(®ulator_list_mutex); | 1421 | mutex_unlock(®ulator_list_mutex); |
| 1416 | } | 1422 | } |
| 1417 | EXPORT_SYMBOL_GPL(regulator_put); | 1423 | EXPORT_SYMBOL_GPL(regulator_put); |
| @@ -1974,7 +1980,7 @@ int regulator_is_supported_voltage(struct regulator *regulator, | |||
| 1974 | if (!(rdev->constraints->valid_ops_mask & REGULATOR_CHANGE_VOLTAGE)) { | 1980 | if (!(rdev->constraints->valid_ops_mask & REGULATOR_CHANGE_VOLTAGE)) { |
| 1975 | ret = regulator_get_voltage(regulator); | 1981 | ret = regulator_get_voltage(regulator); |
| 1976 | if (ret >= 0) | 1982 | if (ret >= 0) |
| 1977 | return (min_uV >= ret && ret <= max_uV); | 1983 | return (min_uV <= ret && ret <= max_uV); |
| 1978 | else | 1984 | else |
| 1979 | return ret; | 1985 | return ret; |
| 1980 | } | 1986 | } |
| @@ -3365,7 +3371,7 @@ regulator_register(const struct regulator_desc *regulator_desc, | |||
| 3365 | if (ret != 0) { | 3371 | if (ret != 0) { |
| 3366 | rdev_err(rdev, "Failed to request enable GPIO%d: %d\n", | 3372 | rdev_err(rdev, "Failed to request enable GPIO%d: %d\n", |
| 3367 | config->ena_gpio, ret); | 3373 | config->ena_gpio, ret); |
| 3368 | goto clean; | 3374 | goto wash; |
| 3369 | } | 3375 | } |
| 3370 | 3376 | ||
| 3371 | rdev->ena_gpio = config->ena_gpio; | 3377 | rdev->ena_gpio = config->ena_gpio; |
| @@ -3445,10 +3451,11 @@ unset_supplies: | |||
| 3445 | 3451 | ||
| 3446 | scrub: | 3452 | scrub: |
| 3447 | if (rdev->supply) | 3453 | if (rdev->supply) |
| 3448 | regulator_put(rdev->supply); | 3454 | _regulator_put(rdev->supply); |
| 3449 | if (rdev->ena_gpio) | 3455 | if (rdev->ena_gpio) |
| 3450 | gpio_free(rdev->ena_gpio); | 3456 | gpio_free(rdev->ena_gpio); |
| 3451 | kfree(rdev->constraints); | 3457 | kfree(rdev->constraints); |
| 3458 | wash: | ||
| 3452 | device_unregister(&rdev->dev); | 3459 | device_unregister(&rdev->dev); |
| 3453 | /* device core frees rdev */ | 3460 | /* device core frees rdev */ |
| 3454 | rdev = ERR_PTR(ret); | 3461 | rdev = ERR_PTR(ret); |
diff --git a/drivers/remoteproc/remoteproc_virtio.c b/drivers/remoteproc/remoteproc_virtio.c index e7a4780e93db..9e198e590675 100644 --- a/drivers/remoteproc/remoteproc_virtio.c +++ b/drivers/remoteproc/remoteproc_virtio.c | |||
| @@ -120,15 +120,11 @@ static struct virtqueue *rp_find_vq(struct virtio_device *vdev, | |||
| 120 | return vq; | 120 | return vq; |
| 121 | } | 121 | } |
| 122 | 122 | ||
| 123 | static void rproc_virtio_del_vqs(struct virtio_device *vdev) | 123 | static void __rproc_virtio_del_vqs(struct virtio_device *vdev) |
| 124 | { | 124 | { |
| 125 | struct virtqueue *vq, *n; | 125 | struct virtqueue *vq, *n; |
| 126 | struct rproc *rproc = vdev_to_rproc(vdev); | ||
| 127 | struct rproc_vring *rvring; | 126 | struct rproc_vring *rvring; |
| 128 | 127 | ||
| 129 | /* power down the remote processor before deleting vqs */ | ||
| 130 | rproc_shutdown(rproc); | ||
| 131 | |||
| 132 | list_for_each_entry_safe(vq, n, &vdev->vqs, list) { | 128 | list_for_each_entry_safe(vq, n, &vdev->vqs, list) { |
| 133 | rvring = vq->priv; | 129 | rvring = vq->priv; |
| 134 | rvring->vq = NULL; | 130 | rvring->vq = NULL; |
| @@ -137,6 +133,16 @@ static void rproc_virtio_del_vqs(struct virtio_device *vdev) | |||
| 137 | } | 133 | } |
| 138 | } | 134 | } |
| 139 | 135 | ||
| 136 | static void rproc_virtio_del_vqs(struct virtio_device *vdev) | ||
| 137 | { | ||
| 138 | struct rproc *rproc = vdev_to_rproc(vdev); | ||
| 139 | |||
| 140 | /* power down the remote processor before deleting vqs */ | ||
| 141 | rproc_shutdown(rproc); | ||
| 142 | |||
| 143 | __rproc_virtio_del_vqs(vdev); | ||
| 144 | } | ||
| 145 | |||
| 140 | static int rproc_virtio_find_vqs(struct virtio_device *vdev, unsigned nvqs, | 146 | static int rproc_virtio_find_vqs(struct virtio_device *vdev, unsigned nvqs, |
| 141 | struct virtqueue *vqs[], | 147 | struct virtqueue *vqs[], |
| 142 | vq_callback_t *callbacks[], | 148 | vq_callback_t *callbacks[], |
| @@ -163,7 +169,7 @@ static int rproc_virtio_find_vqs(struct virtio_device *vdev, unsigned nvqs, | |||
| 163 | return 0; | 169 | return 0; |
| 164 | 170 | ||
| 165 | error: | 171 | error: |
| 166 | rproc_virtio_del_vqs(vdev); | 172 | __rproc_virtio_del_vqs(vdev); |
| 167 | return ret; | 173 | return ret; |
| 168 | } | 174 | } |
| 169 | 175 | ||
diff --git a/drivers/rtc/rtc-imxdi.c b/drivers/rtc/rtc-imxdi.c index 891cd6c61d0a..4eed51044c5d 100644 --- a/drivers/rtc/rtc-imxdi.c +++ b/drivers/rtc/rtc-imxdi.c | |||
| @@ -392,6 +392,8 @@ static int dryice_rtc_probe(struct platform_device *pdev) | |||
| 392 | if (imxdi->ioaddr == NULL) | 392 | if (imxdi->ioaddr == NULL) |
| 393 | return -ENOMEM; | 393 | return -ENOMEM; |
| 394 | 394 | ||
| 395 | spin_lock_init(&imxdi->irq_lock); | ||
| 396 | |||
| 395 | imxdi->irq = platform_get_irq(pdev, 0); | 397 | imxdi->irq = platform_get_irq(pdev, 0); |
| 396 | if (imxdi->irq < 0) | 398 | if (imxdi->irq < 0) |
| 397 | return imxdi->irq; | 399 | return imxdi->irq; |
diff --git a/drivers/rtc/rtc-tps65910.c b/drivers/rtc/rtc-tps65910.c index 7a82337e4dee..073108dcf9e7 100644 --- a/drivers/rtc/rtc-tps65910.c +++ b/drivers/rtc/rtc-tps65910.c | |||
| @@ -288,11 +288,11 @@ static int __devinit tps65910_rtc_probe(struct platform_device *pdev) | |||
| 288 | static int __devexit tps65910_rtc_remove(struct platform_device *pdev) | 288 | static int __devexit tps65910_rtc_remove(struct platform_device *pdev) |
| 289 | { | 289 | { |
| 290 | /* leave rtc running, but disable irqs */ | 290 | /* leave rtc running, but disable irqs */ |
| 291 | struct rtc_device *rtc = platform_get_drvdata(pdev); | 291 | struct tps65910_rtc *tps_rtc = platform_get_drvdata(pdev); |
| 292 | 292 | ||
| 293 | tps65910_rtc_alarm_irq_enable(&rtc->dev, 0); | 293 | tps65910_rtc_alarm_irq_enable(&pdev->dev, 0); |
| 294 | 294 | ||
| 295 | rtc_device_unregister(rtc); | 295 | rtc_device_unregister(tps_rtc->rtc); |
| 296 | return 0; | 296 | return 0; |
| 297 | } | 297 | } |
| 298 | 298 | ||
diff --git a/drivers/s390/char/con3215.c b/drivers/s390/char/con3215.c index 9ffb6d5f17aa..4ed343e4eb41 100644 --- a/drivers/s390/char/con3215.c +++ b/drivers/s390/char/con3215.c | |||
| @@ -44,7 +44,6 @@ | |||
| 44 | #define RAW3215_NR_CCWS 3 | 44 | #define RAW3215_NR_CCWS 3 |
| 45 | #define RAW3215_TIMEOUT HZ/10 /* time for delayed output */ | 45 | #define RAW3215_TIMEOUT HZ/10 /* time for delayed output */ |
| 46 | 46 | ||
| 47 | #define RAW3215_FIXED 1 /* 3215 console device is not be freed */ | ||
| 48 | #define RAW3215_WORKING 4 /* set if a request is being worked on */ | 47 | #define RAW3215_WORKING 4 /* set if a request is being worked on */ |
| 49 | #define RAW3215_THROTTLED 8 /* set if reading is disabled */ | 48 | #define RAW3215_THROTTLED 8 /* set if reading is disabled */ |
| 50 | #define RAW3215_STOPPED 16 /* set if writing is disabled */ | 49 | #define RAW3215_STOPPED 16 /* set if writing is disabled */ |
| @@ -339,8 +338,10 @@ static void raw3215_wakeup(unsigned long data) | |||
| 339 | struct tty_struct *tty; | 338 | struct tty_struct *tty; |
| 340 | 339 | ||
| 341 | tty = tty_port_tty_get(&raw->port); | 340 | tty = tty_port_tty_get(&raw->port); |
| 342 | tty_wakeup(tty); | 341 | if (tty) { |
| 343 | tty_kref_put(tty); | 342 | tty_wakeup(tty); |
| 343 | tty_kref_put(tty); | ||
| 344 | } | ||
| 344 | } | 345 | } |
| 345 | 346 | ||
| 346 | /* | 347 | /* |
| @@ -629,8 +630,7 @@ static void raw3215_shutdown(struct raw3215_info *raw) | |||
| 629 | DECLARE_WAITQUEUE(wait, current); | 630 | DECLARE_WAITQUEUE(wait, current); |
| 630 | unsigned long flags; | 631 | unsigned long flags; |
| 631 | 632 | ||
| 632 | if (!(raw->port.flags & ASYNC_INITIALIZED) || | 633 | if (!(raw->port.flags & ASYNC_INITIALIZED)) |
| 633 | (raw->flags & RAW3215_FIXED)) | ||
| 634 | return; | 634 | return; |
| 635 | /* Wait for outstanding requests, then free irq */ | 635 | /* Wait for outstanding requests, then free irq */ |
| 636 | spin_lock_irqsave(get_ccwdev_lock(raw->cdev), flags); | 636 | spin_lock_irqsave(get_ccwdev_lock(raw->cdev), flags); |
| @@ -926,8 +926,6 @@ static int __init con3215_init(void) | |||
| 926 | dev_set_drvdata(&cdev->dev, raw); | 926 | dev_set_drvdata(&cdev->dev, raw); |
| 927 | cdev->handler = raw3215_irq; | 927 | cdev->handler = raw3215_irq; |
| 928 | 928 | ||
| 929 | raw->flags |= RAW3215_FIXED; | ||
| 930 | |||
| 931 | /* Request the console irq */ | 929 | /* Request the console irq */ |
| 932 | if (raw3215_startup(raw) != 0) { | 930 | if (raw3215_startup(raw) != 0) { |
| 933 | raw3215_free_info(raw); | 931 | raw3215_free_info(raw); |
diff --git a/drivers/s390/cio/css.c b/drivers/s390/cio/css.c index b4d572f65f07..fd00afd8b850 100644 --- a/drivers/s390/cio/css.c +++ b/drivers/s390/cio/css.c | |||
| @@ -377,7 +377,11 @@ static int css_evaluate_new_subchannel(struct subchannel_id schid, int slow) | |||
| 377 | /* Will be done on the slow path. */ | 377 | /* Will be done on the slow path. */ |
| 378 | return -EAGAIN; | 378 | return -EAGAIN; |
| 379 | } | 379 | } |
| 380 | if (stsch_err(schid, &schib) || !css_sch_is_valid(&schib)) { | 380 | if (stsch_err(schid, &schib)) { |
| 381 | /* Subchannel is not provided. */ | ||
| 382 | return -ENXIO; | ||
| 383 | } | ||
| 384 | if (!css_sch_is_valid(&schib)) { | ||
| 381 | /* Unusable - ignore. */ | 385 | /* Unusable - ignore. */ |
| 382 | return 0; | 386 | return 0; |
| 383 | } | 387 | } |
| @@ -536,6 +540,7 @@ static int slow_eval_unknown_fn(struct subchannel_id schid, void *data) | |||
| 536 | case -ENOMEM: | 540 | case -ENOMEM: |
| 537 | case -EIO: | 541 | case -EIO: |
| 538 | /* These should abort looping */ | 542 | /* These should abort looping */ |
| 543 | idset_sch_del_subseq(slow_subchannel_set, schid); | ||
| 539 | break; | 544 | break; |
| 540 | default: | 545 | default: |
| 541 | rc = 0; | 546 | rc = 0; |
diff --git a/drivers/s390/cio/css.h b/drivers/s390/cio/css.h index 33bb4d891e16..4af3dfe70ef5 100644 --- a/drivers/s390/cio/css.h +++ b/drivers/s390/cio/css.h | |||
| @@ -112,9 +112,6 @@ extern int for_each_subchannel(int(*fn)(struct subchannel_id, void *), void *); | |||
| 112 | extern void css_reiterate_subchannels(void); | 112 | extern void css_reiterate_subchannels(void); |
| 113 | void css_update_ssd_info(struct subchannel *sch); | 113 | void css_update_ssd_info(struct subchannel *sch); |
| 114 | 114 | ||
| 115 | #define __MAX_SUBCHANNEL 65535 | ||
| 116 | #define __MAX_SSID 3 | ||
| 117 | |||
| 118 | struct channel_subsystem { | 115 | struct channel_subsystem { |
| 119 | u8 cssid; | 116 | u8 cssid; |
| 120 | int valid; | 117 | int valid; |
diff --git a/drivers/s390/cio/device.c b/drivers/s390/cio/device.c index fc916f5d7314..fd3143c291c6 100644 --- a/drivers/s390/cio/device.c +++ b/drivers/s390/cio/device.c | |||
| @@ -1424,7 +1424,7 @@ static enum io_sch_action sch_get_action(struct subchannel *sch) | |||
| 1424 | } | 1424 | } |
| 1425 | if (device_is_disconnected(cdev)) | 1425 | if (device_is_disconnected(cdev)) |
| 1426 | return IO_SCH_REPROBE; | 1426 | return IO_SCH_REPROBE; |
| 1427 | if (cdev->online) | 1427 | if (cdev->online && !cdev->private->flags.resuming) |
| 1428 | return IO_SCH_VERIFY; | 1428 | return IO_SCH_VERIFY; |
| 1429 | if (cdev->private->state == DEV_STATE_NOT_OPER) | 1429 | if (cdev->private->state == DEV_STATE_NOT_OPER) |
| 1430 | return IO_SCH_UNREG_ATTACH; | 1430 | return IO_SCH_UNREG_ATTACH; |
| @@ -1469,12 +1469,6 @@ static int io_subchannel_sch_event(struct subchannel *sch, int process) | |||
| 1469 | rc = 0; | 1469 | rc = 0; |
| 1470 | goto out_unlock; | 1470 | goto out_unlock; |
| 1471 | case IO_SCH_VERIFY: | 1471 | case IO_SCH_VERIFY: |
| 1472 | if (cdev->private->flags.resuming == 1) { | ||
| 1473 | if (cio_enable_subchannel(sch, (u32)(addr_t)sch)) { | ||
| 1474 | ccw_device_set_notoper(cdev); | ||
| 1475 | break; | ||
| 1476 | } | ||
| 1477 | } | ||
| 1478 | /* Trigger path verification. */ | 1472 | /* Trigger path verification. */ |
| 1479 | io_subchannel_verify(sch); | 1473 | io_subchannel_verify(sch); |
| 1480 | rc = 0; | 1474 | rc = 0; |
diff --git a/drivers/s390/cio/idset.c b/drivers/s390/cio/idset.c index e6d5f8c49524..65d13e38803f 100644 --- a/drivers/s390/cio/idset.c +++ b/drivers/s390/cio/idset.c | |||
| @@ -1,9 +1,10 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * Copyright IBM Corp. 2007 | 2 | * Copyright IBM Corp. 2007, 2012 |
| 3 | * Author(s): Peter Oberparleiter <peter.oberparleiter@de.ibm.com> | 3 | * Author(s): Peter Oberparleiter <peter.oberparleiter@de.ibm.com> |
| 4 | */ | 4 | */ |
| 5 | 5 | ||
| 6 | #include <linux/vmalloc.h> | 6 | #include <linux/vmalloc.h> |
| 7 | #include <linux/bitmap.h> | ||
| 7 | #include <linux/bitops.h> | 8 | #include <linux/bitops.h> |
| 8 | #include "idset.h" | 9 | #include "idset.h" |
| 9 | #include "css.h" | 10 | #include "css.h" |
| @@ -89,6 +90,14 @@ void idset_sch_del(struct idset *set, struct subchannel_id schid) | |||
| 89 | idset_del(set, schid.ssid, schid.sch_no); | 90 | idset_del(set, schid.ssid, schid.sch_no); |
| 90 | } | 91 | } |
| 91 | 92 | ||
| 93 | /* Clear ids starting from @schid up to end of subchannel set. */ | ||
| 94 | void idset_sch_del_subseq(struct idset *set, struct subchannel_id schid) | ||
| 95 | { | ||
| 96 | int pos = schid.ssid * set->num_id + schid.sch_no; | ||
| 97 | |||
| 98 | bitmap_clear(set->bitmap, pos, set->num_id - schid.sch_no); | ||
| 99 | } | ||
| 100 | |||
| 92 | int idset_sch_contains(struct idset *set, struct subchannel_id schid) | 101 | int idset_sch_contains(struct idset *set, struct subchannel_id schid) |
| 93 | { | 102 | { |
| 94 | return idset_contains(set, schid.ssid, schid.sch_no); | 103 | return idset_contains(set, schid.ssid, schid.sch_no); |
| @@ -111,20 +120,12 @@ int idset_sch_get_first(struct idset *set, struct subchannel_id *schid) | |||
| 111 | 120 | ||
| 112 | int idset_is_empty(struct idset *set) | 121 | int idset_is_empty(struct idset *set) |
| 113 | { | 122 | { |
| 114 | int bitnum; | 123 | return bitmap_empty(set->bitmap, set->num_ssid * set->num_id); |
| 115 | |||
| 116 | bitnum = find_first_bit(set->bitmap, set->num_ssid * set->num_id); | ||
| 117 | if (bitnum >= set->num_ssid * set->num_id) | ||
| 118 | return 1; | ||
| 119 | return 0; | ||
| 120 | } | 124 | } |
| 121 | 125 | ||
| 122 | void idset_add_set(struct idset *to, struct idset *from) | 126 | void idset_add_set(struct idset *to, struct idset *from) |
| 123 | { | 127 | { |
| 124 | unsigned long i, len; | 128 | int len = min(to->num_ssid * to->num_id, from->num_ssid * from->num_id); |
| 125 | 129 | ||
| 126 | len = min(__BITOPS_WORDS(to->num_ssid * to->num_id), | 130 | bitmap_or(to->bitmap, to->bitmap, from->bitmap, len); |
| 127 | __BITOPS_WORDS(from->num_ssid * from->num_id)); | ||
| 128 | for (i = 0; i < len ; i++) | ||
| 129 | to->bitmap[i] |= from->bitmap[i]; | ||
| 130 | } | 131 | } |
diff --git a/drivers/s390/cio/idset.h b/drivers/s390/cio/idset.h index 3d943f03591e..06d3bc01bb09 100644 --- a/drivers/s390/cio/idset.h +++ b/drivers/s390/cio/idset.h | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * Copyright IBM Corp. 2007 | 2 | * Copyright IBM Corp. 2007, 2012 |
| 3 | * Author(s): Peter Oberparleiter <peter.oberparleiter@de.ibm.com> | 3 | * Author(s): Peter Oberparleiter <peter.oberparleiter@de.ibm.com> |
| 4 | */ | 4 | */ |
| 5 | 5 | ||
| @@ -17,6 +17,7 @@ void idset_fill(struct idset *set); | |||
| 17 | struct idset *idset_sch_new(void); | 17 | struct idset *idset_sch_new(void); |
| 18 | void idset_sch_add(struct idset *set, struct subchannel_id id); | 18 | void idset_sch_add(struct idset *set, struct subchannel_id id); |
| 19 | void idset_sch_del(struct idset *set, struct subchannel_id id); | 19 | void idset_sch_del(struct idset *set, struct subchannel_id id); |
| 20 | void idset_sch_del_subseq(struct idset *set, struct subchannel_id schid); | ||
| 20 | int idset_sch_contains(struct idset *set, struct subchannel_id id); | 21 | int idset_sch_contains(struct idset *set, struct subchannel_id id); |
| 21 | int idset_sch_get_first(struct idset *set, struct subchannel_id *id); | 22 | int idset_sch_get_first(struct idset *set, struct subchannel_id *id); |
| 22 | int idset_is_empty(struct idset *set); | 23 | int idset_is_empty(struct idset *set); |
diff --git a/drivers/s390/net/qeth_core_main.c b/drivers/s390/net/qeth_core_main.c index 3e25d3150456..4d6ba00d0047 100644 --- a/drivers/s390/net/qeth_core_main.c +++ b/drivers/s390/net/qeth_core_main.c | |||
| @@ -2942,13 +2942,33 @@ static int qeth_query_ipassists_cb(struct qeth_card *card, | |||
| 2942 | QETH_DBF_TEXT(SETUP, 2, "qipasscb"); | 2942 | QETH_DBF_TEXT(SETUP, 2, "qipasscb"); |
| 2943 | 2943 | ||
| 2944 | cmd = (struct qeth_ipa_cmd *) data; | 2944 | cmd = (struct qeth_ipa_cmd *) data; |
| 2945 | |||
| 2946 | switch (cmd->hdr.return_code) { | ||
| 2947 | case IPA_RC_NOTSUPP: | ||
| 2948 | case IPA_RC_L2_UNSUPPORTED_CMD: | ||
| 2949 | QETH_DBF_TEXT(SETUP, 2, "ipaunsup"); | ||
| 2950 | card->options.ipa4.supported_funcs |= IPA_SETADAPTERPARMS; | ||
| 2951 | card->options.ipa6.supported_funcs |= IPA_SETADAPTERPARMS; | ||
| 2952 | return -0; | ||
| 2953 | default: | ||
| 2954 | if (cmd->hdr.return_code) { | ||
| 2955 | QETH_DBF_MESSAGE(1, "%s IPA_CMD_QIPASSIST: Unhandled " | ||
| 2956 | "rc=%d\n", | ||
| 2957 | dev_name(&card->gdev->dev), | ||
| 2958 | cmd->hdr.return_code); | ||
| 2959 | return 0; | ||
| 2960 | } | ||
| 2961 | } | ||
| 2962 | |||
| 2945 | if (cmd->hdr.prot_version == QETH_PROT_IPV4) { | 2963 | if (cmd->hdr.prot_version == QETH_PROT_IPV4) { |
| 2946 | card->options.ipa4.supported_funcs = cmd->hdr.ipa_supported; | 2964 | card->options.ipa4.supported_funcs = cmd->hdr.ipa_supported; |
| 2947 | card->options.ipa4.enabled_funcs = cmd->hdr.ipa_enabled; | 2965 | card->options.ipa4.enabled_funcs = cmd->hdr.ipa_enabled; |
| 2948 | } else { | 2966 | } else if (cmd->hdr.prot_version == QETH_PROT_IPV6) { |
| 2949 | card->options.ipa6.supported_funcs = cmd->hdr.ipa_supported; | 2967 | card->options.ipa6.supported_funcs = cmd->hdr.ipa_supported; |
| 2950 | card->options.ipa6.enabled_funcs = cmd->hdr.ipa_enabled; | 2968 | card->options.ipa6.enabled_funcs = cmd->hdr.ipa_enabled; |
| 2951 | } | 2969 | } else |
| 2970 | QETH_DBF_MESSAGE(1, "%s IPA_CMD_QIPASSIST: Flawed LIC detected" | ||
| 2971 | "\n", dev_name(&card->gdev->dev)); | ||
| 2952 | QETH_DBF_TEXT(SETUP, 2, "suppenbl"); | 2972 | QETH_DBF_TEXT(SETUP, 2, "suppenbl"); |
| 2953 | QETH_DBF_TEXT_(SETUP, 2, "%08x", (__u32)cmd->hdr.ipa_supported); | 2973 | QETH_DBF_TEXT_(SETUP, 2, "%08x", (__u32)cmd->hdr.ipa_supported); |
| 2954 | QETH_DBF_TEXT_(SETUP, 2, "%08x", (__u32)cmd->hdr.ipa_enabled); | 2974 | QETH_DBF_TEXT_(SETUP, 2, "%08x", (__u32)cmd->hdr.ipa_enabled); |
diff --git a/drivers/s390/net/qeth_l2_main.c b/drivers/s390/net/qeth_l2_main.c index 2db409330c21..fddb62654b6a 100644 --- a/drivers/s390/net/qeth_l2_main.c +++ b/drivers/s390/net/qeth_l2_main.c | |||
| @@ -626,10 +626,13 @@ static int qeth_l2_request_initial_mac(struct qeth_card *card) | |||
| 626 | QETH_DBF_TEXT(SETUP, 2, "doL2init"); | 626 | QETH_DBF_TEXT(SETUP, 2, "doL2init"); |
| 627 | QETH_DBF_TEXT_(SETUP, 2, "doL2%s", CARD_BUS_ID(card)); | 627 | QETH_DBF_TEXT_(SETUP, 2, "doL2%s", CARD_BUS_ID(card)); |
| 628 | 628 | ||
| 629 | rc = qeth_query_setadapterparms(card); | 629 | if (qeth_is_supported(card, IPA_SETADAPTERPARMS)) { |
| 630 | if (rc) { | 630 | rc = qeth_query_setadapterparms(card); |
| 631 | QETH_DBF_MESSAGE(2, "could not query adapter parameters on " | 631 | if (rc) { |
| 632 | "device %s: x%x\n", CARD_BUS_ID(card), rc); | 632 | QETH_DBF_MESSAGE(2, "could not query adapter " |
| 633 | "parameters on device %s: x%x\n", | ||
| 634 | CARD_BUS_ID(card), rc); | ||
| 635 | } | ||
| 633 | } | 636 | } |
| 634 | 637 | ||
| 635 | if (card->info.type == QETH_CARD_TYPE_IQD || | 638 | if (card->info.type == QETH_CARD_TYPE_IQD || |
| @@ -676,7 +679,7 @@ static int qeth_l2_set_mac_address(struct net_device *dev, void *p) | |||
| 676 | return -ERESTARTSYS; | 679 | return -ERESTARTSYS; |
| 677 | } | 680 | } |
| 678 | rc = qeth_l2_send_delmac(card, &card->dev->dev_addr[0]); | 681 | rc = qeth_l2_send_delmac(card, &card->dev->dev_addr[0]); |
| 679 | if (!rc) | 682 | if (!rc || (rc == IPA_RC_L2_MAC_NOT_FOUND)) |
| 680 | rc = qeth_l2_send_setmac(card, addr->sa_data); | 683 | rc = qeth_l2_send_setmac(card, addr->sa_data); |
| 681 | return rc ? -EINVAL : 0; | 684 | return rc ? -EINVAL : 0; |
| 682 | } | 685 | } |
| @@ -1141,11 +1144,12 @@ static int qeth_l2_recover(void *ptr) | |||
| 1141 | dev_info(&card->gdev->dev, | 1144 | dev_info(&card->gdev->dev, |
| 1142 | "Device successfully recovered!\n"); | 1145 | "Device successfully recovered!\n"); |
| 1143 | else { | 1146 | else { |
| 1144 | rtnl_lock(); | 1147 | if (rtnl_trylock()) { |
| 1145 | dev_close(card->dev); | 1148 | dev_close(card->dev); |
| 1146 | rtnl_unlock(); | 1149 | rtnl_unlock(); |
| 1147 | dev_warn(&card->gdev->dev, "The qeth device driver " | 1150 | dev_warn(&card->gdev->dev, "The qeth device driver " |
| 1148 | "failed to recover an error on the device\n"); | 1151 | "failed to recover an error on the device\n"); |
| 1152 | } | ||
| 1149 | } | 1153 | } |
| 1150 | qeth_clear_thread_start_bit(card, QETH_RECOVER_THREAD); | 1154 | qeth_clear_thread_start_bit(card, QETH_RECOVER_THREAD); |
| 1151 | qeth_clear_thread_running_bit(card, QETH_RECOVER_THREAD); | 1155 | qeth_clear_thread_running_bit(card, QETH_RECOVER_THREAD); |
diff --git a/drivers/s390/net/qeth_l3_main.c b/drivers/s390/net/qeth_l3_main.c index 4cd310cb5bdf..5ba390658498 100644 --- a/drivers/s390/net/qeth_l3_main.c +++ b/drivers/s390/net/qeth_l3_main.c | |||
| @@ -3510,11 +3510,12 @@ static int qeth_l3_recover(void *ptr) | |||
| 3510 | dev_info(&card->gdev->dev, | 3510 | dev_info(&card->gdev->dev, |
| 3511 | "Device successfully recovered!\n"); | 3511 | "Device successfully recovered!\n"); |
| 3512 | else { | 3512 | else { |
| 3513 | rtnl_lock(); | 3513 | if (rtnl_trylock()) { |
| 3514 | dev_close(card->dev); | 3514 | dev_close(card->dev); |
| 3515 | rtnl_unlock(); | 3515 | rtnl_unlock(); |
| 3516 | dev_warn(&card->gdev->dev, "The qeth device driver " | 3516 | dev_warn(&card->gdev->dev, "The qeth device driver " |
| 3517 | "failed to recover an error on the device\n"); | 3517 | "failed to recover an error on the device\n"); |
| 3518 | } | ||
| 3518 | } | 3519 | } |
| 3519 | qeth_clear_thread_start_bit(card, QETH_RECOVER_THREAD); | 3520 | qeth_clear_thread_start_bit(card, QETH_RECOVER_THREAD); |
| 3520 | qeth_clear_thread_running_bit(card, QETH_RECOVER_THREAD); | 3521 | qeth_clear_thread_running_bit(card, QETH_RECOVER_THREAD); |
diff --git a/drivers/s390/net/smsgiucv.c b/drivers/s390/net/smsgiucv.c index 207b7d742443..d8f990b6b332 100644 --- a/drivers/s390/net/smsgiucv.c +++ b/drivers/s390/net/smsgiucv.c | |||
| @@ -157,7 +157,7 @@ static int smsg_pm_restore_thaw(struct device *dev) | |||
| 157 | #ifdef CONFIG_PM_DEBUG | 157 | #ifdef CONFIG_PM_DEBUG |
| 158 | printk(KERN_WARNING "smsg_pm_restore_thaw\n"); | 158 | printk(KERN_WARNING "smsg_pm_restore_thaw\n"); |
| 159 | #endif | 159 | #endif |
| 160 | if (smsg_path && iucv_path_connected) { | 160 | if (smsg_path && !iucv_path_connected) { |
| 161 | memset(smsg_path, 0, sizeof(*smsg_path)); | 161 | memset(smsg_path, 0, sizeof(*smsg_path)); |
| 162 | smsg_path->msglim = 255; | 162 | smsg_path->msglim = 255; |
| 163 | smsg_path->flags = 0; | 163 | smsg_path->flags = 0; |
diff --git a/drivers/scsi/arm/fas216.c b/drivers/scsi/arm/fas216.c index 6206a666a8ec..737554c37d9e 100644 --- a/drivers/scsi/arm/fas216.c +++ b/drivers/scsi/arm/fas216.c | |||
| @@ -179,6 +179,7 @@ static void print_SCp(struct scsi_pointer *SCp, const char *prefix, const char * | |||
| 179 | SCp->buffers_residual, suffix); | 179 | SCp->buffers_residual, suffix); |
| 180 | } | 180 | } |
| 181 | 181 | ||
| 182 | #ifdef CHECK_STRUCTURE | ||
| 182 | static void fas216_dumpinfo(FAS216_Info *info) | 183 | static void fas216_dumpinfo(FAS216_Info *info) |
| 183 | { | 184 | { |
| 184 | static int used = 0; | 185 | static int used = 0; |
| @@ -223,7 +224,6 @@ static void fas216_dumpinfo(FAS216_Info *info) | |||
| 223 | info->internal_done, info->magic_end); | 224 | info->internal_done, info->magic_end); |
| 224 | } | 225 | } |
| 225 | 226 | ||
| 226 | #ifdef CHECK_STRUCTURE | ||
| 227 | static void __fas216_checkmagic(FAS216_Info *info, const char *func) | 227 | static void __fas216_checkmagic(FAS216_Info *info, const char *func) |
| 228 | { | 228 | { |
| 229 | int corruption = 0; | 229 | int corruption = 0; |
diff --git a/drivers/scsi/arm/oak.c b/drivers/scsi/arm/oak.c index d25f944b59c2..fc6a5aabf66e 100644 --- a/drivers/scsi/arm/oak.c +++ b/drivers/scsi/arm/oak.c | |||
| @@ -21,6 +21,7 @@ | |||
| 21 | /*#define PSEUDO_DMA*/ | 21 | /*#define PSEUDO_DMA*/ |
| 22 | 22 | ||
| 23 | #define OAKSCSI_PUBLIC_RELEASE 1 | 23 | #define OAKSCSI_PUBLIC_RELEASE 1 |
| 24 | #define DONT_USE_INTR | ||
| 24 | 25 | ||
| 25 | #define priv(host) ((struct NCR5380_hostdata *)(host)->hostdata) | 26 | #define priv(host) ((struct NCR5380_hostdata *)(host)->hostdata) |
| 26 | #define NCR5380_local_declare() void __iomem *_base | 27 | #define NCR5380_local_declare() void __iomem *_base |
diff --git a/drivers/scsi/isci/request.c b/drivers/scsi/isci/request.c index c1bafc3f3fb1..9594ab62702b 100644 --- a/drivers/scsi/isci/request.c +++ b/drivers/scsi/isci/request.c | |||
| @@ -1972,7 +1972,7 @@ sci_io_request_frame_handler(struct isci_request *ireq, | |||
| 1972 | frame_index, | 1972 | frame_index, |
| 1973 | (void **)&frame_buffer); | 1973 | (void **)&frame_buffer); |
| 1974 | 1974 | ||
| 1975 | sci_controller_copy_sata_response(&ireq->stp.req, | 1975 | sci_controller_copy_sata_response(&ireq->stp.rsp, |
| 1976 | frame_header, | 1976 | frame_header, |
| 1977 | frame_buffer); | 1977 | frame_buffer); |
| 1978 | 1978 | ||
diff --git a/drivers/scsi/megaraid/megaraid_sas.h b/drivers/scsi/megaraid/megaraid_sas.h index 16b7a72a70c4..3b2365c8eab2 100644 --- a/drivers/scsi/megaraid/megaraid_sas.h +++ b/drivers/scsi/megaraid/megaraid_sas.h | |||
| @@ -1276,7 +1276,7 @@ struct megasas_evt_detail { | |||
| 1276 | } __attribute__ ((packed)); | 1276 | } __attribute__ ((packed)); |
| 1277 | 1277 | ||
| 1278 | struct megasas_aen_event { | 1278 | struct megasas_aen_event { |
| 1279 | struct work_struct hotplug_work; | 1279 | struct delayed_work hotplug_work; |
| 1280 | struct megasas_instance *instance; | 1280 | struct megasas_instance *instance; |
| 1281 | }; | 1281 | }; |
| 1282 | 1282 | ||
diff --git a/drivers/scsi/megaraid/megaraid_sas_base.c b/drivers/scsi/megaraid/megaraid_sas_base.c index d2c5366aff7f..e4f2baacf1e1 100644 --- a/drivers/scsi/megaraid/megaraid_sas_base.c +++ b/drivers/scsi/megaraid/megaraid_sas_base.c | |||
| @@ -2060,9 +2060,9 @@ megasas_service_aen(struct megasas_instance *instance, struct megasas_cmd *cmd) | |||
| 2060 | } else { | 2060 | } else { |
| 2061 | ev->instance = instance; | 2061 | ev->instance = instance; |
| 2062 | instance->ev = ev; | 2062 | instance->ev = ev; |
| 2063 | INIT_WORK(&ev->hotplug_work, megasas_aen_polling); | 2063 | INIT_DELAYED_WORK(&ev->hotplug_work, |
| 2064 | schedule_delayed_work( | 2064 | megasas_aen_polling); |
| 2065 | (struct delayed_work *)&ev->hotplug_work, 0); | 2065 | schedule_delayed_work(&ev->hotplug_work, 0); |
| 2066 | } | 2066 | } |
| 2067 | } | 2067 | } |
| 2068 | } | 2068 | } |
| @@ -4352,8 +4352,7 @@ megasas_suspend(struct pci_dev *pdev, pm_message_t state) | |||
| 4352 | /* cancel the delayed work if this work still in queue */ | 4352 | /* cancel the delayed work if this work still in queue */ |
| 4353 | if (instance->ev != NULL) { | 4353 | if (instance->ev != NULL) { |
| 4354 | struct megasas_aen_event *ev = instance->ev; | 4354 | struct megasas_aen_event *ev = instance->ev; |
| 4355 | cancel_delayed_work_sync( | 4355 | cancel_delayed_work_sync(&ev->hotplug_work); |
| 4356 | (struct delayed_work *)&ev->hotplug_work); | ||
| 4357 | instance->ev = NULL; | 4356 | instance->ev = NULL; |
| 4358 | } | 4357 | } |
| 4359 | 4358 | ||
| @@ -4545,8 +4544,7 @@ static void __devexit megasas_detach_one(struct pci_dev *pdev) | |||
| 4545 | /* cancel the delayed work if this work still in queue*/ | 4544 | /* cancel the delayed work if this work still in queue*/ |
| 4546 | if (instance->ev != NULL) { | 4545 | if (instance->ev != NULL) { |
| 4547 | struct megasas_aen_event *ev = instance->ev; | 4546 | struct megasas_aen_event *ev = instance->ev; |
| 4548 | cancel_delayed_work_sync( | 4547 | cancel_delayed_work_sync(&ev->hotplug_work); |
| 4549 | (struct delayed_work *)&ev->hotplug_work); | ||
| 4550 | instance->ev = NULL; | 4548 | instance->ev = NULL; |
| 4551 | } | 4549 | } |
| 4552 | 4550 | ||
| @@ -5190,7 +5188,7 @@ static void | |||
| 5190 | megasas_aen_polling(struct work_struct *work) | 5188 | megasas_aen_polling(struct work_struct *work) |
| 5191 | { | 5189 | { |
| 5192 | struct megasas_aen_event *ev = | 5190 | struct megasas_aen_event *ev = |
| 5193 | container_of(work, struct megasas_aen_event, hotplug_work); | 5191 | container_of(work, struct megasas_aen_event, hotplug_work.work); |
| 5194 | struct megasas_instance *instance = ev->instance; | 5192 | struct megasas_instance *instance = ev->instance; |
| 5195 | union megasas_evt_class_locale class_locale; | 5193 | union megasas_evt_class_locale class_locale; |
| 5196 | struct Scsi_Host *host; | 5194 | struct Scsi_Host *host; |
diff --git a/drivers/scsi/qla2xxx/qla_mid.c b/drivers/scsi/qla2xxx/qla_mid.c index bd4708a422cd..20fd974f903a 100644 --- a/drivers/scsi/qla2xxx/qla_mid.c +++ b/drivers/scsi/qla2xxx/qla_mid.c | |||
| @@ -149,6 +149,7 @@ qla2x00_mark_vp_devices_dead(scsi_qla_host_t *vha) | |||
| 149 | int | 149 | int |
| 150 | qla24xx_disable_vp(scsi_qla_host_t *vha) | 150 | qla24xx_disable_vp(scsi_qla_host_t *vha) |
| 151 | { | 151 | { |
| 152 | unsigned long flags; | ||
| 152 | int ret; | 153 | int ret; |
| 153 | 154 | ||
| 154 | ret = qla24xx_control_vp(vha, VCE_COMMAND_DISABLE_VPS_LOGO_ALL); | 155 | ret = qla24xx_control_vp(vha, VCE_COMMAND_DISABLE_VPS_LOGO_ALL); |
| @@ -156,7 +157,9 @@ qla24xx_disable_vp(scsi_qla_host_t *vha) | |||
| 156 | atomic_set(&vha->loop_down_timer, LOOP_DOWN_TIME); | 157 | atomic_set(&vha->loop_down_timer, LOOP_DOWN_TIME); |
| 157 | 158 | ||
| 158 | /* Remove port id from vp target map */ | 159 | /* Remove port id from vp target map */ |
| 160 | spin_lock_irqsave(&vha->hw->vport_slock, flags); | ||
| 159 | qlt_update_vp_map(vha, RESET_AL_PA); | 161 | qlt_update_vp_map(vha, RESET_AL_PA); |
| 162 | spin_unlock_irqrestore(&vha->hw->vport_slock, flags); | ||
| 160 | 163 | ||
| 161 | qla2x00_mark_vp_devices_dead(vha); | 164 | qla2x00_mark_vp_devices_dead(vha); |
| 162 | atomic_set(&vha->vp_state, VP_FAILED); | 165 | atomic_set(&vha->vp_state, VP_FAILED); |
diff --git a/drivers/scsi/qla2xxx/qla_target.c b/drivers/scsi/qla2xxx/qla_target.c index 0e09d8f433d1..62aa5584f644 100644 --- a/drivers/scsi/qla2xxx/qla_target.c +++ b/drivers/scsi/qla2xxx/qla_target.c | |||
| @@ -557,6 +557,7 @@ static bool qlt_check_fcport_exist(struct scsi_qla_host *vha, | |||
| 557 | int pmap_len; | 557 | int pmap_len; |
| 558 | fc_port_t *fcport; | 558 | fc_port_t *fcport; |
| 559 | int global_resets; | 559 | int global_resets; |
| 560 | unsigned long flags; | ||
| 560 | 561 | ||
| 561 | retry: | 562 | retry: |
| 562 | global_resets = atomic_read(&ha->tgt.qla_tgt->tgt_global_resets_count); | 563 | global_resets = atomic_read(&ha->tgt.qla_tgt->tgt_global_resets_count); |
| @@ -625,10 +626,10 @@ retry: | |||
| 625 | sess->s_id.b.area, sess->loop_id, fcport->d_id.b.domain, | 626 | sess->s_id.b.area, sess->loop_id, fcport->d_id.b.domain, |
| 626 | fcport->d_id.b.al_pa, fcport->d_id.b.area, fcport->loop_id); | 627 | fcport->d_id.b.al_pa, fcport->d_id.b.area, fcport->loop_id); |
| 627 | 628 | ||
| 628 | sess->s_id = fcport->d_id; | 629 | spin_lock_irqsave(&ha->hardware_lock, flags); |
| 629 | sess->loop_id = fcport->loop_id; | 630 | ha->tgt.tgt_ops->update_sess(sess, fcport->d_id, fcport->loop_id, |
| 630 | sess->conf_compl_supported = !!(fcport->flags & | 631 | (fcport->flags & FCF_CONF_COMP_SUPPORTED)); |
| 631 | FCF_CONF_COMP_SUPPORTED); | 632 | spin_unlock_irqrestore(&ha->hardware_lock, flags); |
| 632 | 633 | ||
| 633 | res = true; | 634 | res = true; |
| 634 | 635 | ||
| @@ -740,10 +741,9 @@ static struct qla_tgt_sess *qlt_create_sess( | |||
| 740 | qlt_undelete_sess(sess); | 741 | qlt_undelete_sess(sess); |
| 741 | 742 | ||
| 742 | kref_get(&sess->se_sess->sess_kref); | 743 | kref_get(&sess->se_sess->sess_kref); |
| 743 | sess->s_id = fcport->d_id; | 744 | ha->tgt.tgt_ops->update_sess(sess, fcport->d_id, fcport->loop_id, |
| 744 | sess->loop_id = fcport->loop_id; | 745 | (fcport->flags & FCF_CONF_COMP_SUPPORTED)); |
| 745 | sess->conf_compl_supported = !!(fcport->flags & | 746 | |
| 746 | FCF_CONF_COMP_SUPPORTED); | ||
| 747 | if (sess->local && !local) | 747 | if (sess->local && !local) |
| 748 | sess->local = 0; | 748 | sess->local = 0; |
| 749 | spin_unlock_irqrestore(&ha->hardware_lock, flags); | 749 | spin_unlock_irqrestore(&ha->hardware_lock, flags); |
| @@ -796,8 +796,7 @@ static struct qla_tgt_sess *qlt_create_sess( | |||
| 796 | */ | 796 | */ |
| 797 | kref_get(&sess->se_sess->sess_kref); | 797 | kref_get(&sess->se_sess->sess_kref); |
| 798 | 798 | ||
| 799 | sess->conf_compl_supported = !!(fcport->flags & | 799 | sess->conf_compl_supported = (fcport->flags & FCF_CONF_COMP_SUPPORTED); |
| 800 | FCF_CONF_COMP_SUPPORTED); | ||
| 801 | BUILD_BUG_ON(sizeof(sess->port_name) != sizeof(fcport->port_name)); | 800 | BUILD_BUG_ON(sizeof(sess->port_name) != sizeof(fcport->port_name)); |
| 802 | memcpy(sess->port_name, fcport->port_name, sizeof(sess->port_name)); | 801 | memcpy(sess->port_name, fcport->port_name, sizeof(sess->port_name)); |
| 803 | 802 | ||
| @@ -869,10 +868,8 @@ void qlt_fc_port_added(struct scsi_qla_host *vha, fc_port_t *fcport) | |||
| 869 | ql_dbg(ql_dbg_tgt_mgt, vha, 0xf007, | 868 | ql_dbg(ql_dbg_tgt_mgt, vha, 0xf007, |
| 870 | "Reappeared sess %p\n", sess); | 869 | "Reappeared sess %p\n", sess); |
| 871 | } | 870 | } |
| 872 | sess->s_id = fcport->d_id; | 871 | ha->tgt.tgt_ops->update_sess(sess, fcport->d_id, fcport->loop_id, |
| 873 | sess->loop_id = fcport->loop_id; | 872 | (fcport->flags & FCF_CONF_COMP_SUPPORTED)); |
| 874 | sess->conf_compl_supported = !!(fcport->flags & | ||
| 875 | FCF_CONF_COMP_SUPPORTED); | ||
| 876 | } | 873 | } |
| 877 | 874 | ||
| 878 | if (sess && sess->local) { | 875 | if (sess && sess->local) { |
diff --git a/drivers/scsi/qla2xxx/qla_target.h b/drivers/scsi/qla2xxx/qla_target.h index 170af1571214..bad749561ec2 100644 --- a/drivers/scsi/qla2xxx/qla_target.h +++ b/drivers/scsi/qla2xxx/qla_target.h | |||
| @@ -648,6 +648,7 @@ struct qla_tgt_func_tmpl { | |||
| 648 | 648 | ||
| 649 | int (*check_initiator_node_acl)(struct scsi_qla_host *, unsigned char *, | 649 | int (*check_initiator_node_acl)(struct scsi_qla_host *, unsigned char *, |
| 650 | void *, uint8_t *, uint16_t); | 650 | void *, uint8_t *, uint16_t); |
| 651 | void (*update_sess)(struct qla_tgt_sess *, port_id_t, uint16_t, bool); | ||
| 651 | struct qla_tgt_sess *(*find_sess_by_loop_id)(struct scsi_qla_host *, | 652 | struct qla_tgt_sess *(*find_sess_by_loop_id)(struct scsi_qla_host *, |
| 652 | const uint16_t); | 653 | const uint16_t); |
| 653 | struct qla_tgt_sess *(*find_sess_by_s_id)(struct scsi_qla_host *, | 654 | struct qla_tgt_sess *(*find_sess_by_s_id)(struct scsi_qla_host *, |
diff --git a/drivers/scsi/qla2xxx/tcm_qla2xxx.c b/drivers/scsi/qla2xxx/tcm_qla2xxx.c index 2358c16c4c8e..3d74f2f39ae1 100644 --- a/drivers/scsi/qla2xxx/tcm_qla2xxx.c +++ b/drivers/scsi/qla2xxx/tcm_qla2xxx.c | |||
| @@ -237,7 +237,7 @@ static char *tcm_qla2xxx_get_fabric_wwn(struct se_portal_group *se_tpg) | |||
| 237 | struct tcm_qla2xxx_tpg, se_tpg); | 237 | struct tcm_qla2xxx_tpg, se_tpg); |
| 238 | struct tcm_qla2xxx_lport *lport = tpg->lport; | 238 | struct tcm_qla2xxx_lport *lport = tpg->lport; |
| 239 | 239 | ||
| 240 | return &lport->lport_name[0]; | 240 | return lport->lport_naa_name; |
| 241 | } | 241 | } |
| 242 | 242 | ||
| 243 | static char *tcm_qla2xxx_npiv_get_fabric_wwn(struct se_portal_group *se_tpg) | 243 | static char *tcm_qla2xxx_npiv_get_fabric_wwn(struct se_portal_group *se_tpg) |
| @@ -1457,6 +1457,78 @@ static int tcm_qla2xxx_check_initiator_node_acl( | |||
| 1457 | return 0; | 1457 | return 0; |
| 1458 | } | 1458 | } |
| 1459 | 1459 | ||
| 1460 | static void tcm_qla2xxx_update_sess(struct qla_tgt_sess *sess, port_id_t s_id, | ||
| 1461 | uint16_t loop_id, bool conf_compl_supported) | ||
| 1462 | { | ||
| 1463 | struct qla_tgt *tgt = sess->tgt; | ||
| 1464 | struct qla_hw_data *ha = tgt->ha; | ||
| 1465 | struct tcm_qla2xxx_lport *lport = ha->tgt.target_lport_ptr; | ||
| 1466 | struct se_node_acl *se_nacl = sess->se_sess->se_node_acl; | ||
| 1467 | struct tcm_qla2xxx_nacl *nacl = container_of(se_nacl, | ||
| 1468 | struct tcm_qla2xxx_nacl, se_node_acl); | ||
| 1469 | u32 key; | ||
| 1470 | |||
| 1471 | |||
| 1472 | if (sess->loop_id != loop_id || sess->s_id.b24 != s_id.b24) | ||
| 1473 | pr_info("Updating session %p from port %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x loop_id %d -> %d s_id %x:%x:%x -> %x:%x:%x\n", | ||
| 1474 | sess, | ||
| 1475 | sess->port_name[0], sess->port_name[1], | ||
| 1476 | sess->port_name[2], sess->port_name[3], | ||
| 1477 | sess->port_name[4], sess->port_name[5], | ||
| 1478 | sess->port_name[6], sess->port_name[7], | ||
| 1479 | sess->loop_id, loop_id, | ||
| 1480 | sess->s_id.b.domain, sess->s_id.b.area, sess->s_id.b.al_pa, | ||
| 1481 | s_id.b.domain, s_id.b.area, s_id.b.al_pa); | ||
| 1482 | |||
| 1483 | if (sess->loop_id != loop_id) { | ||
| 1484 | /* | ||
| 1485 | * Because we can shuffle loop IDs around and we | ||
| 1486 | * update different sessions non-atomically, we might | ||
| 1487 | * have overwritten this session's old loop ID | ||
| 1488 | * already, and we might end up overwriting some other | ||
| 1489 | * session that will be updated later. So we have to | ||
| 1490 | * be extra careful and we can't warn about those things... | ||
| 1491 | */ | ||
| 1492 | if (lport->lport_loopid_map[sess->loop_id].se_nacl == se_nacl) | ||
| 1493 | lport->lport_loopid_map[sess->loop_id].se_nacl = NULL; | ||
| 1494 | |||
| 1495 | lport->lport_loopid_map[loop_id].se_nacl = se_nacl; | ||
| 1496 | |||
| 1497 | sess->loop_id = loop_id; | ||
| 1498 | } | ||
| 1499 | |||
| 1500 | if (sess->s_id.b24 != s_id.b24) { | ||
| 1501 | key = (((u32) sess->s_id.b.domain << 16) | | ||
| 1502 | ((u32) sess->s_id.b.area << 8) | | ||
| 1503 | ((u32) sess->s_id.b.al_pa)); | ||
| 1504 | |||
| 1505 | if (btree_lookup32(&lport->lport_fcport_map, key)) | ||
| 1506 | WARN(btree_remove32(&lport->lport_fcport_map, key) != se_nacl, | ||
| 1507 | "Found wrong se_nacl when updating s_id %x:%x:%x\n", | ||
| 1508 | sess->s_id.b.domain, sess->s_id.b.area, sess->s_id.b.al_pa); | ||
| 1509 | else | ||
| 1510 | WARN(1, "No lport_fcport_map entry for s_id %x:%x:%x\n", | ||
| 1511 | sess->s_id.b.domain, sess->s_id.b.area, sess->s_id.b.al_pa); | ||
| 1512 | |||
| 1513 | key = (((u32) s_id.b.domain << 16) | | ||
| 1514 | ((u32) s_id.b.area << 8) | | ||
| 1515 | ((u32) s_id.b.al_pa)); | ||
| 1516 | |||
| 1517 | if (btree_lookup32(&lport->lport_fcport_map, key)) { | ||
| 1518 | WARN(1, "Already have lport_fcport_map entry for s_id %x:%x:%x\n", | ||
| 1519 | s_id.b.domain, s_id.b.area, s_id.b.al_pa); | ||
| 1520 | btree_update32(&lport->lport_fcport_map, key, se_nacl); | ||
| 1521 | } else { | ||
| 1522 | btree_insert32(&lport->lport_fcport_map, key, se_nacl, GFP_ATOMIC); | ||
| 1523 | } | ||
| 1524 | |||
| 1525 | sess->s_id = s_id; | ||
| 1526 | nacl->nport_id = key; | ||
| 1527 | } | ||
| 1528 | |||
| 1529 | sess->conf_compl_supported = conf_compl_supported; | ||
| 1530 | } | ||
| 1531 | |||
| 1460 | /* | 1532 | /* |
| 1461 | * Calls into tcm_qla2xxx used by qla2xxx LLD I/O path. | 1533 | * Calls into tcm_qla2xxx used by qla2xxx LLD I/O path. |
| 1462 | */ | 1534 | */ |
| @@ -1467,6 +1539,7 @@ static struct qla_tgt_func_tmpl tcm_qla2xxx_template = { | |||
| 1467 | .free_cmd = tcm_qla2xxx_free_cmd, | 1539 | .free_cmd = tcm_qla2xxx_free_cmd, |
| 1468 | .free_mcmd = tcm_qla2xxx_free_mcmd, | 1540 | .free_mcmd = tcm_qla2xxx_free_mcmd, |
| 1469 | .free_session = tcm_qla2xxx_free_session, | 1541 | .free_session = tcm_qla2xxx_free_session, |
| 1542 | .update_sess = tcm_qla2xxx_update_sess, | ||
| 1470 | .check_initiator_node_acl = tcm_qla2xxx_check_initiator_node_acl, | 1543 | .check_initiator_node_acl = tcm_qla2xxx_check_initiator_node_acl, |
| 1471 | .find_sess_by_s_id = tcm_qla2xxx_find_sess_by_s_id, | 1544 | .find_sess_by_s_id = tcm_qla2xxx_find_sess_by_s_id, |
| 1472 | .find_sess_by_loop_id = tcm_qla2xxx_find_sess_by_loop_id, | 1545 | .find_sess_by_loop_id = tcm_qla2xxx_find_sess_by_loop_id, |
| @@ -1534,6 +1607,7 @@ static struct se_wwn *tcm_qla2xxx_make_lport( | |||
| 1534 | lport->lport_wwpn = wwpn; | 1607 | lport->lport_wwpn = wwpn; |
| 1535 | tcm_qla2xxx_format_wwn(&lport->lport_name[0], TCM_QLA2XXX_NAMELEN, | 1608 | tcm_qla2xxx_format_wwn(&lport->lport_name[0], TCM_QLA2XXX_NAMELEN, |
| 1536 | wwpn); | 1609 | wwpn); |
| 1610 | sprintf(lport->lport_naa_name, "naa.%016llx", (unsigned long long) wwpn); | ||
| 1537 | 1611 | ||
| 1538 | ret = tcm_qla2xxx_init_lport(lport); | 1612 | ret = tcm_qla2xxx_init_lport(lport); |
| 1539 | if (ret != 0) | 1613 | if (ret != 0) |
| @@ -1601,6 +1675,7 @@ static struct se_wwn *tcm_qla2xxx_npiv_make_lport( | |||
| 1601 | lport->lport_npiv_wwnn = npiv_wwnn; | 1675 | lport->lport_npiv_wwnn = npiv_wwnn; |
| 1602 | tcm_qla2xxx_npiv_format_wwn(&lport->lport_npiv_name[0], | 1676 | tcm_qla2xxx_npiv_format_wwn(&lport->lport_npiv_name[0], |
| 1603 | TCM_QLA2XXX_NAMELEN, npiv_wwpn, npiv_wwnn); | 1677 | TCM_QLA2XXX_NAMELEN, npiv_wwpn, npiv_wwnn); |
| 1678 | sprintf(lport->lport_naa_name, "naa.%016llx", (unsigned long long) npiv_wwpn); | ||
| 1604 | 1679 | ||
| 1605 | /* FIXME: tcm_qla2xxx_npiv_make_lport */ | 1680 | /* FIXME: tcm_qla2xxx_npiv_make_lport */ |
| 1606 | ret = -ENOSYS; | 1681 | ret = -ENOSYS; |
diff --git a/drivers/scsi/qla2xxx/tcm_qla2xxx.h b/drivers/scsi/qla2xxx/tcm_qla2xxx.h index 825498103352..9ba075fe9781 100644 --- a/drivers/scsi/qla2xxx/tcm_qla2xxx.h +++ b/drivers/scsi/qla2xxx/tcm_qla2xxx.h | |||
| @@ -61,6 +61,8 @@ struct tcm_qla2xxx_lport { | |||
| 61 | u64 lport_npiv_wwnn; | 61 | u64 lport_npiv_wwnn; |
| 62 | /* ASCII formatted WWPN for FC Target Lport */ | 62 | /* ASCII formatted WWPN for FC Target Lport */ |
| 63 | char lport_name[TCM_QLA2XXX_NAMELEN]; | 63 | char lport_name[TCM_QLA2XXX_NAMELEN]; |
| 64 | /* ASCII formatted naa WWPN for VPD page 83 etc */ | ||
| 65 | char lport_naa_name[TCM_QLA2XXX_NAMELEN]; | ||
| 64 | /* ASCII formatted WWPN+WWNN for NPIV FC Target Lport */ | 66 | /* ASCII formatted WWPN+WWNN for NPIV FC Target Lport */ |
| 65 | char lport_npiv_name[TCM_QLA2XXX_NPIV_NAMELEN]; | 67 | char lport_npiv_name[TCM_QLA2XXX_NPIV_NAMELEN]; |
| 66 | /* map for fc_port pointers in 24-bit FC Port ID space */ | 68 | /* map for fc_port pointers in 24-bit FC Port ID space */ |
diff --git a/drivers/scsi/qlogicpti.c b/drivers/scsi/qlogicpti.c index b191dd549207..71fddbc60f18 100644 --- a/drivers/scsi/qlogicpti.c +++ b/drivers/scsi/qlogicpti.c | |||
| @@ -1294,26 +1294,19 @@ static struct scsi_host_template qpti_template = { | |||
| 1294 | static const struct of_device_id qpti_match[]; | 1294 | static const struct of_device_id qpti_match[]; |
| 1295 | static int __devinit qpti_sbus_probe(struct platform_device *op) | 1295 | static int __devinit qpti_sbus_probe(struct platform_device *op) |
| 1296 | { | 1296 | { |
| 1297 | const struct of_device_id *match; | ||
| 1298 | struct scsi_host_template *tpnt; | ||
| 1299 | struct device_node *dp = op->dev.of_node; | 1297 | struct device_node *dp = op->dev.of_node; |
| 1300 | struct Scsi_Host *host; | 1298 | struct Scsi_Host *host; |
| 1301 | struct qlogicpti *qpti; | 1299 | struct qlogicpti *qpti; |
| 1302 | static int nqptis; | 1300 | static int nqptis; |
| 1303 | const char *fcode; | 1301 | const char *fcode; |
| 1304 | 1302 | ||
| 1305 | match = of_match_device(qpti_match, &op->dev); | ||
| 1306 | if (!match) | ||
| 1307 | return -EINVAL; | ||
| 1308 | tpnt = match->data; | ||
| 1309 | |||
| 1310 | /* Sometimes Antares cards come up not completely | 1303 | /* Sometimes Antares cards come up not completely |
| 1311 | * setup, and we get a report of a zero IRQ. | 1304 | * setup, and we get a report of a zero IRQ. |
| 1312 | */ | 1305 | */ |
| 1313 | if (op->archdata.irqs[0] == 0) | 1306 | if (op->archdata.irqs[0] == 0) |
| 1314 | return -ENODEV; | 1307 | return -ENODEV; |
| 1315 | 1308 | ||
| 1316 | host = scsi_host_alloc(tpnt, sizeof(struct qlogicpti)); | 1309 | host = scsi_host_alloc(&qpti_template, sizeof(struct qlogicpti)); |
| 1317 | if (!host) | 1310 | if (!host) |
| 1318 | return -ENOMEM; | 1311 | return -ENOMEM; |
| 1319 | 1312 | ||
| @@ -1445,19 +1438,15 @@ static int __devexit qpti_sbus_remove(struct platform_device *op) | |||
| 1445 | static const struct of_device_id qpti_match[] = { | 1438 | static const struct of_device_id qpti_match[] = { |
| 1446 | { | 1439 | { |
| 1447 | .name = "ptisp", | 1440 | .name = "ptisp", |
| 1448 | .data = &qpti_template, | ||
| 1449 | }, | 1441 | }, |
| 1450 | { | 1442 | { |
| 1451 | .name = "PTI,ptisp", | 1443 | .name = "PTI,ptisp", |
| 1452 | .data = &qpti_template, | ||
| 1453 | }, | 1444 | }, |
| 1454 | { | 1445 | { |
| 1455 | .name = "QLGC,isp", | 1446 | .name = "QLGC,isp", |
| 1456 | .data = &qpti_template, | ||
| 1457 | }, | 1447 | }, |
| 1458 | { | 1448 | { |
| 1459 | .name = "SUNW,isp", | 1449 | .name = "SUNW,isp", |
| 1460 | .data = &qpti_template, | ||
| 1461 | }, | 1450 | }, |
| 1462 | {}, | 1451 | {}, |
| 1463 | }; | 1452 | }; |
diff --git a/drivers/scsi/scsi.c b/drivers/scsi/scsi.c index 2936b447cae9..2c0d0ec8150b 100644 --- a/drivers/scsi/scsi.c +++ b/drivers/scsi/scsi.c | |||
| @@ -55,6 +55,7 @@ | |||
| 55 | #include <linux/cpu.h> | 55 | #include <linux/cpu.h> |
| 56 | #include <linux/mutex.h> | 56 | #include <linux/mutex.h> |
| 57 | #include <linux/async.h> | 57 | #include <linux/async.h> |
| 58 | #include <asm/unaligned.h> | ||
| 58 | 59 | ||
| 59 | #include <scsi/scsi.h> | 60 | #include <scsi/scsi.h> |
| 60 | #include <scsi/scsi_cmnd.h> | 61 | #include <scsi/scsi_cmnd.h> |
| @@ -1062,6 +1063,50 @@ int scsi_get_vpd_page(struct scsi_device *sdev, u8 page, unsigned char *buf, | |||
| 1062 | EXPORT_SYMBOL_GPL(scsi_get_vpd_page); | 1063 | EXPORT_SYMBOL_GPL(scsi_get_vpd_page); |
| 1063 | 1064 | ||
| 1064 | /** | 1065 | /** |
| 1066 | * scsi_report_opcode - Find out if a given command opcode is supported | ||
| 1067 | * @sdev: scsi device to query | ||
| 1068 | * @buffer: scratch buffer (must be at least 20 bytes long) | ||
| 1069 | * @len: length of buffer | ||
| 1070 | * @opcode: opcode for command to look up | ||
| 1071 | * | ||
| 1072 | * Uses the REPORT SUPPORTED OPERATION CODES to look up the given | ||
| 1073 | * opcode. Returns 0 if RSOC fails or if the command opcode is | ||
| 1074 | * unsupported. Returns 1 if the device claims to support the command. | ||
| 1075 | */ | ||
| 1076 | int scsi_report_opcode(struct scsi_device *sdev, unsigned char *buffer, | ||
| 1077 | unsigned int len, unsigned char opcode) | ||
| 1078 | { | ||
| 1079 | unsigned char cmd[16]; | ||
| 1080 | struct scsi_sense_hdr sshdr; | ||
| 1081 | int result; | ||
| 1082 | |||
| 1083 | if (sdev->no_report_opcodes || sdev->scsi_level < SCSI_SPC_3) | ||
| 1084 | return 0; | ||
| 1085 | |||
| 1086 | memset(cmd, 0, 16); | ||
| 1087 | cmd[0] = MAINTENANCE_IN; | ||
| 1088 | cmd[1] = MI_REPORT_SUPPORTED_OPERATION_CODES; | ||
| 1089 | cmd[2] = 1; /* One command format */ | ||
| 1090 | cmd[3] = opcode; | ||
| 1091 | put_unaligned_be32(len, &cmd[6]); | ||
| 1092 | memset(buffer, 0, len); | ||
| 1093 | |||
| 1094 | result = scsi_execute_req(sdev, cmd, DMA_FROM_DEVICE, buffer, len, | ||
| 1095 | &sshdr, 30 * HZ, 3, NULL); | ||
| 1096 | |||
| 1097 | if (result && scsi_sense_valid(&sshdr) && | ||
| 1098 | sshdr.sense_key == ILLEGAL_REQUEST && | ||
| 1099 | (sshdr.asc == 0x20 || sshdr.asc == 0x24) && sshdr.ascq == 0x00) | ||
| 1100 | return 0; | ||
| 1101 | |||
| 1102 | if ((buffer[1] & 3) == 3) /* Command supported */ | ||
| 1103 | return 1; | ||
| 1104 | |||
| 1105 | return 0; | ||
| 1106 | } | ||
| 1107 | EXPORT_SYMBOL(scsi_report_opcode); | ||
| 1108 | |||
| 1109 | /** | ||
| 1065 | * scsi_device_get - get an additional reference to a scsi_device | 1110 | * scsi_device_get - get an additional reference to a scsi_device |
| 1066 | * @sdev: device to get a reference to | 1111 | * @sdev: device to get a reference to |
| 1067 | * | 1112 | * |
diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c index da36a3a81a9e..9032e910bca3 100644 --- a/drivers/scsi/scsi_lib.c +++ b/drivers/scsi/scsi_lib.c | |||
| @@ -900,11 +900,23 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes) | |||
| 900 | action = ACTION_FAIL; | 900 | action = ACTION_FAIL; |
| 901 | error = -EILSEQ; | 901 | error = -EILSEQ; |
| 902 | /* INVALID COMMAND OPCODE or INVALID FIELD IN CDB */ | 902 | /* INVALID COMMAND OPCODE or INVALID FIELD IN CDB */ |
| 903 | } else if ((sshdr.asc == 0x20 || sshdr.asc == 0x24) && | 903 | } else if (sshdr.asc == 0x20 || sshdr.asc == 0x24) { |
| 904 | (cmd->cmnd[0] == UNMAP || | 904 | switch (cmd->cmnd[0]) { |
| 905 | cmd->cmnd[0] == WRITE_SAME_16 || | 905 | case UNMAP: |
| 906 | cmd->cmnd[0] == WRITE_SAME)) { | 906 | description = "Discard failure"; |
| 907 | description = "Discard failure"; | 907 | break; |
| 908 | case WRITE_SAME: | ||
| 909 | case WRITE_SAME_16: | ||
| 910 | if (cmd->cmnd[1] & 0x8) | ||
| 911 | description = "Discard failure"; | ||
| 912 | else | ||
| 913 | description = | ||
| 914 | "Write same failure"; | ||
| 915 | break; | ||
| 916 | default: | ||
| 917 | description = "Invalid command failure"; | ||
| 918 | break; | ||
| 919 | } | ||
| 908 | action = ACTION_FAIL; | 920 | action = ACTION_FAIL; |
| 909 | error = -EREMOTEIO; | 921 | error = -EREMOTEIO; |
| 910 | } else | 922 | } else |
diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index 12f6fdfc1147..352bc77b7c88 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c | |||
| @@ -99,6 +99,7 @@ MODULE_ALIAS_SCSI_DEVICE(TYPE_RBC); | |||
| 99 | #endif | 99 | #endif |
| 100 | 100 | ||
| 101 | static void sd_config_discard(struct scsi_disk *, unsigned int); | 101 | static void sd_config_discard(struct scsi_disk *, unsigned int); |
| 102 | static void sd_config_write_same(struct scsi_disk *); | ||
| 102 | static int sd_revalidate_disk(struct gendisk *); | 103 | static int sd_revalidate_disk(struct gendisk *); |
| 103 | static void sd_unlock_native_capacity(struct gendisk *disk); | 104 | static void sd_unlock_native_capacity(struct gendisk *disk); |
| 104 | static int sd_probe(struct device *); | 105 | static int sd_probe(struct device *); |
| @@ -395,6 +396,45 @@ sd_store_max_medium_access_timeouts(struct device *dev, | |||
| 395 | return err ? err : count; | 396 | return err ? err : count; |
| 396 | } | 397 | } |
| 397 | 398 | ||
| 399 | static ssize_t | ||
| 400 | sd_show_write_same_blocks(struct device *dev, struct device_attribute *attr, | ||
| 401 | char *buf) | ||
| 402 | { | ||
| 403 | struct scsi_disk *sdkp = to_scsi_disk(dev); | ||
| 404 | |||
| 405 | return snprintf(buf, 20, "%u\n", sdkp->max_ws_blocks); | ||
| 406 | } | ||
| 407 | |||
| 408 | static ssize_t | ||
| 409 | sd_store_write_same_blocks(struct device *dev, struct device_attribute *attr, | ||
| 410 | const char *buf, size_t count) | ||
| 411 | { | ||
| 412 | struct scsi_disk *sdkp = to_scsi_disk(dev); | ||
| 413 | struct scsi_device *sdp = sdkp->device; | ||
| 414 | unsigned long max; | ||
| 415 | int err; | ||
| 416 | |||
| 417 | if (!capable(CAP_SYS_ADMIN)) | ||
| 418 | return -EACCES; | ||
| 419 | |||
| 420 | if (sdp->type != TYPE_DISK) | ||
| 421 | return -EINVAL; | ||
| 422 | |||
| 423 | err = kstrtoul(buf, 10, &max); | ||
| 424 | |||
| 425 | if (err) | ||
| 426 | return err; | ||
| 427 | |||
| 428 | if (max == 0) | ||
| 429 | sdp->no_write_same = 1; | ||
| 430 | else if (max <= SD_MAX_WS16_BLOCKS) | ||
| 431 | sdkp->max_ws_blocks = max; | ||
| 432 | |||
| 433 | sd_config_write_same(sdkp); | ||
| 434 | |||
| 435 | return count; | ||
| 436 | } | ||
| 437 | |||
| 398 | static struct device_attribute sd_disk_attrs[] = { | 438 | static struct device_attribute sd_disk_attrs[] = { |
| 399 | __ATTR(cache_type, S_IRUGO|S_IWUSR, sd_show_cache_type, | 439 | __ATTR(cache_type, S_IRUGO|S_IWUSR, sd_show_cache_type, |
| 400 | sd_store_cache_type), | 440 | sd_store_cache_type), |
| @@ -410,6 +450,8 @@ static struct device_attribute sd_disk_attrs[] = { | |||
| 410 | __ATTR(thin_provisioning, S_IRUGO, sd_show_thin_provisioning, NULL), | 450 | __ATTR(thin_provisioning, S_IRUGO, sd_show_thin_provisioning, NULL), |
| 411 | __ATTR(provisioning_mode, S_IRUGO|S_IWUSR, sd_show_provisioning_mode, | 451 | __ATTR(provisioning_mode, S_IRUGO|S_IWUSR, sd_show_provisioning_mode, |
| 412 | sd_store_provisioning_mode), | 452 | sd_store_provisioning_mode), |
| 453 | __ATTR(max_write_same_blocks, S_IRUGO|S_IWUSR, | ||
| 454 | sd_show_write_same_blocks, sd_store_write_same_blocks), | ||
| 413 | __ATTR(max_medium_access_timeouts, S_IRUGO|S_IWUSR, | 455 | __ATTR(max_medium_access_timeouts, S_IRUGO|S_IWUSR, |
| 414 | sd_show_max_medium_access_timeouts, | 456 | sd_show_max_medium_access_timeouts, |
| 415 | sd_store_max_medium_access_timeouts), | 457 | sd_store_max_medium_access_timeouts), |
| @@ -561,19 +603,23 @@ static void sd_config_discard(struct scsi_disk *sdkp, unsigned int mode) | |||
| 561 | return; | 603 | return; |
| 562 | 604 | ||
| 563 | case SD_LBP_UNMAP: | 605 | case SD_LBP_UNMAP: |
| 564 | max_blocks = min_not_zero(sdkp->max_unmap_blocks, 0xffffffff); | 606 | max_blocks = min_not_zero(sdkp->max_unmap_blocks, |
| 607 | (u32)SD_MAX_WS16_BLOCKS); | ||
| 565 | break; | 608 | break; |
| 566 | 609 | ||
| 567 | case SD_LBP_WS16: | 610 | case SD_LBP_WS16: |
| 568 | max_blocks = min_not_zero(sdkp->max_ws_blocks, 0xffffffff); | 611 | max_blocks = min_not_zero(sdkp->max_ws_blocks, |
| 612 | (u32)SD_MAX_WS16_BLOCKS); | ||
| 569 | break; | 613 | break; |
| 570 | 614 | ||
| 571 | case SD_LBP_WS10: | 615 | case SD_LBP_WS10: |
| 572 | max_blocks = min_not_zero(sdkp->max_ws_blocks, (u32)0xffff); | 616 | max_blocks = min_not_zero(sdkp->max_ws_blocks, |
| 617 | (u32)SD_MAX_WS10_BLOCKS); | ||
| 573 | break; | 618 | break; |
| 574 | 619 | ||
| 575 | case SD_LBP_ZERO: | 620 | case SD_LBP_ZERO: |
| 576 | max_blocks = min_not_zero(sdkp->max_ws_blocks, (u32)0xffff); | 621 | max_blocks = min_not_zero(sdkp->max_ws_blocks, |
| 622 | (u32)SD_MAX_WS10_BLOCKS); | ||
| 577 | q->limits.discard_zeroes_data = 1; | 623 | q->limits.discard_zeroes_data = 1; |
| 578 | break; | 624 | break; |
| 579 | } | 625 | } |
| @@ -583,29 +629,26 @@ static void sd_config_discard(struct scsi_disk *sdkp, unsigned int mode) | |||
| 583 | } | 629 | } |
| 584 | 630 | ||
| 585 | /** | 631 | /** |
| 586 | * scsi_setup_discard_cmnd - unmap blocks on thinly provisioned device | 632 | * sd_setup_discard_cmnd - unmap blocks on thinly provisioned device |
| 587 | * @sdp: scsi device to operate one | 633 | * @sdp: scsi device to operate one |
| 588 | * @rq: Request to prepare | 634 | * @rq: Request to prepare |
| 589 | * | 635 | * |
| 590 | * Will issue either UNMAP or WRITE SAME(16) depending on preference | 636 | * Will issue either UNMAP or WRITE SAME(16) depending on preference |
| 591 | * indicated by target device. | 637 | * indicated by target device. |
| 592 | **/ | 638 | **/ |
| 593 | static int scsi_setup_discard_cmnd(struct scsi_device *sdp, struct request *rq) | 639 | static int sd_setup_discard_cmnd(struct scsi_device *sdp, struct request *rq) |
| 594 | { | 640 | { |
| 595 | struct scsi_disk *sdkp = scsi_disk(rq->rq_disk); | 641 | struct scsi_disk *sdkp = scsi_disk(rq->rq_disk); |
| 596 | struct bio *bio = rq->bio; | 642 | sector_t sector = blk_rq_pos(rq); |
| 597 | sector_t sector = bio->bi_sector; | 643 | unsigned int nr_sectors = blk_rq_sectors(rq); |
| 598 | unsigned int nr_sectors = bio_sectors(bio); | 644 | unsigned int nr_bytes = blk_rq_bytes(rq); |
| 599 | unsigned int len; | 645 | unsigned int len; |
| 600 | int ret; | 646 | int ret; |
| 601 | char *buf; | 647 | char *buf; |
| 602 | struct page *page; | 648 | struct page *page; |
| 603 | 649 | ||
| 604 | if (sdkp->device->sector_size == 4096) { | 650 | sector >>= ilog2(sdp->sector_size) - 9; |
| 605 | sector >>= 3; | 651 | nr_sectors >>= ilog2(sdp->sector_size) - 9; |
| 606 | nr_sectors >>= 3; | ||
| 607 | } | ||
| 608 | |||
| 609 | rq->timeout = SD_TIMEOUT; | 652 | rq->timeout = SD_TIMEOUT; |
| 610 | 653 | ||
| 611 | memset(rq->cmd, 0, rq->cmd_len); | 654 | memset(rq->cmd, 0, rq->cmd_len); |
| @@ -660,6 +703,7 @@ static int scsi_setup_discard_cmnd(struct scsi_device *sdp, struct request *rq) | |||
| 660 | blk_add_request_payload(rq, page, len); | 703 | blk_add_request_payload(rq, page, len); |
| 661 | ret = scsi_setup_blk_pc_cmnd(sdp, rq); | 704 | ret = scsi_setup_blk_pc_cmnd(sdp, rq); |
| 662 | rq->buffer = page_address(page); | 705 | rq->buffer = page_address(page); |
| 706 | rq->__data_len = nr_bytes; | ||
| 663 | 707 | ||
| 664 | out: | 708 | out: |
| 665 | if (ret != BLKPREP_OK) { | 709 | if (ret != BLKPREP_OK) { |
| @@ -669,6 +713,83 @@ out: | |||
| 669 | return ret; | 713 | return ret; |
| 670 | } | 714 | } |
| 671 | 715 | ||
| 716 | static void sd_config_write_same(struct scsi_disk *sdkp) | ||
| 717 | { | ||
| 718 | struct request_queue *q = sdkp->disk->queue; | ||
| 719 | unsigned int logical_block_size = sdkp->device->sector_size; | ||
| 720 | unsigned int blocks = 0; | ||
| 721 | |||
| 722 | if (sdkp->device->no_write_same) { | ||
| 723 | sdkp->max_ws_blocks = 0; | ||
| 724 | goto out; | ||
| 725 | } | ||
| 726 | |||
| 727 | /* Some devices can not handle block counts above 0xffff despite | ||
| 728 | * supporting WRITE SAME(16). Consequently we default to 64k | ||
| 729 | * blocks per I/O unless the device explicitly advertises a | ||
| 730 | * bigger limit. | ||
| 731 | */ | ||
| 732 | if (sdkp->max_ws_blocks == 0) | ||
| 733 | sdkp->max_ws_blocks = SD_MAX_WS10_BLOCKS; | ||
| 734 | |||
| 735 | if (sdkp->ws16 || sdkp->max_ws_blocks > SD_MAX_WS10_BLOCKS) | ||
| 736 | blocks = min_not_zero(sdkp->max_ws_blocks, | ||
| 737 | (u32)SD_MAX_WS16_BLOCKS); | ||
| 738 | else | ||
| 739 | blocks = min_not_zero(sdkp->max_ws_blocks, | ||
| 740 | (u32)SD_MAX_WS10_BLOCKS); | ||
| 741 | |||
| 742 | out: | ||
| 743 | blk_queue_max_write_same_sectors(q, blocks * (logical_block_size >> 9)); | ||
| 744 | } | ||
| 745 | |||
| 746 | /** | ||
| 747 | * sd_setup_write_same_cmnd - write the same data to multiple blocks | ||
| 748 | * @sdp: scsi device to operate one | ||
| 749 | * @rq: Request to prepare | ||
| 750 | * | ||
| 751 | * Will issue either WRITE SAME(10) or WRITE SAME(16) depending on | ||
| 752 | * preference indicated by target device. | ||
| 753 | **/ | ||
| 754 | static int sd_setup_write_same_cmnd(struct scsi_device *sdp, struct request *rq) | ||
| 755 | { | ||
| 756 | struct scsi_disk *sdkp = scsi_disk(rq->rq_disk); | ||
| 757 | struct bio *bio = rq->bio; | ||
| 758 | sector_t sector = blk_rq_pos(rq); | ||
| 759 | unsigned int nr_sectors = blk_rq_sectors(rq); | ||
| 760 | unsigned int nr_bytes = blk_rq_bytes(rq); | ||
| 761 | int ret; | ||
| 762 | |||
| 763 | if (sdkp->device->no_write_same) | ||
| 764 | return BLKPREP_KILL; | ||
| 765 | |||
| 766 | BUG_ON(bio_offset(bio) || bio_iovec(bio)->bv_len != sdp->sector_size); | ||
| 767 | |||
| 768 | sector >>= ilog2(sdp->sector_size) - 9; | ||
| 769 | nr_sectors >>= ilog2(sdp->sector_size) - 9; | ||
| 770 | |||
| 771 | rq->__data_len = sdp->sector_size; | ||
| 772 | rq->timeout = SD_WRITE_SAME_TIMEOUT; | ||
| 773 | memset(rq->cmd, 0, rq->cmd_len); | ||
| 774 | |||
| 775 | if (sdkp->ws16 || sector > 0xffffffff || nr_sectors > 0xffff) { | ||
| 776 | rq->cmd_len = 16; | ||
| 777 | rq->cmd[0] = WRITE_SAME_16; | ||
| 778 | put_unaligned_be64(sector, &rq->cmd[2]); | ||
| 779 | put_unaligned_be32(nr_sectors, &rq->cmd[10]); | ||
| 780 | } else { | ||
| 781 | rq->cmd_len = 10; | ||
| 782 | rq->cmd[0] = WRITE_SAME; | ||
| 783 | put_unaligned_be32(sector, &rq->cmd[2]); | ||
| 784 | put_unaligned_be16(nr_sectors, &rq->cmd[7]); | ||
| 785 | } | ||
| 786 | |||
| 787 | ret = scsi_setup_blk_pc_cmnd(sdp, rq); | ||
| 788 | rq->__data_len = nr_bytes; | ||
| 789 | |||
| 790 | return ret; | ||
| 791 | } | ||
| 792 | |||
| 672 | static int scsi_setup_flush_cmnd(struct scsi_device *sdp, struct request *rq) | 793 | static int scsi_setup_flush_cmnd(struct scsi_device *sdp, struct request *rq) |
| 673 | { | 794 | { |
| 674 | rq->timeout = SD_FLUSH_TIMEOUT; | 795 | rq->timeout = SD_FLUSH_TIMEOUT; |
| @@ -712,7 +833,10 @@ static int sd_prep_fn(struct request_queue *q, struct request *rq) | |||
| 712 | * block PC requests to make life easier. | 833 | * block PC requests to make life easier. |
| 713 | */ | 834 | */ |
| 714 | if (rq->cmd_flags & REQ_DISCARD) { | 835 | if (rq->cmd_flags & REQ_DISCARD) { |
| 715 | ret = scsi_setup_discard_cmnd(sdp, rq); | 836 | ret = sd_setup_discard_cmnd(sdp, rq); |
| 837 | goto out; | ||
| 838 | } else if (rq->cmd_flags & REQ_WRITE_SAME) { | ||
| 839 | ret = sd_setup_write_same_cmnd(sdp, rq); | ||
| 716 | goto out; | 840 | goto out; |
| 717 | } else if (rq->cmd_flags & REQ_FLUSH) { | 841 | } else if (rq->cmd_flags & REQ_FLUSH) { |
| 718 | ret = scsi_setup_flush_cmnd(sdp, rq); | 842 | ret = scsi_setup_flush_cmnd(sdp, rq); |
| @@ -1482,12 +1606,21 @@ static int sd_done(struct scsi_cmnd *SCpnt) | |||
| 1482 | unsigned int good_bytes = result ? 0 : scsi_bufflen(SCpnt); | 1606 | unsigned int good_bytes = result ? 0 : scsi_bufflen(SCpnt); |
| 1483 | struct scsi_sense_hdr sshdr; | 1607 | struct scsi_sense_hdr sshdr; |
| 1484 | struct scsi_disk *sdkp = scsi_disk(SCpnt->request->rq_disk); | 1608 | struct scsi_disk *sdkp = scsi_disk(SCpnt->request->rq_disk); |
| 1609 | struct request *req = SCpnt->request; | ||
| 1485 | int sense_valid = 0; | 1610 | int sense_valid = 0; |
| 1486 | int sense_deferred = 0; | 1611 | int sense_deferred = 0; |
| 1487 | unsigned char op = SCpnt->cmnd[0]; | 1612 | unsigned char op = SCpnt->cmnd[0]; |
| 1613 | unsigned char unmap = SCpnt->cmnd[1] & 8; | ||
| 1488 | 1614 | ||
| 1489 | if ((SCpnt->request->cmd_flags & REQ_DISCARD) && !result) | 1615 | if (req->cmd_flags & REQ_DISCARD || req->cmd_flags & REQ_WRITE_SAME) { |
| 1490 | scsi_set_resid(SCpnt, 0); | 1616 | if (!result) { |
| 1617 | good_bytes = blk_rq_bytes(req); | ||
| 1618 | scsi_set_resid(SCpnt, 0); | ||
| 1619 | } else { | ||
| 1620 | good_bytes = 0; | ||
| 1621 | scsi_set_resid(SCpnt, blk_rq_bytes(req)); | ||
| 1622 | } | ||
| 1623 | } | ||
| 1491 | 1624 | ||
| 1492 | if (result) { | 1625 | if (result) { |
| 1493 | sense_valid = scsi_command_normalize_sense(SCpnt, &sshdr); | 1626 | sense_valid = scsi_command_normalize_sense(SCpnt, &sshdr); |
| @@ -1536,9 +1669,25 @@ static int sd_done(struct scsi_cmnd *SCpnt) | |||
| 1536 | if (sshdr.asc == 0x10) /* DIX: Host detected corruption */ | 1669 | if (sshdr.asc == 0x10) /* DIX: Host detected corruption */ |
| 1537 | good_bytes = sd_completed_bytes(SCpnt); | 1670 | good_bytes = sd_completed_bytes(SCpnt); |
| 1538 | /* INVALID COMMAND OPCODE or INVALID FIELD IN CDB */ | 1671 | /* INVALID COMMAND OPCODE or INVALID FIELD IN CDB */ |
| 1539 | if ((sshdr.asc == 0x20 || sshdr.asc == 0x24) && | 1672 | if (sshdr.asc == 0x20 || sshdr.asc == 0x24) { |
| 1540 | (op == UNMAP || op == WRITE_SAME_16 || op == WRITE_SAME)) | 1673 | switch (op) { |
| 1541 | sd_config_discard(sdkp, SD_LBP_DISABLE); | 1674 | case UNMAP: |
| 1675 | sd_config_discard(sdkp, SD_LBP_DISABLE); | ||
| 1676 | break; | ||
| 1677 | case WRITE_SAME_16: | ||
| 1678 | case WRITE_SAME: | ||
| 1679 | if (unmap) | ||
| 1680 | sd_config_discard(sdkp, SD_LBP_DISABLE); | ||
| 1681 | else { | ||
| 1682 | sdkp->device->no_write_same = 1; | ||
| 1683 | sd_config_write_same(sdkp); | ||
| 1684 | |||
| 1685 | good_bytes = 0; | ||
| 1686 | req->__data_len = blk_rq_bytes(req); | ||
| 1687 | req->cmd_flags |= REQ_QUIET; | ||
| 1688 | } | ||
| 1689 | } | ||
| 1690 | } | ||
| 1542 | break; | 1691 | break; |
| 1543 | default: | 1692 | default: |
| 1544 | break; | 1693 | break; |
| @@ -2374,9 +2523,7 @@ static void sd_read_block_limits(struct scsi_disk *sdkp) | |||
| 2374 | if (buffer[3] == 0x3c) { | 2523 | if (buffer[3] == 0x3c) { |
| 2375 | unsigned int lba_count, desc_count; | 2524 | unsigned int lba_count, desc_count; |
| 2376 | 2525 | ||
| 2377 | sdkp->max_ws_blocks = | 2526 | sdkp->max_ws_blocks = (u32)get_unaligned_be64(&buffer[36]); |
| 2378 | (u32) min_not_zero(get_unaligned_be64(&buffer[36]), | ||
| 2379 | (u64)0xffffffff); | ||
| 2380 | 2527 | ||
| 2381 | if (!sdkp->lbpme) | 2528 | if (!sdkp->lbpme) |
| 2382 | goto out; | 2529 | goto out; |
| @@ -2469,6 +2616,13 @@ static void sd_read_block_provisioning(struct scsi_disk *sdkp) | |||
| 2469 | kfree(buffer); | 2616 | kfree(buffer); |
| 2470 | } | 2617 | } |
| 2471 | 2618 | ||
| 2619 | static void sd_read_write_same(struct scsi_disk *sdkp, unsigned char *buffer) | ||
| 2620 | { | ||
| 2621 | if (scsi_report_opcode(sdkp->device, buffer, SD_BUF_SIZE, | ||
| 2622 | WRITE_SAME_16)) | ||
| 2623 | sdkp->ws16 = 1; | ||
| 2624 | } | ||
| 2625 | |||
| 2472 | static int sd_try_extended_inquiry(struct scsi_device *sdp) | 2626 | static int sd_try_extended_inquiry(struct scsi_device *sdp) |
| 2473 | { | 2627 | { |
| 2474 | /* | 2628 | /* |
| @@ -2528,6 +2682,7 @@ static int sd_revalidate_disk(struct gendisk *disk) | |||
| 2528 | sd_read_write_protect_flag(sdkp, buffer); | 2682 | sd_read_write_protect_flag(sdkp, buffer); |
| 2529 | sd_read_cache_type(sdkp, buffer); | 2683 | sd_read_cache_type(sdkp, buffer); |
| 2530 | sd_read_app_tag_own(sdkp, buffer); | 2684 | sd_read_app_tag_own(sdkp, buffer); |
| 2685 | sd_read_write_same(sdkp, buffer); | ||
| 2531 | } | 2686 | } |
| 2532 | 2687 | ||
| 2533 | sdkp->first_scan = 0; | 2688 | sdkp->first_scan = 0; |
| @@ -2545,6 +2700,7 @@ static int sd_revalidate_disk(struct gendisk *disk) | |||
| 2545 | blk_queue_flush(sdkp->disk->queue, flush); | 2700 | blk_queue_flush(sdkp->disk->queue, flush); |
| 2546 | 2701 | ||
| 2547 | set_capacity(disk, sdkp->capacity); | 2702 | set_capacity(disk, sdkp->capacity); |
| 2703 | sd_config_write_same(sdkp); | ||
| 2548 | kfree(buffer); | 2704 | kfree(buffer); |
| 2549 | 2705 | ||
| 2550 | out: | 2706 | out: |
diff --git a/drivers/scsi/sd.h b/drivers/scsi/sd.h index 47c52a6d733c..74a1e4ca5401 100644 --- a/drivers/scsi/sd.h +++ b/drivers/scsi/sd.h | |||
| @@ -14,6 +14,7 @@ | |||
| 14 | #define SD_TIMEOUT (30 * HZ) | 14 | #define SD_TIMEOUT (30 * HZ) |
| 15 | #define SD_MOD_TIMEOUT (75 * HZ) | 15 | #define SD_MOD_TIMEOUT (75 * HZ) |
| 16 | #define SD_FLUSH_TIMEOUT (60 * HZ) | 16 | #define SD_FLUSH_TIMEOUT (60 * HZ) |
| 17 | #define SD_WRITE_SAME_TIMEOUT (120 * HZ) | ||
| 17 | 18 | ||
| 18 | /* | 19 | /* |
| 19 | * Number of allowed retries | 20 | * Number of allowed retries |
| @@ -39,6 +40,11 @@ enum { | |||
| 39 | }; | 40 | }; |
| 40 | 41 | ||
| 41 | enum { | 42 | enum { |
| 43 | SD_MAX_WS10_BLOCKS = 0xffff, | ||
| 44 | SD_MAX_WS16_BLOCKS = 0x7fffff, | ||
| 45 | }; | ||
| 46 | |||
| 47 | enum { | ||
| 42 | SD_LBP_FULL = 0, /* Full logical block provisioning */ | 48 | SD_LBP_FULL = 0, /* Full logical block provisioning */ |
| 43 | SD_LBP_UNMAP, /* Use UNMAP command */ | 49 | SD_LBP_UNMAP, /* Use UNMAP command */ |
| 44 | SD_LBP_WS16, /* Use WRITE SAME(16) with UNMAP bit */ | 50 | SD_LBP_WS16, /* Use WRITE SAME(16) with UNMAP bit */ |
| @@ -77,6 +83,7 @@ struct scsi_disk { | |||
| 77 | unsigned lbpws : 1; | 83 | unsigned lbpws : 1; |
| 78 | unsigned lbpws10 : 1; | 84 | unsigned lbpws10 : 1; |
| 79 | unsigned lbpvpd : 1; | 85 | unsigned lbpvpd : 1; |
| 86 | unsigned ws16 : 1; | ||
| 80 | }; | 87 | }; |
| 81 | #define to_scsi_disk(obj) container_of(obj,struct scsi_disk,dev) | 88 | #define to_scsi_disk(obj) container_of(obj,struct scsi_disk,dev) |
| 82 | 89 | ||
diff --git a/drivers/sh/intc/access.c b/drivers/sh/intc/access.c index f892ae1d212a..114390f967d2 100644 --- a/drivers/sh/intc/access.c +++ b/drivers/sh/intc/access.c | |||
| @@ -75,54 +75,61 @@ unsigned long intc_get_field_from_handle(unsigned int value, unsigned int handle | |||
| 75 | static unsigned long test_8(unsigned long addr, unsigned long h, | 75 | static unsigned long test_8(unsigned long addr, unsigned long h, |
| 76 | unsigned long ignore) | 76 | unsigned long ignore) |
| 77 | { | 77 | { |
| 78 | return intc_get_field_from_handle(__raw_readb(addr), h); | 78 | void __iomem *ptr = (void __iomem *)addr; |
| 79 | return intc_get_field_from_handle(__raw_readb(ptr), h); | ||
| 79 | } | 80 | } |
| 80 | 81 | ||
| 81 | static unsigned long test_16(unsigned long addr, unsigned long h, | 82 | static unsigned long test_16(unsigned long addr, unsigned long h, |
| 82 | unsigned long ignore) | 83 | unsigned long ignore) |
| 83 | { | 84 | { |
| 84 | return intc_get_field_from_handle(__raw_readw(addr), h); | 85 | void __iomem *ptr = (void __iomem *)addr; |
| 86 | return intc_get_field_from_handle(__raw_readw(ptr), h); | ||
| 85 | } | 87 | } |
| 86 | 88 | ||
| 87 | static unsigned long test_32(unsigned long addr, unsigned long h, | 89 | static unsigned long test_32(unsigned long addr, unsigned long h, |
| 88 | unsigned long ignore) | 90 | unsigned long ignore) |
| 89 | { | 91 | { |
| 90 | return intc_get_field_from_handle(__raw_readl(addr), h); | 92 | void __iomem *ptr = (void __iomem *)addr; |
| 93 | return intc_get_field_from_handle(__raw_readl(ptr), h); | ||
| 91 | } | 94 | } |
| 92 | 95 | ||
| 93 | static unsigned long write_8(unsigned long addr, unsigned long h, | 96 | static unsigned long write_8(unsigned long addr, unsigned long h, |
| 94 | unsigned long data) | 97 | unsigned long data) |
| 95 | { | 98 | { |
| 96 | __raw_writeb(intc_set_field_from_handle(0, data, h), addr); | 99 | void __iomem *ptr = (void __iomem *)addr; |
| 97 | (void)__raw_readb(addr); /* Defeat write posting */ | 100 | __raw_writeb(intc_set_field_from_handle(0, data, h), ptr); |
| 101 | (void)__raw_readb(ptr); /* Defeat write posting */ | ||
| 98 | return 0; | 102 | return 0; |
| 99 | } | 103 | } |
| 100 | 104 | ||
| 101 | static unsigned long write_16(unsigned long addr, unsigned long h, | 105 | static unsigned long write_16(unsigned long addr, unsigned long h, |
| 102 | unsigned long data) | 106 | unsigned long data) |
| 103 | { | 107 | { |
| 104 | __raw_writew(intc_set_field_from_handle(0, data, h), addr); | 108 | void __iomem *ptr = (void __iomem *)addr; |
| 105 | (void)__raw_readw(addr); /* Defeat write posting */ | 109 | __raw_writew(intc_set_field_from_handle(0, data, h), ptr); |
| 110 | (void)__raw_readw(ptr); /* Defeat write posting */ | ||
| 106 | return 0; | 111 | return 0; |
| 107 | } | 112 | } |
| 108 | 113 | ||
| 109 | static unsigned long write_32(unsigned long addr, unsigned long h, | 114 | static unsigned long write_32(unsigned long addr, unsigned long h, |
| 110 | unsigned long data) | 115 | unsigned long data) |
| 111 | { | 116 | { |
| 112 | __raw_writel(intc_set_field_from_handle(0, data, h), addr); | 117 | void __iomem *ptr = (void __iomem *)addr; |
| 113 | (void)__raw_readl(addr); /* Defeat write posting */ | 118 | __raw_writel(intc_set_field_from_handle(0, data, h), ptr); |
| 119 | (void)__raw_readl(ptr); /* Defeat write posting */ | ||
| 114 | return 0; | 120 | return 0; |
| 115 | } | 121 | } |
| 116 | 122 | ||
| 117 | static unsigned long modify_8(unsigned long addr, unsigned long h, | 123 | static unsigned long modify_8(unsigned long addr, unsigned long h, |
| 118 | unsigned long data) | 124 | unsigned long data) |
| 119 | { | 125 | { |
| 126 | void __iomem *ptr = (void __iomem *)addr; | ||
| 120 | unsigned long flags; | 127 | unsigned long flags; |
| 121 | unsigned int value; | 128 | unsigned int value; |
| 122 | local_irq_save(flags); | 129 | local_irq_save(flags); |
| 123 | value = intc_set_field_from_handle(__raw_readb(addr), data, h); | 130 | value = intc_set_field_from_handle(__raw_readb(ptr), data, h); |
| 124 | __raw_writeb(value, addr); | 131 | __raw_writeb(value, ptr); |
| 125 | (void)__raw_readb(addr); /* Defeat write posting */ | 132 | (void)__raw_readb(ptr); /* Defeat write posting */ |
| 126 | local_irq_restore(flags); | 133 | local_irq_restore(flags); |
| 127 | return 0; | 134 | return 0; |
| 128 | } | 135 | } |
| @@ -130,12 +137,13 @@ static unsigned long modify_8(unsigned long addr, unsigned long h, | |||
| 130 | static unsigned long modify_16(unsigned long addr, unsigned long h, | 137 | static unsigned long modify_16(unsigned long addr, unsigned long h, |
| 131 | unsigned long data) | 138 | unsigned long data) |
| 132 | { | 139 | { |
| 140 | void __iomem *ptr = (void __iomem *)addr; | ||
| 133 | unsigned long flags; | 141 | unsigned long flags; |
| 134 | unsigned int value; | 142 | unsigned int value; |
| 135 | local_irq_save(flags); | 143 | local_irq_save(flags); |
| 136 | value = intc_set_field_from_handle(__raw_readw(addr), data, h); | 144 | value = intc_set_field_from_handle(__raw_readw(ptr), data, h); |
| 137 | __raw_writew(value, addr); | 145 | __raw_writew(value, ptr); |
| 138 | (void)__raw_readw(addr); /* Defeat write posting */ | 146 | (void)__raw_readw(ptr); /* Defeat write posting */ |
| 139 | local_irq_restore(flags); | 147 | local_irq_restore(flags); |
| 140 | return 0; | 148 | return 0; |
| 141 | } | 149 | } |
| @@ -143,12 +151,13 @@ static unsigned long modify_16(unsigned long addr, unsigned long h, | |||
| 143 | static unsigned long modify_32(unsigned long addr, unsigned long h, | 151 | static unsigned long modify_32(unsigned long addr, unsigned long h, |
| 144 | unsigned long data) | 152 | unsigned long data) |
| 145 | { | 153 | { |
| 154 | void __iomem *ptr = (void __iomem *)addr; | ||
| 146 | unsigned long flags; | 155 | unsigned long flags; |
| 147 | unsigned int value; | 156 | unsigned int value; |
| 148 | local_irq_save(flags); | 157 | local_irq_save(flags); |
| 149 | value = intc_set_field_from_handle(__raw_readl(addr), data, h); | 158 | value = intc_set_field_from_handle(__raw_readl(ptr), data, h); |
| 150 | __raw_writel(value, addr); | 159 | __raw_writel(value, ptr); |
| 151 | (void)__raw_readl(addr); /* Defeat write posting */ | 160 | (void)__raw_readl(ptr); /* Defeat write posting */ |
| 152 | local_irq_restore(flags); | 161 | local_irq_restore(flags); |
| 153 | return 0; | 162 | return 0; |
| 154 | } | 163 | } |
diff --git a/drivers/sh/intc/chip.c b/drivers/sh/intc/chip.c index 012df2676a26..46427b48e2f1 100644 --- a/drivers/sh/intc/chip.c +++ b/drivers/sh/intc/chip.c | |||
| @@ -83,7 +83,7 @@ static void intc_mask_ack(struct irq_data *data) | |||
| 83 | unsigned int irq = data->irq; | 83 | unsigned int irq = data->irq; |
| 84 | struct intc_desc_int *d = get_intc_desc(irq); | 84 | struct intc_desc_int *d = get_intc_desc(irq); |
| 85 | unsigned long handle = intc_get_ack_handle(irq); | 85 | unsigned long handle = intc_get_ack_handle(irq); |
| 86 | unsigned long addr; | 86 | void __iomem *addr; |
| 87 | 87 | ||
| 88 | intc_disable(data); | 88 | intc_disable(data); |
| 89 | 89 | ||
| @@ -91,7 +91,7 @@ static void intc_mask_ack(struct irq_data *data) | |||
| 91 | if (handle) { | 91 | if (handle) { |
| 92 | unsigned int value; | 92 | unsigned int value; |
| 93 | 93 | ||
| 94 | addr = INTC_REG(d, _INTC_ADDR_D(handle), 0); | 94 | addr = (void __iomem *)INTC_REG(d, _INTC_ADDR_D(handle), 0); |
| 95 | value = intc_set_field_from_handle(0, 1, handle); | 95 | value = intc_set_field_from_handle(0, 1, handle); |
| 96 | 96 | ||
| 97 | switch (_INTC_FN(handle)) { | 97 | switch (_INTC_FN(handle)) { |
diff --git a/drivers/spi/spi-mxs.c b/drivers/spi/spi-mxs.c index edf1360ab09e..86dd04d6bc87 100644 --- a/drivers/spi/spi-mxs.c +++ b/drivers/spi/spi-mxs.c | |||
| @@ -323,6 +323,7 @@ static int mxs_spi_txrx_dma(struct mxs_spi *spi, int cs, | |||
| 323 | if (!ret) { | 323 | if (!ret) { |
| 324 | dev_err(ssp->dev, "DMA transfer timeout\n"); | 324 | dev_err(ssp->dev, "DMA transfer timeout\n"); |
| 325 | ret = -ETIMEDOUT; | 325 | ret = -ETIMEDOUT; |
| 326 | dmaengine_terminate_all(ssp->dmach); | ||
| 326 | goto err_vmalloc; | 327 | goto err_vmalloc; |
| 327 | } | 328 | } |
| 328 | 329 | ||
| @@ -480,7 +481,7 @@ static int mxs_spi_transfer_one(struct spi_master *master, | |||
| 480 | first = last = 0; | 481 | first = last = 0; |
| 481 | } | 482 | } |
| 482 | 483 | ||
| 483 | m->status = 0; | 484 | m->status = status; |
| 484 | spi_finalize_current_message(master); | 485 | spi_finalize_current_message(master); |
| 485 | 486 | ||
| 486 | return status; | 487 | return status; |
diff --git a/drivers/spi/spi-pl022.c b/drivers/spi/spi-pl022.c index 919464102d33..a1db91a99b89 100644 --- a/drivers/spi/spi-pl022.c +++ b/drivers/spi/spi-pl022.c | |||
| @@ -2186,8 +2186,6 @@ pl022_probe(struct amba_device *adev, const struct amba_id *id) | |||
| 2186 | printk(KERN_INFO "pl022: mapped registers from 0x%08x to %p\n", | 2186 | printk(KERN_INFO "pl022: mapped registers from 0x%08x to %p\n", |
| 2187 | adev->res.start, pl022->virtbase); | 2187 | adev->res.start, pl022->virtbase); |
| 2188 | 2188 | ||
| 2189 | pm_runtime_resume(dev); | ||
| 2190 | |||
| 2191 | pl022->clk = devm_clk_get(&adev->dev, NULL); | 2189 | pl022->clk = devm_clk_get(&adev->dev, NULL); |
| 2192 | if (IS_ERR(pl022->clk)) { | 2190 | if (IS_ERR(pl022->clk)) { |
| 2193 | status = PTR_ERR(pl022->clk); | 2191 | status = PTR_ERR(pl022->clk); |
| @@ -2292,7 +2290,6 @@ pl022_remove(struct amba_device *adev) | |||
| 2292 | 2290 | ||
| 2293 | clk_disable(pl022->clk); | 2291 | clk_disable(pl022->clk); |
| 2294 | clk_unprepare(pl022->clk); | 2292 | clk_unprepare(pl022->clk); |
| 2295 | pm_runtime_disable(&adev->dev); | ||
| 2296 | amba_release_regions(adev); | 2293 | amba_release_regions(adev); |
| 2297 | tasklet_disable(&pl022->pump_transfers); | 2294 | tasklet_disable(&pl022->pump_transfers); |
| 2298 | spi_unregister_master(pl022->master); | 2295 | spi_unregister_master(pl022->master); |
diff --git a/drivers/spi/spi-rspi.c b/drivers/spi/spi-rspi.c index 4894bde4bbff..30faf6d4ab91 100644 --- a/drivers/spi/spi-rspi.c +++ b/drivers/spi/spi-rspi.c | |||
| @@ -147,8 +147,6 @@ struct rspi_data { | |||
| 147 | unsigned char spsr; | 147 | unsigned char spsr; |
| 148 | 148 | ||
| 149 | /* for dmaengine */ | 149 | /* for dmaengine */ |
| 150 | struct sh_dmae_slave dma_tx; | ||
| 151 | struct sh_dmae_slave dma_rx; | ||
| 152 | struct dma_chan *chan_tx; | 150 | struct dma_chan *chan_tx; |
| 153 | struct dma_chan *chan_rx; | 151 | struct dma_chan *chan_rx; |
| 154 | int irq; | 152 | int irq; |
| @@ -663,20 +661,16 @@ static irqreturn_t rspi_irq(int irq, void *_sr) | |||
| 663 | return ret; | 661 | return ret; |
| 664 | } | 662 | } |
| 665 | 663 | ||
| 666 | static bool rspi_filter(struct dma_chan *chan, void *filter_param) | 664 | static int __devinit rspi_request_dma(struct rspi_data *rspi, |
| 667 | { | 665 | struct platform_device *pdev) |
| 668 | chan->private = filter_param; | ||
| 669 | return true; | ||
| 670 | } | ||
| 671 | |||
| 672 | static void __devinit rspi_request_dma(struct rspi_data *rspi, | ||
| 673 | struct platform_device *pdev) | ||
| 674 | { | 666 | { |
| 675 | struct rspi_plat_data *rspi_pd = pdev->dev.platform_data; | 667 | struct rspi_plat_data *rspi_pd = pdev->dev.platform_data; |
| 676 | dma_cap_mask_t mask; | 668 | dma_cap_mask_t mask; |
| 669 | struct dma_slave_config cfg; | ||
| 670 | int ret; | ||
| 677 | 671 | ||
| 678 | if (!rspi_pd) | 672 | if (!rspi_pd) |
| 679 | return; | 673 | return 0; /* The driver assumes no error. */ |
| 680 | 674 | ||
| 681 | rspi->dma_width_16bit = rspi_pd->dma_width_16bit; | 675 | rspi->dma_width_16bit = rspi_pd->dma_width_16bit; |
| 682 | 676 | ||
| @@ -684,21 +678,35 @@ static void __devinit rspi_request_dma(struct rspi_data *rspi, | |||
| 684 | if (rspi_pd->dma_rx_id && rspi_pd->dma_tx_id) { | 678 | if (rspi_pd->dma_rx_id && rspi_pd->dma_tx_id) { |
| 685 | dma_cap_zero(mask); | 679 | dma_cap_zero(mask); |
| 686 | dma_cap_set(DMA_SLAVE, mask); | 680 | dma_cap_set(DMA_SLAVE, mask); |
| 687 | rspi->dma_rx.slave_id = rspi_pd->dma_rx_id; | 681 | rspi->chan_rx = dma_request_channel(mask, shdma_chan_filter, |
| 688 | rspi->chan_rx = dma_request_channel(mask, rspi_filter, | 682 | (void *)rspi_pd->dma_rx_id); |
| 689 | &rspi->dma_rx); | 683 | if (rspi->chan_rx) { |
| 690 | if (rspi->chan_rx) | 684 | cfg.slave_id = rspi_pd->dma_rx_id; |
| 691 | dev_info(&pdev->dev, "Use DMA when rx.\n"); | 685 | cfg.direction = DMA_DEV_TO_MEM; |
| 686 | ret = dmaengine_slave_config(rspi->chan_rx, &cfg); | ||
| 687 | if (!ret) | ||
| 688 | dev_info(&pdev->dev, "Use DMA when rx.\n"); | ||
| 689 | else | ||
| 690 | return ret; | ||
| 691 | } | ||
| 692 | } | 692 | } |
| 693 | if (rspi_pd->dma_tx_id) { | 693 | if (rspi_pd->dma_tx_id) { |
| 694 | dma_cap_zero(mask); | 694 | dma_cap_zero(mask); |
| 695 | dma_cap_set(DMA_SLAVE, mask); | 695 | dma_cap_set(DMA_SLAVE, mask); |
| 696 | rspi->dma_tx.slave_id = rspi_pd->dma_tx_id; | 696 | rspi->chan_tx = dma_request_channel(mask, shdma_chan_filter, |
| 697 | rspi->chan_tx = dma_request_channel(mask, rspi_filter, | 697 | (void *)rspi_pd->dma_tx_id); |
| 698 | &rspi->dma_tx); | 698 | if (rspi->chan_tx) { |
| 699 | if (rspi->chan_tx) | 699 | cfg.slave_id = rspi_pd->dma_tx_id; |
| 700 | dev_info(&pdev->dev, "Use DMA when tx\n"); | 700 | cfg.direction = DMA_MEM_TO_DEV; |
| 701 | ret = dmaengine_slave_config(rspi->chan_tx, &cfg); | ||
| 702 | if (!ret) | ||
| 703 | dev_info(&pdev->dev, "Use DMA when tx\n"); | ||
| 704 | else | ||
| 705 | return ret; | ||
| 706 | } | ||
| 701 | } | 707 | } |
| 708 | |||
| 709 | return 0; | ||
| 702 | } | 710 | } |
| 703 | 711 | ||
| 704 | static void __devexit rspi_release_dma(struct rspi_data *rspi) | 712 | static void __devexit rspi_release_dma(struct rspi_data *rspi) |
| @@ -788,7 +796,11 @@ static int __devinit rspi_probe(struct platform_device *pdev) | |||
| 788 | } | 796 | } |
| 789 | 797 | ||
| 790 | rspi->irq = irq; | 798 | rspi->irq = irq; |
| 791 | rspi_request_dma(rspi, pdev); | 799 | ret = rspi_request_dma(rspi, pdev); |
| 800 | if (ret < 0) { | ||
| 801 | dev_err(&pdev->dev, "rspi_request_dma failed.\n"); | ||
| 802 | goto error4; | ||
| 803 | } | ||
| 792 | 804 | ||
| 793 | ret = spi_register_master(master); | 805 | ret = spi_register_master(master); |
| 794 | if (ret < 0) { | 806 | if (ret < 0) { |
diff --git a/drivers/spi/spi-s3c64xx.c b/drivers/spi/spi-s3c64xx.c index 1a81c90a4a71..6e7a805d324d 100644 --- a/drivers/spi/spi-s3c64xx.c +++ b/drivers/spi/spi-s3c64xx.c | |||
| @@ -132,7 +132,7 @@ | |||
| 132 | 132 | ||
| 133 | struct s3c64xx_spi_dma_data { | 133 | struct s3c64xx_spi_dma_data { |
| 134 | unsigned ch; | 134 | unsigned ch; |
| 135 | enum dma_data_direction direction; | 135 | enum dma_transfer_direction direction; |
| 136 | enum dma_ch dmach; | 136 | enum dma_ch dmach; |
| 137 | struct property *dma_prop; | 137 | struct property *dma_prop; |
| 138 | }; | 138 | }; |
| @@ -1067,11 +1067,11 @@ static int __devinit s3c64xx_spi_get_dmares( | |||
| 1067 | 1067 | ||
| 1068 | if (tx) { | 1068 | if (tx) { |
| 1069 | dma_data = &sdd->tx_dma; | 1069 | dma_data = &sdd->tx_dma; |
| 1070 | dma_data->direction = DMA_TO_DEVICE; | 1070 | dma_data->direction = DMA_MEM_TO_DEV; |
| 1071 | chan_str = "tx"; | 1071 | chan_str = "tx"; |
| 1072 | } else { | 1072 | } else { |
| 1073 | dma_data = &sdd->rx_dma; | 1073 | dma_data = &sdd->rx_dma; |
| 1074 | dma_data->direction = DMA_FROM_DEVICE; | 1074 | dma_data->direction = DMA_DEV_TO_MEM; |
| 1075 | chan_str = "rx"; | 1075 | chan_str = "rx"; |
| 1076 | } | 1076 | } |
| 1077 | 1077 | ||
diff --git a/drivers/staging/android/android_alarm.h b/drivers/staging/android/android_alarm.h index f2ffd963f1c3..d0cafd637199 100644 --- a/drivers/staging/android/android_alarm.h +++ b/drivers/staging/android/android_alarm.h | |||
| @@ -51,12 +51,10 @@ enum android_alarm_return_flags { | |||
| 51 | #define ANDROID_ALARM_WAIT _IO('a', 1) | 51 | #define ANDROID_ALARM_WAIT _IO('a', 1) |
| 52 | 52 | ||
| 53 | #define ALARM_IOW(c, type, size) _IOW('a', (c) | ((type) << 4), size) | 53 | #define ALARM_IOW(c, type, size) _IOW('a', (c) | ((type) << 4), size) |
| 54 | #define ALARM_IOR(c, type, size) _IOR('a', (c) | ((type) << 4), size) | ||
| 55 | |||
| 56 | /* Set alarm */ | 54 | /* Set alarm */ |
| 57 | #define ANDROID_ALARM_SET(type) ALARM_IOW(2, type, struct timespec) | 55 | #define ANDROID_ALARM_SET(type) ALARM_IOW(2, type, struct timespec) |
| 58 | #define ANDROID_ALARM_SET_AND_WAIT(type) ALARM_IOW(3, type, struct timespec) | 56 | #define ANDROID_ALARM_SET_AND_WAIT(type) ALARM_IOW(3, type, struct timespec) |
| 59 | #define ANDROID_ALARM_GET_TIME(type) ALARM_IOR(4, type, struct timespec) | 57 | #define ANDROID_ALARM_GET_TIME(type) ALARM_IOW(4, type, struct timespec) |
| 60 | #define ANDROID_ALARM_SET_RTC _IOW('a', 5, struct timespec) | 58 | #define ANDROID_ALARM_SET_RTC _IOW('a', 5, struct timespec) |
| 61 | #define ANDROID_ALARM_BASE_CMD(cmd) (cmd & ~(_IOC(0, 0, 0xf0, 0))) | 59 | #define ANDROID_ALARM_BASE_CMD(cmd) (cmd & ~(_IOC(0, 0, 0xf0, 0))) |
| 62 | #define ANDROID_ALARM_IOCTL_TO_TYPE(cmd) (_IOC_NR(cmd) >> 4) | 60 | #define ANDROID_ALARM_IOCTL_TO_TYPE(cmd) (_IOC_NR(cmd) >> 4) |
diff --git a/drivers/staging/android/binder.c b/drivers/staging/android/binder.c index 7b0ba92e7e46..5d4610babd8a 100644 --- a/drivers/staging/android/binder.c +++ b/drivers/staging/android/binder.c | |||
| @@ -567,7 +567,7 @@ static int binder_update_page_range(struct binder_proc *proc, int allocate, | |||
| 567 | page = &proc->pages[(page_addr - proc->buffer) / PAGE_SIZE]; | 567 | page = &proc->pages[(page_addr - proc->buffer) / PAGE_SIZE]; |
| 568 | 568 | ||
| 569 | BUG_ON(*page); | 569 | BUG_ON(*page); |
| 570 | *page = alloc_page(GFP_KERNEL | __GFP_ZERO); | 570 | *page = alloc_page(GFP_KERNEL | __GFP_HIGHMEM | __GFP_ZERO); |
| 571 | if (*page == NULL) { | 571 | if (*page == NULL) { |
| 572 | pr_err("binder: %d: binder_alloc_buf failed " | 572 | pr_err("binder: %d: binder_alloc_buf failed " |
| 573 | "for page at %p\n", proc->pid, page_addr); | 573 | "for page at %p\n", proc->pid, page_addr); |
| @@ -2419,14 +2419,38 @@ static void binder_release_work(struct list_head *list) | |||
| 2419 | struct binder_transaction *t; | 2419 | struct binder_transaction *t; |
| 2420 | 2420 | ||
| 2421 | t = container_of(w, struct binder_transaction, work); | 2421 | t = container_of(w, struct binder_transaction, work); |
| 2422 | if (t->buffer->target_node && !(t->flags & TF_ONE_WAY)) | 2422 | if (t->buffer->target_node && |
| 2423 | !(t->flags & TF_ONE_WAY)) { | ||
| 2423 | binder_send_failed_reply(t, BR_DEAD_REPLY); | 2424 | binder_send_failed_reply(t, BR_DEAD_REPLY); |
| 2425 | } else { | ||
| 2426 | binder_debug(BINDER_DEBUG_DEAD_TRANSACTION, | ||
| 2427 | "binder: undelivered transaction %d\n", | ||
| 2428 | t->debug_id); | ||
| 2429 | t->buffer->transaction = NULL; | ||
| 2430 | kfree(t); | ||
| 2431 | binder_stats_deleted(BINDER_STAT_TRANSACTION); | ||
| 2432 | } | ||
| 2424 | } break; | 2433 | } break; |
| 2425 | case BINDER_WORK_TRANSACTION_COMPLETE: { | 2434 | case BINDER_WORK_TRANSACTION_COMPLETE: { |
| 2435 | binder_debug(BINDER_DEBUG_DEAD_TRANSACTION, | ||
| 2436 | "binder: undelivered TRANSACTION_COMPLETE\n"); | ||
| 2426 | kfree(w); | 2437 | kfree(w); |
| 2427 | binder_stats_deleted(BINDER_STAT_TRANSACTION_COMPLETE); | 2438 | binder_stats_deleted(BINDER_STAT_TRANSACTION_COMPLETE); |
| 2428 | } break; | 2439 | } break; |
| 2440 | case BINDER_WORK_DEAD_BINDER_AND_CLEAR: | ||
| 2441 | case BINDER_WORK_CLEAR_DEATH_NOTIFICATION: { | ||
| 2442 | struct binder_ref_death *death; | ||
| 2443 | |||
| 2444 | death = container_of(w, struct binder_ref_death, work); | ||
| 2445 | binder_debug(BINDER_DEBUG_DEAD_TRANSACTION, | ||
| 2446 | "binder: undelivered death notification, %p\n", | ||
| 2447 | death->cookie); | ||
| 2448 | kfree(death); | ||
| 2449 | binder_stats_deleted(BINDER_STAT_DEATH); | ||
| 2450 | } break; | ||
| 2429 | default: | 2451 | default: |
| 2452 | pr_err("binder: unexpected work type, %d, not freed\n", | ||
| 2453 | w->type); | ||
| 2430 | break; | 2454 | break; |
| 2431 | } | 2455 | } |
| 2432 | } | 2456 | } |
| @@ -2899,6 +2923,7 @@ static void binder_deferred_release(struct binder_proc *proc) | |||
| 2899 | nodes++; | 2923 | nodes++; |
| 2900 | rb_erase(&node->rb_node, &proc->nodes); | 2924 | rb_erase(&node->rb_node, &proc->nodes); |
| 2901 | list_del_init(&node->work.entry); | 2925 | list_del_init(&node->work.entry); |
| 2926 | binder_release_work(&node->async_todo); | ||
| 2902 | if (hlist_empty(&node->refs)) { | 2927 | if (hlist_empty(&node->refs)) { |
| 2903 | kfree(node); | 2928 | kfree(node); |
| 2904 | binder_stats_deleted(BINDER_STAT_NODE); | 2929 | binder_stats_deleted(BINDER_STAT_NODE); |
| @@ -2937,6 +2962,7 @@ static void binder_deferred_release(struct binder_proc *proc) | |||
| 2937 | binder_delete_ref(ref); | 2962 | binder_delete_ref(ref); |
| 2938 | } | 2963 | } |
| 2939 | binder_release_work(&proc->todo); | 2964 | binder_release_work(&proc->todo); |
| 2965 | binder_release_work(&proc->delivered_death); | ||
| 2940 | buffers = 0; | 2966 | buffers = 0; |
| 2941 | 2967 | ||
| 2942 | while ((n = rb_first(&proc->allocated_buffers))) { | 2968 | while ((n = rb_first(&proc->allocated_buffers))) { |
diff --git a/drivers/staging/comedi/drivers/8255_pci.c b/drivers/staging/comedi/drivers/8255_pci.c index 7dff3c01dc29..d00aff6671df 100644 --- a/drivers/staging/comedi/drivers/8255_pci.c +++ b/drivers/staging/comedi/drivers/8255_pci.c | |||
| @@ -289,6 +289,8 @@ static void pci_8255_detach(struct comedi_device *dev) | |||
| 289 | struct comedi_subdevice *s; | 289 | struct comedi_subdevice *s; |
| 290 | int i; | 290 | int i; |
| 291 | 291 | ||
| 292 | if (!board || !devpriv) | ||
| 293 | return; | ||
| 292 | if (dev->subdevices) { | 294 | if (dev->subdevices) { |
| 293 | for (i = 0; i < board->n_8255; i++) { | 295 | for (i = 0; i < board->n_8255; i++) { |
| 294 | s = &dev->subdevices[i]; | 296 | s = &dev->subdevices[i]; |
diff --git a/drivers/staging/comedi/drivers/amplc_dio200.c b/drivers/staging/comedi/drivers/amplc_dio200.c index 08f305210a69..29eb52d11d2f 100644 --- a/drivers/staging/comedi/drivers/amplc_dio200.c +++ b/drivers/staging/comedi/drivers/amplc_dio200.c | |||
| @@ -1410,6 +1410,8 @@ static void dio200_detach(struct comedi_device *dev) | |||
| 1410 | const struct dio200_layout_struct *layout; | 1410 | const struct dio200_layout_struct *layout; |
| 1411 | unsigned n; | 1411 | unsigned n; |
| 1412 | 1412 | ||
| 1413 | if (!thisboard) | ||
| 1414 | return; | ||
| 1413 | if (dev->irq) | 1415 | if (dev->irq) |
| 1414 | free_irq(dev->irq, dev); | 1416 | free_irq(dev->irq, dev); |
| 1415 | if (dev->subdevices) { | 1417 | if (dev->subdevices) { |
diff --git a/drivers/staging/comedi/drivers/amplc_pc236.c b/drivers/staging/comedi/drivers/amplc_pc236.c index eacb5e4735d7..4e4f3c15df87 100644 --- a/drivers/staging/comedi/drivers/amplc_pc236.c +++ b/drivers/staging/comedi/drivers/amplc_pc236.c | |||
| @@ -573,9 +573,10 @@ static int __devinit pc236_attach_pci(struct comedi_device *dev, | |||
| 573 | static void pc236_detach(struct comedi_device *dev) | 573 | static void pc236_detach(struct comedi_device *dev) |
| 574 | { | 574 | { |
| 575 | const struct pc236_board *thisboard = comedi_board(dev); | 575 | const struct pc236_board *thisboard = comedi_board(dev); |
| 576 | struct pc236_private *devpriv = dev->private; | ||
| 577 | 576 | ||
| 578 | if (devpriv) | 577 | if (!thisboard) |
| 578 | return; | ||
| 579 | if (dev->iobase) | ||
| 579 | pc236_intr_disable(dev); | 580 | pc236_intr_disable(dev); |
| 580 | if (dev->irq) | 581 | if (dev->irq) |
| 581 | free_irq(dev->irq, dev); | 582 | free_irq(dev->irq, dev); |
diff --git a/drivers/staging/comedi/drivers/amplc_pc263.c b/drivers/staging/comedi/drivers/amplc_pc263.c index 60830ccfb903..d0a4c441228b 100644 --- a/drivers/staging/comedi/drivers/amplc_pc263.c +++ b/drivers/staging/comedi/drivers/amplc_pc263.c | |||
| @@ -323,6 +323,8 @@ static void pc263_detach(struct comedi_device *dev) | |||
| 323 | { | 323 | { |
| 324 | const struct pc263_board *thisboard = comedi_board(dev); | 324 | const struct pc263_board *thisboard = comedi_board(dev); |
| 325 | 325 | ||
| 326 | if (!thisboard) | ||
| 327 | return; | ||
| 326 | if (is_isa_board(thisboard)) { | 328 | if (is_isa_board(thisboard)) { |
| 327 | if (dev->iobase) | 329 | if (dev->iobase) |
| 328 | release_region(dev->iobase, PC263_IO_SIZE); | 330 | release_region(dev->iobase, PC263_IO_SIZE); |
diff --git a/drivers/staging/comedi/drivers/das08.c b/drivers/staging/comedi/drivers/das08.c index 5fd21fa6c1c7..c304528cfb13 100644 --- a/drivers/staging/comedi/drivers/das08.c +++ b/drivers/staging/comedi/drivers/das08.c | |||
| @@ -846,6 +846,8 @@ static void __maybe_unused das08_detach(struct comedi_device *dev) | |||
| 846 | { | 846 | { |
| 847 | const struct das08_board_struct *thisboard = comedi_board(dev); | 847 | const struct das08_board_struct *thisboard = comedi_board(dev); |
| 848 | 848 | ||
| 849 | if (!thisboard) | ||
| 850 | return; | ||
| 849 | das08_common_detach(dev); | 851 | das08_common_detach(dev); |
| 850 | if (is_isa_board(thisboard)) { | 852 | if (is_isa_board(thisboard)) { |
| 851 | if (dev->iobase) | 853 | if (dev->iobase) |
diff --git a/drivers/staging/comedi/drivers/ni_daq_700.c b/drivers/staging/comedi/drivers/ni_daq_700.c index 2ba0ade45c64..68d7c6a5db7d 100644 --- a/drivers/staging/comedi/drivers/ni_daq_700.c +++ b/drivers/staging/comedi/drivers/ni_daq_700.c | |||
| @@ -95,7 +95,7 @@ static int daq700_dio_insn_bits(struct comedi_device *dev, | |||
| 95 | } | 95 | } |
| 96 | 96 | ||
| 97 | data[1] = s->state & 0xff; | 97 | data[1] = s->state & 0xff; |
| 98 | data[1] |= inb(dev->iobase + DIO_R); | 98 | data[1] |= inb(dev->iobase + DIO_R) << 8; |
| 99 | 99 | ||
| 100 | return insn->n; | 100 | return insn->n; |
| 101 | } | 101 | } |
diff --git a/drivers/staging/comedi/drivers/ni_labpc.c b/drivers/staging/comedi/drivers/ni_labpc.c index 28b91a6c3789..b5a19a0863fb 100644 --- a/drivers/staging/comedi/drivers/ni_labpc.c +++ b/drivers/staging/comedi/drivers/ni_labpc.c | |||
| @@ -772,6 +772,8 @@ void labpc_common_detach(struct comedi_device *dev) | |||
| 772 | { | 772 | { |
| 773 | struct comedi_subdevice *s; | 773 | struct comedi_subdevice *s; |
| 774 | 774 | ||
| 775 | if (!thisboard) | ||
| 776 | return; | ||
| 775 | if (dev->subdevices) { | 777 | if (dev->subdevices) { |
| 776 | s = &dev->subdevices[2]; | 778 | s = &dev->subdevices[2]; |
| 777 | subdev_8255_cleanup(dev, s); | 779 | subdev_8255_cleanup(dev, s); |
diff --git a/drivers/staging/dgrp/dgrp_mon_ops.c b/drivers/staging/dgrp/dgrp_mon_ops.c index 268dcb95204b..4792d056a365 100644 --- a/drivers/staging/dgrp/dgrp_mon_ops.c +++ b/drivers/staging/dgrp/dgrp_mon_ops.c | |||
| @@ -38,6 +38,7 @@ | |||
| 38 | #include <linux/sched.h> | 38 | #include <linux/sched.h> |
| 39 | #include <asm/unaligned.h> | 39 | #include <asm/unaligned.h> |
| 40 | #include <linux/proc_fs.h> | 40 | #include <linux/proc_fs.h> |
| 41 | #include <linux/uaccess.h> | ||
| 41 | 42 | ||
| 42 | #include "dgrp_common.h" | 43 | #include "dgrp_common.h" |
| 43 | 44 | ||
diff --git a/drivers/staging/dgrp/dgrp_specproc.c b/drivers/staging/dgrp/dgrp_specproc.c index 28f5c9ab6b43..24327c3bad83 100644 --- a/drivers/staging/dgrp/dgrp_specproc.c +++ b/drivers/staging/dgrp/dgrp_specproc.c | |||
| @@ -39,6 +39,7 @@ | |||
| 39 | #include <linux/proc_fs.h> | 39 | #include <linux/proc_fs.h> |
| 40 | #include <linux/ctype.h> | 40 | #include <linux/ctype.h> |
| 41 | #include <linux/seq_file.h> | 41 | #include <linux/seq_file.h> |
| 42 | #include <linux/uaccess.h> | ||
| 42 | #include <linux/vmalloc.h> | 43 | #include <linux/vmalloc.h> |
| 43 | 44 | ||
| 44 | #include "dgrp_common.h" | 45 | #include "dgrp_common.h" |
| @@ -228,6 +229,9 @@ static void register_proc_table(struct dgrp_proc_entry *table, | |||
| 228 | int len; | 229 | int len; |
| 229 | mode_t mode; | 230 | mode_t mode; |
| 230 | 231 | ||
| 232 | if (table == NULL) | ||
| 233 | return; | ||
| 234 | |||
| 231 | for (; table->id; table++) { | 235 | for (; table->id; table++) { |
| 232 | /* Can't do anything without a proc name. */ | 236 | /* Can't do anything without a proc name. */ |
| 233 | if (!table->name) | 237 | if (!table->name) |
| @@ -296,6 +300,9 @@ static void unregister_proc_table(struct dgrp_proc_entry *table, | |||
| 296 | struct proc_dir_entry *de; | 300 | struct proc_dir_entry *de; |
| 297 | struct nd_struct *tmp; | 301 | struct nd_struct *tmp; |
| 298 | 302 | ||
| 303 | if (table == NULL) | ||
| 304 | return; | ||
| 305 | |||
| 299 | list_for_each_entry(tmp, &nd_struct_list, list) { | 306 | list_for_each_entry(tmp, &nd_struct_list, list) { |
| 300 | if ((table == dgrp_net_table) && (tmp->nd_net_de)) { | 307 | if ((table == dgrp_net_table) && (tmp->nd_net_de)) { |
| 301 | unregister_dgrp_device(tmp->nd_net_de); | 308 | unregister_dgrp_device(tmp->nd_net_de); |
diff --git a/drivers/staging/dgrp/dgrp_tty.c b/drivers/staging/dgrp/dgrp_tty.c index 7d7de873870c..e125b03598d7 100644 --- a/drivers/staging/dgrp/dgrp_tty.c +++ b/drivers/staging/dgrp/dgrp_tty.c | |||
| @@ -40,6 +40,7 @@ | |||
| 40 | #include <linux/tty.h> | 40 | #include <linux/tty.h> |
| 41 | #include <linux/tty_flip.h> | 41 | #include <linux/tty_flip.h> |
| 42 | #include <linux/sched.h> | 42 | #include <linux/sched.h> |
| 43 | #include <linux/uaccess.h> | ||
| 43 | 44 | ||
| 44 | #include "dgrp_common.h" | 45 | #include "dgrp_common.h" |
| 45 | 46 | ||
| @@ -3172,6 +3173,9 @@ dgrp_tty_init(struct nd_struct *nd) | |||
| 3172 | */ | 3173 | */ |
| 3173 | 3174 | ||
| 3174 | nd->nd_serial_ttdriver = alloc_tty_driver(CHAN_MAX); | 3175 | nd->nd_serial_ttdriver = alloc_tty_driver(CHAN_MAX); |
| 3176 | if (!nd->nd_serial_ttdriver) | ||
| 3177 | return -ENOMEM; | ||
| 3178 | |||
| 3175 | sprintf(nd->nd_serial_name, "tty_dgrp_%s_", id); | 3179 | sprintf(nd->nd_serial_name, "tty_dgrp_%s_", id); |
| 3176 | 3180 | ||
| 3177 | nd->nd_serial_ttdriver->owner = THIS_MODULE; | 3181 | nd->nd_serial_ttdriver->owner = THIS_MODULE; |
| @@ -3231,6 +3235,9 @@ dgrp_tty_init(struct nd_struct *nd) | |||
| 3231 | } | 3235 | } |
| 3232 | 3236 | ||
| 3233 | nd->nd_callout_ttdriver = alloc_tty_driver(CHAN_MAX); | 3237 | nd->nd_callout_ttdriver = alloc_tty_driver(CHAN_MAX); |
| 3238 | if (!nd->nd_callout_ttdriver) | ||
| 3239 | return -ENOMEM; | ||
| 3240 | |||
| 3234 | sprintf(nd->nd_callout_name, "cu_dgrp_%s_", id); | 3241 | sprintf(nd->nd_callout_name, "cu_dgrp_%s_", id); |
| 3235 | 3242 | ||
| 3236 | nd->nd_callout_ttdriver->owner = THIS_MODULE; | 3243 | nd->nd_callout_ttdriver->owner = THIS_MODULE; |
| @@ -3268,6 +3275,9 @@ dgrp_tty_init(struct nd_struct *nd) | |||
| 3268 | 3275 | ||
| 3269 | 3276 | ||
| 3270 | nd->nd_xprint_ttdriver = alloc_tty_driver(CHAN_MAX); | 3277 | nd->nd_xprint_ttdriver = alloc_tty_driver(CHAN_MAX); |
| 3278 | if (!nd->nd_xprint_ttdriver) | ||
| 3279 | return -ENOMEM; | ||
| 3280 | |||
| 3271 | sprintf(nd->nd_xprint_name, "pr_dgrp_%s_", id); | 3281 | sprintf(nd->nd_xprint_name, "pr_dgrp_%s_", id); |
| 3272 | 3282 | ||
| 3273 | nd->nd_xprint_ttdriver->owner = THIS_MODULE; | 3283 | nd->nd_xprint_ttdriver->owner = THIS_MODULE; |
diff --git a/drivers/staging/iio/accel/adis16201_core.c b/drivers/staging/iio/accel/adis16201_core.c index 8e37d6e04277..b12ca68cd9e4 100644 --- a/drivers/staging/iio/accel/adis16201_core.c +++ b/drivers/staging/iio/accel/adis16201_core.c | |||
| @@ -310,30 +310,32 @@ static int adis16201_read_raw(struct iio_dev *indio_dev, | |||
| 310 | case IIO_CHAN_INFO_SCALE: | 310 | case IIO_CHAN_INFO_SCALE: |
| 311 | switch (chan->type) { | 311 | switch (chan->type) { |
| 312 | case IIO_VOLTAGE: | 312 | case IIO_VOLTAGE: |
| 313 | *val = 0; | 313 | if (chan->channel == 0) { |
| 314 | if (chan->channel == 0) | 314 | *val = 1; |
| 315 | *val2 = 1220; | 315 | *val2 = 220000; /* 1.22 mV */ |
| 316 | else | 316 | } else { |
| 317 | *val2 = 610; | 317 | *val = 0; |
| 318 | *val2 = 610000; /* 0.610 mV */ | ||
| 319 | } | ||
| 318 | return IIO_VAL_INT_PLUS_MICRO; | 320 | return IIO_VAL_INT_PLUS_MICRO; |
| 319 | case IIO_TEMP: | 321 | case IIO_TEMP: |
| 320 | *val = 0; | 322 | *val = -470; /* 0.47 C */ |
| 321 | *val2 = -470000; | 323 | *val2 = 0; |
| 322 | return IIO_VAL_INT_PLUS_MICRO; | 324 | return IIO_VAL_INT_PLUS_MICRO; |
| 323 | case IIO_ACCEL: | 325 | case IIO_ACCEL: |
| 324 | *val = 0; | 326 | *val = 0; |
| 325 | *val2 = 462500; | 327 | *val2 = IIO_G_TO_M_S_2(462400); /* 0.4624 mg */ |
| 326 | return IIO_VAL_INT_PLUS_MICRO; | 328 | return IIO_VAL_INT_PLUS_NANO; |
| 327 | case IIO_INCLI: | 329 | case IIO_INCLI: |
| 328 | *val = 0; | 330 | *val = 0; |
| 329 | *val2 = 100000; | 331 | *val2 = 100000; /* 0.1 degree */ |
| 330 | return IIO_VAL_INT_PLUS_MICRO; | 332 | return IIO_VAL_INT_PLUS_MICRO; |
| 331 | default: | 333 | default: |
| 332 | return -EINVAL; | 334 | return -EINVAL; |
| 333 | } | 335 | } |
| 334 | break; | 336 | break; |
| 335 | case IIO_CHAN_INFO_OFFSET: | 337 | case IIO_CHAN_INFO_OFFSET: |
| 336 | *val = 25; | 338 | *val = 25000 / -470 - 1278; /* 25 C = 1278 */ |
| 337 | return IIO_VAL_INT; | 339 | return IIO_VAL_INT; |
| 338 | case IIO_CHAN_INFO_CALIBBIAS: | 340 | case IIO_CHAN_INFO_CALIBBIAS: |
| 339 | switch (chan->type) { | 341 | switch (chan->type) { |
diff --git a/drivers/staging/iio/accel/adis16203_core.c b/drivers/staging/iio/accel/adis16203_core.c index 002fa9dfc375..e7b3441115ae 100644 --- a/drivers/staging/iio/accel/adis16203_core.c +++ b/drivers/staging/iio/accel/adis16203_core.c | |||
| @@ -316,25 +316,27 @@ static int adis16203_read_raw(struct iio_dev *indio_dev, | |||
| 316 | case IIO_CHAN_INFO_SCALE: | 316 | case IIO_CHAN_INFO_SCALE: |
| 317 | switch (chan->type) { | 317 | switch (chan->type) { |
| 318 | case IIO_VOLTAGE: | 318 | case IIO_VOLTAGE: |
| 319 | *val = 0; | 319 | if (chan->channel == 0) { |
| 320 | if (chan->channel == 0) | 320 | *val = 1; |
| 321 | *val2 = 1220; | 321 | *val2 = 220000; /* 1.22 mV */ |
| 322 | else | 322 | } else { |
| 323 | *val2 = 610; | 323 | *val = 0; |
| 324 | *val2 = 610000; /* 0.61 mV */ | ||
| 325 | } | ||
| 324 | return IIO_VAL_INT_PLUS_MICRO; | 326 | return IIO_VAL_INT_PLUS_MICRO; |
| 325 | case IIO_TEMP: | 327 | case IIO_TEMP: |
| 326 | *val = 0; | 328 | *val = -470; /* -0.47 C */ |
| 327 | *val2 = -470000; | 329 | *val2 = 0; |
| 328 | return IIO_VAL_INT_PLUS_MICRO; | 330 | return IIO_VAL_INT_PLUS_MICRO; |
| 329 | case IIO_INCLI: | 331 | case IIO_INCLI: |
| 330 | *val = 0; | 332 | *val = 0; |
| 331 | *val2 = 25000; | 333 | *val2 = 25000; /* 0.025 degree */ |
| 332 | return IIO_VAL_INT_PLUS_MICRO; | 334 | return IIO_VAL_INT_PLUS_MICRO; |
| 333 | default: | 335 | default: |
| 334 | return -EINVAL; | 336 | return -EINVAL; |
| 335 | } | 337 | } |
| 336 | case IIO_CHAN_INFO_OFFSET: | 338 | case IIO_CHAN_INFO_OFFSET: |
| 337 | *val = 25; | 339 | *val = 25000 / -470 - 1278; /* 25 C = 1278 */ |
| 338 | return IIO_VAL_INT; | 340 | return IIO_VAL_INT; |
| 339 | case IIO_CHAN_INFO_CALIBBIAS: | 341 | case IIO_CHAN_INFO_CALIBBIAS: |
| 340 | bits = 14; | 342 | bits = 14; |
diff --git a/drivers/staging/iio/accel/adis16204_core.c b/drivers/staging/iio/accel/adis16204_core.c index 05bdb7c2c8e3..c6234c2f46aa 100644 --- a/drivers/staging/iio/accel/adis16204_core.c +++ b/drivers/staging/iio/accel/adis16204_core.c | |||
| @@ -317,26 +317,28 @@ static int adis16204_read_raw(struct iio_dev *indio_dev, | |||
| 317 | case IIO_CHAN_INFO_SCALE: | 317 | case IIO_CHAN_INFO_SCALE: |
| 318 | switch (chan->type) { | 318 | switch (chan->type) { |
| 319 | case IIO_VOLTAGE: | 319 | case IIO_VOLTAGE: |
| 320 | *val = 0; | 320 | if (chan->channel == 0) { |
| 321 | if (chan->channel == 0) | 321 | *val = 1; |
| 322 | *val2 = 1220; | 322 | *val2 = 220000; /* 1.22 mV */ |
| 323 | else | 323 | } else { |
| 324 | *val2 = 610; | 324 | *val = 0; |
| 325 | *val2 = 610000; /* 0.61 mV */ | ||
| 326 | } | ||
| 325 | return IIO_VAL_INT_PLUS_MICRO; | 327 | return IIO_VAL_INT_PLUS_MICRO; |
| 326 | case IIO_TEMP: | 328 | case IIO_TEMP: |
| 327 | *val = 0; | 329 | *val = -470; /* 0.47 C */ |
| 328 | *val2 = -470000; | 330 | *val2 = 0; |
| 329 | return IIO_VAL_INT_PLUS_MICRO; | 331 | return IIO_VAL_INT_PLUS_MICRO; |
| 330 | case IIO_ACCEL: | 332 | case IIO_ACCEL: |
| 331 | *val = 0; | 333 | *val = 0; |
| 332 | switch (chan->channel2) { | 334 | switch (chan->channel2) { |
| 333 | case IIO_MOD_X: | 335 | case IIO_MOD_X: |
| 334 | case IIO_MOD_ROOT_SUM_SQUARED_X_Y: | 336 | case IIO_MOD_ROOT_SUM_SQUARED_X_Y: |
| 335 | *val2 = 17125; | 337 | *val2 = IIO_G_TO_M_S_2(17125); /* 17.125 mg */ |
| 336 | break; | 338 | break; |
| 337 | case IIO_MOD_Y: | 339 | case IIO_MOD_Y: |
| 338 | case IIO_MOD_Z: | 340 | case IIO_MOD_Z: |
| 339 | *val2 = 8407; | 341 | *val2 = IIO_G_TO_M_S_2(8407); /* 8.407 mg */ |
| 340 | break; | 342 | break; |
| 341 | } | 343 | } |
| 342 | return IIO_VAL_INT_PLUS_MICRO; | 344 | return IIO_VAL_INT_PLUS_MICRO; |
| @@ -345,7 +347,7 @@ static int adis16204_read_raw(struct iio_dev *indio_dev, | |||
| 345 | } | 347 | } |
| 346 | break; | 348 | break; |
| 347 | case IIO_CHAN_INFO_OFFSET: | 349 | case IIO_CHAN_INFO_OFFSET: |
| 348 | *val = 25; | 350 | *val = 25000 / -470 - 1278; /* 25 C = 1278 */ |
| 349 | return IIO_VAL_INT; | 351 | return IIO_VAL_INT; |
| 350 | case IIO_CHAN_INFO_CALIBBIAS: | 352 | case IIO_CHAN_INFO_CALIBBIAS: |
| 351 | case IIO_CHAN_INFO_PEAK: | 353 | case IIO_CHAN_INFO_PEAK: |
diff --git a/drivers/staging/iio/accel/adis16209_core.c b/drivers/staging/iio/accel/adis16209_core.c index b7333bfe0b2f..7ee974b45d7d 100644 --- a/drivers/staging/iio/accel/adis16209_core.c +++ b/drivers/staging/iio/accel/adis16209_core.c | |||
| @@ -343,28 +343,29 @@ static int adis16209_read_raw(struct iio_dev *indio_dev, | |||
| 343 | case IIO_VOLTAGE: | 343 | case IIO_VOLTAGE: |
| 344 | *val = 0; | 344 | *val = 0; |
| 345 | if (chan->channel == 0) | 345 | if (chan->channel == 0) |
| 346 | *val2 = 305180; | 346 | *val2 = 305180; /* 0.30518 mV */ |
| 347 | else | 347 | else |
| 348 | *val2 = 610500; | 348 | *val2 = 610500; /* 0.6105 mV */ |
| 349 | return IIO_VAL_INT_PLUS_MICRO; | 349 | return IIO_VAL_INT_PLUS_MICRO; |
| 350 | case IIO_TEMP: | 350 | case IIO_TEMP: |
| 351 | *val = 0; | 351 | *val = -470; /* -0.47 C */ |
| 352 | *val2 = -470000; | 352 | *val2 = 0; |
| 353 | return IIO_VAL_INT_PLUS_MICRO; | 353 | return IIO_VAL_INT_PLUS_MICRO; |
| 354 | case IIO_ACCEL: | 354 | case IIO_ACCEL: |
| 355 | *val = 0; | 355 | *val = 0; |
| 356 | *val2 = 2394; | 356 | *val2 = IIO_G_TO_M_S_2(244140); /* 0.244140 mg */ |
| 357 | return IIO_VAL_INT_PLUS_MICRO; | 357 | return IIO_VAL_INT_PLUS_NANO; |
| 358 | case IIO_INCLI: | 358 | case IIO_INCLI: |
| 359 | case IIO_ROT: | ||
| 359 | *val = 0; | 360 | *val = 0; |
| 360 | *val2 = 436; | 361 | *val2 = 25000; /* 0.025 degree */ |
| 361 | return IIO_VAL_INT_PLUS_MICRO; | 362 | return IIO_VAL_INT_PLUS_MICRO; |
| 362 | default: | 363 | default: |
| 363 | return -EINVAL; | 364 | return -EINVAL; |
| 364 | } | 365 | } |
| 365 | break; | 366 | break; |
| 366 | case IIO_CHAN_INFO_OFFSET: | 367 | case IIO_CHAN_INFO_OFFSET: |
| 367 | *val = 25; | 368 | *val = 25000 / -470 - 0x4FE; /* 25 C = 0x4FE */ |
| 368 | return IIO_VAL_INT; | 369 | return IIO_VAL_INT; |
| 369 | case IIO_CHAN_INFO_CALIBBIAS: | 370 | case IIO_CHAN_INFO_CALIBBIAS: |
| 370 | switch (chan->type) { | 371 | switch (chan->type) { |
| @@ -491,6 +492,7 @@ static const struct iio_chan_spec adis16209_channels[] = { | |||
| 491 | .modified = 1, | 492 | .modified = 1, |
| 492 | .channel2 = IIO_MOD_X, | 493 | .channel2 = IIO_MOD_X, |
| 493 | .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT, | 494 | .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT, |
| 495 | IIO_CHAN_INFO_SCALE_SHARED_BIT, | ||
| 494 | .address = rot, | 496 | .address = rot, |
| 495 | .scan_index = ADIS16209_SCAN_ROT, | 497 | .scan_index = ADIS16209_SCAN_ROT, |
| 496 | .scan_type = { | 498 | .scan_type = { |
diff --git a/drivers/staging/iio/accel/adis16220_core.c b/drivers/staging/iio/accel/adis16220_core.c index c755089c7117..eaadd9df3f78 100644 --- a/drivers/staging/iio/accel/adis16220_core.c +++ b/drivers/staging/iio/accel/adis16220_core.c | |||
| @@ -486,7 +486,7 @@ static int adis16220_read_raw(struct iio_dev *indio_dev, | |||
| 486 | break; | 486 | break; |
| 487 | case IIO_CHAN_INFO_OFFSET: | 487 | case IIO_CHAN_INFO_OFFSET: |
| 488 | if (chan->type == IIO_TEMP) { | 488 | if (chan->type == IIO_TEMP) { |
| 489 | *val = 25; | 489 | *val = 25000 / -470 - 1278; /* 25 C = 1278 */ |
| 490 | return IIO_VAL_INT; | 490 | return IIO_VAL_INT; |
| 491 | } | 491 | } |
| 492 | addrind = 1; | 492 | addrind = 1; |
| @@ -495,19 +495,22 @@ static int adis16220_read_raw(struct iio_dev *indio_dev, | |||
| 495 | addrind = 2; | 495 | addrind = 2; |
| 496 | break; | 496 | break; |
| 497 | case IIO_CHAN_INFO_SCALE: | 497 | case IIO_CHAN_INFO_SCALE: |
| 498 | *val = 0; | ||
| 499 | switch (chan->type) { | 498 | switch (chan->type) { |
| 500 | case IIO_TEMP: | 499 | case IIO_TEMP: |
| 501 | *val2 = -470000; | 500 | *val = -470; /* -0.47 C */ |
| 501 | *val2 = 0; | ||
| 502 | return IIO_VAL_INT_PLUS_MICRO; | 502 | return IIO_VAL_INT_PLUS_MICRO; |
| 503 | case IIO_ACCEL: | 503 | case IIO_ACCEL: |
| 504 | *val2 = 1887042; | 504 | *val2 = IIO_G_TO_M_S_2(19073); /* 19.073 g */ |
| 505 | return IIO_VAL_INT_PLUS_MICRO; | 505 | return IIO_VAL_INT_PLUS_MICRO; |
| 506 | case IIO_VOLTAGE: | 506 | case IIO_VOLTAGE: |
| 507 | if (chan->channel == 0) | 507 | if (chan->channel == 0) { |
| 508 | *val2 = 0012221; | 508 | *val = 1; |
| 509 | else /* Should really be dependent on VDD */ | 509 | *val2 = 220700; /* 1.2207 mV */ |
| 510 | *val2 = 305; | 510 | } else { |
| 511 | /* Should really be dependent on VDD */ | ||
| 512 | *val2 = 305180; /* 305.18 uV */ | ||
| 513 | } | ||
| 511 | return IIO_VAL_INT_PLUS_MICRO; | 514 | return IIO_VAL_INT_PLUS_MICRO; |
| 512 | default: | 515 | default: |
| 513 | return -EINVAL; | 516 | return -EINVAL; |
diff --git a/drivers/staging/iio/accel/adis16240_core.c b/drivers/staging/iio/accel/adis16240_core.c index 0fc26a49d681..35e093973d5c 100644 --- a/drivers/staging/iio/accel/adis16240_core.c +++ b/drivers/staging/iio/accel/adis16240_core.c | |||
| @@ -373,30 +373,31 @@ static int adis16240_read_raw(struct iio_dev *indio_dev, | |||
| 373 | case IIO_CHAN_INFO_SCALE: | 373 | case IIO_CHAN_INFO_SCALE: |
| 374 | switch (chan->type) { | 374 | switch (chan->type) { |
| 375 | case IIO_VOLTAGE: | 375 | case IIO_VOLTAGE: |
| 376 | *val = 0; | 376 | if (chan->channel == 0) { |
| 377 | if (chan->channel == 0) | 377 | *val = 4; |
| 378 | *val2 = 4880; | 378 | *val2 = 880000; /* 4.88 mV */ |
| 379 | else | 379 | return IIO_VAL_INT_PLUS_MICRO; |
| 380 | } else { | ||
| 380 | return -EINVAL; | 381 | return -EINVAL; |
| 381 | return IIO_VAL_INT_PLUS_MICRO; | 382 | } |
| 382 | case IIO_TEMP: | 383 | case IIO_TEMP: |
| 383 | *val = 0; | 384 | *val = 244; /* 0.244 C */ |
| 384 | *val2 = 244000; | 385 | *val2 = 0; |
| 385 | return IIO_VAL_INT_PLUS_MICRO; | 386 | return IIO_VAL_INT_PLUS_MICRO; |
| 386 | case IIO_ACCEL: | 387 | case IIO_ACCEL: |
| 387 | *val = 0; | 388 | *val = 0; |
| 388 | *val2 = 504062; | 389 | *val2 = IIO_G_TO_M_S_2(51400); /* 51.4 mg */ |
| 389 | return IIO_VAL_INT_PLUS_MICRO; | 390 | return IIO_VAL_INT_PLUS_MICRO; |
| 390 | default: | 391 | default: |
| 391 | return -EINVAL; | 392 | return -EINVAL; |
| 392 | } | 393 | } |
| 393 | break; | 394 | break; |
| 394 | case IIO_CHAN_INFO_PEAK_SCALE: | 395 | case IIO_CHAN_INFO_PEAK_SCALE: |
| 395 | *val = 6; | 396 | *val = 0; |
| 396 | *val2 = 629295; | 397 | *val2 = IIO_G_TO_M_S_2(51400); /* 51.4 mg */ |
| 397 | return IIO_VAL_INT_PLUS_MICRO; | 398 | return IIO_VAL_INT_PLUS_MICRO; |
| 398 | case IIO_CHAN_INFO_OFFSET: | 399 | case IIO_CHAN_INFO_OFFSET: |
| 399 | *val = 25; | 400 | *val = 25000 / 244 - 0x133; /* 25 C = 0x133 */ |
| 400 | return IIO_VAL_INT; | 401 | return IIO_VAL_INT; |
| 401 | case IIO_CHAN_INFO_CALIBBIAS: | 402 | case IIO_CHAN_INFO_CALIBBIAS: |
| 402 | bits = 10; | 403 | bits = 10; |
diff --git a/drivers/staging/iio/gyro/adis16260_core.c b/drivers/staging/iio/gyro/adis16260_core.c index 9571c03aa4cc..aa964a2d8290 100644 --- a/drivers/staging/iio/gyro/adis16260_core.c +++ b/drivers/staging/iio/gyro/adis16260_core.c | |||
| @@ -498,28 +498,33 @@ static int adis16260_read_raw(struct iio_dev *indio_dev, | |||
| 498 | switch (chan->type) { | 498 | switch (chan->type) { |
| 499 | case IIO_ANGL_VEL: | 499 | case IIO_ANGL_VEL: |
| 500 | *val = 0; | 500 | *val = 0; |
| 501 | if (spi_get_device_id(st->us)->driver_data) | 501 | if (spi_get_device_id(st->us)->driver_data) { |
| 502 | *val2 = 320; | 502 | /* 0.01832 degree / sec */ |
| 503 | else | 503 | *val2 = IIO_DEGREE_TO_RAD(18320); |
| 504 | *val2 = 1278; | 504 | } else { |
| 505 | /* 0.07326 degree / sec */ | ||
| 506 | *val2 = IIO_DEGREE_TO_RAD(73260); | ||
| 507 | } | ||
| 505 | return IIO_VAL_INT_PLUS_MICRO; | 508 | return IIO_VAL_INT_PLUS_MICRO; |
| 506 | case IIO_VOLTAGE: | 509 | case IIO_VOLTAGE: |
| 507 | *val = 0; | 510 | if (chan->channel == 0) { |
| 508 | if (chan->channel == 0) | 511 | *val = 1; |
| 509 | *val2 = 18315; | 512 | *val2 = 831500; /* 1.8315 mV */ |
| 510 | else | 513 | } else { |
| 511 | *val2 = 610500; | 514 | *val = 0; |
| 515 | *val2 = 610500; /* 610.5 uV */ | ||
| 516 | } | ||
| 512 | return IIO_VAL_INT_PLUS_MICRO; | 517 | return IIO_VAL_INT_PLUS_MICRO; |
| 513 | case IIO_TEMP: | 518 | case IIO_TEMP: |
| 514 | *val = 0; | 519 | *val = 145; |
| 515 | *val2 = 145300; | 520 | *val2 = 300000; /* 0.1453 C */ |
| 516 | return IIO_VAL_INT_PLUS_MICRO; | 521 | return IIO_VAL_INT_PLUS_MICRO; |
| 517 | default: | 522 | default: |
| 518 | return -EINVAL; | 523 | return -EINVAL; |
| 519 | } | 524 | } |
| 520 | break; | 525 | break; |
| 521 | case IIO_CHAN_INFO_OFFSET: | 526 | case IIO_CHAN_INFO_OFFSET: |
| 522 | *val = 25; | 527 | *val = 250000 / 1453; /* 25 C = 0x00 */ |
| 523 | return IIO_VAL_INT; | 528 | return IIO_VAL_INT; |
| 524 | case IIO_CHAN_INFO_CALIBBIAS: | 529 | case IIO_CHAN_INFO_CALIBBIAS: |
| 525 | switch (chan->type) { | 530 | switch (chan->type) { |
diff --git a/drivers/staging/iio/imu/adis16400.h b/drivers/staging/iio/imu/adis16400.h index d59d7ac856a9..77c601da1846 100644 --- a/drivers/staging/iio/imu/adis16400.h +++ b/drivers/staging/iio/imu/adis16400.h | |||
| @@ -139,6 +139,8 @@ struct adis16400_chip_info { | |||
| 139 | const long flags; | 139 | const long flags; |
| 140 | unsigned int gyro_scale_micro; | 140 | unsigned int gyro_scale_micro; |
| 141 | unsigned int accel_scale_micro; | 141 | unsigned int accel_scale_micro; |
| 142 | int temp_scale_nano; | ||
| 143 | int temp_offset; | ||
| 142 | unsigned long default_scan_mask; | 144 | unsigned long default_scan_mask; |
| 143 | }; | 145 | }; |
| 144 | 146 | ||
diff --git a/drivers/staging/iio/imu/adis16400_core.c b/drivers/staging/iio/imu/adis16400_core.c index b302c9ba2712..3144a7b1e1c4 100644 --- a/drivers/staging/iio/imu/adis16400_core.c +++ b/drivers/staging/iio/imu/adis16400_core.c | |||
| @@ -553,10 +553,13 @@ static int adis16400_read_raw(struct iio_dev *indio_dev, | |||
| 553 | return IIO_VAL_INT_PLUS_MICRO; | 553 | return IIO_VAL_INT_PLUS_MICRO; |
| 554 | case IIO_VOLTAGE: | 554 | case IIO_VOLTAGE: |
| 555 | *val = 0; | 555 | *val = 0; |
| 556 | if (chan->channel == 0) | 556 | if (chan->channel == 0) { |
| 557 | *val2 = 2418; | 557 | *val = 2; |
| 558 | else | 558 | *val2 = 418000; /* 2.418 mV */ |
| 559 | *val2 = 806; | 559 | } else { |
| 560 | *val = 0; | ||
| 561 | *val2 = 805800; /* 805.8 uV */ | ||
| 562 | } | ||
| 560 | return IIO_VAL_INT_PLUS_MICRO; | 563 | return IIO_VAL_INT_PLUS_MICRO; |
| 561 | case IIO_ACCEL: | 564 | case IIO_ACCEL: |
| 562 | *val = 0; | 565 | *val = 0; |
| @@ -564,11 +567,11 @@ static int adis16400_read_raw(struct iio_dev *indio_dev, | |||
| 564 | return IIO_VAL_INT_PLUS_MICRO; | 567 | return IIO_VAL_INT_PLUS_MICRO; |
| 565 | case IIO_MAGN: | 568 | case IIO_MAGN: |
| 566 | *val = 0; | 569 | *val = 0; |
| 567 | *val2 = 500; | 570 | *val2 = 500; /* 0.5 mgauss */ |
| 568 | return IIO_VAL_INT_PLUS_MICRO; | 571 | return IIO_VAL_INT_PLUS_MICRO; |
| 569 | case IIO_TEMP: | 572 | case IIO_TEMP: |
| 570 | *val = 0; | 573 | *val = st->variant->temp_scale_nano / 1000000; |
| 571 | *val2 = 140000; | 574 | *val2 = (st->variant->temp_scale_nano % 1000000); |
| 572 | return IIO_VAL_INT_PLUS_MICRO; | 575 | return IIO_VAL_INT_PLUS_MICRO; |
| 573 | default: | 576 | default: |
| 574 | return -EINVAL; | 577 | return -EINVAL; |
| @@ -586,9 +589,8 @@ static int adis16400_read_raw(struct iio_dev *indio_dev, | |||
| 586 | return IIO_VAL_INT; | 589 | return IIO_VAL_INT; |
| 587 | case IIO_CHAN_INFO_OFFSET: | 590 | case IIO_CHAN_INFO_OFFSET: |
| 588 | /* currently only temperature */ | 591 | /* currently only temperature */ |
| 589 | *val = 198; | 592 | *val = st->variant->temp_offset; |
| 590 | *val2 = 160000; | 593 | return IIO_VAL_INT; |
| 591 | return IIO_VAL_INT_PLUS_MICRO; | ||
| 592 | case IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY: | 594 | case IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY: |
| 593 | mutex_lock(&indio_dev->mlock); | 595 | mutex_lock(&indio_dev->mlock); |
| 594 | /* Need both the number of taps and the sampling frequency */ | 596 | /* Need both the number of taps and the sampling frequency */ |
| @@ -1035,7 +1037,7 @@ static const struct iio_chan_spec adis16334_channels[] = { | |||
| 1035 | .indexed = 1, | 1037 | .indexed = 1, |
| 1036 | .channel = 0, | 1038 | .channel = 0, |
| 1037 | .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | | 1039 | .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | |
| 1038 | IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT | | 1040 | IIO_CHAN_INFO_OFFSET_SEPARATE_BIT | |
| 1039 | IIO_CHAN_INFO_SCALE_SHARED_BIT, | 1041 | IIO_CHAN_INFO_SCALE_SHARED_BIT, |
| 1040 | .address = temp0, | 1042 | .address = temp0, |
| 1041 | .scan_index = ADIS16400_SCAN_TEMP, | 1043 | .scan_index = ADIS16400_SCAN_TEMP, |
| @@ -1058,8 +1060,10 @@ static struct adis16400_chip_info adis16400_chips[] = { | |||
| 1058 | [ADIS16300] = { | 1060 | [ADIS16300] = { |
| 1059 | .channels = adis16300_channels, | 1061 | .channels = adis16300_channels, |
| 1060 | .num_channels = ARRAY_SIZE(adis16300_channels), | 1062 | .num_channels = ARRAY_SIZE(adis16300_channels), |
| 1061 | .gyro_scale_micro = 873, | 1063 | .gyro_scale_micro = IIO_DEGREE_TO_RAD(50000), /* 0.05 deg/s */ |
| 1062 | .accel_scale_micro = 5884, | 1064 | .accel_scale_micro = 5884, |
| 1065 | .temp_scale_nano = 140000000, /* 0.14 C */ | ||
| 1066 | .temp_offset = 25000000 / 140000, /* 25 C = 0x00 */ | ||
| 1063 | .default_scan_mask = (1 << ADIS16400_SCAN_SUPPLY) | | 1067 | .default_scan_mask = (1 << ADIS16400_SCAN_SUPPLY) | |
| 1064 | (1 << ADIS16400_SCAN_GYRO_X) | (1 << ADIS16400_SCAN_ACC_X) | | 1068 | (1 << ADIS16400_SCAN_GYRO_X) | (1 << ADIS16400_SCAN_ACC_X) | |
| 1065 | (1 << ADIS16400_SCAN_ACC_Y) | (1 << ADIS16400_SCAN_ACC_Z) | | 1069 | (1 << ADIS16400_SCAN_ACC_Y) | (1 << ADIS16400_SCAN_ACC_Z) | |
| @@ -1070,8 +1074,10 @@ static struct adis16400_chip_info adis16400_chips[] = { | |||
| 1070 | [ADIS16334] = { | 1074 | [ADIS16334] = { |
| 1071 | .channels = adis16334_channels, | 1075 | .channels = adis16334_channels, |
| 1072 | .num_channels = ARRAY_SIZE(adis16334_channels), | 1076 | .num_channels = ARRAY_SIZE(adis16334_channels), |
| 1073 | .gyro_scale_micro = 873, | 1077 | .gyro_scale_micro = IIO_DEGREE_TO_RAD(50000), /* 0.05 deg/s */ |
| 1074 | .accel_scale_micro = 981, | 1078 | .accel_scale_micro = IIO_G_TO_M_S_2(1000), /* 1 mg */ |
| 1079 | .temp_scale_nano = 67850000, /* 0.06785 C */ | ||
| 1080 | .temp_offset = 25000000 / 67850, /* 25 C = 0x00 */ | ||
| 1075 | .default_scan_mask = (1 << ADIS16400_SCAN_GYRO_X) | | 1081 | .default_scan_mask = (1 << ADIS16400_SCAN_GYRO_X) | |
| 1076 | (1 << ADIS16400_SCAN_GYRO_Y) | (1 << ADIS16400_SCAN_GYRO_Z) | | 1082 | (1 << ADIS16400_SCAN_GYRO_Y) | (1 << ADIS16400_SCAN_GYRO_Z) | |
| 1077 | (1 << ADIS16400_SCAN_ACC_X) | (1 << ADIS16400_SCAN_ACC_Y) | | 1083 | (1 << ADIS16400_SCAN_ACC_X) | (1 << ADIS16400_SCAN_ACC_Y) | |
| @@ -1080,8 +1086,10 @@ static struct adis16400_chip_info adis16400_chips[] = { | |||
| 1080 | [ADIS16350] = { | 1086 | [ADIS16350] = { |
| 1081 | .channels = adis16350_channels, | 1087 | .channels = adis16350_channels, |
| 1082 | .num_channels = ARRAY_SIZE(adis16350_channels), | 1088 | .num_channels = ARRAY_SIZE(adis16350_channels), |
| 1083 | .gyro_scale_micro = 872664, | 1089 | .gyro_scale_micro = IIO_DEGREE_TO_RAD(73260), /* 0.07326 deg/s */ |
| 1084 | .accel_scale_micro = 24732, | 1090 | .accel_scale_micro = IIO_G_TO_M_S_2(2522), /* 0.002522 g */ |
| 1091 | .temp_scale_nano = 145300000, /* 0.1453 C */ | ||
| 1092 | .temp_offset = 25000000 / 145300, /* 25 C = 0x00 */ | ||
| 1085 | .default_scan_mask = 0x7FF, | 1093 | .default_scan_mask = 0x7FF, |
| 1086 | .flags = ADIS16400_NO_BURST, | 1094 | .flags = ADIS16400_NO_BURST, |
| 1087 | }, | 1095 | }, |
| @@ -1090,8 +1098,10 @@ static struct adis16400_chip_info adis16400_chips[] = { | |||
| 1090 | .num_channels = ARRAY_SIZE(adis16350_channels), | 1098 | .num_channels = ARRAY_SIZE(adis16350_channels), |
| 1091 | .flags = ADIS16400_HAS_PROD_ID, | 1099 | .flags = ADIS16400_HAS_PROD_ID, |
| 1092 | .product_id = 0x3FE8, | 1100 | .product_id = 0x3FE8, |
| 1093 | .gyro_scale_micro = 1279, | 1101 | .gyro_scale_micro = IIO_DEGREE_TO_RAD(50000), /* 0.05 deg/s */ |
| 1094 | .accel_scale_micro = 24732, | 1102 | .accel_scale_micro = IIO_G_TO_M_S_2(3333), /* 3.333 mg */ |
| 1103 | .temp_scale_nano = 136000000, /* 0.136 C */ | ||
| 1104 | .temp_offset = 25000000 / 136000, /* 25 C = 0x00 */ | ||
| 1095 | .default_scan_mask = 0x7FF, | 1105 | .default_scan_mask = 0x7FF, |
| 1096 | }, | 1106 | }, |
| 1097 | [ADIS16362] = { | 1107 | [ADIS16362] = { |
| @@ -1099,8 +1109,10 @@ static struct adis16400_chip_info adis16400_chips[] = { | |||
| 1099 | .num_channels = ARRAY_SIZE(adis16350_channels), | 1109 | .num_channels = ARRAY_SIZE(adis16350_channels), |
| 1100 | .flags = ADIS16400_HAS_PROD_ID, | 1110 | .flags = ADIS16400_HAS_PROD_ID, |
| 1101 | .product_id = 0x3FEA, | 1111 | .product_id = 0x3FEA, |
| 1102 | .gyro_scale_micro = 1279, | 1112 | .gyro_scale_micro = IIO_DEGREE_TO_RAD(50000), /* 0.05 deg/s */ |
| 1103 | .accel_scale_micro = 24732, | 1113 | .accel_scale_micro = IIO_G_TO_M_S_2(333), /* 0.333 mg */ |
| 1114 | .temp_scale_nano = 136000000, /* 0.136 C */ | ||
| 1115 | .temp_offset = 25000000 / 136000, /* 25 C = 0x00 */ | ||
| 1104 | .default_scan_mask = 0x7FF, | 1116 | .default_scan_mask = 0x7FF, |
| 1105 | }, | 1117 | }, |
| 1106 | [ADIS16364] = { | 1118 | [ADIS16364] = { |
| @@ -1108,8 +1120,10 @@ static struct adis16400_chip_info adis16400_chips[] = { | |||
| 1108 | .num_channels = ARRAY_SIZE(adis16350_channels), | 1120 | .num_channels = ARRAY_SIZE(adis16350_channels), |
| 1109 | .flags = ADIS16400_HAS_PROD_ID, | 1121 | .flags = ADIS16400_HAS_PROD_ID, |
| 1110 | .product_id = 0x3FEC, | 1122 | .product_id = 0x3FEC, |
| 1111 | .gyro_scale_micro = 1279, | 1123 | .gyro_scale_micro = IIO_DEGREE_TO_RAD(50000), /* 0.05 deg/s */ |
| 1112 | .accel_scale_micro = 24732, | 1124 | .accel_scale_micro = IIO_G_TO_M_S_2(1000), /* 1 mg */ |
| 1125 | .temp_scale_nano = 136000000, /* 0.136 C */ | ||
| 1126 | .temp_offset = 25000000 / 136000, /* 25 C = 0x00 */ | ||
| 1113 | .default_scan_mask = 0x7FF, | 1127 | .default_scan_mask = 0x7FF, |
| 1114 | }, | 1128 | }, |
| 1115 | [ADIS16365] = { | 1129 | [ADIS16365] = { |
| @@ -1117,8 +1131,10 @@ static struct adis16400_chip_info adis16400_chips[] = { | |||
| 1117 | .num_channels = ARRAY_SIZE(adis16350_channels), | 1131 | .num_channels = ARRAY_SIZE(adis16350_channels), |
| 1118 | .flags = ADIS16400_HAS_PROD_ID, | 1132 | .flags = ADIS16400_HAS_PROD_ID, |
| 1119 | .product_id = 0x3FED, | 1133 | .product_id = 0x3FED, |
| 1120 | .gyro_scale_micro = 1279, | 1134 | .gyro_scale_micro = IIO_DEGREE_TO_RAD(50000), /* 0.05 deg/s */ |
| 1121 | .accel_scale_micro = 24732, | 1135 | .accel_scale_micro = IIO_G_TO_M_S_2(1000), /* 1 mg */ |
| 1136 | .temp_scale_nano = 136000000, /* 0.136 C */ | ||
| 1137 | .temp_offset = 25000000 / 136000, /* 25 C = 0x00 */ | ||
| 1122 | .default_scan_mask = 0x7FF, | 1138 | .default_scan_mask = 0x7FF, |
| 1123 | }, | 1139 | }, |
| 1124 | [ADIS16400] = { | 1140 | [ADIS16400] = { |
| @@ -1126,9 +1142,11 @@ static struct adis16400_chip_info adis16400_chips[] = { | |||
| 1126 | .num_channels = ARRAY_SIZE(adis16400_channels), | 1142 | .num_channels = ARRAY_SIZE(adis16400_channels), |
| 1127 | .flags = ADIS16400_HAS_PROD_ID, | 1143 | .flags = ADIS16400_HAS_PROD_ID, |
| 1128 | .product_id = 0x4015, | 1144 | .product_id = 0x4015, |
| 1129 | .gyro_scale_micro = 873, | 1145 | .gyro_scale_micro = IIO_DEGREE_TO_RAD(50000), /* 0.05 deg/s */ |
| 1130 | .accel_scale_micro = 32656, | 1146 | .accel_scale_micro = IIO_G_TO_M_S_2(3333), /* 3.333 mg */ |
| 1131 | .default_scan_mask = 0xFFF, | 1147 | .default_scan_mask = 0xFFF, |
| 1148 | .temp_scale_nano = 140000000, /* 0.14 C */ | ||
| 1149 | .temp_offset = 25000000 / 140000, /* 25 C = 0x00 */ | ||
| 1132 | } | 1150 | } |
| 1133 | }; | 1151 | }; |
| 1134 | 1152 | ||
diff --git a/drivers/staging/ipack/bridges/tpci200.c b/drivers/staging/ipack/bridges/tpci200.c index bb8aa70281cd..46d6657280b8 100644 --- a/drivers/staging/ipack/bridges/tpci200.c +++ b/drivers/staging/ipack/bridges/tpci200.c | |||
| @@ -12,6 +12,7 @@ | |||
| 12 | */ | 12 | */ |
| 13 | 13 | ||
| 14 | #include <linux/module.h> | 14 | #include <linux/module.h> |
| 15 | #include <linux/slab.h> | ||
| 15 | #include "tpci200.h" | 16 | #include "tpci200.h" |
| 16 | 17 | ||
| 17 | static u16 tpci200_status_timeout[] = { | 18 | static u16 tpci200_status_timeout[] = { |
diff --git a/drivers/staging/omapdrm/omap_gem.c b/drivers/staging/omapdrm/omap_gem.c index 3434e6ec0142..66e2c2f8a239 100644 --- a/drivers/staging/omapdrm/omap_gem.c +++ b/drivers/staging/omapdrm/omap_gem.c | |||
| @@ -246,7 +246,7 @@ static int omap_gem_attach_pages(struct drm_gem_object *obj) | |||
| 246 | * DSS, GPU, etc. are not cache coherent: | 246 | * DSS, GPU, etc. are not cache coherent: |
| 247 | */ | 247 | */ |
| 248 | if (omap_obj->flags & (OMAP_BO_WC|OMAP_BO_UNCACHED)) { | 248 | if (omap_obj->flags & (OMAP_BO_WC|OMAP_BO_UNCACHED)) { |
| 249 | addrs = kmalloc(npages * sizeof(addrs), GFP_KERNEL); | 249 | addrs = kmalloc(npages * sizeof(*addrs), GFP_KERNEL); |
| 250 | if (!addrs) { | 250 | if (!addrs) { |
| 251 | ret = -ENOMEM; | 251 | ret = -ENOMEM; |
| 252 | goto free_pages; | 252 | goto free_pages; |
| @@ -257,7 +257,7 @@ static int omap_gem_attach_pages(struct drm_gem_object *obj) | |||
| 257 | 0, PAGE_SIZE, DMA_BIDIRECTIONAL); | 257 | 0, PAGE_SIZE, DMA_BIDIRECTIONAL); |
| 258 | } | 258 | } |
| 259 | } else { | 259 | } else { |
| 260 | addrs = kzalloc(npages * sizeof(addrs), GFP_KERNEL); | 260 | addrs = kzalloc(npages * sizeof(*addrs), GFP_KERNEL); |
| 261 | if (!addrs) { | 261 | if (!addrs) { |
| 262 | ret = -ENOMEM; | 262 | ret = -ENOMEM; |
| 263 | goto free_pages; | 263 | goto free_pages; |
diff --git a/drivers/staging/ramster/Kconfig b/drivers/staging/ramster/Kconfig index 843c54101438..3abf6619dace 100644 --- a/drivers/staging/ramster/Kconfig +++ b/drivers/staging/ramster/Kconfig | |||
| @@ -18,6 +18,7 @@ config ZCACHE2 | |||
| 18 | config RAMSTER | 18 | config RAMSTER |
| 19 | bool "Cross-machine RAM capacity sharing, aka peer-to-peer tmem" | 19 | bool "Cross-machine RAM capacity sharing, aka peer-to-peer tmem" |
| 20 | depends on CONFIGFS_FS=y && SYSFS=y && !HIGHMEM && ZCACHE2=y | 20 | depends on CONFIGFS_FS=y && SYSFS=y && !HIGHMEM && ZCACHE2=y |
| 21 | depends on NET | ||
| 21 | # must ensure struct page is 8-byte aligned | 22 | # must ensure struct page is 8-byte aligned |
| 22 | select HAVE_ALIGNED_STRUCT_PAGE if !64_BIT | 23 | select HAVE_ALIGNED_STRUCT_PAGE if !64_BIT |
| 23 | default n | 24 | default n |
diff --git a/drivers/staging/tidspbridge/core/tiomap3430.c b/drivers/staging/tidspbridge/core/tiomap3430.c index 066a3ceec65e..f619fb3c56d2 100644 --- a/drivers/staging/tidspbridge/core/tiomap3430.c +++ b/drivers/staging/tidspbridge/core/tiomap3430.c | |||
| @@ -126,7 +126,8 @@ static int mem_map_vmalloc(struct bridge_dev_context *dev_context, | |||
| 126 | u32 ul_num_bytes, | 126 | u32 ul_num_bytes, |
| 127 | struct hw_mmu_map_attrs_t *hw_attrs); | 127 | struct hw_mmu_map_attrs_t *hw_attrs); |
| 128 | 128 | ||
| 129 | bool wait_for_start(struct bridge_dev_context *dev_context, u32 dw_sync_addr); | 129 | bool wait_for_start(struct bridge_dev_context *dev_context, |
| 130 | void __iomem *sync_addr); | ||
| 130 | 131 | ||
| 131 | /* ----------------------------------- Globals */ | 132 | /* ----------------------------------- Globals */ |
| 132 | 133 | ||
| @@ -363,10 +364,11 @@ static int bridge_brd_start(struct bridge_dev_context *dev_ctxt, | |||
| 363 | { | 364 | { |
| 364 | int status = 0; | 365 | int status = 0; |
| 365 | struct bridge_dev_context *dev_context = dev_ctxt; | 366 | struct bridge_dev_context *dev_context = dev_ctxt; |
| 366 | u32 dw_sync_addr = 0; | 367 | void __iomem *sync_addr; |
| 367 | u32 ul_shm_base; /* Gpp Phys SM base addr(byte) */ | 368 | u32 ul_shm_base; /* Gpp Phys SM base addr(byte) */ |
| 368 | u32 ul_shm_base_virt; /* Dsp Virt SM base addr */ | 369 | u32 ul_shm_base_virt; /* Dsp Virt SM base addr */ |
| 369 | u32 ul_tlb_base_virt; /* Base of MMU TLB entry */ | 370 | u32 ul_tlb_base_virt; /* Base of MMU TLB entry */ |
| 371 | u32 shm_sync_pa; | ||
| 370 | /* Offset of shm_base_virt from tlb_base_virt */ | 372 | /* Offset of shm_base_virt from tlb_base_virt */ |
| 371 | u32 ul_shm_offset_virt; | 373 | u32 ul_shm_offset_virt; |
| 372 | s32 entry_ndx; | 374 | s32 entry_ndx; |
| @@ -397,15 +399,22 @@ static int bridge_brd_start(struct bridge_dev_context *dev_ctxt, | |||
| 397 | /* Kernel logical address */ | 399 | /* Kernel logical address */ |
| 398 | ul_shm_base = dev_context->atlb_entry[0].gpp_va + ul_shm_offset_virt; | 400 | ul_shm_base = dev_context->atlb_entry[0].gpp_va + ul_shm_offset_virt; |
| 399 | 401 | ||
| 402 | /* SHM physical sync address */ | ||
| 403 | shm_sync_pa = dev_context->atlb_entry[0].gpp_pa + ul_shm_offset_virt + | ||
| 404 | SHMSYNCOFFSET; | ||
| 405 | |||
| 400 | /* 2nd wd is used as sync field */ | 406 | /* 2nd wd is used as sync field */ |
| 401 | dw_sync_addr = ul_shm_base + SHMSYNCOFFSET; | 407 | sync_addr = ioremap(shm_sync_pa, SZ_32); |
| 408 | if (!sync_addr) | ||
| 409 | return -ENOMEM; | ||
| 410 | |||
| 402 | /* Write a signature into the shm base + offset; this will | 411 | /* Write a signature into the shm base + offset; this will |
| 403 | * get cleared when the DSP program starts. */ | 412 | * get cleared when the DSP program starts. */ |
| 404 | if ((ul_shm_base_virt == 0) || (ul_shm_base == 0)) { | 413 | if ((ul_shm_base_virt == 0) || (ul_shm_base == 0)) { |
| 405 | pr_err("%s: Illegal SM base\n", __func__); | 414 | pr_err("%s: Illegal SM base\n", __func__); |
| 406 | status = -EPERM; | 415 | status = -EPERM; |
| 407 | } else | 416 | } else |
| 408 | __raw_writel(0xffffffff, dw_sync_addr); | 417 | __raw_writel(0xffffffff, sync_addr); |
| 409 | 418 | ||
| 410 | if (!status) { | 419 | if (!status) { |
| 411 | resources = dev_context->resources; | 420 | resources = dev_context->resources; |
| @@ -419,8 +428,10 @@ static int bridge_brd_start(struct bridge_dev_context *dev_ctxt, | |||
| 419 | * function is made available. | 428 | * function is made available. |
| 420 | */ | 429 | */ |
| 421 | void __iomem *ctrl = ioremap(0x48002000, SZ_4K); | 430 | void __iomem *ctrl = ioremap(0x48002000, SZ_4K); |
| 422 | if (!ctrl) | 431 | if (!ctrl) { |
| 432 | iounmap(sync_addr); | ||
| 423 | return -ENOMEM; | 433 | return -ENOMEM; |
| 434 | } | ||
| 424 | 435 | ||
| 425 | (*pdata->dsp_prm_rmw_bits)(OMAP3430_RST1_IVA2_MASK, | 436 | (*pdata->dsp_prm_rmw_bits)(OMAP3430_RST1_IVA2_MASK, |
| 426 | OMAP3430_RST1_IVA2_MASK, OMAP3430_IVA2_MOD, | 437 | OMAP3430_RST1_IVA2_MASK, OMAP3430_IVA2_MOD, |
| @@ -588,15 +599,15 @@ static int bridge_brd_start(struct bridge_dev_context *dev_ctxt, | |||
| 588 | (*pdata->dsp_prm_rmw_bits)(OMAP3430_RST1_IVA2_MASK, 0, | 599 | (*pdata->dsp_prm_rmw_bits)(OMAP3430_RST1_IVA2_MASK, 0, |
| 589 | OMAP3430_IVA2_MOD, OMAP2_RM_RSTCTRL); | 600 | OMAP3430_IVA2_MOD, OMAP2_RM_RSTCTRL); |
| 590 | 601 | ||
| 591 | dev_dbg(bridge, "Waiting for Sync @ 0x%x\n", dw_sync_addr); | 602 | dev_dbg(bridge, "Waiting for Sync @ 0x%x\n", *(u32 *)sync_addr); |
| 592 | dev_dbg(bridge, "DSP c_int00 Address = 0x%x\n", dsp_addr); | 603 | dev_dbg(bridge, "DSP c_int00 Address = 0x%x\n", dsp_addr); |
| 593 | if (dsp_debug) | 604 | if (dsp_debug) |
| 594 | while (__raw_readw(dw_sync_addr)) | 605 | while (__raw_readw(sync_addr)) |
| 595 | ; | 606 | ; |
| 596 | 607 | ||
| 597 | /* Wait for DSP to clear word in shared memory */ | 608 | /* Wait for DSP to clear word in shared memory */ |
| 598 | /* Read the Location */ | 609 | /* Read the Location */ |
| 599 | if (!wait_for_start(dev_context, dw_sync_addr)) | 610 | if (!wait_for_start(dev_context, sync_addr)) |
| 600 | status = -ETIMEDOUT; | 611 | status = -ETIMEDOUT; |
| 601 | 612 | ||
| 602 | dev_get_symbol(dev_context->dev_obj, "_WDT_enable", &wdt_en); | 613 | dev_get_symbol(dev_context->dev_obj, "_WDT_enable", &wdt_en); |
| @@ -612,7 +623,7 @@ static int bridge_brd_start(struct bridge_dev_context *dev_ctxt, | |||
| 612 | /* Write the synchronization bit to indicate the | 623 | /* Write the synchronization bit to indicate the |
| 613 | * completion of OPP table update to DSP | 624 | * completion of OPP table update to DSP |
| 614 | */ | 625 | */ |
| 615 | __raw_writel(0XCAFECAFE, dw_sync_addr); | 626 | __raw_writel(0XCAFECAFE, sync_addr); |
| 616 | 627 | ||
| 617 | /* update board state */ | 628 | /* update board state */ |
| 618 | dev_context->brd_state = BRD_RUNNING; | 629 | dev_context->brd_state = BRD_RUNNING; |
| @@ -621,6 +632,9 @@ static int bridge_brd_start(struct bridge_dev_context *dev_ctxt, | |||
| 621 | dev_context->brd_state = BRD_UNKNOWN; | 632 | dev_context->brd_state = BRD_UNKNOWN; |
| 622 | } | 633 | } |
| 623 | } | 634 | } |
| 635 | |||
| 636 | iounmap(sync_addr); | ||
| 637 | |||
| 624 | return status; | 638 | return status; |
| 625 | } | 639 | } |
| 626 | 640 | ||
| @@ -1796,12 +1810,13 @@ static int mem_map_vmalloc(struct bridge_dev_context *dev_context, | |||
| 1796 | * ======== wait_for_start ======== | 1810 | * ======== wait_for_start ======== |
| 1797 | * Wait for the singal from DSP that it has started, or time out. | 1811 | * Wait for the singal from DSP that it has started, or time out. |
| 1798 | */ | 1812 | */ |
| 1799 | bool wait_for_start(struct bridge_dev_context *dev_context, u32 dw_sync_addr) | 1813 | bool wait_for_start(struct bridge_dev_context *dev_context, |
| 1814 | void __iomem *sync_addr) | ||
| 1800 | { | 1815 | { |
| 1801 | u16 timeout = TIHELEN_ACKTIMEOUT; | 1816 | u16 timeout = TIHELEN_ACKTIMEOUT; |
| 1802 | 1817 | ||
| 1803 | /* Wait for response from board */ | 1818 | /* Wait for response from board */ |
| 1804 | while (__raw_readw(dw_sync_addr) && --timeout) | 1819 | while (__raw_readw(sync_addr) && --timeout) |
| 1805 | udelay(10); | 1820 | udelay(10); |
| 1806 | 1821 | ||
| 1807 | /* If timed out: return false */ | 1822 | /* If timed out: return false */ |
diff --git a/drivers/staging/tidspbridge/hw/hw_mmu.c b/drivers/staging/tidspbridge/hw/hw_mmu.c index 71cb82293649..50244a474178 100644 --- a/drivers/staging/tidspbridge/hw/hw_mmu.c +++ b/drivers/staging/tidspbridge/hw/hw_mmu.c | |||
| @@ -48,37 +48,12 @@ enum hw_mmu_page_size_t { | |||
| 48 | }; | 48 | }; |
| 49 | 49 | ||
| 50 | /* | 50 | /* |
| 51 | * FUNCTION : mmu_flush_entry | ||
| 52 | * | ||
| 53 | * INPUTS: | ||
| 54 | * | ||
| 55 | * Identifier : base_address | ||
| 56 | * Type : const u32 | ||
| 57 | * Description : Base Address of instance of MMU module | ||
| 58 | * | ||
| 59 | * RETURNS: | ||
| 60 | * | ||
| 61 | * Type : hw_status | ||
| 62 | * Description : 0 -- No errors occurred | ||
| 63 | * RET_BAD_NULL_PARAM -- A Pointer | ||
| 64 | * Parameter was set to NULL | ||
| 65 | * | ||
| 66 | * PURPOSE: : Flush the TLB entry pointed by the | ||
| 67 | * lock counter register | ||
| 68 | * even if this entry is set protected | ||
| 69 | * | ||
| 70 | * METHOD: : Check the Input parameter and Flush a | ||
| 71 | * single entry in the TLB. | ||
| 72 | */ | ||
| 73 | static hw_status mmu_flush_entry(const void __iomem *base_address); | ||
| 74 | |||
| 75 | /* | ||
| 76 | * FUNCTION : mmu_set_cam_entry | 51 | * FUNCTION : mmu_set_cam_entry |
| 77 | * | 52 | * |
| 78 | * INPUTS: | 53 | * INPUTS: |
| 79 | * | 54 | * |
| 80 | * Identifier : base_address | 55 | * Identifier : base_address |
| 81 | * TypE : const u32 | 56 | * Type : void __iomem * |
| 82 | * Description : Base Address of instance of MMU module | 57 | * Description : Base Address of instance of MMU module |
| 83 | * | 58 | * |
| 84 | * Identifier : page_sz | 59 | * Identifier : page_sz |
| @@ -112,7 +87,7 @@ static hw_status mmu_flush_entry(const void __iomem *base_address); | |||
| 112 | * | 87 | * |
| 113 | * METHOD: : Check the Input parameters and set the CAM entry. | 88 | * METHOD: : Check the Input parameters and set the CAM entry. |
| 114 | */ | 89 | */ |
| 115 | static hw_status mmu_set_cam_entry(const void __iomem *base_address, | 90 | static hw_status mmu_set_cam_entry(void __iomem *base_address, |
| 116 | const u32 page_sz, | 91 | const u32 page_sz, |
| 117 | const u32 preserved_bit, | 92 | const u32 preserved_bit, |
| 118 | const u32 valid_bit, | 93 | const u32 valid_bit, |
| @@ -124,7 +99,7 @@ static hw_status mmu_set_cam_entry(const void __iomem *base_address, | |||
| 124 | * INPUTS: | 99 | * INPUTS: |
| 125 | * | 100 | * |
| 126 | * Identifier : base_address | 101 | * Identifier : base_address |
| 127 | * Type : const u32 | 102 | * Type : void __iomem * |
| 128 | * Description : Base Address of instance of MMU module | 103 | * Description : Base Address of instance of MMU module |
| 129 | * | 104 | * |
| 130 | * Identifier : physical_addr | 105 | * Identifier : physical_addr |
| @@ -157,7 +132,7 @@ static hw_status mmu_set_cam_entry(const void __iomem *base_address, | |||
| 157 | * | 132 | * |
| 158 | * METHOD: : Check the Input parameters and set the RAM entry. | 133 | * METHOD: : Check the Input parameters and set the RAM entry. |
| 159 | */ | 134 | */ |
| 160 | static hw_status mmu_set_ram_entry(const void __iomem *base_address, | 135 | static hw_status mmu_set_ram_entry(void __iomem *base_address, |
| 161 | const u32 physical_addr, | 136 | const u32 physical_addr, |
| 162 | enum hw_endianism_t endianism, | 137 | enum hw_endianism_t endianism, |
| 163 | enum hw_element_size_t element_size, | 138 | enum hw_element_size_t element_size, |
| @@ -165,7 +140,7 @@ static hw_status mmu_set_ram_entry(const void __iomem *base_address, | |||
| 165 | 140 | ||
| 166 | /* HW FUNCTIONS */ | 141 | /* HW FUNCTIONS */ |
| 167 | 142 | ||
| 168 | hw_status hw_mmu_enable(const void __iomem *base_address) | 143 | hw_status hw_mmu_enable(void __iomem *base_address) |
| 169 | { | 144 | { |
| 170 | hw_status status = 0; | 145 | hw_status status = 0; |
| 171 | 146 | ||
| @@ -174,7 +149,7 @@ hw_status hw_mmu_enable(const void __iomem *base_address) | |||
| 174 | return status; | 149 | return status; |
| 175 | } | 150 | } |
| 176 | 151 | ||
| 177 | hw_status hw_mmu_disable(const void __iomem *base_address) | 152 | hw_status hw_mmu_disable(void __iomem *base_address) |
| 178 | { | 153 | { |
| 179 | hw_status status = 0; | 154 | hw_status status = 0; |
| 180 | 155 | ||
| @@ -183,7 +158,7 @@ hw_status hw_mmu_disable(const void __iomem *base_address) | |||
| 183 | return status; | 158 | return status; |
| 184 | } | 159 | } |
| 185 | 160 | ||
| 186 | hw_status hw_mmu_num_locked_set(const void __iomem *base_address, | 161 | hw_status hw_mmu_num_locked_set(void __iomem *base_address, |
| 187 | u32 num_locked_entries) | 162 | u32 num_locked_entries) |
| 188 | { | 163 | { |
| 189 | hw_status status = 0; | 164 | hw_status status = 0; |
| @@ -193,7 +168,7 @@ hw_status hw_mmu_num_locked_set(const void __iomem *base_address, | |||
| 193 | return status; | 168 | return status; |
| 194 | } | 169 | } |
| 195 | 170 | ||
| 196 | hw_status hw_mmu_victim_num_set(const void __iomem *base_address, | 171 | hw_status hw_mmu_victim_num_set(void __iomem *base_address, |
| 197 | u32 victim_entry_num) | 172 | u32 victim_entry_num) |
| 198 | { | 173 | { |
| 199 | hw_status status = 0; | 174 | hw_status status = 0; |
| @@ -203,7 +178,7 @@ hw_status hw_mmu_victim_num_set(const void __iomem *base_address, | |||
| 203 | return status; | 178 | return status; |
| 204 | } | 179 | } |
| 205 | 180 | ||
| 206 | hw_status hw_mmu_event_ack(const void __iomem *base_address, u32 irq_mask) | 181 | hw_status hw_mmu_event_ack(void __iomem *base_address, u32 irq_mask) |
| 207 | { | 182 | { |
| 208 | hw_status status = 0; | 183 | hw_status status = 0; |
| 209 | 184 | ||
| @@ -212,7 +187,7 @@ hw_status hw_mmu_event_ack(const void __iomem *base_address, u32 irq_mask) | |||
| 212 | return status; | 187 | return status; |
| 213 | } | 188 | } |
| 214 | 189 | ||
| 215 | hw_status hw_mmu_event_disable(const void __iomem *base_address, u32 irq_mask) | 190 | hw_status hw_mmu_event_disable(void __iomem *base_address, u32 irq_mask) |
| 216 | { | 191 | { |
| 217 | hw_status status = 0; | 192 | hw_status status = 0; |
| 218 | u32 irq_reg; | 193 | u32 irq_reg; |
| @@ -224,7 +199,7 @@ hw_status hw_mmu_event_disable(const void __iomem *base_address, u32 irq_mask) | |||
| 224 | return status; | 199 | return status; |
| 225 | } | 200 | } |
| 226 | 201 | ||
| 227 | hw_status hw_mmu_event_enable(const void __iomem *base_address, u32 irq_mask) | 202 | hw_status hw_mmu_event_enable(void __iomem *base_address, u32 irq_mask) |
| 228 | { | 203 | { |
| 229 | hw_status status = 0; | 204 | hw_status status = 0; |
| 230 | u32 irq_reg; | 205 | u32 irq_reg; |
| @@ -236,7 +211,7 @@ hw_status hw_mmu_event_enable(const void __iomem *base_address, u32 irq_mask) | |||
| 236 | return status; | 211 | return status; |
| 237 | } | 212 | } |
| 238 | 213 | ||
| 239 | hw_status hw_mmu_event_status(const void __iomem *base_address, u32 *irq_mask) | 214 | hw_status hw_mmu_event_status(void __iomem *base_address, u32 *irq_mask) |
| 240 | { | 215 | { |
| 241 | hw_status status = 0; | 216 | hw_status status = 0; |
| 242 | 217 | ||
| @@ -245,7 +220,7 @@ hw_status hw_mmu_event_status(const void __iomem *base_address, u32 *irq_mask) | |||
| 245 | return status; | 220 | return status; |
| 246 | } | 221 | } |
| 247 | 222 | ||
| 248 | hw_status hw_mmu_fault_addr_read(const void __iomem *base_address, u32 *addr) | 223 | hw_status hw_mmu_fault_addr_read(void __iomem *base_address, u32 *addr) |
| 249 | { | 224 | { |
| 250 | hw_status status = 0; | 225 | hw_status status = 0; |
| 251 | 226 | ||
| @@ -255,7 +230,7 @@ hw_status hw_mmu_fault_addr_read(const void __iomem *base_address, u32 *addr) | |||
| 255 | return status; | 230 | return status; |
| 256 | } | 231 | } |
| 257 | 232 | ||
| 258 | hw_status hw_mmu_ttb_set(const void __iomem *base_address, u32 ttb_phys_addr) | 233 | hw_status hw_mmu_ttb_set(void __iomem *base_address, u32 ttb_phys_addr) |
| 259 | { | 234 | { |
| 260 | hw_status status = 0; | 235 | hw_status status = 0; |
| 261 | u32 load_ttb; | 236 | u32 load_ttb; |
| @@ -267,7 +242,7 @@ hw_status hw_mmu_ttb_set(const void __iomem *base_address, u32 ttb_phys_addr) | |||
| 267 | return status; | 242 | return status; |
| 268 | } | 243 | } |
| 269 | 244 | ||
| 270 | hw_status hw_mmu_twl_enable(const void __iomem *base_address) | 245 | hw_status hw_mmu_twl_enable(void __iomem *base_address) |
| 271 | { | 246 | { |
| 272 | hw_status status = 0; | 247 | hw_status status = 0; |
| 273 | 248 | ||
| @@ -276,7 +251,7 @@ hw_status hw_mmu_twl_enable(const void __iomem *base_address) | |||
| 276 | return status; | 251 | return status; |
| 277 | } | 252 | } |
| 278 | 253 | ||
| 279 | hw_status hw_mmu_twl_disable(const void __iomem *base_address) | 254 | hw_status hw_mmu_twl_disable(void __iomem *base_address) |
| 280 | { | 255 | { |
| 281 | hw_status status = 0; | 256 | hw_status status = 0; |
| 282 | 257 | ||
| @@ -285,45 +260,7 @@ hw_status hw_mmu_twl_disable(const void __iomem *base_address) | |||
| 285 | return status; | 260 | return status; |
| 286 | } | 261 | } |
| 287 | 262 | ||
| 288 | hw_status hw_mmu_tlb_flush(const void __iomem *base_address, u32 virtual_addr, | 263 | hw_status hw_mmu_tlb_add(void __iomem *base_address, |
| 289 | u32 page_sz) | ||
| 290 | { | ||
| 291 | hw_status status = 0; | ||
| 292 | u32 virtual_addr_tag; | ||
| 293 | enum hw_mmu_page_size_t pg_size_bits; | ||
| 294 | |||
| 295 | switch (page_sz) { | ||
| 296 | case HW_PAGE_SIZE4KB: | ||
| 297 | pg_size_bits = HW_MMU_SMALL_PAGE; | ||
| 298 | break; | ||
| 299 | |||
| 300 | case HW_PAGE_SIZE64KB: | ||
| 301 | pg_size_bits = HW_MMU_LARGE_PAGE; | ||
| 302 | break; | ||
| 303 | |||
| 304 | case HW_PAGE_SIZE1MB: | ||
| 305 | pg_size_bits = HW_MMU_SECTION; | ||
| 306 | break; | ||
| 307 | |||
| 308 | case HW_PAGE_SIZE16MB: | ||
| 309 | pg_size_bits = HW_MMU_SUPERSECTION; | ||
| 310 | break; | ||
| 311 | |||
| 312 | default: | ||
| 313 | return -EINVAL; | ||
| 314 | } | ||
| 315 | |||
| 316 | /* Generate the 20-bit tag from virtual address */ | ||
| 317 | virtual_addr_tag = ((virtual_addr & MMU_ADDR_MASK) >> 12); | ||
| 318 | |||
| 319 | mmu_set_cam_entry(base_address, pg_size_bits, 0, 0, virtual_addr_tag); | ||
| 320 | |||
| 321 | mmu_flush_entry(base_address); | ||
| 322 | |||
| 323 | return status; | ||
| 324 | } | ||
| 325 | |||
| 326 | hw_status hw_mmu_tlb_add(const void __iomem *base_address, | ||
| 327 | u32 physical_addr, | 264 | u32 physical_addr, |
| 328 | u32 virtual_addr, | 265 | u32 virtual_addr, |
| 329 | u32 page_sz, | 266 | u32 page_sz, |
| @@ -503,20 +440,8 @@ hw_status hw_mmu_pte_clear(const u32 pg_tbl_va, u32 virtual_addr, u32 page_size) | |||
| 503 | return status; | 440 | return status; |
| 504 | } | 441 | } |
| 505 | 442 | ||
| 506 | /* mmu_flush_entry */ | ||
| 507 | static hw_status mmu_flush_entry(const void __iomem *base_address) | ||
| 508 | { | ||
| 509 | hw_status status = 0; | ||
| 510 | u32 flush_entry_data = 0x1; | ||
| 511 | |||
| 512 | /* write values to register */ | ||
| 513 | MMUMMU_FLUSH_ENTRY_WRITE_REGISTER32(base_address, flush_entry_data); | ||
| 514 | |||
| 515 | return status; | ||
| 516 | } | ||
| 517 | |||
| 518 | /* mmu_set_cam_entry */ | 443 | /* mmu_set_cam_entry */ |
| 519 | static hw_status mmu_set_cam_entry(const void __iomem *base_address, | 444 | static hw_status mmu_set_cam_entry(void __iomem *base_address, |
| 520 | const u32 page_sz, | 445 | const u32 page_sz, |
| 521 | const u32 preserved_bit, | 446 | const u32 preserved_bit, |
| 522 | const u32 valid_bit, | 447 | const u32 valid_bit, |
| @@ -536,7 +461,7 @@ static hw_status mmu_set_cam_entry(const void __iomem *base_address, | |||
| 536 | } | 461 | } |
| 537 | 462 | ||
| 538 | /* mmu_set_ram_entry */ | 463 | /* mmu_set_ram_entry */ |
| 539 | static hw_status mmu_set_ram_entry(const void __iomem *base_address, | 464 | static hw_status mmu_set_ram_entry(void __iomem *base_address, |
| 540 | const u32 physical_addr, | 465 | const u32 physical_addr, |
| 541 | enum hw_endianism_t endianism, | 466 | enum hw_endianism_t endianism, |
| 542 | enum hw_element_size_t element_size, | 467 | enum hw_element_size_t element_size, |
| @@ -556,7 +481,7 @@ static hw_status mmu_set_ram_entry(const void __iomem *base_address, | |||
| 556 | 481 | ||
| 557 | } | 482 | } |
| 558 | 483 | ||
| 559 | void hw_mmu_tlb_flush_all(const void __iomem *base) | 484 | void hw_mmu_tlb_flush_all(void __iomem *base) |
| 560 | { | 485 | { |
| 561 | __raw_writel(1, base + MMU_GFLUSH); | 486 | __raw_writel(1, base + MMU_GFLUSH); |
| 562 | } | 487 | } |
diff --git a/drivers/staging/tidspbridge/hw/hw_mmu.h b/drivers/staging/tidspbridge/hw/hw_mmu.h index 1458a2c6027b..1c50bb36edfe 100644 --- a/drivers/staging/tidspbridge/hw/hw_mmu.h +++ b/drivers/staging/tidspbridge/hw/hw_mmu.h | |||
| @@ -42,44 +42,41 @@ struct hw_mmu_map_attrs_t { | |||
| 42 | bool donotlockmpupage; | 42 | bool donotlockmpupage; |
| 43 | }; | 43 | }; |
| 44 | 44 | ||
| 45 | extern hw_status hw_mmu_enable(const void __iomem *base_address); | 45 | extern hw_status hw_mmu_enable(void __iomem *base_address); |
| 46 | 46 | ||
| 47 | extern hw_status hw_mmu_disable(const void __iomem *base_address); | 47 | extern hw_status hw_mmu_disable(void __iomem *base_address); |
| 48 | 48 | ||
| 49 | extern hw_status hw_mmu_num_locked_set(const void __iomem *base_address, | 49 | extern hw_status hw_mmu_num_locked_set(void __iomem *base_address, |
| 50 | u32 num_locked_entries); | 50 | u32 num_locked_entries); |
| 51 | 51 | ||
| 52 | extern hw_status hw_mmu_victim_num_set(const void __iomem *base_address, | 52 | extern hw_status hw_mmu_victim_num_set(void __iomem *base_address, |
| 53 | u32 victim_entry_num); | 53 | u32 victim_entry_num); |
| 54 | 54 | ||
| 55 | /* For MMU faults */ | 55 | /* For MMU faults */ |
| 56 | extern hw_status hw_mmu_event_ack(const void __iomem *base_address, | 56 | extern hw_status hw_mmu_event_ack(void __iomem *base_address, |
| 57 | u32 irq_mask); | 57 | u32 irq_mask); |
| 58 | 58 | ||
| 59 | extern hw_status hw_mmu_event_disable(const void __iomem *base_address, | 59 | extern hw_status hw_mmu_event_disable(void __iomem *base_address, |
| 60 | u32 irq_mask); | 60 | u32 irq_mask); |
| 61 | 61 | ||
| 62 | extern hw_status hw_mmu_event_enable(const void __iomem *base_address, | 62 | extern hw_status hw_mmu_event_enable(void __iomem *base_address, |
| 63 | u32 irq_mask); | 63 | u32 irq_mask); |
| 64 | 64 | ||
| 65 | extern hw_status hw_mmu_event_status(const void __iomem *base_address, | 65 | extern hw_status hw_mmu_event_status(void __iomem *base_address, |
| 66 | u32 *irq_mask); | 66 | u32 *irq_mask); |
| 67 | 67 | ||
| 68 | extern hw_status hw_mmu_fault_addr_read(const void __iomem *base_address, | 68 | extern hw_status hw_mmu_fault_addr_read(void __iomem *base_address, |
| 69 | u32 *addr); | 69 | u32 *addr); |
| 70 | 70 | ||
| 71 | /* Set the TT base address */ | 71 | /* Set the TT base address */ |
| 72 | extern hw_status hw_mmu_ttb_set(const void __iomem *base_address, | 72 | extern hw_status hw_mmu_ttb_set(void __iomem *base_address, |
| 73 | u32 ttb_phys_addr); | 73 | u32 ttb_phys_addr); |
| 74 | 74 | ||
| 75 | extern hw_status hw_mmu_twl_enable(const void __iomem *base_address); | 75 | extern hw_status hw_mmu_twl_enable(void __iomem *base_address); |
| 76 | 76 | ||
| 77 | extern hw_status hw_mmu_twl_disable(const void __iomem *base_address); | 77 | extern hw_status hw_mmu_twl_disable(void __iomem *base_address); |
| 78 | 78 | ||
| 79 | extern hw_status hw_mmu_tlb_flush(const void __iomem *base_address, | 79 | extern hw_status hw_mmu_tlb_add(void __iomem *base_address, |
| 80 | u32 virtual_addr, u32 page_sz); | ||
| 81 | |||
| 82 | extern hw_status hw_mmu_tlb_add(const void __iomem *base_address, | ||
| 83 | u32 physical_addr, | 80 | u32 physical_addr, |
| 84 | u32 virtual_addr, | 81 | u32 virtual_addr, |
| 85 | u32 page_sz, | 82 | u32 page_sz, |
| @@ -97,7 +94,7 @@ extern hw_status hw_mmu_pte_set(const u32 pg_tbl_va, | |||
| 97 | extern hw_status hw_mmu_pte_clear(const u32 pg_tbl_va, | 94 | extern hw_status hw_mmu_pte_clear(const u32 pg_tbl_va, |
| 98 | u32 virtual_addr, u32 page_size); | 95 | u32 virtual_addr, u32 page_size); |
| 99 | 96 | ||
| 100 | void hw_mmu_tlb_flush_all(const void __iomem *base); | 97 | void hw_mmu_tlb_flush_all(void __iomem *base); |
| 101 | 98 | ||
| 102 | static inline u32 hw_mmu_pte_addr_l1(u32 l1_base, u32 va) | 99 | static inline u32 hw_mmu_pte_addr_l1(u32 l1_base, u32 va) |
| 103 | { | 100 | { |
diff --git a/drivers/staging/tidspbridge/include/dspbridge/cfgdefs.h b/drivers/staging/tidspbridge/include/dspbridge/cfgdefs.h index 60a278136bdf..b32c75673ab4 100644 --- a/drivers/staging/tidspbridge/include/dspbridge/cfgdefs.h +++ b/drivers/staging/tidspbridge/include/dspbridge/cfgdefs.h | |||
| @@ -53,8 +53,8 @@ struct cfg_hostres { | |||
| 53 | u32 chnl_buf_size; | 53 | u32 chnl_buf_size; |
| 54 | u32 num_chnls; | 54 | u32 num_chnls; |
| 55 | void __iomem *per_base; | 55 | void __iomem *per_base; |
| 56 | u32 per_pm_base; | 56 | void __iomem *per_pm_base; |
| 57 | u32 core_pm_base; | 57 | void __iomem *core_pm_base; |
| 58 | void __iomem *dmmu_base; | 58 | void __iomem *dmmu_base; |
| 59 | }; | 59 | }; |
| 60 | 60 | ||
diff --git a/drivers/staging/tidspbridge/include/dspbridge/host_os.h b/drivers/staging/tidspbridge/include/dspbridge/host_os.h index ed00d3da3205..5e2f4d82d925 100644 --- a/drivers/staging/tidspbridge/include/dspbridge/host_os.h +++ b/drivers/staging/tidspbridge/include/dspbridge/host_os.h | |||
| @@ -47,8 +47,8 @@ | |||
| 47 | #include <asm/cacheflush.h> | 47 | #include <asm/cacheflush.h> |
| 48 | #include <linux/dma-mapping.h> | 48 | #include <linux/dma-mapping.h> |
| 49 | 49 | ||
| 50 | /* TODO -- Remove, once BP defines them */ | 50 | /* TODO -- Remove, once omap-iommu is used */ |
| 51 | #define INT_DSP_MMU_IRQ 28 | 51 | #define INT_DSP_MMU_IRQ (28 + NR_IRQS) |
| 52 | 52 | ||
| 53 | #define PRCM_VDD1 1 | 53 | #define PRCM_VDD1 1 |
| 54 | 54 | ||
diff --git a/drivers/staging/tidspbridge/rmgr/drv.c b/drivers/staging/tidspbridge/rmgr/drv.c index 6795205b0155..db1da28cecba 100644 --- a/drivers/staging/tidspbridge/rmgr/drv.c +++ b/drivers/staging/tidspbridge/rmgr/drv.c | |||
| @@ -667,10 +667,10 @@ int drv_request_bridge_res_dsp(void **phost_resources) | |||
| 667 | OMAP_DSP_MEM3_SIZE); | 667 | OMAP_DSP_MEM3_SIZE); |
| 668 | host_res->per_base = ioremap(OMAP_PER_CM_BASE, | 668 | host_res->per_base = ioremap(OMAP_PER_CM_BASE, |
| 669 | OMAP_PER_CM_SIZE); | 669 | OMAP_PER_CM_SIZE); |
| 670 | host_res->per_pm_base = (u32) ioremap(OMAP_PER_PRM_BASE, | 670 | host_res->per_pm_base = ioremap(OMAP_PER_PRM_BASE, |
| 671 | OMAP_PER_PRM_SIZE); | 671 | OMAP_PER_PRM_SIZE); |
| 672 | host_res->core_pm_base = (u32) ioremap(OMAP_CORE_PRM_BASE, | 672 | host_res->core_pm_base = ioremap(OMAP_CORE_PRM_BASE, |
| 673 | OMAP_CORE_PRM_SIZE); | 673 | OMAP_CORE_PRM_SIZE); |
| 674 | host_res->dmmu_base = ioremap(OMAP_DMMU_BASE, | 674 | host_res->dmmu_base = ioremap(OMAP_DMMU_BASE, |
| 675 | OMAP_DMMU_SIZE); | 675 | OMAP_DMMU_SIZE); |
| 676 | 676 | ||
diff --git a/drivers/staging/tidspbridge/rmgr/node.c b/drivers/staging/tidspbridge/rmgr/node.c index c2fc6137c770..294e9b40f516 100644 --- a/drivers/staging/tidspbridge/rmgr/node.c +++ b/drivers/staging/tidspbridge/rmgr/node.c | |||
| @@ -304,8 +304,7 @@ int node_allocate(struct proc_object *hprocessor, | |||
| 304 | u32 pul_value; | 304 | u32 pul_value; |
| 305 | u32 dynext_base; | 305 | u32 dynext_base; |
| 306 | u32 off_set = 0; | 306 | u32 off_set = 0; |
| 307 | u32 ul_stack_seg_addr, ul_stack_seg_val; | 307 | u32 ul_stack_seg_val; |
| 308 | u32 ul_gpp_mem_base; | ||
| 309 | struct cfg_hostres *host_res; | 308 | struct cfg_hostres *host_res; |
| 310 | struct bridge_dev_context *pbridge_context; | 309 | struct bridge_dev_context *pbridge_context; |
| 311 | u32 mapped_addr = 0; | 310 | u32 mapped_addr = 0; |
| @@ -581,6 +580,9 @@ func_cont: | |||
| 581 | if (strcmp((char *) | 580 | if (strcmp((char *) |
| 582 | pnode->dcd_props.obj_data.node_obj.ndb_props. | 581 | pnode->dcd_props.obj_data.node_obj.ndb_props. |
| 583 | stack_seg_name, STACKSEGLABEL) == 0) { | 582 | stack_seg_name, STACKSEGLABEL) == 0) { |
| 583 | void __iomem *stack_seg; | ||
| 584 | u32 stack_seg_pa; | ||
| 585 | |||
| 584 | status = | 586 | status = |
| 585 | hnode_mgr->nldr_fxns. | 587 | hnode_mgr->nldr_fxns. |
| 586 | get_fxn_addr(pnode->nldr_node_obj, "DYNEXT_BEG", | 588 | get_fxn_addr(pnode->nldr_node_obj, "DYNEXT_BEG", |
| @@ -608,14 +610,21 @@ func_cont: | |||
| 608 | goto func_end; | 610 | goto func_end; |
| 609 | } | 611 | } |
| 610 | 612 | ||
| 611 | ul_gpp_mem_base = (u32) host_res->mem_base[1]; | ||
| 612 | off_set = pul_value - dynext_base; | 613 | off_set = pul_value - dynext_base; |
| 613 | ul_stack_seg_addr = ul_gpp_mem_base + off_set; | 614 | stack_seg_pa = host_res->mem_phys[1] + off_set; |
| 614 | ul_stack_seg_val = readl(ul_stack_seg_addr); | 615 | stack_seg = ioremap(stack_seg_pa, SZ_32); |
| 616 | if (!stack_seg) { | ||
| 617 | status = -ENOMEM; | ||
| 618 | goto func_end; | ||
| 619 | } | ||
| 620 | |||
| 621 | ul_stack_seg_val = readl(stack_seg); | ||
| 622 | |||
| 623 | iounmap(stack_seg); | ||
| 615 | 624 | ||
| 616 | dev_dbg(bridge, "%s: StackSegVal = 0x%x, StackSegAddr =" | 625 | dev_dbg(bridge, "%s: StackSegVal = 0x%x, StackSegAddr =" |
| 617 | " 0x%x\n", __func__, ul_stack_seg_val, | 626 | " 0x%x\n", __func__, ul_stack_seg_val, |
| 618 | ul_stack_seg_addr); | 627 | host_res->mem_base[1] + off_set); |
| 619 | 628 | ||
| 620 | pnode->create_args.asa.task_arg_obj.stack_seg = | 629 | pnode->create_args.asa.task_arg_obj.stack_seg = |
| 621 | ul_stack_seg_val; | 630 | ul_stack_seg_val; |
diff --git a/drivers/staging/zram/zram_drv.c b/drivers/staging/zram/zram_drv.c index 653b074035f7..6edefde23722 100644 --- a/drivers/staging/zram/zram_drv.c +++ b/drivers/staging/zram/zram_drv.c | |||
| @@ -223,8 +223,13 @@ static int zram_bvec_read(struct zram *zram, struct bio_vec *bvec, | |||
| 223 | cmem = zs_map_object(zram->mem_pool, zram->table[index].handle, | 223 | cmem = zs_map_object(zram->mem_pool, zram->table[index].handle, |
| 224 | ZS_MM_RO); | 224 | ZS_MM_RO); |
| 225 | 225 | ||
| 226 | ret = lzo1x_decompress_safe(cmem, zram->table[index].size, | 226 | if (zram->table[index].size == PAGE_SIZE) { |
| 227 | memcpy(uncmem, cmem, PAGE_SIZE); | ||
| 228 | ret = LZO_E_OK; | ||
| 229 | } else { | ||
| 230 | ret = lzo1x_decompress_safe(cmem, zram->table[index].size, | ||
| 227 | uncmem, &clen); | 231 | uncmem, &clen); |
| 232 | } | ||
| 228 | 233 | ||
| 229 | if (is_partial_io(bvec)) { | 234 | if (is_partial_io(bvec)) { |
| 230 | memcpy(user_mem + bvec->bv_offset, uncmem + offset, | 235 | memcpy(user_mem + bvec->bv_offset, uncmem + offset, |
| @@ -342,8 +347,11 @@ static int zram_bvec_write(struct zram *zram, struct bio_vec *bvec, u32 index, | |||
| 342 | goto out; | 347 | goto out; |
| 343 | } | 348 | } |
| 344 | 349 | ||
| 345 | if (unlikely(clen > max_zpage_size)) | 350 | if (unlikely(clen > max_zpage_size)) { |
| 346 | zram_stat_inc(&zram->stats.bad_compress); | 351 | zram_stat_inc(&zram->stats.bad_compress); |
| 352 | src = uncmem; | ||
| 353 | clen = PAGE_SIZE; | ||
| 354 | } | ||
| 347 | 355 | ||
| 348 | handle = zs_malloc(zram->mem_pool, clen); | 356 | handle = zs_malloc(zram->mem_pool, clen); |
| 349 | if (!handle) { | 357 | if (!handle) { |
diff --git a/drivers/target/iscsi/iscsi_target.c b/drivers/target/iscsi/iscsi_target.c index d6ce2182e672..035c2c762537 100644 --- a/drivers/target/iscsi/iscsi_target.c +++ b/drivers/target/iscsi/iscsi_target.c | |||
| @@ -3719,7 +3719,9 @@ restart: | |||
| 3719 | */ | 3719 | */ |
| 3720 | iscsit_thread_check_cpumask(conn, current, 1); | 3720 | iscsit_thread_check_cpumask(conn, current, 1); |
| 3721 | 3721 | ||
| 3722 | schedule_timeout_interruptible(MAX_SCHEDULE_TIMEOUT); | 3722 | wait_event_interruptible(conn->queues_wq, |
| 3723 | !iscsit_conn_all_queues_empty(conn) || | ||
| 3724 | ts->status == ISCSI_THREAD_SET_RESET); | ||
| 3723 | 3725 | ||
| 3724 | if ((ts->status == ISCSI_THREAD_SET_RESET) || | 3726 | if ((ts->status == ISCSI_THREAD_SET_RESET) || |
| 3725 | signal_pending(current)) | 3727 | signal_pending(current)) |
diff --git a/drivers/target/iscsi/iscsi_target_core.h b/drivers/target/iscsi/iscsi_target_core.h index 2ba9f9b9435c..21048dbf7d13 100644 --- a/drivers/target/iscsi/iscsi_target_core.h +++ b/drivers/target/iscsi/iscsi_target_core.h | |||
| @@ -486,6 +486,7 @@ struct iscsi_tmr_req { | |||
| 486 | }; | 486 | }; |
| 487 | 487 | ||
| 488 | struct iscsi_conn { | 488 | struct iscsi_conn { |
| 489 | wait_queue_head_t queues_wq; | ||
| 489 | /* Authentication Successful for this connection */ | 490 | /* Authentication Successful for this connection */ |
| 490 | u8 auth_complete; | 491 | u8 auth_complete; |
| 491 | /* State connection is currently in */ | 492 | /* State connection is currently in */ |
diff --git a/drivers/target/iscsi/iscsi_target_login.c b/drivers/target/iscsi/iscsi_target_login.c index cdc8a10939c3..f8dbec05d5e5 100644 --- a/drivers/target/iscsi/iscsi_target_login.c +++ b/drivers/target/iscsi/iscsi_target_login.c | |||
| @@ -41,6 +41,7 @@ | |||
| 41 | 41 | ||
| 42 | static int iscsi_login_init_conn(struct iscsi_conn *conn) | 42 | static int iscsi_login_init_conn(struct iscsi_conn *conn) |
| 43 | { | 43 | { |
| 44 | init_waitqueue_head(&conn->queues_wq); | ||
| 44 | INIT_LIST_HEAD(&conn->conn_list); | 45 | INIT_LIST_HEAD(&conn->conn_list); |
| 45 | INIT_LIST_HEAD(&conn->conn_cmd_list); | 46 | INIT_LIST_HEAD(&conn->conn_cmd_list); |
| 46 | INIT_LIST_HEAD(&conn->immed_queue_list); | 47 | INIT_LIST_HEAD(&conn->immed_queue_list); |
diff --git a/drivers/target/iscsi/iscsi_target_util.c b/drivers/target/iscsi/iscsi_target_util.c index afd98ccd40ae..1a91195ab619 100644 --- a/drivers/target/iscsi/iscsi_target_util.c +++ b/drivers/target/iscsi/iscsi_target_util.c | |||
| @@ -488,7 +488,7 @@ void iscsit_add_cmd_to_immediate_queue( | |||
| 488 | atomic_set(&conn->check_immediate_queue, 1); | 488 | atomic_set(&conn->check_immediate_queue, 1); |
| 489 | spin_unlock_bh(&conn->immed_queue_lock); | 489 | spin_unlock_bh(&conn->immed_queue_lock); |
| 490 | 490 | ||
| 491 | wake_up_process(conn->thread_set->tx_thread); | 491 | wake_up(&conn->queues_wq); |
| 492 | } | 492 | } |
| 493 | 493 | ||
| 494 | struct iscsi_queue_req *iscsit_get_cmd_from_immediate_queue(struct iscsi_conn *conn) | 494 | struct iscsi_queue_req *iscsit_get_cmd_from_immediate_queue(struct iscsi_conn *conn) |
| @@ -562,7 +562,7 @@ void iscsit_add_cmd_to_response_queue( | |||
| 562 | atomic_inc(&cmd->response_queue_count); | 562 | atomic_inc(&cmd->response_queue_count); |
| 563 | spin_unlock_bh(&conn->response_queue_lock); | 563 | spin_unlock_bh(&conn->response_queue_lock); |
| 564 | 564 | ||
| 565 | wake_up_process(conn->thread_set->tx_thread); | 565 | wake_up(&conn->queues_wq); |
| 566 | } | 566 | } |
| 567 | 567 | ||
| 568 | struct iscsi_queue_req *iscsit_get_cmd_from_response_queue(struct iscsi_conn *conn) | 568 | struct iscsi_queue_req *iscsit_get_cmd_from_response_queue(struct iscsi_conn *conn) |
| @@ -616,6 +616,24 @@ static void iscsit_remove_cmd_from_response_queue( | |||
| 616 | } | 616 | } |
| 617 | } | 617 | } |
| 618 | 618 | ||
| 619 | bool iscsit_conn_all_queues_empty(struct iscsi_conn *conn) | ||
| 620 | { | ||
| 621 | bool empty; | ||
| 622 | |||
| 623 | spin_lock_bh(&conn->immed_queue_lock); | ||
| 624 | empty = list_empty(&conn->immed_queue_list); | ||
| 625 | spin_unlock_bh(&conn->immed_queue_lock); | ||
| 626 | |||
| 627 | if (!empty) | ||
| 628 | return empty; | ||
| 629 | |||
| 630 | spin_lock_bh(&conn->response_queue_lock); | ||
| 631 | empty = list_empty(&conn->response_queue_list); | ||
| 632 | spin_unlock_bh(&conn->response_queue_lock); | ||
| 633 | |||
| 634 | return empty; | ||
| 635 | } | ||
| 636 | |||
| 619 | void iscsit_free_queue_reqs_for_conn(struct iscsi_conn *conn) | 637 | void iscsit_free_queue_reqs_for_conn(struct iscsi_conn *conn) |
| 620 | { | 638 | { |
| 621 | struct iscsi_queue_req *qr, *qr_tmp; | 639 | struct iscsi_queue_req *qr, *qr_tmp; |
diff --git a/drivers/target/iscsi/iscsi_target_util.h b/drivers/target/iscsi/iscsi_target_util.h index 44054bd35437..894d0f837924 100644 --- a/drivers/target/iscsi/iscsi_target_util.h +++ b/drivers/target/iscsi/iscsi_target_util.h | |||
| @@ -25,6 +25,7 @@ extern struct iscsi_queue_req *iscsit_get_cmd_from_immediate_queue(struct iscsi_ | |||
| 25 | extern void iscsit_add_cmd_to_response_queue(struct iscsi_cmd *, struct iscsi_conn *, u8); | 25 | extern void iscsit_add_cmd_to_response_queue(struct iscsi_cmd *, struct iscsi_conn *, u8); |
| 26 | extern struct iscsi_queue_req *iscsit_get_cmd_from_response_queue(struct iscsi_conn *); | 26 | extern struct iscsi_queue_req *iscsit_get_cmd_from_response_queue(struct iscsi_conn *); |
| 27 | extern void iscsit_remove_cmd_from_tx_queues(struct iscsi_cmd *, struct iscsi_conn *); | 27 | extern void iscsit_remove_cmd_from_tx_queues(struct iscsi_cmd *, struct iscsi_conn *); |
| 28 | extern bool iscsit_conn_all_queues_empty(struct iscsi_conn *); | ||
| 28 | extern void iscsit_free_queue_reqs_for_conn(struct iscsi_conn *); | 29 | extern void iscsit_free_queue_reqs_for_conn(struct iscsi_conn *); |
| 29 | extern void iscsit_release_cmd(struct iscsi_cmd *); | 30 | extern void iscsit_release_cmd(struct iscsi_cmd *); |
| 30 | extern void iscsit_free_cmd(struct iscsi_cmd *); | 31 | extern void iscsit_free_cmd(struct iscsi_cmd *); |
diff --git a/drivers/target/target_core_configfs.c b/drivers/target/target_core_configfs.c index 015f5be27bf6..c123327499a3 100644 --- a/drivers/target/target_core_configfs.c +++ b/drivers/target/target_core_configfs.c | |||
| @@ -3206,7 +3206,8 @@ static int __init target_core_init_configfs(void) | |||
| 3206 | if (ret < 0) | 3206 | if (ret < 0) |
| 3207 | goto out; | 3207 | goto out; |
| 3208 | 3208 | ||
| 3209 | if (core_dev_setup_virtual_lun0() < 0) | 3209 | ret = core_dev_setup_virtual_lun0(); |
| 3210 | if (ret < 0) | ||
| 3210 | goto out; | 3211 | goto out; |
| 3211 | 3212 | ||
| 3212 | return 0; | 3213 | return 0; |
diff --git a/drivers/target/target_core_device.c b/drivers/target/target_core_device.c index 8d774da16320..9abef9f8eb76 100644 --- a/drivers/target/target_core_device.c +++ b/drivers/target/target_core_device.c | |||
| @@ -850,20 +850,20 @@ int se_dev_check_shutdown(struct se_device *dev) | |||
| 850 | 850 | ||
| 851 | static u32 se_dev_align_max_sectors(u32 max_sectors, u32 block_size) | 851 | static u32 se_dev_align_max_sectors(u32 max_sectors, u32 block_size) |
| 852 | { | 852 | { |
| 853 | u32 tmp, aligned_max_sectors; | 853 | u32 aligned_max_sectors; |
| 854 | u32 alignment; | ||
| 854 | /* | 855 | /* |
| 855 | * Limit max_sectors to a PAGE_SIZE aligned value for modern | 856 | * Limit max_sectors to a PAGE_SIZE aligned value for modern |
| 856 | * transport_allocate_data_tasks() operation. | 857 | * transport_allocate_data_tasks() operation. |
| 857 | */ | 858 | */ |
| 858 | tmp = rounddown((max_sectors * block_size), PAGE_SIZE); | 859 | alignment = max(1ul, PAGE_SIZE / block_size); |
| 859 | aligned_max_sectors = (tmp / block_size); | 860 | aligned_max_sectors = rounddown(max_sectors, alignment); |
| 860 | if (max_sectors != aligned_max_sectors) { | 861 | |
| 861 | printk(KERN_INFO "Rounding down aligned max_sectors from %u" | 862 | if (max_sectors != aligned_max_sectors) |
| 862 | " to %u\n", max_sectors, aligned_max_sectors); | 863 | pr_info("Rounding down aligned max_sectors from %u to %u\n", |
| 863 | return aligned_max_sectors; | 864 | max_sectors, aligned_max_sectors); |
| 864 | } | ||
| 865 | 865 | ||
| 866 | return max_sectors; | 866 | return aligned_max_sectors; |
| 867 | } | 867 | } |
| 868 | 868 | ||
| 869 | void se_dev_set_default_attribs( | 869 | void se_dev_set_default_attribs( |
diff --git a/drivers/target/target_core_sbc.c b/drivers/target/target_core_sbc.c index 868f8aa04f13..a6e27d967c7b 100644 --- a/drivers/target/target_core_sbc.c +++ b/drivers/target/target_core_sbc.c | |||
| @@ -135,6 +135,12 @@ static int sbc_emulate_verify(struct se_cmd *cmd) | |||
| 135 | return 0; | 135 | return 0; |
| 136 | } | 136 | } |
| 137 | 137 | ||
| 138 | static int sbc_emulate_noop(struct se_cmd *cmd) | ||
| 139 | { | ||
| 140 | target_complete_cmd(cmd, GOOD); | ||
| 141 | return 0; | ||
| 142 | } | ||
| 143 | |||
| 138 | static inline u32 sbc_get_size(struct se_cmd *cmd, u32 sectors) | 144 | static inline u32 sbc_get_size(struct se_cmd *cmd, u32 sectors) |
| 139 | { | 145 | { |
| 140 | return cmd->se_dev->se_sub_dev->se_dev_attrib.block_size * sectors; | 146 | return cmd->se_dev->se_sub_dev->se_dev_attrib.block_size * sectors; |
| @@ -531,6 +537,18 @@ int sbc_parse_cdb(struct se_cmd *cmd, struct spc_ops *ops) | |||
| 531 | size = 0; | 537 | size = 0; |
| 532 | cmd->execute_cmd = sbc_emulate_verify; | 538 | cmd->execute_cmd = sbc_emulate_verify; |
| 533 | break; | 539 | break; |
| 540 | case REZERO_UNIT: | ||
| 541 | case SEEK_6: | ||
| 542 | case SEEK_10: | ||
| 543 | /* | ||
| 544 | * There are still clients out there which use these old SCSI-2 | ||
| 545 | * commands. This mainly happens when running VMs with legacy | ||
| 546 | * guest systems, connected via SCSI command pass-through to | ||
| 547 | * iSCSI targets. Make them happy and return status GOOD. | ||
| 548 | */ | ||
| 549 | size = 0; | ||
| 550 | cmd->execute_cmd = sbc_emulate_noop; | ||
| 551 | break; | ||
| 534 | default: | 552 | default: |
| 535 | ret = spc_parse_cdb(cmd, &size); | 553 | ret = spc_parse_cdb(cmd, &size); |
| 536 | if (ret) | 554 | if (ret) |
diff --git a/drivers/target/target_core_spc.c b/drivers/target/target_core_spc.c index 9229bd9ad61b..6fd434d3d7e4 100644 --- a/drivers/target/target_core_spc.c +++ b/drivers/target/target_core_spc.c | |||
| @@ -605,6 +605,8 @@ static int spc_emulate_inquiry(struct se_cmd *cmd) | |||
| 605 | unsigned char buf[SE_INQUIRY_BUF]; | 605 | unsigned char buf[SE_INQUIRY_BUF]; |
| 606 | int p, ret; | 606 | int p, ret; |
| 607 | 607 | ||
| 608 | memset(buf, 0, SE_INQUIRY_BUF); | ||
| 609 | |||
| 608 | if (dev == tpg->tpg_virt_lun0.lun_se_dev) | 610 | if (dev == tpg->tpg_virt_lun0.lun_se_dev) |
| 609 | buf[0] = 0x3f; /* Not connected */ | 611 | buf[0] = 0x3f; /* Not connected */ |
| 610 | else | 612 | else |
diff --git a/drivers/target/target_core_tmr.c b/drivers/target/target_core_tmr.c index 1c59a3c23b2c..be75c4331a92 100644 --- a/drivers/target/target_core_tmr.c +++ b/drivers/target/target_core_tmr.c | |||
| @@ -140,15 +140,15 @@ void core_tmr_abort_task( | |||
| 140 | printk("ABORT_TASK: Found referenced %s task_tag: %u\n", | 140 | printk("ABORT_TASK: Found referenced %s task_tag: %u\n", |
| 141 | se_cmd->se_tfo->get_fabric_name(), ref_tag); | 141 | se_cmd->se_tfo->get_fabric_name(), ref_tag); |
| 142 | 142 | ||
| 143 | spin_lock_irq(&se_cmd->t_state_lock); | 143 | spin_lock(&se_cmd->t_state_lock); |
| 144 | if (se_cmd->transport_state & CMD_T_COMPLETE) { | 144 | if (se_cmd->transport_state & CMD_T_COMPLETE) { |
| 145 | printk("ABORT_TASK: ref_tag: %u already complete, skipping\n", ref_tag); | 145 | printk("ABORT_TASK: ref_tag: %u already complete, skipping\n", ref_tag); |
| 146 | spin_unlock_irq(&se_cmd->t_state_lock); | 146 | spin_unlock(&se_cmd->t_state_lock); |
| 147 | spin_unlock_irqrestore(&se_sess->sess_cmd_lock, flags); | 147 | spin_unlock_irqrestore(&se_sess->sess_cmd_lock, flags); |
| 148 | goto out; | 148 | goto out; |
| 149 | } | 149 | } |
| 150 | se_cmd->transport_state |= CMD_T_ABORTED; | 150 | se_cmd->transport_state |= CMD_T_ABORTED; |
| 151 | spin_unlock_irq(&se_cmd->t_state_lock); | 151 | spin_unlock(&se_cmd->t_state_lock); |
| 152 | 152 | ||
| 153 | list_del_init(&se_cmd->se_cmd_list); | 153 | list_del_init(&se_cmd->se_cmd_list); |
| 154 | kref_get(&se_cmd->cmd_kref); | 154 | kref_get(&se_cmd->cmd_kref); |
diff --git a/drivers/target/target_core_transport.c b/drivers/target/target_core_transport.c index c33baff86aa6..dcecbfb17243 100644 --- a/drivers/target/target_core_transport.c +++ b/drivers/target/target_core_transport.c | |||
| @@ -1616,7 +1616,6 @@ static void target_complete_tmr_failure(struct work_struct *work) | |||
| 1616 | 1616 | ||
| 1617 | se_cmd->se_tmr_req->response = TMR_LUN_DOES_NOT_EXIST; | 1617 | se_cmd->se_tmr_req->response = TMR_LUN_DOES_NOT_EXIST; |
| 1618 | se_cmd->se_tfo->queue_tm_rsp(se_cmd); | 1618 | se_cmd->se_tfo->queue_tm_rsp(se_cmd); |
| 1619 | transport_generic_free_cmd(se_cmd, 0); | ||
| 1620 | } | 1619 | } |
| 1621 | 1620 | ||
| 1622 | /** | 1621 | /** |
| @@ -1820,8 +1819,10 @@ void target_execute_cmd(struct se_cmd *cmd) | |||
| 1820 | /* | 1819 | /* |
| 1821 | * If the received CDB has aleady been aborted stop processing it here. | 1820 | * If the received CDB has aleady been aborted stop processing it here. |
| 1822 | */ | 1821 | */ |
| 1823 | if (transport_check_aborted_status(cmd, 1)) | 1822 | if (transport_check_aborted_status(cmd, 1)) { |
| 1823 | complete(&cmd->t_transport_stop_comp); | ||
| 1824 | return; | 1824 | return; |
| 1825 | } | ||
| 1825 | 1826 | ||
| 1826 | /* | 1827 | /* |
| 1827 | * Determine if IOCTL context caller in requesting the stopping of this | 1828 | * Determine if IOCTL context caller in requesting the stopping of this |
| @@ -3068,7 +3069,7 @@ void transport_send_task_abort(struct se_cmd *cmd) | |||
| 3068 | unsigned long flags; | 3069 | unsigned long flags; |
| 3069 | 3070 | ||
| 3070 | spin_lock_irqsave(&cmd->t_state_lock, flags); | 3071 | spin_lock_irqsave(&cmd->t_state_lock, flags); |
| 3071 | if (cmd->se_cmd_flags & SCF_SENT_CHECK_CONDITION) { | 3072 | if (cmd->se_cmd_flags & (SCF_SENT_CHECK_CONDITION | SCF_SENT_DELAYED_TAS)) { |
| 3072 | spin_unlock_irqrestore(&cmd->t_state_lock, flags); | 3073 | spin_unlock_irqrestore(&cmd->t_state_lock, flags); |
| 3073 | return; | 3074 | return; |
| 3074 | } | 3075 | } |
diff --git a/drivers/thermal/Kconfig b/drivers/thermal/Kconfig index edfd67d25013..e1cb6bd75f60 100644 --- a/drivers/thermal/Kconfig +++ b/drivers/thermal/Kconfig | |||
| @@ -22,6 +22,7 @@ config THERMAL_HWMON | |||
| 22 | config CPU_THERMAL | 22 | config CPU_THERMAL |
| 23 | bool "generic cpu cooling support" | 23 | bool "generic cpu cooling support" |
| 24 | depends on THERMAL && CPU_FREQ | 24 | depends on THERMAL && CPU_FREQ |
| 25 | select CPU_FREQ_TABLE | ||
| 25 | help | 26 | help |
| 26 | This implements the generic cpu cooling mechanism through frequency | 27 | This implements the generic cpu cooling mechanism through frequency |
| 27 | reduction, cpu hotplug and any other ways of reducing temperature. An | 28 | reduction, cpu hotplug and any other ways of reducing temperature. An |
| @@ -50,6 +51,7 @@ config RCAR_THERMAL | |||
| 50 | config EXYNOS_THERMAL | 51 | config EXYNOS_THERMAL |
| 51 | tristate "Temperature sensor on Samsung EXYNOS" | 52 | tristate "Temperature sensor on Samsung EXYNOS" |
| 52 | depends on (ARCH_EXYNOS4 || ARCH_EXYNOS5) && THERMAL | 53 | depends on (ARCH_EXYNOS4 || ARCH_EXYNOS5) && THERMAL |
| 54 | select CPU_FREQ_TABLE | ||
| 53 | help | 55 | help |
| 54 | If you say yes here you get support for TMU (Thermal Managment | 56 | If you say yes here you get support for TMU (Thermal Managment |
| 55 | Unit) on SAMSUNG EXYNOS series of SoC. | 57 | Unit) on SAMSUNG EXYNOS series of SoC. |
diff --git a/drivers/thermal/exynos_thermal.c b/drivers/thermal/exynos_thermal.c index fd03e8581afc..6dd29e4ce36b 100644 --- a/drivers/thermal/exynos_thermal.c +++ b/drivers/thermal/exynos_thermal.c | |||
| @@ -815,7 +815,7 @@ static struct platform_device_id exynos_tmu_driver_ids[] = { | |||
| 815 | }, | 815 | }, |
| 816 | { }, | 816 | { }, |
| 817 | }; | 817 | }; |
| 818 | MODULE_DEVICE_TABLE(platform, exynos4_tmu_driver_ids); | 818 | MODULE_DEVICE_TABLE(platform, exynos_tmu_driver_ids); |
| 819 | 819 | ||
| 820 | static inline struct exynos_tmu_platform_data *exynos_get_driver_data( | 820 | static inline struct exynos_tmu_platform_data *exynos_get_driver_data( |
| 821 | struct platform_device *pdev) | 821 | struct platform_device *pdev) |
diff --git a/drivers/thermal/rcar_thermal.c b/drivers/thermal/rcar_thermal.c index d4452716aaab..f7a1b574a304 100644 --- a/drivers/thermal/rcar_thermal.c +++ b/drivers/thermal/rcar_thermal.c | |||
| @@ -210,7 +210,7 @@ static int rcar_thermal_probe(struct platform_device *pdev) | |||
| 210 | goto error_free_priv; | 210 | goto error_free_priv; |
| 211 | } | 211 | } |
| 212 | 212 | ||
| 213 | zone = thermal_zone_device_register("rcar_thermal", 0, priv, | 213 | zone = thermal_zone_device_register("rcar_thermal", 0, 0, priv, |
| 214 | &rcar_thermal_zone_ops, 0, 0); | 214 | &rcar_thermal_zone_ops, 0, 0); |
| 215 | if (IS_ERR(zone)) { | 215 | if (IS_ERR(zone)) { |
| 216 | dev_err(&pdev->dev, "thermal zone device is NULL\n"); | 216 | dev_err(&pdev->dev, "thermal zone device is NULL\n"); |
diff --git a/drivers/tty/hvc/hvc_console.c b/drivers/tty/hvc/hvc_console.c index a5dec1ca1b82..13ee53bd0bf6 100644 --- a/drivers/tty/hvc/hvc_console.c +++ b/drivers/tty/hvc/hvc_console.c | |||
| @@ -424,7 +424,6 @@ static void hvc_hangup(struct tty_struct *tty) | |||
| 424 | { | 424 | { |
| 425 | struct hvc_struct *hp = tty->driver_data; | 425 | struct hvc_struct *hp = tty->driver_data; |
| 426 | unsigned long flags; | 426 | unsigned long flags; |
| 427 | int temp_open_count; | ||
| 428 | 427 | ||
| 429 | if (!hp) | 428 | if (!hp) |
| 430 | return; | 429 | return; |
| @@ -444,7 +443,6 @@ static void hvc_hangup(struct tty_struct *tty) | |||
| 444 | return; | 443 | return; |
| 445 | } | 444 | } |
| 446 | 445 | ||
| 447 | temp_open_count = hp->port.count; | ||
| 448 | hp->port.count = 0; | 446 | hp->port.count = 0; |
| 449 | spin_unlock_irqrestore(&hp->port.lock, flags); | 447 | spin_unlock_irqrestore(&hp->port.lock, flags); |
| 450 | tty_port_tty_set(&hp->port, NULL); | 448 | tty_port_tty_set(&hp->port, NULL); |
| @@ -453,11 +451,6 @@ static void hvc_hangup(struct tty_struct *tty) | |||
| 453 | 451 | ||
| 454 | if (hp->ops->notifier_hangup) | 452 | if (hp->ops->notifier_hangup) |
| 455 | hp->ops->notifier_hangup(hp, hp->data); | 453 | hp->ops->notifier_hangup(hp, hp->data); |
| 456 | |||
| 457 | while(temp_open_count) { | ||
| 458 | --temp_open_count; | ||
| 459 | tty_port_put(&hp->port); | ||
| 460 | } | ||
| 461 | } | 454 | } |
| 462 | 455 | ||
| 463 | /* | 456 | /* |
diff --git a/drivers/tty/serial/8250/8250_hp300.c b/drivers/tty/serial/8250/8250_hp300.c index 8f1dd2cc00a8..f3d0edf46644 100644 --- a/drivers/tty/serial/8250/8250_hp300.c +++ b/drivers/tty/serial/8250/8250_hp300.c | |||
| @@ -162,7 +162,7 @@ int __init hp300_setup_serial_console(void) | |||
| 162 | static int __devinit hpdca_init_one(struct dio_dev *d, | 162 | static int __devinit hpdca_init_one(struct dio_dev *d, |
| 163 | const struct dio_device_id *ent) | 163 | const struct dio_device_id *ent) |
| 164 | { | 164 | { |
| 165 | struct uart_port port; | 165 | struct uart_8250_port uart; |
| 166 | int line; | 166 | int line; |
| 167 | 167 | ||
| 168 | #ifdef CONFIG_SERIAL_8250_CONSOLE | 168 | #ifdef CONFIG_SERIAL_8250_CONSOLE |
| @@ -174,19 +174,19 @@ static int __devinit hpdca_init_one(struct dio_dev *d, | |||
| 174 | memset(&uart, 0, sizeof(uart)); | 174 | memset(&uart, 0, sizeof(uart)); |
| 175 | 175 | ||
| 176 | /* Memory mapped I/O */ | 176 | /* Memory mapped I/O */ |
| 177 | port.iotype = UPIO_MEM; | 177 | uart.port.iotype = UPIO_MEM; |
| 178 | port.flags = UPF_SKIP_TEST | UPF_SHARE_IRQ | UPF_BOOT_AUTOCONF; | 178 | uart.port.flags = UPF_SKIP_TEST | UPF_SHARE_IRQ | UPF_BOOT_AUTOCONF; |
| 179 | port.irq = d->ipl; | 179 | uart.port.irq = d->ipl; |
| 180 | port.uartclk = HPDCA_BAUD_BASE * 16; | 180 | uart.port.uartclk = HPDCA_BAUD_BASE * 16; |
| 181 | port.mapbase = (d->resource.start + UART_OFFSET); | 181 | uart.port.mapbase = (d->resource.start + UART_OFFSET); |
| 182 | port.membase = (char *)(port.mapbase + DIO_VIRADDRBASE); | 182 | uart.port.membase = (char *)(uart.port.mapbase + DIO_VIRADDRBASE); |
| 183 | port.regshift = 1; | 183 | uart.port.regshift = 1; |
| 184 | port.dev = &d->dev; | 184 | uart.port.dev = &d->dev; |
| 185 | line = serial8250_register_8250_port(&uart); | 185 | line = serial8250_register_8250_port(&uart); |
| 186 | 186 | ||
| 187 | if (line < 0) { | 187 | if (line < 0) { |
| 188 | printk(KERN_NOTICE "8250_hp300: register_serial() DCA scode %d" | 188 | printk(KERN_NOTICE "8250_hp300: register_serial() DCA scode %d" |
| 189 | " irq %d failed\n", d->scode, port.irq); | 189 | " irq %d failed\n", d->scode, uart.port.irq); |
| 190 | return -ENOMEM; | 190 | return -ENOMEM; |
| 191 | } | 191 | } |
| 192 | 192 | ||
diff --git a/drivers/tty/serial/Kconfig b/drivers/tty/serial/Kconfig index 233fbaaf2559..2a53be5f010d 100644 --- a/drivers/tty/serial/Kconfig +++ b/drivers/tty/serial/Kconfig | |||
| @@ -1150,7 +1150,7 @@ config SERIAL_SC26XX_CONSOLE | |||
| 1150 | Support for Console on SC2681/SC2692 serial ports. | 1150 | Support for Console on SC2681/SC2692 serial ports. |
| 1151 | 1151 | ||
| 1152 | config SERIAL_SCCNXP | 1152 | config SERIAL_SCCNXP |
| 1153 | bool "SCCNXP serial port support" | 1153 | tristate "SCCNXP serial port support" |
| 1154 | depends on !SERIAL_SC26XX | 1154 | depends on !SERIAL_SC26XX |
| 1155 | select SERIAL_CORE | 1155 | select SERIAL_CORE |
| 1156 | default n | 1156 | default n |
| @@ -1162,7 +1162,7 @@ config SERIAL_SCCNXP | |||
| 1162 | 1162 | ||
| 1163 | config SERIAL_SCCNXP_CONSOLE | 1163 | config SERIAL_SCCNXP_CONSOLE |
| 1164 | bool "Console on SCCNXP serial port" | 1164 | bool "Console on SCCNXP serial port" |
| 1165 | depends on SERIAL_SCCNXP | 1165 | depends on SERIAL_SCCNXP=y |
| 1166 | select SERIAL_CORE_CONSOLE | 1166 | select SERIAL_CORE_CONSOLE |
| 1167 | help | 1167 | help |
| 1168 | Support for console on SCCNXP serial ports. | 1168 | Support for console on SCCNXP serial ports. |
diff --git a/drivers/tty/serial/max310x.c b/drivers/tty/serial/max310x.c index 2bc28a59d385..1ab1d2c66de4 100644 --- a/drivers/tty/serial/max310x.c +++ b/drivers/tty/serial/max310x.c | |||
| @@ -1239,6 +1239,7 @@ static int __devexit max310x_remove(struct spi_device *spi) | |||
| 1239 | static const struct spi_device_id max310x_id_table[] = { | 1239 | static const struct spi_device_id max310x_id_table[] = { |
| 1240 | { "max3107", MAX310X_TYPE_MAX3107 }, | 1240 | { "max3107", MAX310X_TYPE_MAX3107 }, |
| 1241 | { "max3108", MAX310X_TYPE_MAX3108 }, | 1241 | { "max3108", MAX310X_TYPE_MAX3108 }, |
| 1242 | { } | ||
| 1242 | }; | 1243 | }; |
| 1243 | MODULE_DEVICE_TABLE(spi, max310x_id_table); | 1244 | MODULE_DEVICE_TABLE(spi, max310x_id_table); |
| 1244 | 1245 | ||
diff --git a/drivers/tty/serial/omap-serial.c b/drivers/tty/serial/omap-serial.c index 6ede6fd92b4c..6d3d26a607b9 100644 --- a/drivers/tty/serial/omap-serial.c +++ b/drivers/tty/serial/omap-serial.c | |||
| @@ -671,19 +671,19 @@ serial_omap_configure_xonxoff | |||
| 671 | 671 | ||
| 672 | /* | 672 | /* |
| 673 | * IXON Flag: | 673 | * IXON Flag: |
| 674 | * Flow control for OMAP.TX | 674 | * Enable XON/XOFF flow control on output. |
| 675 | * OMAP.RX should listen for XON/XOFF | 675 | * Transmit XON1, XOFF1 |
| 676 | */ | 676 | */ |
| 677 | if (termios->c_iflag & IXON) | 677 | if (termios->c_iflag & IXON) |
| 678 | up->efr |= OMAP_UART_SW_RX; | 678 | up->efr |= OMAP_UART_SW_TX; |
| 679 | 679 | ||
| 680 | /* | 680 | /* |
| 681 | * IXOFF Flag: | 681 | * IXOFF Flag: |
| 682 | * Flow control for OMAP.RX | 682 | * Enable XON/XOFF flow control on input. |
| 683 | * OMAP.TX should send XON/XOFF | 683 | * Receiver compares XON1, XOFF1. |
| 684 | */ | 684 | */ |
| 685 | if (termios->c_iflag & IXOFF) | 685 | if (termios->c_iflag & IXOFF) |
| 686 | up->efr |= OMAP_UART_SW_TX; | 686 | up->efr |= OMAP_UART_SW_RX; |
| 687 | 687 | ||
| 688 | serial_out(up, UART_EFR, up->efr | UART_EFR_ECB); | 688 | serial_out(up, UART_EFR, up->efr | UART_EFR_ECB); |
| 689 | serial_out(up, UART_LCR, UART_LCR_CONF_MODE_A); | 689 | serial_out(up, UART_LCR, UART_LCR_CONF_MODE_A); |
diff --git a/drivers/tty/serial/sccnxp.c b/drivers/tty/serial/sccnxp.c index b7086d004f5f..e821068cd95b 100644 --- a/drivers/tty/serial/sccnxp.c +++ b/drivers/tty/serial/sccnxp.c | |||
| @@ -971,6 +971,7 @@ static const struct platform_device_id sccnxp_id_table[] = { | |||
| 971 | { "sc28202", SCCNXP_TYPE_SC28202 }, | 971 | { "sc28202", SCCNXP_TYPE_SC28202 }, |
| 972 | { "sc68681", SCCNXP_TYPE_SC68681 }, | 972 | { "sc68681", SCCNXP_TYPE_SC68681 }, |
| 973 | { "sc68692", SCCNXP_TYPE_SC68692 }, | 973 | { "sc68692", SCCNXP_TYPE_SC68692 }, |
| 974 | { }, | ||
| 974 | }; | 975 | }; |
| 975 | MODULE_DEVICE_TABLE(platform, sccnxp_id_table); | 976 | MODULE_DEVICE_TABLE(platform, sccnxp_id_table); |
| 976 | 977 | ||
diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c index 9be296cf7295..6ee59001d61d 100644 --- a/drivers/tty/serial/sh-sci.c +++ b/drivers/tty/serial/sh-sci.c | |||
| @@ -530,7 +530,8 @@ static inline int sci_rxd_in(struct uart_port *port) | |||
| 530 | if (s->cfg->port_reg <= 0) | 530 | if (s->cfg->port_reg <= 0) |
| 531 | return 1; | 531 | return 1; |
| 532 | 532 | ||
| 533 | return !!__raw_readb(s->cfg->port_reg); | 533 | /* Cast for ARM damage */ |
| 534 | return !!__raw_readb((void __iomem *)s->cfg->port_reg); | ||
| 534 | } | 535 | } |
| 535 | 536 | ||
| 536 | /* ********************************************************************** * | 537 | /* ********************************************************************** * |
diff --git a/drivers/tty/sysrq.c b/drivers/tty/sysrq.c index 05728894a88c..16ee6cee07da 100644 --- a/drivers/tty/sysrq.c +++ b/drivers/tty/sysrq.c | |||
| @@ -452,6 +452,7 @@ static struct sysrq_key_op *sysrq_key_table[36] = { | |||
| 452 | NULL, /* v */ | 452 | NULL, /* v */ |
| 453 | &sysrq_showstate_blocked_op, /* w */ | 453 | &sysrq_showstate_blocked_op, /* w */ |
| 454 | /* x: May be registered on ppc/powerpc for xmon */ | 454 | /* x: May be registered on ppc/powerpc for xmon */ |
| 455 | /* x: May be registered on sparc64 for global PMU dump */ | ||
| 455 | NULL, /* x */ | 456 | NULL, /* x */ |
| 456 | /* y: May be registered on sparc64 for global register dump */ | 457 | /* y: May be registered on sparc64 for global register dump */ |
| 457 | NULL, /* y */ | 458 | NULL, /* y */ |
diff --git a/drivers/tty/vt/vt.c b/drivers/tty/vt/vt.c index f87d7e8964bf..4e0d0c3734b3 100644 --- a/drivers/tty/vt/vt.c +++ b/drivers/tty/vt/vt.c | |||
| @@ -539,25 +539,25 @@ static void insert_char(struct vc_data *vc, unsigned int nr) | |||
| 539 | { | 539 | { |
| 540 | unsigned short *p = (unsigned short *) vc->vc_pos; | 540 | unsigned short *p = (unsigned short *) vc->vc_pos; |
| 541 | 541 | ||
| 542 | scr_memmovew(p + nr, p, vc->vc_cols - vc->vc_x); | 542 | scr_memmovew(p + nr, p, (vc->vc_cols - vc->vc_x) * 2); |
| 543 | scr_memsetw(p, vc->vc_video_erase_char, nr * 2); | 543 | scr_memsetw(p, vc->vc_video_erase_char, nr * 2); |
| 544 | vc->vc_need_wrap = 0; | 544 | vc->vc_need_wrap = 0; |
| 545 | if (DO_UPDATE(vc)) | 545 | if (DO_UPDATE(vc)) |
| 546 | do_update_region(vc, (unsigned long) p, | 546 | do_update_region(vc, (unsigned long) p, |
| 547 | (vc->vc_cols - vc->vc_x) / 2 + 1); | 547 | vc->vc_cols - vc->vc_x); |
| 548 | } | 548 | } |
| 549 | 549 | ||
| 550 | static void delete_char(struct vc_data *vc, unsigned int nr) | 550 | static void delete_char(struct vc_data *vc, unsigned int nr) |
| 551 | { | 551 | { |
| 552 | unsigned short *p = (unsigned short *) vc->vc_pos; | 552 | unsigned short *p = (unsigned short *) vc->vc_pos; |
| 553 | 553 | ||
| 554 | scr_memcpyw(p, p + nr, vc->vc_cols - vc->vc_x - nr); | 554 | scr_memcpyw(p, p + nr, (vc->vc_cols - vc->vc_x - nr) * 2); |
| 555 | scr_memsetw(p + vc->vc_cols - vc->vc_x - nr, vc->vc_video_erase_char, | 555 | scr_memsetw(p + vc->vc_cols - vc->vc_x - nr, vc->vc_video_erase_char, |
| 556 | nr * 2); | 556 | nr * 2); |
| 557 | vc->vc_need_wrap = 0; | 557 | vc->vc_need_wrap = 0; |
| 558 | if (DO_UPDATE(vc)) | 558 | if (DO_UPDATE(vc)) |
| 559 | do_update_region(vc, (unsigned long) p, | 559 | do_update_region(vc, (unsigned long) p, |
| 560 | (vc->vc_cols - vc->vc_x) / 2); | 560 | vc->vc_cols - vc->vc_x); |
| 561 | } | 561 | } |
| 562 | 562 | ||
| 563 | static int softcursor_original; | 563 | static int softcursor_original; |
diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c index 981f2132d128..6e49ec6f3adc 100644 --- a/drivers/usb/class/cdc-acm.c +++ b/drivers/usb/class/cdc-acm.c | |||
| @@ -817,10 +817,6 @@ static const __u32 acm_tty_speed[] = { | |||
| 817 | 2500000, 3000000, 3500000, 4000000 | 817 | 2500000, 3000000, 3500000, 4000000 |
| 818 | }; | 818 | }; |
| 819 | 819 | ||
| 820 | static const __u8 acm_tty_size[] = { | ||
| 821 | 5, 6, 7, 8 | ||
| 822 | }; | ||
| 823 | |||
| 824 | static void acm_tty_set_termios(struct tty_struct *tty, | 820 | static void acm_tty_set_termios(struct tty_struct *tty, |
| 825 | struct ktermios *termios_old) | 821 | struct ktermios *termios_old) |
| 826 | { | 822 | { |
| @@ -834,7 +830,21 @@ static void acm_tty_set_termios(struct tty_struct *tty, | |||
| 834 | newline.bParityType = termios->c_cflag & PARENB ? | 830 | newline.bParityType = termios->c_cflag & PARENB ? |
| 835 | (termios->c_cflag & PARODD ? 1 : 2) + | 831 | (termios->c_cflag & PARODD ? 1 : 2) + |
| 836 | (termios->c_cflag & CMSPAR ? 2 : 0) : 0; | 832 | (termios->c_cflag & CMSPAR ? 2 : 0) : 0; |
| 837 | newline.bDataBits = acm_tty_size[(termios->c_cflag & CSIZE) >> 4]; | 833 | switch (termios->c_cflag & CSIZE) { |
| 834 | case CS5: | ||
| 835 | newline.bDataBits = 5; | ||
| 836 | break; | ||
| 837 | case CS6: | ||
| 838 | newline.bDataBits = 6; | ||
| 839 | break; | ||
| 840 | case CS7: | ||
| 841 | newline.bDataBits = 7; | ||
| 842 | break; | ||
| 843 | case CS8: | ||
| 844 | default: | ||
| 845 | newline.bDataBits = 8; | ||
| 846 | break; | ||
| 847 | } | ||
| 838 | /* FIXME: Needs to clear unsupported bits in the termios */ | 848 | /* FIXME: Needs to clear unsupported bits in the termios */ |
| 839 | acm->clocal = ((termios->c_cflag & CLOCAL) != 0); | 849 | acm->clocal = ((termios->c_cflag & CLOCAL) != 0); |
| 840 | 850 | ||
| @@ -1233,7 +1243,7 @@ made_compressed_probe: | |||
| 1233 | 1243 | ||
| 1234 | if (usb_endpoint_xfer_int(epwrite)) | 1244 | if (usb_endpoint_xfer_int(epwrite)) |
| 1235 | usb_fill_int_urb(snd->urb, usb_dev, | 1245 | usb_fill_int_urb(snd->urb, usb_dev, |
| 1236 | usb_sndbulkpipe(usb_dev, epwrite->bEndpointAddress), | 1246 | usb_sndintpipe(usb_dev, epwrite->bEndpointAddress), |
| 1237 | NULL, acm->writesize, acm_write_bulk, snd, epwrite->bInterval); | 1247 | NULL, acm->writesize, acm_write_bulk, snd, epwrite->bInterval); |
| 1238 | else | 1248 | else |
| 1239 | usb_fill_bulk_urb(snd->urb, usb_dev, | 1249 | usb_fill_bulk_urb(snd->urb, usb_dev, |
diff --git a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c index e0356cb859b5..b78fbe222b72 100644 --- a/drivers/usb/core/devio.c +++ b/drivers/usb/core/devio.c | |||
| @@ -1348,6 +1348,7 @@ static int proc_do_submiturb(struct dev_state *ps, struct usbdevfs_urb *uurb, | |||
| 1348 | ret = -EFAULT; | 1348 | ret = -EFAULT; |
| 1349 | goto error; | 1349 | goto error; |
| 1350 | } | 1350 | } |
| 1351 | uurb->buffer += u; | ||
| 1351 | } | 1352 | } |
| 1352 | totlen -= u; | 1353 | totlen -= u; |
| 1353 | } | 1354 | } |
diff --git a/drivers/usb/core/driver.c b/drivers/usb/core/driver.c index ddd820d25288..6056db7af410 100644 --- a/drivers/usb/core/driver.c +++ b/drivers/usb/core/driver.c | |||
| @@ -367,6 +367,10 @@ static int usb_probe_interface(struct device *dev) | |||
| 367 | intf->condition = USB_INTERFACE_UNBOUND; | 367 | intf->condition = USB_INTERFACE_UNBOUND; |
| 368 | usb_cancel_queued_reset(intf); | 368 | usb_cancel_queued_reset(intf); |
| 369 | 369 | ||
| 370 | /* If the LPM disable succeeded, balance the ref counts. */ | ||
| 371 | if (!lpm_disable_error) | ||
| 372 | usb_unlocked_enable_lpm(udev); | ||
| 373 | |||
| 370 | /* Unbound interfaces are always runtime-PM-disabled and -suspended */ | 374 | /* Unbound interfaces are always runtime-PM-disabled and -suspended */ |
| 371 | if (driver->supports_autosuspend) | 375 | if (driver->supports_autosuspend) |
| 372 | pm_runtime_disable(dev); | 376 | pm_runtime_disable(dev); |
diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c index 1e741bca0265..f034716190ff 100644 --- a/drivers/usb/core/hcd.c +++ b/drivers/usb/core/hcd.c | |||
| @@ -2151,8 +2151,15 @@ EXPORT_SYMBOL_GPL(usb_bus_start_enum); | |||
| 2151 | irqreturn_t usb_hcd_irq (int irq, void *__hcd) | 2151 | irqreturn_t usb_hcd_irq (int irq, void *__hcd) |
| 2152 | { | 2152 | { |
| 2153 | struct usb_hcd *hcd = __hcd; | 2153 | struct usb_hcd *hcd = __hcd; |
| 2154 | unsigned long flags; | ||
| 2154 | irqreturn_t rc; | 2155 | irqreturn_t rc; |
| 2155 | 2156 | ||
| 2157 | /* IRQF_DISABLED doesn't work correctly with shared IRQs | ||
| 2158 | * when the first handler doesn't use it. So let's just | ||
| 2159 | * assume it's never used. | ||
| 2160 | */ | ||
| 2161 | local_irq_save(flags); | ||
| 2162 | |||
| 2156 | if (unlikely(HCD_DEAD(hcd) || !HCD_HW_ACCESSIBLE(hcd))) | 2163 | if (unlikely(HCD_DEAD(hcd) || !HCD_HW_ACCESSIBLE(hcd))) |
| 2157 | rc = IRQ_NONE; | 2164 | rc = IRQ_NONE; |
| 2158 | else if (hcd->driver->irq(hcd) == IRQ_NONE) | 2165 | else if (hcd->driver->irq(hcd) == IRQ_NONE) |
| @@ -2160,6 +2167,7 @@ irqreturn_t usb_hcd_irq (int irq, void *__hcd) | |||
| 2160 | else | 2167 | else |
| 2161 | rc = IRQ_HANDLED; | 2168 | rc = IRQ_HANDLED; |
| 2162 | 2169 | ||
| 2170 | local_irq_restore(flags); | ||
| 2163 | return rc; | 2171 | return rc; |
| 2164 | } | 2172 | } |
| 2165 | EXPORT_SYMBOL_GPL(usb_hcd_irq); | 2173 | EXPORT_SYMBOL_GPL(usb_hcd_irq); |
| @@ -2347,6 +2355,14 @@ static int usb_hcd_request_irqs(struct usb_hcd *hcd, | |||
| 2347 | int retval; | 2355 | int retval; |
| 2348 | 2356 | ||
| 2349 | if (hcd->driver->irq) { | 2357 | if (hcd->driver->irq) { |
| 2358 | |||
| 2359 | /* IRQF_DISABLED doesn't work as advertised when used together | ||
| 2360 | * with IRQF_SHARED. As usb_hcd_irq() will always disable | ||
| 2361 | * interrupts we can remove it here. | ||
| 2362 | */ | ||
| 2363 | if (irqflags & IRQF_SHARED) | ||
| 2364 | irqflags &= ~IRQF_DISABLED; | ||
| 2365 | |||
| 2350 | snprintf(hcd->irq_descr, sizeof(hcd->irq_descr), "%s:usb%d", | 2366 | snprintf(hcd->irq_descr, sizeof(hcd->irq_descr), "%s:usb%d", |
| 2351 | hcd->driver->description, hcd->self.busnum); | 2367 | hcd->driver->description, hcd->self.busnum); |
| 2352 | retval = request_irq(irqnum, &usb_hcd_irq, irqflags, | 2368 | retval = request_irq(irqnum, &usb_hcd_irq, irqflags, |
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index 673ee4696262..1af04bdeaf0c 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c | |||
| @@ -739,13 +739,16 @@ static void hub_tt_work(struct work_struct *work) | |||
| 739 | int limit = 100; | 739 | int limit = 100; |
| 740 | 740 | ||
| 741 | spin_lock_irqsave (&hub->tt.lock, flags); | 741 | spin_lock_irqsave (&hub->tt.lock, flags); |
| 742 | while (--limit && !list_empty (&hub->tt.clear_list)) { | 742 | while (!list_empty(&hub->tt.clear_list)) { |
| 743 | struct list_head *next; | 743 | struct list_head *next; |
| 744 | struct usb_tt_clear *clear; | 744 | struct usb_tt_clear *clear; |
| 745 | struct usb_device *hdev = hub->hdev; | 745 | struct usb_device *hdev = hub->hdev; |
| 746 | const struct hc_driver *drv; | 746 | const struct hc_driver *drv; |
| 747 | int status; | 747 | int status; |
| 748 | 748 | ||
| 749 | if (!hub->quiescing && --limit < 0) | ||
| 750 | break; | ||
| 751 | |||
| 749 | next = hub->tt.clear_list.next; | 752 | next = hub->tt.clear_list.next; |
| 750 | clear = list_entry (next, struct usb_tt_clear, clear_list); | 753 | clear = list_entry (next, struct usb_tt_clear, clear_list); |
| 751 | list_del (&clear->clear_list); | 754 | list_del (&clear->clear_list); |
| @@ -1210,7 +1213,7 @@ static void hub_quiesce(struct usb_hub *hub, enum hub_quiescing_type type) | |||
| 1210 | if (hub->has_indicators) | 1213 | if (hub->has_indicators) |
| 1211 | cancel_delayed_work_sync(&hub->leds); | 1214 | cancel_delayed_work_sync(&hub->leds); |
| 1212 | if (hub->tt.hub) | 1215 | if (hub->tt.hub) |
| 1213 | cancel_work_sync(&hub->tt.clear_work); | 1216 | flush_work(&hub->tt.clear_work); |
| 1214 | } | 1217 | } |
| 1215 | 1218 | ||
| 1216 | /* caller has locked the hub device */ | 1219 | /* caller has locked the hub device */ |
| @@ -3241,8 +3244,7 @@ static int usb_req_set_sel(struct usb_device *udev, enum usb3_link_state state) | |||
| 3241 | (state == USB3_LPM_U2 && | 3244 | (state == USB3_LPM_U2 && |
| 3242 | (u2_sel > USB3_LPM_MAX_U2_SEL_PEL || | 3245 | (u2_sel > USB3_LPM_MAX_U2_SEL_PEL || |
| 3243 | u2_pel > USB3_LPM_MAX_U2_SEL_PEL))) { | 3246 | u2_pel > USB3_LPM_MAX_U2_SEL_PEL))) { |
| 3244 | dev_dbg(&udev->dev, "Device-initiated %s disabled due " | 3247 | dev_dbg(&udev->dev, "Device-initiated %s disabled due to long SEL %llu us or PEL %llu us\n", |
| 3245 | "to long SEL %llu ms or PEL %llu ms\n", | ||
| 3246 | usb3_lpm_names[state], u1_sel, u1_pel); | 3248 | usb3_lpm_names[state], u1_sel, u1_pel); |
| 3247 | return -EINVAL; | 3249 | return -EINVAL; |
| 3248 | } | 3250 | } |
| @@ -3320,16 +3322,6 @@ static int usb_set_device_initiated_lpm(struct usb_device *udev, | |||
| 3320 | 3322 | ||
| 3321 | if (enable) { | 3323 | if (enable) { |
| 3322 | /* | 3324 | /* |
| 3323 | * First, let the device know about the exit latencies | ||
| 3324 | * associated with the link state we're about to enable. | ||
| 3325 | */ | ||
| 3326 | ret = usb_req_set_sel(udev, state); | ||
| 3327 | if (ret < 0) { | ||
| 3328 | dev_warn(&udev->dev, "Set SEL for device-initiated " | ||
| 3329 | "%s failed.\n", usb3_lpm_names[state]); | ||
| 3330 | return -EBUSY; | ||
| 3331 | } | ||
| 3332 | /* | ||
| 3333 | * Now send the control transfer to enable device-initiated LPM | 3325 | * Now send the control transfer to enable device-initiated LPM |
| 3334 | * for either U1 or U2. | 3326 | * for either U1 or U2. |
| 3335 | */ | 3327 | */ |
| @@ -3414,7 +3406,28 @@ static int usb_set_lpm_timeout(struct usb_device *udev, | |||
| 3414 | static void usb_enable_link_state(struct usb_hcd *hcd, struct usb_device *udev, | 3406 | static void usb_enable_link_state(struct usb_hcd *hcd, struct usb_device *udev, |
| 3415 | enum usb3_link_state state) | 3407 | enum usb3_link_state state) |
| 3416 | { | 3408 | { |
| 3417 | int timeout; | 3409 | int timeout, ret; |
| 3410 | __u8 u1_mel = udev->bos->ss_cap->bU1devExitLat; | ||
| 3411 | __le16 u2_mel = udev->bos->ss_cap->bU2DevExitLat; | ||
| 3412 | |||
| 3413 | /* If the device says it doesn't have *any* exit latency to come out of | ||
| 3414 | * U1 or U2, it's probably lying. Assume it doesn't implement that link | ||
| 3415 | * state. | ||
| 3416 | */ | ||
| 3417 | if ((state == USB3_LPM_U1 && u1_mel == 0) || | ||
| 3418 | (state == USB3_LPM_U2 && u2_mel == 0)) | ||
| 3419 | return; | ||
| 3420 | |||
| 3421 | /* | ||
| 3422 | * First, let the device know about the exit latencies | ||
| 3423 | * associated with the link state we're about to enable. | ||
| 3424 | */ | ||
| 3425 | ret = usb_req_set_sel(udev, state); | ||
| 3426 | if (ret < 0) { | ||
| 3427 | dev_warn(&udev->dev, "Set SEL for device-initiated %s failed.\n", | ||
| 3428 | usb3_lpm_names[state]); | ||
| 3429 | return; | ||
| 3430 | } | ||
| 3418 | 3431 | ||
| 3419 | /* We allow the host controller to set the U1/U2 timeout internally | 3432 | /* We allow the host controller to set the U1/U2 timeout internally |
| 3420 | * first, so that it can change its schedule to account for the | 3433 | * first, so that it can change its schedule to account for the |
diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c index b415c0c859d3..c14ebc975ba4 100644 --- a/drivers/usb/dwc3/core.c +++ b/drivers/usb/dwc3/core.c | |||
| @@ -409,6 +409,10 @@ static void dwc3_core_exit(struct dwc3 *dwc) | |||
| 409 | { | 409 | { |
| 410 | dwc3_event_buffers_cleanup(dwc); | 410 | dwc3_event_buffers_cleanup(dwc); |
| 411 | dwc3_free_event_buffers(dwc); | 411 | dwc3_free_event_buffers(dwc); |
| 412 | |||
| 413 | usb_phy_shutdown(dwc->usb2_phy); | ||
| 414 | usb_phy_shutdown(dwc->usb3_phy); | ||
| 415 | |||
| 412 | } | 416 | } |
| 413 | 417 | ||
| 414 | #define DWC3_ALIGN_MASK (16 - 1) | 418 | #define DWC3_ALIGN_MASK (16 - 1) |
diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index c9e729a4bf65..7b7deddf6a52 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c | |||
| @@ -1904,7 +1904,7 @@ static void dwc3_stop_active_transfer(struct dwc3 *dwc, u32 epnum) | |||
| 1904 | ret = dwc3_send_gadget_ep_cmd(dwc, dep->number, cmd, ¶ms); | 1904 | ret = dwc3_send_gadget_ep_cmd(dwc, dep->number, cmd, ¶ms); |
| 1905 | WARN_ON_ONCE(ret); | 1905 | WARN_ON_ONCE(ret); |
| 1906 | dep->resource_index = 0; | 1906 | dep->resource_index = 0; |
| 1907 | 1907 | dep->flags &= ~DWC3_EP_BUSY; | |
| 1908 | udelay(100); | 1908 | udelay(100); |
| 1909 | } | 1909 | } |
| 1910 | 1910 | ||
diff --git a/drivers/usb/early/ehci-dbgp.c b/drivers/usb/early/ehci-dbgp.c index e426ad626d74..4bfa78af379c 100644 --- a/drivers/usb/early/ehci-dbgp.c +++ b/drivers/usb/early/ehci-dbgp.c | |||
| @@ -20,6 +20,7 @@ | |||
| 20 | #include <linux/usb/ehci_def.h> | 20 | #include <linux/usb/ehci_def.h> |
| 21 | #include <linux/delay.h> | 21 | #include <linux/delay.h> |
| 22 | #include <linux/serial_core.h> | 22 | #include <linux/serial_core.h> |
| 23 | #include <linux/kconfig.h> | ||
| 23 | #include <linux/kgdb.h> | 24 | #include <linux/kgdb.h> |
| 24 | #include <linux/kthread.h> | 25 | #include <linux/kthread.h> |
| 25 | #include <asm/io.h> | 26 | #include <asm/io.h> |
| @@ -614,12 +615,6 @@ err: | |||
| 614 | return -ENODEV; | 615 | return -ENODEV; |
| 615 | } | 616 | } |
| 616 | 617 | ||
| 617 | int dbgp_external_startup(struct usb_hcd *hcd) | ||
| 618 | { | ||
| 619 | return xen_dbgp_external_startup(hcd) ?: _dbgp_external_startup(); | ||
| 620 | } | ||
| 621 | EXPORT_SYMBOL_GPL(dbgp_external_startup); | ||
| 622 | |||
| 623 | static int ehci_reset_port(int port) | 618 | static int ehci_reset_port(int port) |
| 624 | { | 619 | { |
| 625 | u32 portsc; | 620 | u32 portsc; |
| @@ -979,6 +974,7 @@ struct console early_dbgp_console = { | |||
| 979 | .index = -1, | 974 | .index = -1, |
| 980 | }; | 975 | }; |
| 981 | 976 | ||
| 977 | #if IS_ENABLED(CONFIG_USB_EHCI_HCD) | ||
| 982 | int dbgp_reset_prep(struct usb_hcd *hcd) | 978 | int dbgp_reset_prep(struct usb_hcd *hcd) |
| 983 | { | 979 | { |
| 984 | int ret = xen_dbgp_reset_prep(hcd); | 980 | int ret = xen_dbgp_reset_prep(hcd); |
| @@ -1007,6 +1003,13 @@ int dbgp_reset_prep(struct usb_hcd *hcd) | |||
| 1007 | } | 1003 | } |
| 1008 | EXPORT_SYMBOL_GPL(dbgp_reset_prep); | 1004 | EXPORT_SYMBOL_GPL(dbgp_reset_prep); |
| 1009 | 1005 | ||
| 1006 | int dbgp_external_startup(struct usb_hcd *hcd) | ||
| 1007 | { | ||
| 1008 | return xen_dbgp_external_startup(hcd) ?: _dbgp_external_startup(); | ||
| 1009 | } | ||
| 1010 | EXPORT_SYMBOL_GPL(dbgp_external_startup); | ||
| 1011 | #endif /* USB_EHCI_HCD */ | ||
| 1012 | |||
| 1010 | #ifdef CONFIG_KGDB | 1013 | #ifdef CONFIG_KGDB |
| 1011 | 1014 | ||
| 1012 | static char kgdbdbgp_buf[DBGP_MAX_PACKET]; | 1015 | static char kgdbdbgp_buf[DBGP_MAX_PACKET]; |
diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig index dfb51a45496c..e0ff51b89529 100644 --- a/drivers/usb/gadget/Kconfig +++ b/drivers/usb/gadget/Kconfig | |||
| @@ -952,6 +952,7 @@ endif | |||
| 952 | config USB_G_WEBCAM | 952 | config USB_G_WEBCAM |
| 953 | tristate "USB Webcam Gadget" | 953 | tristate "USB Webcam Gadget" |
| 954 | depends on VIDEO_DEV | 954 | depends on VIDEO_DEV |
| 955 | select USB_LIBCOMPOSITE | ||
| 955 | help | 956 | help |
| 956 | The Webcam Gadget acts as a composite USB Audio and Video Class | 957 | The Webcam Gadget acts as a composite USB Audio and Video Class |
| 957 | device. It provides a userspace API to process UVC control requests | 958 | device. It provides a userspace API to process UVC control requests |
diff --git a/drivers/usb/gadget/lpc32xx_udc.c b/drivers/usb/gadget/lpc32xx_udc.c index f696fb9b136d..21a9861dabf0 100644 --- a/drivers/usb/gadget/lpc32xx_udc.c +++ b/drivers/usb/gadget/lpc32xx_udc.c | |||
| @@ -2930,10 +2930,10 @@ static void vbus_work(struct work_struct *work) | |||
| 2930 | 2930 | ||
| 2931 | /* Get the VBUS status from the transceiver */ | 2931 | /* Get the VBUS status from the transceiver */ |
| 2932 | value = i2c_smbus_read_byte_data(udc->isp1301_i2c_client, | 2932 | value = i2c_smbus_read_byte_data(udc->isp1301_i2c_client, |
| 2933 | ISP1301_I2C_OTG_CONTROL_2); | 2933 | ISP1301_I2C_INTERRUPT_SOURCE); |
| 2934 | 2934 | ||
| 2935 | /* VBUS on or off? */ | 2935 | /* VBUS on or off? */ |
| 2936 | if (value & OTG_B_SESS_VLD) | 2936 | if (value & INT_SESS_VLD) |
| 2937 | udc->vbus = 1; | 2937 | udc->vbus = 1; |
| 2938 | else | 2938 | else |
| 2939 | udc->vbus = 0; | 2939 | udc->vbus = 0; |
diff --git a/drivers/usb/gadget/net2272.c b/drivers/usb/gadget/net2272.c index 43ac7482fa91..c009263a47e3 100644 --- a/drivers/usb/gadget/net2272.c +++ b/drivers/usb/gadget/net2272.c | |||
| @@ -2069,8 +2069,10 @@ static irqreturn_t net2272_irq(int irq, void *_dev) | |||
| 2069 | #if defined(PLX_PCI_RDK2) | 2069 | #if defined(PLX_PCI_RDK2) |
| 2070 | /* see if PCI int for us by checking irqstat */ | 2070 | /* see if PCI int for us by checking irqstat */ |
| 2071 | intcsr = readl(dev->rdk2.fpga_base_addr + RDK2_IRQSTAT); | 2071 | intcsr = readl(dev->rdk2.fpga_base_addr + RDK2_IRQSTAT); |
| 2072 | if (!intcsr & (1 << NET2272_PCI_IRQ)) | 2072 | if (!intcsr & (1 << NET2272_PCI_IRQ)) { |
| 2073 | spin_unlock(&dev->lock); | ||
| 2073 | return IRQ_NONE; | 2074 | return IRQ_NONE; |
| 2075 | } | ||
| 2074 | /* check dma interrupts */ | 2076 | /* check dma interrupts */ |
| 2075 | #endif | 2077 | #endif |
| 2076 | /* Platform/devcice interrupt handler */ | 2078 | /* Platform/devcice interrupt handler */ |
diff --git a/drivers/usb/gadget/u_ether.c b/drivers/usb/gadget/u_ether.c index 6458764994ef..4ec3c0d7a18b 100644 --- a/drivers/usb/gadget/u_ether.c +++ b/drivers/usb/gadget/u_ether.c | |||
| @@ -20,6 +20,7 @@ | |||
| 20 | #include <linux/ctype.h> | 20 | #include <linux/ctype.h> |
| 21 | #include <linux/etherdevice.h> | 21 | #include <linux/etherdevice.h> |
| 22 | #include <linux/ethtool.h> | 22 | #include <linux/ethtool.h> |
| 23 | #include <linux/if_vlan.h> | ||
| 23 | 24 | ||
| 24 | #include "u_ether.h" | 25 | #include "u_ether.h" |
| 25 | 26 | ||
| @@ -295,7 +296,7 @@ static void rx_complete(struct usb_ep *ep, struct usb_request *req) | |||
| 295 | while (skb2) { | 296 | while (skb2) { |
| 296 | if (status < 0 | 297 | if (status < 0 |
| 297 | || ETH_HLEN > skb2->len | 298 | || ETH_HLEN > skb2->len |
| 298 | || skb2->len > ETH_FRAME_LEN) { | 299 | || skb2->len > VLAN_ETH_FRAME_LEN) { |
| 299 | dev->net->stats.rx_errors++; | 300 | dev->net->stats.rx_errors++; |
| 300 | dev->net->stats.rx_length_errors++; | 301 | dev->net->stats.rx_length_errors++; |
| 301 | DBG(dev, "rx length %d\n", skb2->len); | 302 | DBG(dev, "rx length %d\n", skb2->len); |
diff --git a/drivers/usb/host/ehci-fsl.c b/drivers/usb/host/ehci-fsl.c index 9bfde82078ec..0d2f35ca93f1 100644 --- a/drivers/usb/host/ehci-fsl.c +++ b/drivers/usb/host/ehci-fsl.c | |||
| @@ -222,7 +222,7 @@ static int ehci_fsl_setup_phy(struct usb_hcd *hcd, | |||
| 222 | 222 | ||
| 223 | if (pdata->controller_ver < 0) { | 223 | if (pdata->controller_ver < 0) { |
| 224 | dev_warn(hcd->self.controller, "Could not get controller version\n"); | 224 | dev_warn(hcd->self.controller, "Could not get controller version\n"); |
| 225 | return; | 225 | return -ENODEV; |
| 226 | } | 226 | } |
| 227 | 227 | ||
| 228 | portsc = ehci_readl(ehci, &ehci->regs->port_status[port_offset]); | 228 | portsc = ehci_readl(ehci, &ehci->regs->port_status[port_offset]); |
diff --git a/drivers/usb/host/ehci-ls1x.c b/drivers/usb/host/ehci-ls1x.c index ca759652626b..aa0f328922df 100644 --- a/drivers/usb/host/ehci-ls1x.c +++ b/drivers/usb/host/ehci-ls1x.c | |||
| @@ -113,7 +113,7 @@ static int ehci_hcd_ls1x_probe(struct platform_device *pdev) | |||
| 113 | goto err_put_hcd; | 113 | goto err_put_hcd; |
| 114 | } | 114 | } |
| 115 | 115 | ||
| 116 | ret = usb_add_hcd(hcd, irq, IRQF_SHARED); | 116 | ret = usb_add_hcd(hcd, irq, IRQF_DISABLED | IRQF_SHARED); |
| 117 | if (ret) | 117 | if (ret) |
| 118 | goto err_put_hcd; | 118 | goto err_put_hcd; |
| 119 | 119 | ||
diff --git a/drivers/usb/host/ehci-orion.c b/drivers/usb/host/ehci-orion.c index 8e7eca62f169..9c2717d66730 100644 --- a/drivers/usb/host/ehci-orion.c +++ b/drivers/usb/host/ehci-orion.c | |||
| @@ -160,7 +160,7 @@ static const struct hc_driver ehci_orion_hc_driver = { | |||
| 160 | .clear_tt_buffer_complete = ehci_clear_tt_buffer_complete, | 160 | .clear_tt_buffer_complete = ehci_clear_tt_buffer_complete, |
| 161 | }; | 161 | }; |
| 162 | 162 | ||
| 163 | static void __init | 163 | static void __devinit |
| 164 | ehci_orion_conf_mbus_windows(struct usb_hcd *hcd, | 164 | ehci_orion_conf_mbus_windows(struct usb_hcd *hcd, |
| 165 | const struct mbus_dram_target_info *dram) | 165 | const struct mbus_dram_target_info *dram) |
| 166 | { | 166 | { |
diff --git a/drivers/usb/host/ehci-vt8500.c b/drivers/usb/host/ehci-vt8500.c index 96722bfebc84..d3c9a3e397b9 100644 --- a/drivers/usb/host/ehci-vt8500.c +++ b/drivers/usb/host/ehci-vt8500.c | |||
| @@ -85,6 +85,8 @@ static const struct hc_driver vt8500_ehci_hc_driver = { | |||
| 85 | .clear_tt_buffer_complete = ehci_clear_tt_buffer_complete, | 85 | .clear_tt_buffer_complete = ehci_clear_tt_buffer_complete, |
| 86 | }; | 86 | }; |
| 87 | 87 | ||
| 88 | static u64 vt8500_ehci_dma_mask = DMA_BIT_MASK(32); | ||
| 89 | |||
| 88 | static int vt8500_ehci_drv_probe(struct platform_device *pdev) | 90 | static int vt8500_ehci_drv_probe(struct platform_device *pdev) |
| 89 | { | 91 | { |
| 90 | struct usb_hcd *hcd; | 92 | struct usb_hcd *hcd; |
| @@ -95,6 +97,14 @@ static int vt8500_ehci_drv_probe(struct platform_device *pdev) | |||
| 95 | if (usb_disabled()) | 97 | if (usb_disabled()) |
| 96 | return -ENODEV; | 98 | return -ENODEV; |
| 97 | 99 | ||
| 100 | /* | ||
| 101 | * Right now device-tree probed devices don't get dma_mask set. | ||
| 102 | * Since shared usb code relies on it, set it here for now. | ||
| 103 | * Once we have dma capability bindings this can go away. | ||
| 104 | */ | ||
| 105 | if (!pdev->dev.dma_mask) | ||
| 106 | pdev->dev.dma_mask = &vt8500_ehci_dma_mask; | ||
| 107 | |||
| 98 | if (pdev->resource[1].flags != IORESOURCE_IRQ) { | 108 | if (pdev->resource[1].flags != IORESOURCE_IRQ) { |
| 99 | pr_debug("resource[1] is not IORESOURCE_IRQ"); | 109 | pr_debug("resource[1] is not IORESOURCE_IRQ"); |
| 100 | return -ENOMEM; | 110 | return -ENOMEM; |
diff --git a/drivers/usb/host/ohci-xls.c b/drivers/usb/host/ohci-xls.c index 84201cd1a472..41e378f17c66 100644 --- a/drivers/usb/host/ohci-xls.c +++ b/drivers/usb/host/ohci-xls.c | |||
| @@ -56,7 +56,7 @@ static int ohci_xls_probe_internal(const struct hc_driver *driver, | |||
| 56 | goto err3; | 56 | goto err3; |
| 57 | } | 57 | } |
| 58 | 58 | ||
| 59 | retval = usb_add_hcd(hcd, irq, IRQF_SHARED); | 59 | retval = usb_add_hcd(hcd, irq, IRQF_DISABLED | IRQF_SHARED); |
| 60 | if (retval != 0) | 60 | if (retval != 0) |
| 61 | goto err4; | 61 | goto err4; |
| 62 | return retval; | 62 | return retval; |
diff --git a/drivers/usb/host/pci-quirks.c b/drivers/usb/host/pci-quirks.c index 966d1484ee79..39f9e4a9a2d3 100644 --- a/drivers/usb/host/pci-quirks.c +++ b/drivers/usb/host/pci-quirks.c | |||
| @@ -545,7 +545,14 @@ static const struct dmi_system_id __devinitconst ehci_dmi_nohandoff_table[] = { | |||
| 545 | /* Pegatron Lucid (Ordissimo AIRIS) */ | 545 | /* Pegatron Lucid (Ordissimo AIRIS) */ |
| 546 | .matches = { | 546 | .matches = { |
| 547 | DMI_MATCH(DMI_BOARD_NAME, "M11JB"), | 547 | DMI_MATCH(DMI_BOARD_NAME, "M11JB"), |
| 548 | DMI_MATCH(DMI_BIOS_VERSION, "Lucid-GE-133"), | 548 | DMI_MATCH(DMI_BIOS_VERSION, "Lucid-"), |
| 549 | }, | ||
| 550 | }, | ||
| 551 | { | ||
| 552 | /* Pegatron Lucid (Ordissimo) */ | ||
| 553 | .matches = { | ||
| 554 | DMI_MATCH(DMI_BOARD_NAME, "Ordissimo"), | ||
| 555 | DMI_MATCH(DMI_BIOS_VERSION, "Lucid-"), | ||
| 549 | }, | 556 | }, |
| 550 | }, | 557 | }, |
| 551 | { } | 558 | { } |
diff --git a/drivers/usb/host/uhci-platform.c b/drivers/usb/host/uhci-platform.c index e4780491df4a..68ebf20e1519 100644 --- a/drivers/usb/host/uhci-platform.c +++ b/drivers/usb/host/uhci-platform.c | |||
| @@ -60,6 +60,7 @@ static const struct hc_driver uhci_platform_hc_driver = { | |||
| 60 | .hub_control = uhci_hub_control, | 60 | .hub_control = uhci_hub_control, |
| 61 | }; | 61 | }; |
| 62 | 62 | ||
| 63 | static u64 platform_uhci_dma_mask = DMA_BIT_MASK(32); | ||
| 63 | 64 | ||
| 64 | static int __devinit uhci_hcd_platform_probe(struct platform_device *pdev) | 65 | static int __devinit uhci_hcd_platform_probe(struct platform_device *pdev) |
| 65 | { | 66 | { |
| @@ -71,6 +72,14 @@ static int __devinit uhci_hcd_platform_probe(struct platform_device *pdev) | |||
| 71 | if (usb_disabled()) | 72 | if (usb_disabled()) |
| 72 | return -ENODEV; | 73 | return -ENODEV; |
| 73 | 74 | ||
| 75 | /* | ||
| 76 | * Right now device-tree probed devices don't get dma_mask set. | ||
| 77 | * Since shared usb code relies on it, set it here for now. | ||
| 78 | * Once we have dma capability bindings this can go away. | ||
| 79 | */ | ||
| 80 | if (!pdev->dev.dma_mask) | ||
| 81 | pdev->dev.dma_mask = &platform_uhci_dma_mask; | ||
| 82 | |||
| 74 | hcd = usb_create_hcd(&uhci_platform_hc_driver, &pdev->dev, | 83 | hcd = usb_create_hcd(&uhci_platform_hc_driver, &pdev->dev, |
| 75 | pdev->name); | 84 | pdev->name); |
| 76 | if (!hcd) | 85 | if (!hcd) |
diff --git a/drivers/usb/host/xhci-dbg.c b/drivers/usb/host/xhci-dbg.c index 4b436f5a4171..5f3a7c74aa8d 100644 --- a/drivers/usb/host/xhci-dbg.c +++ b/drivers/usb/host/xhci-dbg.c | |||
| @@ -544,7 +544,6 @@ void xhci_dbg_ctx(struct xhci_hcd *xhci, | |||
| 544 | int i; | 544 | int i; |
| 545 | /* Fields are 32 bits wide, DMA addresses are in bytes */ | 545 | /* Fields are 32 bits wide, DMA addresses are in bytes */ |
| 546 | int field_size = 32 / 8; | 546 | int field_size = 32 / 8; |
| 547 | struct xhci_slot_ctx *slot_ctx; | ||
| 548 | dma_addr_t dma = ctx->dma; | 547 | dma_addr_t dma = ctx->dma; |
| 549 | int csz = HCC_64BYTE_CONTEXT(xhci->hcc_params); | 548 | int csz = HCC_64BYTE_CONTEXT(xhci->hcc_params); |
| 550 | 549 | ||
| @@ -570,7 +569,6 @@ void xhci_dbg_ctx(struct xhci_hcd *xhci, | |||
| 570 | dbg_rsvd64(xhci, (u64 *)ctrl_ctx, dma); | 569 | dbg_rsvd64(xhci, (u64 *)ctrl_ctx, dma); |
| 571 | } | 570 | } |
| 572 | 571 | ||
| 573 | slot_ctx = xhci_get_slot_ctx(xhci, ctx); | ||
| 574 | xhci_dbg_slot_ctx(xhci, ctx); | 572 | xhci_dbg_slot_ctx(xhci, ctx); |
| 575 | xhci_dbg_ep_ctx(xhci, ctx, last_ep); | 573 | xhci_dbg_ep_ctx(xhci, ctx, last_ep); |
| 576 | } | 574 | } |
diff --git a/drivers/usb/host/xhci-hub.c b/drivers/usb/host/xhci-hub.c index aa90ad4d4fd5..a686cf4905bb 100644 --- a/drivers/usb/host/xhci-hub.c +++ b/drivers/usb/host/xhci-hub.c | |||
| @@ -151,9 +151,8 @@ static void xhci_usb3_hub_descriptor(struct usb_hcd *hcd, struct xhci_hcd *xhci, | |||
| 151 | if (portsc & PORT_DEV_REMOVE) | 151 | if (portsc & PORT_DEV_REMOVE) |
| 152 | port_removable |= 1 << (i + 1); | 152 | port_removable |= 1 << (i + 1); |
| 153 | } | 153 | } |
| 154 | memset(&desc->u.ss.DeviceRemovable, | 154 | |
| 155 | (__force __u16) cpu_to_le16(port_removable), | 155 | desc->u.ss.DeviceRemovable = cpu_to_le16(port_removable); |
| 156 | sizeof(__u16)); | ||
| 157 | } | 156 | } |
| 158 | 157 | ||
| 159 | static void xhci_hub_descriptor(struct usb_hcd *hcd, struct xhci_hcd *xhci, | 158 | static void xhci_hub_descriptor(struct usb_hcd *hcd, struct xhci_hcd *xhci, |
| @@ -809,11 +808,13 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, | |||
| 809 | temp = xhci_readl(xhci, port_array[wIndex]); | 808 | temp = xhci_readl(xhci, port_array[wIndex]); |
| 810 | xhci_dbg(xhci, "set port power, actual port %d status = 0x%x\n", wIndex, temp); | 809 | xhci_dbg(xhci, "set port power, actual port %d status = 0x%x\n", wIndex, temp); |
| 811 | 810 | ||
| 811 | spin_unlock_irqrestore(&xhci->lock, flags); | ||
| 812 | temp = usb_acpi_power_manageable(hcd->self.root_hub, | 812 | temp = usb_acpi_power_manageable(hcd->self.root_hub, |
| 813 | wIndex); | 813 | wIndex); |
| 814 | if (temp) | 814 | if (temp) |
| 815 | usb_acpi_set_power_state(hcd->self.root_hub, | 815 | usb_acpi_set_power_state(hcd->self.root_hub, |
| 816 | wIndex, true); | 816 | wIndex, true); |
| 817 | spin_lock_irqsave(&xhci->lock, flags); | ||
| 817 | break; | 818 | break; |
| 818 | case USB_PORT_FEAT_RESET: | 819 | case USB_PORT_FEAT_RESET: |
| 819 | temp = (temp | PORT_RESET); | 820 | temp = (temp | PORT_RESET); |
| @@ -917,11 +918,13 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, | |||
| 917 | xhci_writel(xhci, temp & ~PORT_POWER, | 918 | xhci_writel(xhci, temp & ~PORT_POWER, |
| 918 | port_array[wIndex]); | 919 | port_array[wIndex]); |
| 919 | 920 | ||
| 921 | spin_unlock_irqrestore(&xhci->lock, flags); | ||
| 920 | temp = usb_acpi_power_manageable(hcd->self.root_hub, | 922 | temp = usb_acpi_power_manageable(hcd->self.root_hub, |
| 921 | wIndex); | 923 | wIndex); |
| 922 | if (temp) | 924 | if (temp) |
| 923 | usb_acpi_set_power_state(hcd->self.root_hub, | 925 | usb_acpi_set_power_state(hcd->self.root_hub, |
| 924 | wIndex, false); | 926 | wIndex, false); |
| 927 | spin_lock_irqsave(&xhci->lock, flags); | ||
| 925 | break; | 928 | break; |
| 926 | default: | 929 | default: |
| 927 | goto error; | 930 | goto error; |
diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c index c6ebb176dc4f..4e1a8946b8d1 100644 --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c | |||
| @@ -1228,6 +1228,17 @@ static void xhci_cmd_to_noop(struct xhci_hcd *xhci, struct xhci_cd *cur_cd) | |||
| 1228 | cur_seg = find_trb_seg(xhci->cmd_ring->first_seg, | 1228 | cur_seg = find_trb_seg(xhci->cmd_ring->first_seg, |
| 1229 | xhci->cmd_ring->dequeue, &cycle_state); | 1229 | xhci->cmd_ring->dequeue, &cycle_state); |
| 1230 | 1230 | ||
| 1231 | if (!cur_seg) { | ||
| 1232 | xhci_warn(xhci, "Command ring mismatch, dequeue = %p %llx (dma)\n", | ||
| 1233 | xhci->cmd_ring->dequeue, | ||
| 1234 | (unsigned long long) | ||
| 1235 | xhci_trb_virt_to_dma(xhci->cmd_ring->deq_seg, | ||
| 1236 | xhci->cmd_ring->dequeue)); | ||
| 1237 | xhci_debug_ring(xhci, xhci->cmd_ring); | ||
| 1238 | xhci_dbg_ring_ptrs(xhci, xhci->cmd_ring); | ||
| 1239 | return; | ||
| 1240 | } | ||
| 1241 | |||
| 1231 | /* find the command trb matched by cd from command ring */ | 1242 | /* find the command trb matched by cd from command ring */ |
| 1232 | for (cmd_trb = xhci->cmd_ring->dequeue; | 1243 | for (cmd_trb = xhci->cmd_ring->dequeue; |
| 1233 | cmd_trb != xhci->cmd_ring->enqueue; | 1244 | cmd_trb != xhci->cmd_ring->enqueue; |
diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index 8d7fcbbe6ade..c9e419f29b74 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c | |||
| @@ -479,7 +479,8 @@ static bool compliance_mode_recovery_timer_quirk_check(void) | |||
| 479 | 479 | ||
| 480 | if (strstr(dmi_product_name, "Z420") || | 480 | if (strstr(dmi_product_name, "Z420") || |
| 481 | strstr(dmi_product_name, "Z620") || | 481 | strstr(dmi_product_name, "Z620") || |
| 482 | strstr(dmi_product_name, "Z820")) | 482 | strstr(dmi_product_name, "Z820") || |
| 483 | strstr(dmi_product_name, "Z1")) | ||
| 483 | return true; | 484 | return true; |
| 484 | 485 | ||
| 485 | return false; | 486 | return false; |
| @@ -1626,7 +1627,6 @@ int xhci_add_endpoint(struct usb_hcd *hcd, struct usb_device *udev, | |||
| 1626 | struct xhci_hcd *xhci; | 1627 | struct xhci_hcd *xhci; |
| 1627 | struct xhci_container_ctx *in_ctx, *out_ctx; | 1628 | struct xhci_container_ctx *in_ctx, *out_ctx; |
| 1628 | unsigned int ep_index; | 1629 | unsigned int ep_index; |
| 1629 | struct xhci_ep_ctx *ep_ctx; | ||
| 1630 | struct xhci_slot_ctx *slot_ctx; | 1630 | struct xhci_slot_ctx *slot_ctx; |
| 1631 | struct xhci_input_control_ctx *ctrl_ctx; | 1631 | struct xhci_input_control_ctx *ctrl_ctx; |
| 1632 | u32 added_ctxs; | 1632 | u32 added_ctxs; |
| @@ -1662,7 +1662,6 @@ int xhci_add_endpoint(struct usb_hcd *hcd, struct usb_device *udev, | |||
| 1662 | out_ctx = virt_dev->out_ctx; | 1662 | out_ctx = virt_dev->out_ctx; |
| 1663 | ctrl_ctx = xhci_get_input_control_ctx(xhci, in_ctx); | 1663 | ctrl_ctx = xhci_get_input_control_ctx(xhci, in_ctx); |
| 1664 | ep_index = xhci_get_endpoint_index(&ep->desc); | 1664 | ep_index = xhci_get_endpoint_index(&ep->desc); |
| 1665 | ep_ctx = xhci_get_ep_ctx(xhci, out_ctx, ep_index); | ||
| 1666 | 1665 | ||
| 1667 | /* If this endpoint is already in use, and the upper layers are trying | 1666 | /* If this endpoint is already in use, and the upper layers are trying |
| 1668 | * to add it again without dropping it, reject the addition. | 1667 | * to add it again without dropping it, reject the addition. |
| @@ -1816,6 +1815,8 @@ static int xhci_evaluate_context_result(struct xhci_hcd *xhci, | |||
| 1816 | case COMP_EBADSLT: | 1815 | case COMP_EBADSLT: |
| 1817 | dev_warn(&udev->dev, "WARN: slot not enabled for" | 1816 | dev_warn(&udev->dev, "WARN: slot not enabled for" |
| 1818 | "evaluate context command.\n"); | 1817 | "evaluate context command.\n"); |
| 1818 | ret = -EINVAL; | ||
| 1819 | break; | ||
| 1819 | case COMP_CTX_STATE: | 1820 | case COMP_CTX_STATE: |
| 1820 | dev_warn(&udev->dev, "WARN: invalid context state for " | 1821 | dev_warn(&udev->dev, "WARN: invalid context state for " |
| 1821 | "evaluate context command.\n"); | 1822 | "evaluate context command.\n"); |
| @@ -4020,7 +4021,7 @@ int xhci_update_device(struct usb_hcd *hcd, struct usb_device *udev) | |||
| 4020 | static unsigned long long xhci_service_interval_to_ns( | 4021 | static unsigned long long xhci_service_interval_to_ns( |
| 4021 | struct usb_endpoint_descriptor *desc) | 4022 | struct usb_endpoint_descriptor *desc) |
| 4022 | { | 4023 | { |
| 4023 | return (1 << (desc->bInterval - 1)) * 125 * 1000; | 4024 | return (1ULL << (desc->bInterval - 1)) * 125 * 1000; |
| 4024 | } | 4025 | } |
| 4025 | 4026 | ||
| 4026 | static u16 xhci_get_timeout_no_hub_lpm(struct usb_device *udev, | 4027 | static u16 xhci_get_timeout_no_hub_lpm(struct usb_device *udev, |
| @@ -4141,7 +4142,7 @@ static u16 xhci_calculate_intel_u2_timeout(struct usb_device *udev, | |||
| 4141 | (xhci_service_interval_to_ns(desc) > timeout_ns)) | 4142 | (xhci_service_interval_to_ns(desc) > timeout_ns)) |
| 4142 | timeout_ns = xhci_service_interval_to_ns(desc); | 4143 | timeout_ns = xhci_service_interval_to_ns(desc); |
| 4143 | 4144 | ||
| 4144 | u2_del_ns = udev->bos->ss_cap->bU2DevExitLat * 1000; | 4145 | u2_del_ns = le16_to_cpu(udev->bos->ss_cap->bU2DevExitLat) * 1000ULL; |
| 4145 | if (u2_del_ns > timeout_ns) | 4146 | if (u2_del_ns > timeout_ns) |
| 4146 | timeout_ns = u2_del_ns; | 4147 | timeout_ns = u2_del_ns; |
| 4147 | 4148 | ||
diff --git a/drivers/usb/misc/ezusb.c b/drivers/usb/misc/ezusb.c index 4223d761223d..6589268a6515 100644 --- a/drivers/usb/misc/ezusb.c +++ b/drivers/usb/misc/ezusb.c | |||
| @@ -158,3 +158,4 @@ int ezusb_fx2_ihex_firmware_download(struct usb_device *dev, | |||
| 158 | } | 158 | } |
| 159 | EXPORT_SYMBOL_GPL(ezusb_fx2_ihex_firmware_download); | 159 | EXPORT_SYMBOL_GPL(ezusb_fx2_ihex_firmware_download); |
| 160 | 160 | ||
| 161 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/usb/musb/am35x.c b/drivers/usb/musb/am35x.c index 457f25e62c51..c964d6af178b 100644 --- a/drivers/usb/musb/am35x.c +++ b/drivers/usb/musb/am35x.c | |||
| @@ -305,6 +305,12 @@ static irqreturn_t am35x_musb_interrupt(int irq, void *hci) | |||
| 305 | ret = IRQ_HANDLED; | 305 | ret = IRQ_HANDLED; |
| 306 | } | 306 | } |
| 307 | 307 | ||
| 308 | /* Drop spurious RX and TX if device is disconnected */ | ||
| 309 | if (musb->int_usb & MUSB_INTR_DISCONNECT) { | ||
| 310 | musb->int_tx = 0; | ||
| 311 | musb->int_rx = 0; | ||
| 312 | } | ||
| 313 | |||
| 308 | if (musb->int_tx || musb->int_rx || musb->int_usb) | 314 | if (musb->int_tx || musb->int_rx || musb->int_usb) |
| 309 | ret |= musb_interrupt(musb); | 315 | ret |= musb_interrupt(musb); |
| 310 | 316 | ||
diff --git a/drivers/usb/musb/musb_dsps.c b/drivers/usb/musb/musb_dsps.c index 444346e1e10d..ff5f112053d2 100644 --- a/drivers/usb/musb/musb_dsps.c +++ b/drivers/usb/musb/musb_dsps.c | |||
| @@ -458,11 +458,11 @@ static int __devinit dsps_create_musb_pdev(struct dsps_glue *glue, u8 id) | |||
| 458 | struct platform_device *musb; | 458 | struct platform_device *musb; |
| 459 | struct resource *res; | 459 | struct resource *res; |
| 460 | struct resource resources[2]; | 460 | struct resource resources[2]; |
| 461 | char res_name[10]; | 461 | char res_name[11]; |
| 462 | int ret, musbid; | 462 | int ret, musbid; |
| 463 | 463 | ||
| 464 | /* get memory resource */ | 464 | /* get memory resource */ |
| 465 | sprintf(res_name, "musb%d", id); | 465 | snprintf(res_name, sizeof(res_name), "musb%d", id); |
| 466 | res = platform_get_resource_byname(pdev, IORESOURCE_MEM, res_name); | 466 | res = platform_get_resource_byname(pdev, IORESOURCE_MEM, res_name); |
| 467 | if (!res) { | 467 | if (!res) { |
| 468 | dev_err(dev, "%s get mem resource failed\n", res_name); | 468 | dev_err(dev, "%s get mem resource failed\n", res_name); |
| @@ -473,7 +473,7 @@ static int __devinit dsps_create_musb_pdev(struct dsps_glue *glue, u8 id) | |||
| 473 | resources[0] = *res; | 473 | resources[0] = *res; |
| 474 | 474 | ||
| 475 | /* get irq resource */ | 475 | /* get irq resource */ |
| 476 | sprintf(res_name, "musb%d-irq", id); | 476 | snprintf(res_name, sizeof(res_name), "musb%d-irq", id); |
| 477 | res = platform_get_resource_byname(pdev, IORESOURCE_IRQ, res_name); | 477 | res = platform_get_resource_byname(pdev, IORESOURCE_IRQ, res_name); |
| 478 | if (!res) { | 478 | if (!res) { |
| 479 | dev_err(dev, "%s get irq resource failed\n", res_name); | 479 | dev_err(dev, "%s get irq resource failed\n", res_name); |
| @@ -530,7 +530,7 @@ static int __devinit dsps_create_musb_pdev(struct dsps_glue *glue, u8 id) | |||
| 530 | 530 | ||
| 531 | of_property_read_u32(np, "num-eps", (u32 *)&config->num_eps); | 531 | of_property_read_u32(np, "num-eps", (u32 *)&config->num_eps); |
| 532 | of_property_read_u32(np, "ram-bits", (u32 *)&config->ram_bits); | 532 | of_property_read_u32(np, "ram-bits", (u32 *)&config->ram_bits); |
| 533 | sprintf(res_name, "port%d-mode", id); | 533 | snprintf(res_name, sizeof(res_name), "port%d-mode", id); |
| 534 | of_property_read_u32(np, res_name, (u32 *)&pdata->mode); | 534 | of_property_read_u32(np, res_name, (u32 *)&pdata->mode); |
| 535 | of_property_read_u32(np, "power", (u32 *)&pdata->power); | 535 | of_property_read_u32(np, "power", (u32 *)&pdata->power); |
| 536 | config->multipoint = of_property_read_bool(np, "multipoint"); | 536 | config->multipoint = of_property_read_bool(np, "multipoint"); |
diff --git a/drivers/usb/musb/musb_gadget.c b/drivers/usb/musb/musb_gadget.c index d0b87e7b4abf..b6b84dacc791 100644 --- a/drivers/usb/musb/musb_gadget.c +++ b/drivers/usb/musb/musb_gadget.c | |||
| @@ -707,11 +707,12 @@ static void rxstate(struct musb *musb, struct musb_request *req) | |||
| 707 | fifo_count = musb_readw(epio, MUSB_RXCOUNT); | 707 | fifo_count = musb_readw(epio, MUSB_RXCOUNT); |
| 708 | 708 | ||
| 709 | /* | 709 | /* |
| 710 | * use mode 1 only if we expect data of at least ep packet_sz | 710 | * Enable Mode 1 on RX transfers only when short_not_ok flag |
| 711 | * and have not yet received a short packet | 711 | * is set. Currently short_not_ok flag is set only from |
| 712 | * file_storage and f_mass_storage drivers | ||
| 712 | */ | 713 | */ |
| 713 | if ((request->length - request->actual >= musb_ep->packet_sz) && | 714 | |
| 714 | (fifo_count >= musb_ep->packet_sz)) | 715 | if (request->short_not_ok && fifo_count == musb_ep->packet_sz) |
| 715 | use_mode_1 = 1; | 716 | use_mode_1 = 1; |
| 716 | else | 717 | else |
| 717 | use_mode_1 = 0; | 718 | use_mode_1 = 0; |
| @@ -727,6 +728,27 @@ static void rxstate(struct musb *musb, struct musb_request *req) | |||
| 727 | c = musb->dma_controller; | 728 | c = musb->dma_controller; |
| 728 | channel = musb_ep->dma; | 729 | channel = musb_ep->dma; |
| 729 | 730 | ||
| 731 | /* We use DMA Req mode 0 in rx_csr, and DMA controller operates in | ||
| 732 | * mode 0 only. So we do not get endpoint interrupts due to DMA | ||
| 733 | * completion. We only get interrupts from DMA controller. | ||
| 734 | * | ||
| 735 | * We could operate in DMA mode 1 if we knew the size of the tranfer | ||
| 736 | * in advance. For mass storage class, request->length = what the host | ||
| 737 | * sends, so that'd work. But for pretty much everything else, | ||
| 738 | * request->length is routinely more than what the host sends. For | ||
| 739 | * most these gadgets, end of is signified either by a short packet, | ||
| 740 | * or filling the last byte of the buffer. (Sending extra data in | ||
| 741 | * that last pckate should trigger an overflow fault.) But in mode 1, | ||
| 742 | * we don't get DMA completion interrupt for short packets. | ||
| 743 | * | ||
| 744 | * Theoretically, we could enable DMAReq irq (MUSB_RXCSR_DMAMODE = 1), | ||
| 745 | * to get endpoint interrupt on every DMA req, but that didn't seem | ||
| 746 | * to work reliably. | ||
| 747 | * | ||
| 748 | * REVISIT an updated g_file_storage can set req->short_not_ok, which | ||
| 749 | * then becomes usable as a runtime "use mode 1" hint... | ||
| 750 | */ | ||
| 751 | |||
| 730 | /* Experimental: Mode1 works with mass storage use cases */ | 752 | /* Experimental: Mode1 works with mass storage use cases */ |
| 731 | if (use_mode_1) { | 753 | if (use_mode_1) { |
| 732 | csr |= MUSB_RXCSR_AUTOCLEAR; | 754 | csr |= MUSB_RXCSR_AUTOCLEAR; |
diff --git a/drivers/usb/musb/ux500.c b/drivers/usb/musb/ux500.c index d62a91fedc22..0e62f504410e 100644 --- a/drivers/usb/musb/ux500.c +++ b/drivers/usb/musb/ux500.c | |||
| @@ -65,7 +65,7 @@ static int __devinit ux500_probe(struct platform_device *pdev) | |||
| 65 | struct platform_device *musb; | 65 | struct platform_device *musb; |
| 66 | struct ux500_glue *glue; | 66 | struct ux500_glue *glue; |
| 67 | struct clk *clk; | 67 | struct clk *clk; |
| 68 | 68 | int musbid; | |
| 69 | int ret = -ENOMEM; | 69 | int ret = -ENOMEM; |
| 70 | 70 | ||
| 71 | glue = kzalloc(sizeof(*glue), GFP_KERNEL); | 71 | glue = kzalloc(sizeof(*glue), GFP_KERNEL); |
diff --git a/drivers/usb/otg/Kconfig b/drivers/usb/otg/Kconfig index d8c8a42bff3e..6223062d5d1b 100644 --- a/drivers/usb/otg/Kconfig +++ b/drivers/usb/otg/Kconfig | |||
| @@ -58,7 +58,7 @@ config USB_ULPI_VIEWPORT | |||
| 58 | 58 | ||
| 59 | config TWL4030_USB | 59 | config TWL4030_USB |
| 60 | tristate "TWL4030 USB Transceiver Driver" | 60 | tristate "TWL4030 USB Transceiver Driver" |
| 61 | depends on TWL4030_CORE && REGULATOR_TWL4030 | 61 | depends on TWL4030_CORE && REGULATOR_TWL4030 && USB_MUSB_OMAP2PLUS |
| 62 | select USB_OTG_UTILS | 62 | select USB_OTG_UTILS |
| 63 | help | 63 | help |
| 64 | Enable this to support the USB OTG transceiver on TWL4030 | 64 | Enable this to support the USB OTG transceiver on TWL4030 |
| @@ -68,7 +68,7 @@ config TWL4030_USB | |||
| 68 | 68 | ||
| 69 | config TWL6030_USB | 69 | config TWL6030_USB |
| 70 | tristate "TWL6030 USB Transceiver Driver" | 70 | tristate "TWL6030 USB Transceiver Driver" |
| 71 | depends on TWL4030_CORE && OMAP_USB2 | 71 | depends on TWL4030_CORE && OMAP_USB2 && USB_MUSB_OMAP2PLUS |
| 72 | select USB_OTG_UTILS | 72 | select USB_OTG_UTILS |
| 73 | help | 73 | help |
| 74 | Enable this to support the USB OTG transceiver on TWL6030 | 74 | Enable this to support the USB OTG transceiver on TWL6030 |
diff --git a/drivers/usb/renesas_usbhs/fifo.c b/drivers/usb/renesas_usbhs/fifo.c index 143c4e9e1be4..c021b202c0f3 100644 --- a/drivers/usb/renesas_usbhs/fifo.c +++ b/drivers/usb/renesas_usbhs/fifo.c | |||
| @@ -795,6 +795,7 @@ static void xfer_work(struct work_struct *work) | |||
| 795 | dev_dbg(dev, " %s %d (%d/ %d)\n", | 795 | dev_dbg(dev, " %s %d (%d/ %d)\n", |
| 796 | fifo->name, usbhs_pipe_number(pipe), pkt->length, pkt->zero); | 796 | fifo->name, usbhs_pipe_number(pipe), pkt->length, pkt->zero); |
| 797 | 797 | ||
| 798 | usbhs_pipe_enable(pipe); | ||
| 798 | usbhsf_dma_start(pipe, fifo); | 799 | usbhsf_dma_start(pipe, fifo); |
| 799 | dma_async_issue_pending(chan); | 800 | dma_async_issue_pending(chan); |
| 800 | } | 801 | } |
diff --git a/drivers/usb/renesas_usbhs/mod.c b/drivers/usb/renesas_usbhs/mod.c index 35c5208f3249..61933a90e5bf 100644 --- a/drivers/usb/renesas_usbhs/mod.c +++ b/drivers/usb/renesas_usbhs/mod.c | |||
| @@ -273,9 +273,9 @@ static irqreturn_t usbhs_interrupt(int irq, void *data) | |||
| 273 | usbhs_write(priv, INTSTS0, ~irq_state.intsts0 & INTSTS0_MAGIC); | 273 | usbhs_write(priv, INTSTS0, ~irq_state.intsts0 & INTSTS0_MAGIC); |
| 274 | usbhs_write(priv, INTSTS1, ~irq_state.intsts1 & INTSTS1_MAGIC); | 274 | usbhs_write(priv, INTSTS1, ~irq_state.intsts1 & INTSTS1_MAGIC); |
| 275 | 275 | ||
| 276 | usbhs_write(priv, BRDYSTS, 0); | 276 | usbhs_write(priv, BRDYSTS, ~irq_state.brdysts); |
| 277 | usbhs_write(priv, NRDYSTS, 0); | 277 | usbhs_write(priv, NRDYSTS, ~irq_state.nrdysts); |
| 278 | usbhs_write(priv, BEMPSTS, 0); | 278 | usbhs_write(priv, BEMPSTS, ~irq_state.bempsts); |
| 279 | 279 | ||
| 280 | /* | 280 | /* |
| 281 | * call irq callback functions | 281 | * call irq callback functions |
diff --git a/drivers/usb/renesas_usbhs/mod_host.c b/drivers/usb/renesas_usbhs/mod_host.c index 9b69a1323294..069cd765400c 100644 --- a/drivers/usb/renesas_usbhs/mod_host.c +++ b/drivers/usb/renesas_usbhs/mod_host.c | |||
| @@ -334,6 +334,11 @@ static void usbhsh_pipe_detach(struct usbhsh_hpriv *hpriv, | |||
| 334 | struct device *dev = usbhs_priv_to_dev(priv); | 334 | struct device *dev = usbhs_priv_to_dev(priv); |
| 335 | unsigned long flags; | 335 | unsigned long flags; |
| 336 | 336 | ||
| 337 | if (unlikely(!uep)) { | ||
| 338 | dev_err(dev, "no uep\n"); | ||
| 339 | return; | ||
| 340 | } | ||
| 341 | |||
| 337 | /******************** spin lock ********************/ | 342 | /******************** spin lock ********************/ |
| 338 | usbhs_lock(priv, flags); | 343 | usbhs_lock(priv, flags); |
| 339 | 344 | ||
diff --git a/drivers/usb/renesas_usbhs/pipe.h b/drivers/usb/renesas_usbhs/pipe.h index 08786c06dcf1..3d80c7b1fd1b 100644 --- a/drivers/usb/renesas_usbhs/pipe.h +++ b/drivers/usb/renesas_usbhs/pipe.h | |||
| @@ -54,7 +54,7 @@ struct usbhs_pipe_info { | |||
| 54 | * pipe list | 54 | * pipe list |
| 55 | */ | 55 | */ |
| 56 | #define __usbhs_for_each_pipe(start, pos, info, i) \ | 56 | #define __usbhs_for_each_pipe(start, pos, info, i) \ |
| 57 | for (i = start, pos = (info)->pipe; \ | 57 | for (i = start, pos = (info)->pipe + i; \ |
| 58 | i < (info)->size; \ | 58 | i < (info)->size; \ |
| 59 | i++, pos = (info)->pipe + i) | 59 | i++, pos = (info)->pipe + i) |
| 60 | 60 | ||
diff --git a/drivers/usb/serial/ark3116.c b/drivers/usb/serial/ark3116.c index cf2522c397d3..bd50a8a41a0f 100644 --- a/drivers/usb/serial/ark3116.c +++ b/drivers/usb/serial/ark3116.c | |||
| @@ -125,9 +125,6 @@ static inline int calc_divisor(int bps) | |||
| 125 | 125 | ||
| 126 | static int ark3116_attach(struct usb_serial *serial) | 126 | static int ark3116_attach(struct usb_serial *serial) |
| 127 | { | 127 | { |
| 128 | struct usb_serial_port *port = serial->port[0]; | ||
| 129 | struct ark3116_private *priv; | ||
| 130 | |||
| 131 | /* make sure we have our end-points */ | 128 | /* make sure we have our end-points */ |
| 132 | if ((serial->num_bulk_in == 0) || | 129 | if ((serial->num_bulk_in == 0) || |
| 133 | (serial->num_bulk_out == 0) || | 130 | (serial->num_bulk_out == 0) || |
| @@ -142,8 +139,15 @@ static int ark3116_attach(struct usb_serial *serial) | |||
| 142 | return -EINVAL; | 139 | return -EINVAL; |
| 143 | } | 140 | } |
| 144 | 141 | ||
| 145 | priv = kzalloc(sizeof(struct ark3116_private), | 142 | return 0; |
| 146 | GFP_KERNEL); | 143 | } |
| 144 | |||
| 145 | static int ark3116_port_probe(struct usb_serial_port *port) | ||
| 146 | { | ||
| 147 | struct usb_serial *serial = port->serial; | ||
| 148 | struct ark3116_private *priv; | ||
| 149 | |||
| 150 | priv = kzalloc(sizeof(*priv), GFP_KERNEL); | ||
| 147 | if (!priv) | 151 | if (!priv) |
| 148 | return -ENOMEM; | 152 | return -ENOMEM; |
| 149 | 153 | ||
| @@ -198,18 +202,15 @@ static int ark3116_attach(struct usb_serial *serial) | |||
| 198 | return 0; | 202 | return 0; |
| 199 | } | 203 | } |
| 200 | 204 | ||
| 201 | static void ark3116_release(struct usb_serial *serial) | 205 | static int ark3116_port_remove(struct usb_serial_port *port) |
| 202 | { | 206 | { |
| 203 | struct usb_serial_port *port = serial->port[0]; | ||
| 204 | struct ark3116_private *priv = usb_get_serial_port_data(port); | 207 | struct ark3116_private *priv = usb_get_serial_port_data(port); |
| 205 | 208 | ||
| 206 | /* device is closed, so URBs and DMA should be down */ | 209 | /* device is closed, so URBs and DMA should be down */ |
| 207 | |||
| 208 | usb_set_serial_port_data(port, NULL); | ||
| 209 | |||
| 210 | mutex_destroy(&priv->hw_lock); | 210 | mutex_destroy(&priv->hw_lock); |
| 211 | |||
| 212 | kfree(priv); | 211 | kfree(priv); |
| 212 | |||
| 213 | return 0; | ||
| 213 | } | 214 | } |
| 214 | 215 | ||
| 215 | static void ark3116_init_termios(struct tty_struct *tty) | 216 | static void ark3116_init_termios(struct tty_struct *tty) |
| @@ -723,7 +724,8 @@ static struct usb_serial_driver ark3116_device = { | |||
| 723 | .id_table = id_table, | 724 | .id_table = id_table, |
| 724 | .num_ports = 1, | 725 | .num_ports = 1, |
| 725 | .attach = ark3116_attach, | 726 | .attach = ark3116_attach, |
| 726 | .release = ark3116_release, | 727 | .port_probe = ark3116_port_probe, |
| 728 | .port_remove = ark3116_port_remove, | ||
| 727 | .set_termios = ark3116_set_termios, | 729 | .set_termios = ark3116_set_termios, |
| 728 | .init_termios = ark3116_init_termios, | 730 | .init_termios = ark3116_init_termios, |
| 729 | .ioctl = ark3116_ioctl, | 731 | .ioctl = ark3116_ioctl, |
diff --git a/drivers/usb/serial/belkin_sa.c b/drivers/usb/serial/belkin_sa.c index 99449424193f..ea29556f0d72 100644 --- a/drivers/usb/serial/belkin_sa.c +++ b/drivers/usb/serial/belkin_sa.c | |||
| @@ -45,8 +45,8 @@ | |||
| 45 | #define DRIVER_DESC "USB Belkin Serial converter driver" | 45 | #define DRIVER_DESC "USB Belkin Serial converter driver" |
| 46 | 46 | ||
| 47 | /* function prototypes for a Belkin USB Serial Adapter F5U103 */ | 47 | /* function prototypes for a Belkin USB Serial Adapter F5U103 */ |
| 48 | static int belkin_sa_startup(struct usb_serial *serial); | 48 | static int belkin_sa_port_probe(struct usb_serial_port *port); |
| 49 | static void belkin_sa_release(struct usb_serial *serial); | 49 | static int belkin_sa_port_remove(struct usb_serial_port *port); |
| 50 | static int belkin_sa_open(struct tty_struct *tty, | 50 | static int belkin_sa_open(struct tty_struct *tty, |
| 51 | struct usb_serial_port *port); | 51 | struct usb_serial_port *port); |
| 52 | static void belkin_sa_close(struct usb_serial_port *port); | 52 | static void belkin_sa_close(struct usb_serial_port *port); |
| @@ -88,8 +88,8 @@ static struct usb_serial_driver belkin_device = { | |||
| 88 | .break_ctl = belkin_sa_break_ctl, | 88 | .break_ctl = belkin_sa_break_ctl, |
| 89 | .tiocmget = belkin_sa_tiocmget, | 89 | .tiocmget = belkin_sa_tiocmget, |
| 90 | .tiocmset = belkin_sa_tiocmset, | 90 | .tiocmset = belkin_sa_tiocmset, |
| 91 | .attach = belkin_sa_startup, | 91 | .port_probe = belkin_sa_port_probe, |
| 92 | .release = belkin_sa_release, | 92 | .port_remove = belkin_sa_port_remove, |
| 93 | }; | 93 | }; |
| 94 | 94 | ||
| 95 | static struct usb_serial_driver * const serial_drivers[] = { | 95 | static struct usb_serial_driver * const serial_drivers[] = { |
| @@ -118,17 +118,15 @@ struct belkin_sa_private { | |||
| 118 | (c), BELKIN_SA_SET_REQUEST_TYPE, \ | 118 | (c), BELKIN_SA_SET_REQUEST_TYPE, \ |
| 119 | (v), 0, NULL, 0, WDR_TIMEOUT) | 119 | (v), 0, NULL, 0, WDR_TIMEOUT) |
| 120 | 120 | ||
| 121 | /* do some startup allocations not currently performed by usb_serial_probe() */ | 121 | static int belkin_sa_port_probe(struct usb_serial_port *port) |
| 122 | static int belkin_sa_startup(struct usb_serial *serial) | ||
| 123 | { | 122 | { |
| 124 | struct usb_device *dev = serial->dev; | 123 | struct usb_device *dev = port->serial->dev; |
| 125 | struct belkin_sa_private *priv; | 124 | struct belkin_sa_private *priv; |
| 126 | 125 | ||
| 127 | /* allocate the private data structure */ | ||
| 128 | priv = kmalloc(sizeof(struct belkin_sa_private), GFP_KERNEL); | 126 | priv = kmalloc(sizeof(struct belkin_sa_private), GFP_KERNEL); |
| 129 | if (!priv) | 127 | if (!priv) |
| 130 | return -1; /* error */ | 128 | return -ENOMEM; |
| 131 | /* set initial values for control structures */ | 129 | |
| 132 | spin_lock_init(&priv->lock); | 130 | spin_lock_init(&priv->lock); |
| 133 | priv->control_state = 0; | 131 | priv->control_state = 0; |
| 134 | priv->last_lsr = 0; | 132 | priv->last_lsr = 0; |
| @@ -140,18 +138,19 @@ static int belkin_sa_startup(struct usb_serial *serial) | |||
| 140 | le16_to_cpu(dev->descriptor.bcdDevice), | 138 | le16_to_cpu(dev->descriptor.bcdDevice), |
| 141 | priv->bad_flow_control); | 139 | priv->bad_flow_control); |
| 142 | 140 | ||
| 143 | init_waitqueue_head(&serial->port[0]->write_wait); | 141 | usb_set_serial_port_data(port, priv); |
| 144 | usb_set_serial_port_data(serial->port[0], priv); | ||
| 145 | 142 | ||
| 146 | return 0; | 143 | return 0; |
| 147 | } | 144 | } |
| 148 | 145 | ||
| 149 | static void belkin_sa_release(struct usb_serial *serial) | 146 | static int belkin_sa_port_remove(struct usb_serial_port *port) |
| 150 | { | 147 | { |
| 151 | int i; | 148 | struct belkin_sa_private *priv; |
| 152 | 149 | ||
| 153 | for (i = 0; i < serial->num_ports; ++i) | 150 | priv = usb_get_serial_port_data(port); |
| 154 | kfree(usb_get_serial_port_data(serial->port[i])); | 151 | kfree(priv); |
| 152 | |||
| 153 | return 0; | ||
| 155 | } | 154 | } |
| 156 | 155 | ||
| 157 | static int belkin_sa_open(struct tty_struct *tty, | 156 | static int belkin_sa_open(struct tty_struct *tty, |
diff --git a/drivers/usb/serial/ch341.c b/drivers/usb/serial/ch341.c index e9c7046ae355..d255f66e708e 100644 --- a/drivers/usb/serial/ch341.c +++ b/drivers/usb/serial/ch341.c | |||
| @@ -242,13 +242,11 @@ out: kfree(buffer); | |||
| 242 | return r; | 242 | return r; |
| 243 | } | 243 | } |
| 244 | 244 | ||
| 245 | /* allocate private data */ | 245 | static int ch341_port_probe(struct usb_serial_port *port) |
| 246 | static int ch341_attach(struct usb_serial *serial) | ||
| 247 | { | 246 | { |
| 248 | struct ch341_private *priv; | 247 | struct ch341_private *priv; |
| 249 | int r; | 248 | int r; |
| 250 | 249 | ||
| 251 | /* private data */ | ||
| 252 | priv = kzalloc(sizeof(struct ch341_private), GFP_KERNEL); | 250 | priv = kzalloc(sizeof(struct ch341_private), GFP_KERNEL); |
| 253 | if (!priv) | 251 | if (!priv) |
| 254 | return -ENOMEM; | 252 | return -ENOMEM; |
| @@ -258,17 +256,27 @@ static int ch341_attach(struct usb_serial *serial) | |||
| 258 | priv->baud_rate = DEFAULT_BAUD_RATE; | 256 | priv->baud_rate = DEFAULT_BAUD_RATE; |
| 259 | priv->line_control = CH341_BIT_RTS | CH341_BIT_DTR; | 257 | priv->line_control = CH341_BIT_RTS | CH341_BIT_DTR; |
| 260 | 258 | ||
| 261 | r = ch341_configure(serial->dev, priv); | 259 | r = ch341_configure(port->serial->dev, priv); |
| 262 | if (r < 0) | 260 | if (r < 0) |
| 263 | goto error; | 261 | goto error; |
| 264 | 262 | ||
| 265 | usb_set_serial_port_data(serial->port[0], priv); | 263 | usb_set_serial_port_data(port, priv); |
| 266 | return 0; | 264 | return 0; |
| 267 | 265 | ||
| 268 | error: kfree(priv); | 266 | error: kfree(priv); |
| 269 | return r; | 267 | return r; |
| 270 | } | 268 | } |
| 271 | 269 | ||
| 270 | static int ch341_port_remove(struct usb_serial_port *port) | ||
| 271 | { | ||
| 272 | struct ch341_private *priv; | ||
| 273 | |||
| 274 | priv = usb_get_serial_port_data(port); | ||
| 275 | kfree(priv); | ||
| 276 | |||
| 277 | return 0; | ||
| 278 | } | ||
| 279 | |||
| 272 | static int ch341_carrier_raised(struct usb_serial_port *port) | 280 | static int ch341_carrier_raised(struct usb_serial_port *port) |
| 273 | { | 281 | { |
| 274 | struct ch341_private *priv = usb_get_serial_port_data(port); | 282 | struct ch341_private *priv = usb_get_serial_port_data(port); |
| @@ -304,7 +312,7 @@ static void ch341_close(struct usb_serial_port *port) | |||
| 304 | static int ch341_open(struct tty_struct *tty, struct usb_serial_port *port) | 312 | static int ch341_open(struct tty_struct *tty, struct usb_serial_port *port) |
| 305 | { | 313 | { |
| 306 | struct usb_serial *serial = port->serial; | 314 | struct usb_serial *serial = port->serial; |
| 307 | struct ch341_private *priv = usb_get_serial_port_data(serial->port[0]); | 315 | struct ch341_private *priv = usb_get_serial_port_data(port); |
| 308 | int r; | 316 | int r; |
| 309 | 317 | ||
| 310 | priv->baud_rate = DEFAULT_BAUD_RATE; | 318 | priv->baud_rate = DEFAULT_BAUD_RATE; |
| @@ -608,7 +616,8 @@ static struct usb_serial_driver ch341_device = { | |||
| 608 | .tiocmget = ch341_tiocmget, | 616 | .tiocmget = ch341_tiocmget, |
| 609 | .tiocmset = ch341_tiocmset, | 617 | .tiocmset = ch341_tiocmset, |
| 610 | .read_int_callback = ch341_read_int_callback, | 618 | .read_int_callback = ch341_read_int_callback, |
| 611 | .attach = ch341_attach, | 619 | .port_probe = ch341_port_probe, |
| 620 | .port_remove = ch341_port_remove, | ||
| 612 | .reset_resume = ch341_reset_resume, | 621 | .reset_resume = ch341_reset_resume, |
| 613 | }; | 622 | }; |
| 614 | 623 | ||
diff --git a/drivers/usb/serial/cp210x.c b/drivers/usb/serial/cp210x.c index 28af5acc3360..eb033fc92a15 100644 --- a/drivers/usb/serial/cp210x.c +++ b/drivers/usb/serial/cp210x.c | |||
| @@ -162,7 +162,7 @@ static const struct usb_device_id id_table[] = { | |||
| 162 | 162 | ||
| 163 | MODULE_DEVICE_TABLE(usb, id_table); | 163 | MODULE_DEVICE_TABLE(usb, id_table); |
| 164 | 164 | ||
| 165 | struct cp210x_port_private { | 165 | struct cp210x_serial_private { |
| 166 | __u8 bInterfaceNumber; | 166 | __u8 bInterfaceNumber; |
| 167 | }; | 167 | }; |
| 168 | 168 | ||
| @@ -276,7 +276,7 @@ static int cp210x_get_config(struct usb_serial_port *port, u8 request, | |||
| 276 | unsigned int *data, int size) | 276 | unsigned int *data, int size) |
| 277 | { | 277 | { |
| 278 | struct usb_serial *serial = port->serial; | 278 | struct usb_serial *serial = port->serial; |
| 279 | struct cp210x_port_private *port_priv = usb_get_serial_port_data(port); | 279 | struct cp210x_serial_private *spriv = usb_get_serial_data(serial); |
| 280 | __le32 *buf; | 280 | __le32 *buf; |
| 281 | int result, i, length; | 281 | int result, i, length; |
| 282 | 282 | ||
| @@ -292,7 +292,7 @@ static int cp210x_get_config(struct usb_serial_port *port, u8 request, | |||
| 292 | /* Issue the request, attempting to read 'size' bytes */ | 292 | /* Issue the request, attempting to read 'size' bytes */ |
| 293 | result = usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0), | 293 | result = usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0), |
| 294 | request, REQTYPE_INTERFACE_TO_HOST, 0x0000, | 294 | request, REQTYPE_INTERFACE_TO_HOST, 0x0000, |
| 295 | port_priv->bInterfaceNumber, buf, size, | 295 | spriv->bInterfaceNumber, buf, size, |
| 296 | USB_CTRL_GET_TIMEOUT); | 296 | USB_CTRL_GET_TIMEOUT); |
| 297 | 297 | ||
| 298 | /* Convert data into an array of integers */ | 298 | /* Convert data into an array of integers */ |
| @@ -323,7 +323,7 @@ static int cp210x_set_config(struct usb_serial_port *port, u8 request, | |||
| 323 | unsigned int *data, int size) | 323 | unsigned int *data, int size) |
| 324 | { | 324 | { |
| 325 | struct usb_serial *serial = port->serial; | 325 | struct usb_serial *serial = port->serial; |
| 326 | struct cp210x_port_private *port_priv = usb_get_serial_port_data(port); | 326 | struct cp210x_serial_private *spriv = usb_get_serial_data(serial); |
| 327 | __le32 *buf; | 327 | __le32 *buf; |
| 328 | int result, i, length; | 328 | int result, i, length; |
| 329 | 329 | ||
| @@ -345,13 +345,13 @@ static int cp210x_set_config(struct usb_serial_port *port, u8 request, | |||
| 345 | result = usb_control_msg(serial->dev, | 345 | result = usb_control_msg(serial->dev, |
| 346 | usb_sndctrlpipe(serial->dev, 0), | 346 | usb_sndctrlpipe(serial->dev, 0), |
| 347 | request, REQTYPE_HOST_TO_INTERFACE, 0x0000, | 347 | request, REQTYPE_HOST_TO_INTERFACE, 0x0000, |
| 348 | port_priv->bInterfaceNumber, buf, size, | 348 | spriv->bInterfaceNumber, buf, size, |
| 349 | USB_CTRL_SET_TIMEOUT); | 349 | USB_CTRL_SET_TIMEOUT); |
| 350 | } else { | 350 | } else { |
| 351 | result = usb_control_msg(serial->dev, | 351 | result = usb_control_msg(serial->dev, |
| 352 | usb_sndctrlpipe(serial->dev, 0), | 352 | usb_sndctrlpipe(serial->dev, 0), |
| 353 | request, REQTYPE_HOST_TO_INTERFACE, data[0], | 353 | request, REQTYPE_HOST_TO_INTERFACE, data[0], |
| 354 | port_priv->bInterfaceNumber, NULL, 0, | 354 | spriv->bInterfaceNumber, NULL, 0, |
| 355 | USB_CTRL_SET_TIMEOUT); | 355 | USB_CTRL_SET_TIMEOUT); |
| 356 | } | 356 | } |
| 357 | 357 | ||
| @@ -845,36 +845,30 @@ static void cp210x_break_ctl (struct tty_struct *tty, int break_state) | |||
| 845 | 845 | ||
| 846 | static int cp210x_startup(struct usb_serial *serial) | 846 | static int cp210x_startup(struct usb_serial *serial) |
| 847 | { | 847 | { |
| 848 | struct cp210x_port_private *port_priv; | 848 | struct usb_host_interface *cur_altsetting; |
| 849 | int i; | 849 | struct cp210x_serial_private *spriv; |
| 850 | 850 | ||
| 851 | /* cp210x buffers behave strangely unless device is reset */ | 851 | /* cp210x buffers behave strangely unless device is reset */ |
| 852 | usb_reset_device(serial->dev); | 852 | usb_reset_device(serial->dev); |
| 853 | 853 | ||
| 854 | for (i = 0; i < serial->num_ports; i++) { | 854 | spriv = kzalloc(sizeof(*spriv), GFP_KERNEL); |
| 855 | port_priv = kzalloc(sizeof(*port_priv), GFP_KERNEL); | 855 | if (!spriv) |
| 856 | if (!port_priv) | 856 | return -ENOMEM; |
| 857 | return -ENOMEM; | ||
| 858 | 857 | ||
| 859 | port_priv->bInterfaceNumber = | 858 | cur_altsetting = serial->interface->cur_altsetting; |
| 860 | serial->interface->cur_altsetting->desc.bInterfaceNumber; | 859 | spriv->bInterfaceNumber = cur_altsetting->desc.bInterfaceNumber; |
| 861 | 860 | ||
| 862 | usb_set_serial_port_data(serial->port[i], port_priv); | 861 | usb_set_serial_data(serial, spriv); |
| 863 | } | ||
| 864 | 862 | ||
| 865 | return 0; | 863 | return 0; |
| 866 | } | 864 | } |
| 867 | 865 | ||
| 868 | static void cp210x_release(struct usb_serial *serial) | 866 | static void cp210x_release(struct usb_serial *serial) |
| 869 | { | 867 | { |
| 870 | struct cp210x_port_private *port_priv; | 868 | struct cp210x_serial_private *spriv; |
| 871 | int i; | ||
| 872 | 869 | ||
| 873 | for (i = 0; i < serial->num_ports; i++) { | 870 | spriv = usb_get_serial_data(serial); |
| 874 | port_priv = usb_get_serial_port_data(serial->port[i]); | 871 | kfree(spriv); |
| 875 | kfree(port_priv); | ||
| 876 | usb_set_serial_port_data(serial->port[i], NULL); | ||
| 877 | } | ||
| 878 | } | 872 | } |
| 879 | 873 | ||
| 880 | module_usb_serial_driver(serial_drivers, id_table); | 874 | module_usb_serial_driver(serial_drivers, id_table); |
diff --git a/drivers/usb/serial/cyberjack.c b/drivers/usb/serial/cyberjack.c index 2a7aecc72237..4ee77dcbe690 100644 --- a/drivers/usb/serial/cyberjack.c +++ b/drivers/usb/serial/cyberjack.c | |||
| @@ -55,9 +55,9 @@ | |||
| 55 | #define CYBERJACK_PRODUCT_ID 0x0100 | 55 | #define CYBERJACK_PRODUCT_ID 0x0100 |
| 56 | 56 | ||
| 57 | /* Function prototypes */ | 57 | /* Function prototypes */ |
| 58 | static int cyberjack_startup(struct usb_serial *serial); | ||
| 59 | static void cyberjack_disconnect(struct usb_serial *serial); | 58 | static void cyberjack_disconnect(struct usb_serial *serial); |
| 60 | static void cyberjack_release(struct usb_serial *serial); | 59 | static int cyberjack_port_probe(struct usb_serial_port *port); |
| 60 | static int cyberjack_port_remove(struct usb_serial_port *port); | ||
| 61 | static int cyberjack_open(struct tty_struct *tty, | 61 | static int cyberjack_open(struct tty_struct *tty, |
| 62 | struct usb_serial_port *port); | 62 | struct usb_serial_port *port); |
| 63 | static void cyberjack_close(struct usb_serial_port *port); | 63 | static void cyberjack_close(struct usb_serial_port *port); |
| @@ -83,9 +83,9 @@ static struct usb_serial_driver cyberjack_device = { | |||
| 83 | .description = "Reiner SCT Cyberjack USB card reader", | 83 | .description = "Reiner SCT Cyberjack USB card reader", |
| 84 | .id_table = id_table, | 84 | .id_table = id_table, |
| 85 | .num_ports = 1, | 85 | .num_ports = 1, |
| 86 | .attach = cyberjack_startup, | ||
| 87 | .disconnect = cyberjack_disconnect, | 86 | .disconnect = cyberjack_disconnect, |
| 88 | .release = cyberjack_release, | 87 | .port_probe = cyberjack_port_probe, |
| 88 | .port_remove = cyberjack_port_remove, | ||
| 89 | .open = cyberjack_open, | 89 | .open = cyberjack_open, |
| 90 | .close = cyberjack_close, | 90 | .close = cyberjack_close, |
| 91 | .write = cyberjack_write, | 91 | .write = cyberjack_write, |
| @@ -107,56 +107,45 @@ struct cyberjack_private { | |||
| 107 | short wrsent; /* Data already sent */ | 107 | short wrsent; /* Data already sent */ |
| 108 | }; | 108 | }; |
| 109 | 109 | ||
| 110 | /* do some startup allocations not currently performed by usb_serial_probe() */ | 110 | static int cyberjack_port_probe(struct usb_serial_port *port) |
| 111 | static int cyberjack_startup(struct usb_serial *serial) | ||
| 112 | { | 111 | { |
| 113 | struct cyberjack_private *priv; | 112 | struct cyberjack_private *priv; |
| 114 | int i; | 113 | int result; |
| 115 | 114 | ||
| 116 | /* allocate the private data structure */ | ||
| 117 | priv = kmalloc(sizeof(struct cyberjack_private), GFP_KERNEL); | 115 | priv = kmalloc(sizeof(struct cyberjack_private), GFP_KERNEL); |
| 118 | if (!priv) | 116 | if (!priv) |
| 119 | return -ENOMEM; | 117 | return -ENOMEM; |
| 120 | 118 | ||
| 121 | /* set initial values */ | ||
| 122 | spin_lock_init(&priv->lock); | 119 | spin_lock_init(&priv->lock); |
| 123 | priv->rdtodo = 0; | 120 | priv->rdtodo = 0; |
| 124 | priv->wrfilled = 0; | 121 | priv->wrfilled = 0; |
| 125 | priv->wrsent = 0; | 122 | priv->wrsent = 0; |
| 126 | usb_set_serial_port_data(serial->port[0], priv); | ||
| 127 | 123 | ||
| 128 | init_waitqueue_head(&serial->port[0]->write_wait); | 124 | usb_set_serial_port_data(port, priv); |
| 129 | 125 | ||
| 130 | for (i = 0; i < serial->num_ports; ++i) { | 126 | result = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL); |
| 131 | int result; | 127 | if (result) |
| 132 | result = usb_submit_urb(serial->port[i]->interrupt_in_urb, | 128 | dev_err(&port->dev, "usb_submit_urb(read int) failed\n"); |
| 133 | GFP_KERNEL); | ||
| 134 | if (result) | ||
| 135 | dev_err(&serial->dev->dev, | ||
| 136 | "usb_submit_urb(read int) failed\n"); | ||
| 137 | dev_dbg(&serial->dev->dev, "%s - usb_submit_urb(int urb)\n", | ||
| 138 | __func__); | ||
| 139 | } | ||
| 140 | 129 | ||
| 141 | return 0; | 130 | return 0; |
| 142 | } | 131 | } |
| 143 | 132 | ||
| 144 | static void cyberjack_disconnect(struct usb_serial *serial) | 133 | static int cyberjack_port_remove(struct usb_serial_port *port) |
| 145 | { | 134 | { |
| 146 | int i; | 135 | struct cyberjack_private *priv; |
| 147 | 136 | ||
| 148 | for (i = 0; i < serial->num_ports; ++i) | 137 | priv = usb_get_serial_port_data(port); |
| 149 | usb_kill_urb(serial->port[i]->interrupt_in_urb); | 138 | kfree(priv); |
| 139 | |||
| 140 | return 0; | ||
| 150 | } | 141 | } |
| 151 | 142 | ||
| 152 | static void cyberjack_release(struct usb_serial *serial) | 143 | static void cyberjack_disconnect(struct usb_serial *serial) |
| 153 | { | 144 | { |
| 154 | int i; | 145 | int i; |
| 155 | 146 | ||
| 156 | for (i = 0; i < serial->num_ports; ++i) { | 147 | for (i = 0; i < serial->num_ports; ++i) |
| 157 | /* My special items, the standard routines free my urbs */ | 148 | usb_kill_urb(serial->port[i]->interrupt_in_urb); |
| 158 | kfree(usb_get_serial_port_data(serial->port[i])); | ||
| 159 | } | ||
| 160 | } | 149 | } |
| 161 | 150 | ||
| 162 | static int cyberjack_open(struct tty_struct *tty, | 151 | static int cyberjack_open(struct tty_struct *tty, |
diff --git a/drivers/usb/serial/cypress_m8.c b/drivers/usb/serial/cypress_m8.c index 1befce21e173..f0da1279c114 100644 --- a/drivers/usb/serial/cypress_m8.c +++ b/drivers/usb/serial/cypress_m8.c | |||
| @@ -123,10 +123,10 @@ struct cypress_private { | |||
| 123 | }; | 123 | }; |
| 124 | 124 | ||
| 125 | /* function prototypes for the Cypress USB to serial device */ | 125 | /* function prototypes for the Cypress USB to serial device */ |
| 126 | static int cypress_earthmate_startup(struct usb_serial *serial); | 126 | static int cypress_earthmate_port_probe(struct usb_serial_port *port); |
| 127 | static int cypress_hidcom_startup(struct usb_serial *serial); | 127 | static int cypress_hidcom_port_probe(struct usb_serial_port *port); |
| 128 | static int cypress_ca42v2_startup(struct usb_serial *serial); | 128 | static int cypress_ca42v2_port_probe(struct usb_serial_port *port); |
| 129 | static void cypress_release(struct usb_serial *serial); | 129 | static int cypress_port_remove(struct usb_serial_port *port); |
| 130 | static int cypress_open(struct tty_struct *tty, struct usb_serial_port *port); | 130 | static int cypress_open(struct tty_struct *tty, struct usb_serial_port *port); |
| 131 | static void cypress_close(struct usb_serial_port *port); | 131 | static void cypress_close(struct usb_serial_port *port); |
| 132 | static void cypress_dtr_rts(struct usb_serial_port *port, int on); | 132 | static void cypress_dtr_rts(struct usb_serial_port *port, int on); |
| @@ -156,8 +156,8 @@ static struct usb_serial_driver cypress_earthmate_device = { | |||
| 156 | .description = "DeLorme Earthmate USB", | 156 | .description = "DeLorme Earthmate USB", |
| 157 | .id_table = id_table_earthmate, | 157 | .id_table = id_table_earthmate, |
| 158 | .num_ports = 1, | 158 | .num_ports = 1, |
| 159 | .attach = cypress_earthmate_startup, | 159 | .port_probe = cypress_earthmate_port_probe, |
| 160 | .release = cypress_release, | 160 | .port_remove = cypress_port_remove, |
| 161 | .open = cypress_open, | 161 | .open = cypress_open, |
| 162 | .close = cypress_close, | 162 | .close = cypress_close, |
| 163 | .dtr_rts = cypress_dtr_rts, | 163 | .dtr_rts = cypress_dtr_rts, |
| @@ -182,8 +182,8 @@ static struct usb_serial_driver cypress_hidcom_device = { | |||
| 182 | .description = "HID->COM RS232 Adapter", | 182 | .description = "HID->COM RS232 Adapter", |
| 183 | .id_table = id_table_cyphidcomrs232, | 183 | .id_table = id_table_cyphidcomrs232, |
| 184 | .num_ports = 1, | 184 | .num_ports = 1, |
| 185 | .attach = cypress_hidcom_startup, | 185 | .port_probe = cypress_hidcom_port_probe, |
| 186 | .release = cypress_release, | 186 | .port_remove = cypress_port_remove, |
| 187 | .open = cypress_open, | 187 | .open = cypress_open, |
| 188 | .close = cypress_close, | 188 | .close = cypress_close, |
| 189 | .dtr_rts = cypress_dtr_rts, | 189 | .dtr_rts = cypress_dtr_rts, |
| @@ -208,8 +208,8 @@ static struct usb_serial_driver cypress_ca42v2_device = { | |||
| 208 | .description = "Nokia CA-42 V2 Adapter", | 208 | .description = "Nokia CA-42 V2 Adapter", |
| 209 | .id_table = id_table_nokiaca42v2, | 209 | .id_table = id_table_nokiaca42v2, |
| 210 | .num_ports = 1, | 210 | .num_ports = 1, |
| 211 | .attach = cypress_ca42v2_startup, | 211 | .port_probe = cypress_ca42v2_port_probe, |
| 212 | .release = cypress_release, | 212 | .port_remove = cypress_port_remove, |
| 213 | .open = cypress_open, | 213 | .open = cypress_open, |
| 214 | .close = cypress_close, | 214 | .close = cypress_close, |
| 215 | .dtr_rts = cypress_dtr_rts, | 215 | .dtr_rts = cypress_dtr_rts, |
| @@ -438,10 +438,10 @@ static void cypress_set_dead(struct usb_serial_port *port) | |||
| 438 | *****************************************************************************/ | 438 | *****************************************************************************/ |
| 439 | 439 | ||
| 440 | 440 | ||
| 441 | static int generic_startup(struct usb_serial *serial) | 441 | static int cypress_generic_port_probe(struct usb_serial_port *port) |
| 442 | { | 442 | { |
| 443 | struct usb_serial *serial = port->serial; | ||
| 443 | struct cypress_private *priv; | 444 | struct cypress_private *priv; |
| 444 | struct usb_serial_port *port = serial->port[0]; | ||
| 445 | 445 | ||
| 446 | priv = kzalloc(sizeof(struct cypress_private), GFP_KERNEL); | 446 | priv = kzalloc(sizeof(struct cypress_private), GFP_KERNEL); |
| 447 | if (!priv) | 447 | if (!priv) |
| @@ -490,14 +490,16 @@ static int generic_startup(struct usb_serial *serial) | |||
| 490 | } | 490 | } |
| 491 | 491 | ||
| 492 | 492 | ||
| 493 | static int cypress_earthmate_startup(struct usb_serial *serial) | 493 | static int cypress_earthmate_port_probe(struct usb_serial_port *port) |
| 494 | { | 494 | { |
| 495 | struct usb_serial *serial = port->serial; | ||
| 495 | struct cypress_private *priv; | 496 | struct cypress_private *priv; |
| 496 | struct usb_serial_port *port = serial->port[0]; | 497 | int ret; |
| 497 | 498 | ||
| 498 | if (generic_startup(serial)) { | 499 | ret = cypress_generic_port_probe(port); |
| 500 | if (ret) { | ||
| 499 | dev_dbg(&port->dev, "%s - Failed setting up port\n", __func__); | 501 | dev_dbg(&port->dev, "%s - Failed setting up port\n", __func__); |
| 500 | return 1; | 502 | return ret; |
| 501 | } | 503 | } |
| 502 | 504 | ||
| 503 | priv = usb_get_serial_port_data(port); | 505 | priv = usb_get_serial_port_data(port); |
| @@ -518,56 +520,53 @@ static int cypress_earthmate_startup(struct usb_serial *serial) | |||
| 518 | } | 520 | } |
| 519 | 521 | ||
| 520 | return 0; | 522 | return 0; |
| 521 | } /* cypress_earthmate_startup */ | 523 | } |
| 522 | |||
| 523 | 524 | ||
| 524 | static int cypress_hidcom_startup(struct usb_serial *serial) | 525 | static int cypress_hidcom_port_probe(struct usb_serial_port *port) |
| 525 | { | 526 | { |
| 526 | struct cypress_private *priv; | 527 | struct cypress_private *priv; |
| 527 | struct usb_serial_port *port = serial->port[0]; | 528 | int ret; |
| 528 | 529 | ||
| 529 | if (generic_startup(serial)) { | 530 | ret = cypress_generic_port_probe(port); |
| 531 | if (ret) { | ||
| 530 | dev_dbg(&port->dev, "%s - Failed setting up port\n", __func__); | 532 | dev_dbg(&port->dev, "%s - Failed setting up port\n", __func__); |
| 531 | return 1; | 533 | return ret; |
| 532 | } | 534 | } |
| 533 | 535 | ||
| 534 | priv = usb_get_serial_port_data(port); | 536 | priv = usb_get_serial_port_data(port); |
| 535 | priv->chiptype = CT_CYPHIDCOM; | 537 | priv->chiptype = CT_CYPHIDCOM; |
| 536 | 538 | ||
| 537 | return 0; | 539 | return 0; |
| 538 | } /* cypress_hidcom_startup */ | 540 | } |
| 539 | |||
| 540 | 541 | ||
| 541 | static int cypress_ca42v2_startup(struct usb_serial *serial) | 542 | static int cypress_ca42v2_port_probe(struct usb_serial_port *port) |
| 542 | { | 543 | { |
| 543 | struct cypress_private *priv; | 544 | struct cypress_private *priv; |
| 544 | struct usb_serial_port *port = serial->port[0]; | 545 | int ret; |
| 545 | 546 | ||
| 546 | if (generic_startup(serial)) { | 547 | ret = cypress_generic_port_probe(port); |
| 548 | if (ret) { | ||
| 547 | dev_dbg(&port->dev, "%s - Failed setting up port\n", __func__); | 549 | dev_dbg(&port->dev, "%s - Failed setting up port\n", __func__); |
| 548 | return 1; | 550 | return ret; |
| 549 | } | 551 | } |
| 550 | 552 | ||
| 551 | priv = usb_get_serial_port_data(port); | 553 | priv = usb_get_serial_port_data(port); |
| 552 | priv->chiptype = CT_CA42V2; | 554 | priv->chiptype = CT_CA42V2; |
| 553 | 555 | ||
| 554 | return 0; | 556 | return 0; |
| 555 | } /* cypress_ca42v2_startup */ | 557 | } |
| 556 | |||
| 557 | 558 | ||
| 558 | static void cypress_release(struct usb_serial *serial) | 559 | static int cypress_port_remove(struct usb_serial_port *port) |
| 559 | { | 560 | { |
| 560 | struct cypress_private *priv; | 561 | struct cypress_private *priv; |
| 561 | 562 | ||
| 562 | /* all open ports are closed at this point */ | 563 | priv = usb_get_serial_port_data(port); |
| 563 | priv = usb_get_serial_port_data(serial->port[0]); | ||
| 564 | 564 | ||
| 565 | if (priv) { | 565 | kfifo_free(&priv->write_fifo); |
| 566 | kfifo_free(&priv->write_fifo); | 566 | kfree(priv); |
| 567 | kfree(priv); | ||
| 568 | } | ||
| 569 | } | ||
| 570 | 567 | ||
| 568 | return 0; | ||
| 569 | } | ||
| 571 | 570 | ||
| 572 | static int cypress_open(struct tty_struct *tty, struct usb_serial_port *port) | 571 | static int cypress_open(struct tty_struct *tty, struct usb_serial_port *port) |
| 573 | { | 572 | { |
diff --git a/drivers/usb/serial/digi_acceleport.c b/drivers/usb/serial/digi_acceleport.c index c86f68c6b078..b50fa1c6d885 100644 --- a/drivers/usb/serial/digi_acceleport.c +++ b/drivers/usb/serial/digi_acceleport.c | |||
| @@ -244,6 +244,8 @@ static int digi_startup_device(struct usb_serial *serial); | |||
| 244 | static int digi_startup(struct usb_serial *serial); | 244 | static int digi_startup(struct usb_serial *serial); |
| 245 | static void digi_disconnect(struct usb_serial *serial); | 245 | static void digi_disconnect(struct usb_serial *serial); |
| 246 | static void digi_release(struct usb_serial *serial); | 246 | static void digi_release(struct usb_serial *serial); |
| 247 | static int digi_port_probe(struct usb_serial_port *port); | ||
| 248 | static int digi_port_remove(struct usb_serial_port *port); | ||
| 247 | static void digi_read_bulk_callback(struct urb *urb); | 249 | static void digi_read_bulk_callback(struct urb *urb); |
| 248 | static int digi_read_inb_callback(struct urb *urb); | 250 | static int digi_read_inb_callback(struct urb *urb); |
| 249 | static int digi_read_oob_callback(struct urb *urb); | 251 | static int digi_read_oob_callback(struct urb *urb); |
| @@ -294,6 +296,8 @@ static struct usb_serial_driver digi_acceleport_2_device = { | |||
| 294 | .attach = digi_startup, | 296 | .attach = digi_startup, |
| 295 | .disconnect = digi_disconnect, | 297 | .disconnect = digi_disconnect, |
| 296 | .release = digi_release, | 298 | .release = digi_release, |
| 299 | .port_probe = digi_port_probe, | ||
| 300 | .port_remove = digi_port_remove, | ||
| 297 | }; | 301 | }; |
| 298 | 302 | ||
| 299 | static struct usb_serial_driver digi_acceleport_4_device = { | 303 | static struct usb_serial_driver digi_acceleport_4_device = { |
| @@ -320,6 +324,8 @@ static struct usb_serial_driver digi_acceleport_4_device = { | |||
| 320 | .attach = digi_startup, | 324 | .attach = digi_startup, |
| 321 | .disconnect = digi_disconnect, | 325 | .disconnect = digi_disconnect, |
| 322 | .release = digi_release, | 326 | .release = digi_release, |
| 327 | .port_probe = digi_port_probe, | ||
| 328 | .port_remove = digi_port_remove, | ||
| 323 | }; | 329 | }; |
| 324 | 330 | ||
| 325 | static struct usb_serial_driver * const serial_drivers[] = { | 331 | static struct usb_serial_driver * const serial_drivers[] = { |
| @@ -1240,59 +1246,50 @@ static int digi_startup_device(struct usb_serial *serial) | |||
| 1240 | return ret; | 1246 | return ret; |
| 1241 | } | 1247 | } |
| 1242 | 1248 | ||
| 1243 | 1249 | static int digi_port_init(struct usb_serial_port *port, unsigned port_num) | |
| 1244 | static int digi_startup(struct usb_serial *serial) | ||
| 1245 | { | 1250 | { |
| 1246 | |||
| 1247 | int i; | ||
| 1248 | struct digi_port *priv; | 1251 | struct digi_port *priv; |
| 1249 | struct digi_serial *serial_priv; | ||
| 1250 | 1252 | ||
| 1251 | /* allocate the private data structures for all ports */ | 1253 | priv = kzalloc(sizeof(*priv), GFP_KERNEL); |
| 1252 | /* number of regular ports + 1 for the out-of-band port */ | 1254 | if (!priv) |
| 1253 | for (i = 0; i < serial->type->num_ports + 1; i++) { | 1255 | return -ENOMEM; |
| 1254 | /* allocate port private structure */ | ||
| 1255 | priv = kmalloc(sizeof(struct digi_port), GFP_KERNEL); | ||
| 1256 | if (priv == NULL) { | ||
| 1257 | while (--i >= 0) | ||
| 1258 | kfree(usb_get_serial_port_data(serial->port[i])); | ||
| 1259 | return 1; /* error */ | ||
| 1260 | } | ||
| 1261 | 1256 | ||
| 1262 | /* initialize port private structure */ | 1257 | spin_lock_init(&priv->dp_port_lock); |
| 1263 | spin_lock_init(&priv->dp_port_lock); | 1258 | priv->dp_port_num = port_num; |
| 1264 | priv->dp_port_num = i; | 1259 | init_waitqueue_head(&priv->dp_modem_change_wait); |
| 1265 | priv->dp_out_buf_len = 0; | 1260 | init_waitqueue_head(&priv->dp_transmit_idle_wait); |
| 1266 | priv->dp_write_urb_in_use = 0; | 1261 | init_waitqueue_head(&priv->dp_flush_wait); |
| 1267 | priv->dp_modem_signals = 0; | 1262 | init_waitqueue_head(&priv->dp_close_wait); |
| 1268 | init_waitqueue_head(&priv->dp_modem_change_wait); | 1263 | INIT_WORK(&priv->dp_wakeup_work, digi_wakeup_write_lock); |
| 1269 | priv->dp_transmit_idle = 0; | 1264 | priv->dp_port = port; |
| 1270 | init_waitqueue_head(&priv->dp_transmit_idle_wait); | ||
| 1271 | priv->dp_throttled = 0; | ||
| 1272 | priv->dp_throttle_restart = 0; | ||
| 1273 | init_waitqueue_head(&priv->dp_flush_wait); | ||
| 1274 | init_waitqueue_head(&priv->dp_close_wait); | ||
| 1275 | INIT_WORK(&priv->dp_wakeup_work, digi_wakeup_write_lock); | ||
| 1276 | priv->dp_port = serial->port[i]; | ||
| 1277 | /* initialize write wait queue for this port */ | ||
| 1278 | init_waitqueue_head(&serial->port[i]->write_wait); | ||
| 1279 | |||
| 1280 | usb_set_serial_port_data(serial->port[i], priv); | ||
| 1281 | } | ||
| 1282 | 1265 | ||
| 1283 | /* allocate serial private structure */ | 1266 | init_waitqueue_head(&port->write_wait); |
| 1284 | serial_priv = kmalloc(sizeof(struct digi_serial), GFP_KERNEL); | 1267 | |
| 1285 | if (serial_priv == NULL) { | 1268 | usb_set_serial_port_data(port, priv); |
| 1286 | for (i = 0; i < serial->type->num_ports + 1; i++) | 1269 | |
| 1287 | kfree(usb_get_serial_port_data(serial->port[i])); | 1270 | return 0; |
| 1288 | return 1; /* error */ | 1271 | } |
| 1289 | } | 1272 | |
| 1273 | static int digi_startup(struct usb_serial *serial) | ||
| 1274 | { | ||
| 1275 | struct digi_serial *serial_priv; | ||
| 1276 | int ret; | ||
| 1277 | |||
| 1278 | serial_priv = kzalloc(sizeof(*serial_priv), GFP_KERNEL); | ||
| 1279 | if (!serial_priv) | ||
| 1280 | return -ENOMEM; | ||
| 1290 | 1281 | ||
| 1291 | /* initialize serial private structure */ | ||
| 1292 | spin_lock_init(&serial_priv->ds_serial_lock); | 1282 | spin_lock_init(&serial_priv->ds_serial_lock); |
| 1293 | serial_priv->ds_oob_port_num = serial->type->num_ports; | 1283 | serial_priv->ds_oob_port_num = serial->type->num_ports; |
| 1294 | serial_priv->ds_oob_port = serial->port[serial_priv->ds_oob_port_num]; | 1284 | serial_priv->ds_oob_port = serial->port[serial_priv->ds_oob_port_num]; |
| 1295 | serial_priv->ds_device_started = 0; | 1285 | |
| 1286 | ret = digi_port_init(serial_priv->ds_oob_port, | ||
| 1287 | serial_priv->ds_oob_port_num); | ||
| 1288 | if (ret) { | ||
| 1289 | kfree(serial_priv); | ||
| 1290 | return ret; | ||
| 1291 | } | ||
| 1292 | |||
| 1296 | usb_set_serial_data(serial, serial_priv); | 1293 | usb_set_serial_data(serial, serial_priv); |
| 1297 | 1294 | ||
| 1298 | return 0; | 1295 | return 0; |
| @@ -1313,15 +1310,35 @@ static void digi_disconnect(struct usb_serial *serial) | |||
| 1313 | 1310 | ||
| 1314 | static void digi_release(struct usb_serial *serial) | 1311 | static void digi_release(struct usb_serial *serial) |
| 1315 | { | 1312 | { |
| 1316 | int i; | 1313 | struct digi_serial *serial_priv; |
| 1314 | struct digi_port *priv; | ||
| 1315 | |||
| 1316 | serial_priv = usb_get_serial_data(serial); | ||
| 1317 | |||
| 1318 | priv = usb_get_serial_port_data(serial_priv->ds_oob_port); | ||
| 1319 | kfree(priv); | ||
| 1317 | 1320 | ||
| 1318 | /* free the private data structures for all ports */ | 1321 | kfree(serial_priv); |
| 1319 | /* number of regular ports + 1 for the out-of-band port */ | ||
| 1320 | for (i = 0; i < serial->type->num_ports + 1; i++) | ||
| 1321 | kfree(usb_get_serial_port_data(serial->port[i])); | ||
| 1322 | kfree(usb_get_serial_data(serial)); | ||
| 1323 | } | 1322 | } |
| 1324 | 1323 | ||
| 1324 | static int digi_port_probe(struct usb_serial_port *port) | ||
| 1325 | { | ||
| 1326 | unsigned port_num; | ||
| 1327 | |||
| 1328 | port_num = port->number - port->serial->minor; | ||
| 1329 | |||
| 1330 | return digi_port_init(port, port_num); | ||
| 1331 | } | ||
| 1332 | |||
| 1333 | static int digi_port_remove(struct usb_serial_port *port) | ||
| 1334 | { | ||
| 1335 | struct digi_port *priv; | ||
| 1336 | |||
| 1337 | priv = usb_get_serial_port_data(port); | ||
| 1338 | kfree(priv); | ||
| 1339 | |||
| 1340 | return 0; | ||
| 1341 | } | ||
| 1325 | 1342 | ||
| 1326 | static void digi_read_bulk_callback(struct urb *urb) | 1343 | static void digi_read_bulk_callback(struct urb *urb) |
| 1327 | { | 1344 | { |
diff --git a/drivers/usb/serial/f81232.c b/drivers/usb/serial/f81232.c index 244477107e2f..6e4eb57d0177 100644 --- a/drivers/usb/serial/f81232.c +++ b/drivers/usb/serial/f81232.c | |||
| @@ -318,39 +318,30 @@ static int f81232_ioctl(struct tty_struct *tty, | |||
| 318 | return -ENOIOCTLCMD; | 318 | return -ENOIOCTLCMD; |
| 319 | } | 319 | } |
| 320 | 320 | ||
| 321 | static int f81232_startup(struct usb_serial *serial) | 321 | static int f81232_port_probe(struct usb_serial_port *port) |
| 322 | { | 322 | { |
| 323 | struct f81232_private *priv; | 323 | struct f81232_private *priv; |
| 324 | int i; | ||
| 325 | 324 | ||
| 326 | for (i = 0; i < serial->num_ports; ++i) { | 325 | priv = kzalloc(sizeof(*priv), GFP_KERNEL); |
| 327 | priv = kzalloc(sizeof(struct f81232_private), GFP_KERNEL); | 326 | if (!priv) |
| 328 | if (!priv) | 327 | return -ENOMEM; |
| 329 | goto cleanup; | ||
| 330 | spin_lock_init(&priv->lock); | ||
| 331 | init_waitqueue_head(&priv->delta_msr_wait); | ||
| 332 | usb_set_serial_port_data(serial->port[i], priv); | ||
| 333 | } | ||
| 334 | return 0; | ||
| 335 | 328 | ||
| 336 | cleanup: | 329 | spin_lock_init(&priv->lock); |
| 337 | for (--i; i >= 0; --i) { | 330 | init_waitqueue_head(&priv->delta_msr_wait); |
| 338 | priv = usb_get_serial_port_data(serial->port[i]); | 331 | |
| 339 | kfree(priv); | 332 | usb_set_serial_port_data(port, priv); |
| 340 | usb_set_serial_port_data(serial->port[i], NULL); | 333 | |
| 341 | } | 334 | return 0; |
| 342 | return -ENOMEM; | ||
| 343 | } | 335 | } |
| 344 | 336 | ||
| 345 | static void f81232_release(struct usb_serial *serial) | 337 | static int f81232_port_remove(struct usb_serial_port *port) |
| 346 | { | 338 | { |
| 347 | int i; | ||
| 348 | struct f81232_private *priv; | 339 | struct f81232_private *priv; |
| 349 | 340 | ||
| 350 | for (i = 0; i < serial->num_ports; ++i) { | 341 | priv = usb_get_serial_port_data(port); |
| 351 | priv = usb_get_serial_port_data(serial->port[i]); | 342 | kfree(priv); |
| 352 | kfree(priv); | 343 | |
| 353 | } | 344 | return 0; |
| 354 | } | 345 | } |
| 355 | 346 | ||
| 356 | static struct usb_serial_driver f81232_device = { | 347 | static struct usb_serial_driver f81232_device = { |
| @@ -373,8 +364,8 @@ static struct usb_serial_driver f81232_device = { | |||
| 373 | .tiocmset = f81232_tiocmset, | 364 | .tiocmset = f81232_tiocmset, |
| 374 | .process_read_urb = f81232_process_read_urb, | 365 | .process_read_urb = f81232_process_read_urb, |
| 375 | .read_int_callback = f81232_read_int_callback, | 366 | .read_int_callback = f81232_read_int_callback, |
| 376 | .attach = f81232_startup, | 367 | .port_probe = f81232_port_probe, |
| 377 | .release = f81232_release, | 368 | .port_remove = f81232_port_remove, |
| 378 | }; | 369 | }; |
| 379 | 370 | ||
| 380 | static struct usb_serial_driver * const serial_drivers[] = { | 371 | static struct usb_serial_driver * const serial_drivers[] = { |
diff --git a/drivers/usb/serial/garmin_gps.c b/drivers/usb/serial/garmin_gps.c index 3ee92648c02d..203358d7e7bc 100644 --- a/drivers/usb/serial/garmin_gps.c +++ b/drivers/usb/serial/garmin_gps.c | |||
| @@ -1405,11 +1405,10 @@ static void timeout_handler(unsigned long data) | |||
| 1405 | 1405 | ||
| 1406 | 1406 | ||
| 1407 | 1407 | ||
| 1408 | static int garmin_attach(struct usb_serial *serial) | 1408 | static int garmin_port_probe(struct usb_serial_port *port) |
| 1409 | { | 1409 | { |
| 1410 | int status = 0; | 1410 | int status; |
| 1411 | struct usb_serial_port *port = serial->port[0]; | 1411 | struct garmin_data *garmin_data_p; |
| 1412 | struct garmin_data *garmin_data_p = NULL; | ||
| 1413 | 1412 | ||
| 1414 | garmin_data_p = kzalloc(sizeof(struct garmin_data), GFP_KERNEL); | 1413 | garmin_data_p = kzalloc(sizeof(struct garmin_data), GFP_KERNEL); |
| 1415 | if (garmin_data_p == NULL) { | 1414 | if (garmin_data_p == NULL) { |
| @@ -1434,22 +1433,14 @@ static int garmin_attach(struct usb_serial *serial) | |||
| 1434 | } | 1433 | } |
| 1435 | 1434 | ||
| 1436 | 1435 | ||
| 1437 | static void garmin_disconnect(struct usb_serial *serial) | 1436 | static int garmin_port_remove(struct usb_serial_port *port) |
| 1438 | { | 1437 | { |
| 1439 | struct usb_serial_port *port = serial->port[0]; | ||
| 1440 | struct garmin_data *garmin_data_p = usb_get_serial_port_data(port); | 1438 | struct garmin_data *garmin_data_p = usb_get_serial_port_data(port); |
| 1441 | 1439 | ||
| 1442 | usb_kill_urb(port->interrupt_in_urb); | 1440 | usb_kill_urb(port->interrupt_in_urb); |
| 1443 | del_timer_sync(&garmin_data_p->timer); | 1441 | del_timer_sync(&garmin_data_p->timer); |
| 1444 | } | ||
| 1445 | |||
| 1446 | |||
| 1447 | static void garmin_release(struct usb_serial *serial) | ||
| 1448 | { | ||
| 1449 | struct usb_serial_port *port = serial->port[0]; | ||
| 1450 | struct garmin_data *garmin_data_p = usb_get_serial_port_data(port); | ||
| 1451 | |||
| 1452 | kfree(garmin_data_p); | 1442 | kfree(garmin_data_p); |
| 1443 | return 0; | ||
| 1453 | } | 1444 | } |
| 1454 | 1445 | ||
| 1455 | 1446 | ||
| @@ -1466,9 +1457,8 @@ static struct usb_serial_driver garmin_device = { | |||
| 1466 | .close = garmin_close, | 1457 | .close = garmin_close, |
| 1467 | .throttle = garmin_throttle, | 1458 | .throttle = garmin_throttle, |
| 1468 | .unthrottle = garmin_unthrottle, | 1459 | .unthrottle = garmin_unthrottle, |
| 1469 | .attach = garmin_attach, | 1460 | .port_probe = garmin_port_probe, |
| 1470 | .disconnect = garmin_disconnect, | 1461 | .port_remove = garmin_port_remove, |
| 1471 | .release = garmin_release, | ||
| 1472 | .write = garmin_write, | 1462 | .write = garmin_write, |
| 1473 | .write_room = garmin_write_room, | 1463 | .write_room = garmin_write_room, |
| 1474 | .write_bulk_callback = garmin_write_bulk_callback, | 1464 | .write_bulk_callback = garmin_write_bulk_callback, |
diff --git a/drivers/usb/serial/io_edgeport.c b/drivers/usb/serial/io_edgeport.c index 8e6faaf3580c..5acc0d13864a 100644 --- a/drivers/usb/serial/io_edgeport.c +++ b/drivers/usb/serial/io_edgeport.c | |||
| @@ -225,6 +225,8 @@ static int edge_get_icount(struct tty_struct *tty, | |||
| 225 | static int edge_startup(struct usb_serial *serial); | 225 | static int edge_startup(struct usb_serial *serial); |
| 226 | static void edge_disconnect(struct usb_serial *serial); | 226 | static void edge_disconnect(struct usb_serial *serial); |
| 227 | static void edge_release(struct usb_serial *serial); | 227 | static void edge_release(struct usb_serial *serial); |
| 228 | static int edge_port_probe(struct usb_serial_port *port); | ||
| 229 | static int edge_port_remove(struct usb_serial_port *port); | ||
| 228 | 230 | ||
| 229 | #include "io_tables.h" /* all of the devices that this driver supports */ | 231 | #include "io_tables.h" /* all of the devices that this driver supports */ |
| 230 | 232 | ||
| @@ -2875,10 +2877,9 @@ static void load_application_firmware(struct edgeport_serial *edge_serial) | |||
| 2875 | static int edge_startup(struct usb_serial *serial) | 2877 | static int edge_startup(struct usb_serial *serial) |
| 2876 | { | 2878 | { |
| 2877 | struct edgeport_serial *edge_serial; | 2879 | struct edgeport_serial *edge_serial; |
| 2878 | struct edgeport_port *edge_port; | ||
| 2879 | struct usb_device *dev; | 2880 | struct usb_device *dev; |
| 2880 | struct device *ddev = &serial->dev->dev; | 2881 | struct device *ddev = &serial->dev->dev; |
| 2881 | int i, j; | 2882 | int i; |
| 2882 | int response; | 2883 | int response; |
| 2883 | bool interrupt_in_found; | 2884 | bool interrupt_in_found; |
| 2884 | bool bulk_in_found; | 2885 | bool bulk_in_found; |
| @@ -2961,25 +2962,6 @@ static int edge_startup(struct usb_serial *serial) | |||
| 2961 | /* we set up the pointers to the endpoints in the edge_open function, | 2962 | /* we set up the pointers to the endpoints in the edge_open function, |
| 2962 | * as the structures aren't created yet. */ | 2963 | * as the structures aren't created yet. */ |
| 2963 | 2964 | ||
| 2964 | /* set up our port private structures */ | ||
| 2965 | for (i = 0; i < serial->num_ports; ++i) { | ||
| 2966 | edge_port = kzalloc(sizeof(struct edgeport_port), GFP_KERNEL); | ||
| 2967 | if (edge_port == NULL) { | ||
| 2968 | dev_err(ddev, "%s - Out of memory\n", __func__); | ||
| 2969 | for (j = 0; j < i; ++j) { | ||
| 2970 | kfree(usb_get_serial_port_data(serial->port[j])); | ||
| 2971 | usb_set_serial_port_data(serial->port[j], | ||
| 2972 | NULL); | ||
| 2973 | } | ||
| 2974 | usb_set_serial_data(serial, NULL); | ||
| 2975 | kfree(edge_serial); | ||
| 2976 | return -ENOMEM; | ||
| 2977 | } | ||
| 2978 | spin_lock_init(&edge_port->ep_lock); | ||
| 2979 | edge_port->port = serial->port[i]; | ||
| 2980 | usb_set_serial_port_data(serial->port[i], edge_port); | ||
| 2981 | } | ||
| 2982 | |||
| 2983 | response = 0; | 2965 | response = 0; |
| 2984 | 2966 | ||
| 2985 | if (edge_serial->is_epic) { | 2967 | if (edge_serial->is_epic) { |
| @@ -3120,14 +3102,36 @@ static void edge_disconnect(struct usb_serial *serial) | |||
| 3120 | static void edge_release(struct usb_serial *serial) | 3102 | static void edge_release(struct usb_serial *serial) |
| 3121 | { | 3103 | { |
| 3122 | struct edgeport_serial *edge_serial = usb_get_serial_data(serial); | 3104 | struct edgeport_serial *edge_serial = usb_get_serial_data(serial); |
| 3123 | int i; | ||
| 3124 | |||
| 3125 | for (i = 0; i < serial->num_ports; ++i) | ||
| 3126 | kfree(usb_get_serial_port_data(serial->port[i])); | ||
| 3127 | 3105 | ||
| 3128 | kfree(edge_serial); | 3106 | kfree(edge_serial); |
| 3129 | } | 3107 | } |
| 3130 | 3108 | ||
| 3109 | static int edge_port_probe(struct usb_serial_port *port) | ||
| 3110 | { | ||
| 3111 | struct edgeport_port *edge_port; | ||
| 3112 | |||
| 3113 | edge_port = kzalloc(sizeof(*edge_port), GFP_KERNEL); | ||
| 3114 | if (!edge_port) | ||
| 3115 | return -ENOMEM; | ||
| 3116 | |||
| 3117 | spin_lock_init(&edge_port->ep_lock); | ||
| 3118 | edge_port->port = port; | ||
| 3119 | |||
| 3120 | usb_set_serial_port_data(port, edge_port); | ||
| 3121 | |||
| 3122 | return 0; | ||
| 3123 | } | ||
| 3124 | |||
| 3125 | static int edge_port_remove(struct usb_serial_port *port) | ||
| 3126 | { | ||
| 3127 | struct edgeport_port *edge_port; | ||
| 3128 | |||
| 3129 | edge_port = usb_get_serial_port_data(port); | ||
| 3130 | kfree(edge_port); | ||
| 3131 | |||
| 3132 | return 0; | ||
| 3133 | } | ||
| 3134 | |||
| 3131 | module_usb_serial_driver(serial_drivers, id_table_combined); | 3135 | module_usb_serial_driver(serial_drivers, id_table_combined); |
| 3132 | 3136 | ||
| 3133 | MODULE_AUTHOR(DRIVER_AUTHOR); | 3137 | MODULE_AUTHOR(DRIVER_AUTHOR); |
diff --git a/drivers/usb/serial/io_tables.h b/drivers/usb/serial/io_tables.h index 350afddb55ba..1511dd0ad324 100644 --- a/drivers/usb/serial/io_tables.h +++ b/drivers/usb/serial/io_tables.h | |||
| @@ -110,6 +110,8 @@ static struct usb_serial_driver edgeport_2port_device = { | |||
| 110 | .attach = edge_startup, | 110 | .attach = edge_startup, |
| 111 | .disconnect = edge_disconnect, | 111 | .disconnect = edge_disconnect, |
| 112 | .release = edge_release, | 112 | .release = edge_release, |
| 113 | .port_probe = edge_port_probe, | ||
| 114 | .port_remove = edge_port_remove, | ||
| 113 | .ioctl = edge_ioctl, | 115 | .ioctl = edge_ioctl, |
| 114 | .set_termios = edge_set_termios, | 116 | .set_termios = edge_set_termios, |
| 115 | .tiocmget = edge_tiocmget, | 117 | .tiocmget = edge_tiocmget, |
| @@ -139,6 +141,8 @@ static struct usb_serial_driver edgeport_4port_device = { | |||
| 139 | .attach = edge_startup, | 141 | .attach = edge_startup, |
| 140 | .disconnect = edge_disconnect, | 142 | .disconnect = edge_disconnect, |
| 141 | .release = edge_release, | 143 | .release = edge_release, |
| 144 | .port_probe = edge_port_probe, | ||
| 145 | .port_remove = edge_port_remove, | ||
| 142 | .ioctl = edge_ioctl, | 146 | .ioctl = edge_ioctl, |
| 143 | .set_termios = edge_set_termios, | 147 | .set_termios = edge_set_termios, |
| 144 | .tiocmget = edge_tiocmget, | 148 | .tiocmget = edge_tiocmget, |
| @@ -168,6 +172,8 @@ static struct usb_serial_driver edgeport_8port_device = { | |||
| 168 | .attach = edge_startup, | 172 | .attach = edge_startup, |
| 169 | .disconnect = edge_disconnect, | 173 | .disconnect = edge_disconnect, |
| 170 | .release = edge_release, | 174 | .release = edge_release, |
| 175 | .port_probe = edge_port_probe, | ||
| 176 | .port_remove = edge_port_remove, | ||
| 171 | .ioctl = edge_ioctl, | 177 | .ioctl = edge_ioctl, |
| 172 | .set_termios = edge_set_termios, | 178 | .set_termios = edge_set_termios, |
| 173 | .tiocmget = edge_tiocmget, | 179 | .tiocmget = edge_tiocmget, |
| @@ -197,6 +203,8 @@ static struct usb_serial_driver epic_device = { | |||
| 197 | .attach = edge_startup, | 203 | .attach = edge_startup, |
| 198 | .disconnect = edge_disconnect, | 204 | .disconnect = edge_disconnect, |
| 199 | .release = edge_release, | 205 | .release = edge_release, |
| 206 | .port_probe = edge_port_probe, | ||
| 207 | .port_remove = edge_port_remove, | ||
| 200 | .ioctl = edge_ioctl, | 208 | .ioctl = edge_ioctl, |
| 201 | .set_termios = edge_set_termios, | 209 | .set_termios = edge_set_termios, |
| 202 | .tiocmget = edge_tiocmget, | 210 | .tiocmget = edge_tiocmget, |
diff --git a/drivers/usb/serial/io_ti.c b/drivers/usb/serial/io_ti.c index a2209cd45093..60023c2d2a31 100644 --- a/drivers/usb/serial/io_ti.c +++ b/drivers/usb/serial/io_ti.c | |||
| @@ -2532,12 +2532,7 @@ static void edge_break(struct tty_struct *tty, int break_state) | |||
| 2532 | static int edge_startup(struct usb_serial *serial) | 2532 | static int edge_startup(struct usb_serial *serial) |
| 2533 | { | 2533 | { |
| 2534 | struct edgeport_serial *edge_serial; | 2534 | struct edgeport_serial *edge_serial; |
| 2535 | struct edgeport_port *edge_port; | ||
| 2536 | struct usb_device *dev; | ||
| 2537 | int status; | 2535 | int status; |
| 2538 | int i; | ||
| 2539 | |||
| 2540 | dev = serial->dev; | ||
| 2541 | 2536 | ||
| 2542 | /* create our private serial structure */ | 2537 | /* create our private serial structure */ |
| 2543 | edge_serial = kzalloc(sizeof(struct edgeport_serial), GFP_KERNEL); | 2538 | edge_serial = kzalloc(sizeof(struct edgeport_serial), GFP_KERNEL); |
| @@ -2555,40 +2550,7 @@ static int edge_startup(struct usb_serial *serial) | |||
| 2555 | return status; | 2550 | return status; |
| 2556 | } | 2551 | } |
| 2557 | 2552 | ||
| 2558 | /* set up our port private structures */ | ||
| 2559 | for (i = 0; i < serial->num_ports; ++i) { | ||
| 2560 | edge_port = kzalloc(sizeof(struct edgeport_port), GFP_KERNEL); | ||
| 2561 | if (edge_port == NULL) { | ||
| 2562 | dev_err(&serial->dev->dev, "%s - Out of memory\n", | ||
| 2563 | __func__); | ||
| 2564 | goto cleanup; | ||
| 2565 | } | ||
| 2566 | spin_lock_init(&edge_port->ep_lock); | ||
| 2567 | if (kfifo_alloc(&edge_port->write_fifo, EDGE_OUT_BUF_SIZE, | ||
| 2568 | GFP_KERNEL)) { | ||
| 2569 | dev_err(&serial->dev->dev, "%s - Out of memory\n", | ||
| 2570 | __func__); | ||
| 2571 | kfree(edge_port); | ||
| 2572 | goto cleanup; | ||
| 2573 | } | ||
| 2574 | edge_port->port = serial->port[i]; | ||
| 2575 | edge_port->edge_serial = edge_serial; | ||
| 2576 | usb_set_serial_port_data(serial->port[i], edge_port); | ||
| 2577 | edge_port->bUartMode = default_uart_mode; | ||
| 2578 | } | ||
| 2579 | |||
| 2580 | return 0; | 2553 | return 0; |
| 2581 | |||
| 2582 | cleanup: | ||
| 2583 | for (--i; i >= 0; --i) { | ||
| 2584 | edge_port = usb_get_serial_port_data(serial->port[i]); | ||
| 2585 | kfifo_free(&edge_port->write_fifo); | ||
| 2586 | kfree(edge_port); | ||
| 2587 | usb_set_serial_port_data(serial->port[i], NULL); | ||
| 2588 | } | ||
| 2589 | kfree(edge_serial); | ||
| 2590 | usb_set_serial_data(serial, NULL); | ||
| 2591 | return -ENOMEM; | ||
| 2592 | } | 2554 | } |
| 2593 | 2555 | ||
| 2594 | static void edge_disconnect(struct usb_serial *serial) | 2556 | static void edge_disconnect(struct usb_serial *serial) |
| @@ -2597,17 +2559,54 @@ static void edge_disconnect(struct usb_serial *serial) | |||
| 2597 | 2559 | ||
| 2598 | static void edge_release(struct usb_serial *serial) | 2560 | static void edge_release(struct usb_serial *serial) |
| 2599 | { | 2561 | { |
| 2600 | int i; | 2562 | kfree(usb_get_serial_data(serial)); |
| 2563 | } | ||
| 2564 | |||
| 2565 | static int edge_port_probe(struct usb_serial_port *port) | ||
| 2566 | { | ||
| 2601 | struct edgeport_port *edge_port; | 2567 | struct edgeport_port *edge_port; |
| 2568 | int ret; | ||
| 2602 | 2569 | ||
| 2603 | for (i = 0; i < serial->num_ports; ++i) { | 2570 | edge_port = kzalloc(sizeof(*edge_port), GFP_KERNEL); |
| 2604 | edge_port = usb_get_serial_port_data(serial->port[i]); | 2571 | if (!edge_port) |
| 2572 | return -ENOMEM; | ||
| 2573 | |||
| 2574 | ret = kfifo_alloc(&edge_port->write_fifo, EDGE_OUT_BUF_SIZE, | ||
| 2575 | GFP_KERNEL); | ||
| 2576 | if (ret) { | ||
| 2577 | kfree(edge_port); | ||
| 2578 | return -ENOMEM; | ||
| 2579 | } | ||
| 2580 | |||
| 2581 | spin_lock_init(&edge_port->ep_lock); | ||
| 2582 | edge_port->port = port; | ||
| 2583 | edge_port->edge_serial = usb_get_serial_data(port->serial); | ||
| 2584 | edge_port->bUartMode = default_uart_mode; | ||
| 2585 | |||
| 2586 | usb_set_serial_port_data(port, edge_port); | ||
| 2587 | |||
| 2588 | ret = edge_create_sysfs_attrs(port); | ||
| 2589 | if (ret) { | ||
| 2605 | kfifo_free(&edge_port->write_fifo); | 2590 | kfifo_free(&edge_port->write_fifo); |
| 2606 | kfree(edge_port); | 2591 | kfree(edge_port); |
| 2592 | return ret; | ||
| 2607 | } | 2593 | } |
| 2608 | kfree(usb_get_serial_data(serial)); | 2594 | |
| 2595 | return 0; | ||
| 2609 | } | 2596 | } |
| 2610 | 2597 | ||
| 2598 | static int edge_port_remove(struct usb_serial_port *port) | ||
| 2599 | { | ||
| 2600 | struct edgeport_port *edge_port; | ||
| 2601 | |||
| 2602 | edge_port = usb_get_serial_port_data(port); | ||
| 2603 | |||
| 2604 | edge_remove_sysfs_attrs(port); | ||
| 2605 | kfifo_free(&edge_port->write_fifo); | ||
| 2606 | kfree(edge_port); | ||
| 2607 | |||
| 2608 | return 0; | ||
| 2609 | } | ||
| 2611 | 2610 | ||
| 2612 | /* Sysfs Attributes */ | 2611 | /* Sysfs Attributes */ |
| 2613 | 2612 | ||
| @@ -2667,8 +2666,8 @@ static struct usb_serial_driver edgeport_1port_device = { | |||
| 2667 | .attach = edge_startup, | 2666 | .attach = edge_startup, |
| 2668 | .disconnect = edge_disconnect, | 2667 | .disconnect = edge_disconnect, |
| 2669 | .release = edge_release, | 2668 | .release = edge_release, |
| 2670 | .port_probe = edge_create_sysfs_attrs, | 2669 | .port_probe = edge_port_probe, |
| 2671 | .port_remove = edge_remove_sysfs_attrs, | 2670 | .port_remove = edge_port_remove, |
| 2672 | .ioctl = edge_ioctl, | 2671 | .ioctl = edge_ioctl, |
| 2673 | .set_termios = edge_set_termios, | 2672 | .set_termios = edge_set_termios, |
| 2674 | .tiocmget = edge_tiocmget, | 2673 | .tiocmget = edge_tiocmget, |
| @@ -2698,8 +2697,8 @@ static struct usb_serial_driver edgeport_2port_device = { | |||
| 2698 | .attach = edge_startup, | 2697 | .attach = edge_startup, |
| 2699 | .disconnect = edge_disconnect, | 2698 | .disconnect = edge_disconnect, |
| 2700 | .release = edge_release, | 2699 | .release = edge_release, |
| 2701 | .port_probe = edge_create_sysfs_attrs, | 2700 | .port_probe = edge_port_probe, |
| 2702 | .port_remove = edge_remove_sysfs_attrs, | 2701 | .port_remove = edge_port_remove, |
| 2703 | .ioctl = edge_ioctl, | 2702 | .ioctl = edge_ioctl, |
| 2704 | .set_termios = edge_set_termios, | 2703 | .set_termios = edge_set_termios, |
| 2705 | .tiocmget = edge_tiocmget, | 2704 | .tiocmget = edge_tiocmget, |
diff --git a/drivers/usb/serial/ipw.c b/drivers/usb/serial/ipw.c index 20a132ec39e2..4264821a3b34 100644 --- a/drivers/usb/serial/ipw.c +++ b/drivers/usb/serial/ipw.c | |||
| @@ -203,8 +203,7 @@ static int ipw_open(struct tty_struct *tty, struct usb_serial_port *port) | |||
| 203 | return 0; | 203 | return 0; |
| 204 | } | 204 | } |
| 205 | 205 | ||
| 206 | /* fake probe - only to allocate data structures */ | 206 | static int ipw_attach(struct usb_serial *serial) |
| 207 | static int ipw_probe(struct usb_serial *serial, const struct usb_device_id *id) | ||
| 208 | { | 207 | { |
| 209 | struct usb_wwan_intf_private *data; | 208 | struct usb_wwan_intf_private *data; |
| 210 | 209 | ||
| @@ -303,9 +302,9 @@ static struct usb_serial_driver ipw_device = { | |||
| 303 | .num_ports = 1, | 302 | .num_ports = 1, |
| 304 | .open = ipw_open, | 303 | .open = ipw_open, |
| 305 | .close = ipw_close, | 304 | .close = ipw_close, |
| 306 | .probe = ipw_probe, | 305 | .attach = ipw_attach, |
| 307 | .attach = usb_wwan_startup, | ||
| 308 | .release = ipw_release, | 306 | .release = ipw_release, |
| 307 | .port_probe = usb_wwan_port_probe, | ||
| 309 | .port_remove = usb_wwan_port_remove, | 308 | .port_remove = usb_wwan_port_remove, |
| 310 | .dtr_rts = ipw_dtr_rts, | 309 | .dtr_rts = ipw_dtr_rts, |
| 311 | .write = usb_wwan_write, | 310 | .write = usb_wwan_write, |
diff --git a/drivers/usb/serial/iuu_phoenix.c b/drivers/usb/serial/iuu_phoenix.c index 01da3ea36e89..cd5533e81de7 100644 --- a/drivers/usb/serial/iuu_phoenix.c +++ b/drivers/usb/serial/iuu_phoenix.c | |||
| @@ -53,6 +53,8 @@ static int iuu_cardout; | |||
| 53 | static bool xmas; | 53 | static bool xmas; |
| 54 | static int vcc_default = 5; | 54 | static int vcc_default = 5; |
| 55 | 55 | ||
| 56 | static int iuu_create_sysfs_attrs(struct usb_serial_port *port); | ||
| 57 | static int iuu_remove_sysfs_attrs(struct usb_serial_port *port); | ||
| 56 | static void read_rxcmd_callback(struct urb *urb); | 58 | static void read_rxcmd_callback(struct urb *urb); |
| 57 | 59 | ||
| 58 | struct iuu_private { | 60 | struct iuu_private { |
| @@ -72,63 +74,55 @@ struct iuu_private { | |||
| 72 | u32 clk; | 74 | u32 clk; |
| 73 | }; | 75 | }; |
| 74 | 76 | ||
| 75 | 77 | static int iuu_port_probe(struct usb_serial_port *port) | |
| 76 | static void iuu_free_buf(struct iuu_private *priv) | ||
| 77 | { | ||
| 78 | kfree(priv->buf); | ||
| 79 | kfree(priv->writebuf); | ||
| 80 | } | ||
| 81 | |||
| 82 | static int iuu_alloc_buf(struct usb_serial *serial, struct iuu_private *priv) | ||
| 83 | { | ||
| 84 | priv->buf = kzalloc(256, GFP_KERNEL); | ||
| 85 | priv->writebuf = kzalloc(256, GFP_KERNEL); | ||
| 86 | if (!priv->buf || !priv->writebuf) { | ||
| 87 | iuu_free_buf(priv); | ||
| 88 | dev_dbg(&serial->dev->dev, "%s problem allocation buffer\n", __func__); | ||
| 89 | return -ENOMEM; | ||
| 90 | } | ||
| 91 | dev_dbg(&serial->dev->dev, "%s - Privates buffers allocation success\n", __func__); | ||
| 92 | return 0; | ||
| 93 | } | ||
| 94 | |||
| 95 | static int iuu_startup(struct usb_serial *serial) | ||
| 96 | { | 78 | { |
| 97 | struct iuu_private *priv; | 79 | struct iuu_private *priv; |
| 80 | int ret; | ||
| 98 | 81 | ||
| 99 | priv = kzalloc(sizeof(struct iuu_private), GFP_KERNEL); | 82 | priv = kzalloc(sizeof(struct iuu_private), GFP_KERNEL); |
| 100 | dev_dbg(&serial->dev->dev, "%s- priv allocation success\n", __func__); | ||
| 101 | if (!priv) | 83 | if (!priv) |
| 102 | return -ENOMEM; | 84 | return -ENOMEM; |
| 103 | if (iuu_alloc_buf(serial, priv)) { | 85 | |
| 86 | priv->buf = kzalloc(256, GFP_KERNEL); | ||
| 87 | if (!priv->buf) { | ||
| 88 | kfree(priv); | ||
| 89 | return -ENOMEM; | ||
| 90 | } | ||
| 91 | |||
| 92 | priv->writebuf = kzalloc(256, GFP_KERNEL); | ||
| 93 | if (!priv->writebuf) { | ||
| 94 | kfree(priv->buf); | ||
| 104 | kfree(priv); | 95 | kfree(priv); |
| 105 | return -ENOMEM; | 96 | return -ENOMEM; |
| 106 | } | 97 | } |
| 98 | |||
| 107 | priv->vcc = vcc_default; | 99 | priv->vcc = vcc_default; |
| 108 | spin_lock_init(&priv->lock); | 100 | spin_lock_init(&priv->lock); |
| 109 | init_waitqueue_head(&priv->delta_msr_wait); | 101 | init_waitqueue_head(&priv->delta_msr_wait); |
| 110 | usb_set_serial_port_data(serial->port[0], priv); | 102 | |
| 103 | usb_set_serial_port_data(port, priv); | ||
| 104 | |||
| 105 | ret = iuu_create_sysfs_attrs(port); | ||
| 106 | if (ret) { | ||
| 107 | kfree(priv->writebuf); | ||
| 108 | kfree(priv->buf); | ||
| 109 | kfree(priv); | ||
| 110 | return ret; | ||
| 111 | } | ||
| 112 | |||
| 111 | return 0; | 113 | return 0; |
| 112 | } | 114 | } |
| 113 | 115 | ||
| 114 | /* Release function */ | 116 | static int iuu_port_remove(struct usb_serial_port *port) |
| 115 | static void iuu_release(struct usb_serial *serial) | ||
| 116 | { | 117 | { |
| 117 | struct usb_serial_port *port = serial->port[0]; | ||
| 118 | struct iuu_private *priv = usb_get_serial_port_data(port); | 118 | struct iuu_private *priv = usb_get_serial_port_data(port); |
| 119 | if (!port) | ||
| 120 | return; | ||
| 121 | 119 | ||
| 122 | if (priv) { | 120 | iuu_remove_sysfs_attrs(port); |
| 123 | iuu_free_buf(priv); | 121 | kfree(priv->writebuf); |
| 124 | dev_dbg(&port->dev, "%s - I will free all\n", __func__); | 122 | kfree(priv->buf); |
| 125 | usb_set_serial_port_data(port, NULL); | 123 | kfree(priv); |
| 126 | |||
| 127 | dev_dbg(&port->dev, "%s - priv is not anymore in port structure\n", __func__); | ||
| 128 | kfree(priv); | ||
| 129 | 124 | ||
| 130 | dev_dbg(&port->dev, "%s priv is now kfree\n", __func__); | 125 | return 0; |
| 131 | } | ||
| 132 | } | 126 | } |
| 133 | 127 | ||
| 134 | static int iuu_tiocmset(struct tty_struct *tty, | 128 | static int iuu_tiocmset(struct tty_struct *tty, |
| @@ -1215,8 +1209,6 @@ static struct usb_serial_driver iuu_device = { | |||
| 1215 | .num_ports = 1, | 1209 | .num_ports = 1, |
| 1216 | .bulk_in_size = 512, | 1210 | .bulk_in_size = 512, |
| 1217 | .bulk_out_size = 512, | 1211 | .bulk_out_size = 512, |
| 1218 | .port_probe = iuu_create_sysfs_attrs, | ||
| 1219 | .port_remove = iuu_remove_sysfs_attrs, | ||
| 1220 | .open = iuu_open, | 1212 | .open = iuu_open, |
| 1221 | .close = iuu_close, | 1213 | .close = iuu_close, |
| 1222 | .write = iuu_uart_write, | 1214 | .write = iuu_uart_write, |
| @@ -1225,8 +1217,8 @@ static struct usb_serial_driver iuu_device = { | |||
| 1225 | .tiocmset = iuu_tiocmset, | 1217 | .tiocmset = iuu_tiocmset, |
| 1226 | .set_termios = iuu_set_termios, | 1218 | .set_termios = iuu_set_termios, |
| 1227 | .init_termios = iuu_init_termios, | 1219 | .init_termios = iuu_init_termios, |
| 1228 | .attach = iuu_startup, | 1220 | .port_probe = iuu_port_probe, |
| 1229 | .release = iuu_release, | 1221 | .port_remove = iuu_port_remove, |
| 1230 | }; | 1222 | }; |
| 1231 | 1223 | ||
| 1232 | static struct usb_serial_driver * const serial_drivers[] = { | 1224 | static struct usb_serial_driver * const serial_drivers[] = { |
diff --git a/drivers/usb/serial/keyspan.c b/drivers/usb/serial/keyspan.c index 29c943d737d0..cff8dd5b462d 100644 --- a/drivers/usb/serial/keyspan.c +++ b/drivers/usb/serial/keyspan.c | |||
| @@ -1374,13 +1374,9 @@ static struct callbacks { | |||
| 1374 | data in device_details */ | 1374 | data in device_details */ |
| 1375 | static void keyspan_setup_urbs(struct usb_serial *serial) | 1375 | static void keyspan_setup_urbs(struct usb_serial *serial) |
| 1376 | { | 1376 | { |
| 1377 | int i, j; | ||
| 1378 | struct keyspan_serial_private *s_priv; | 1377 | struct keyspan_serial_private *s_priv; |
| 1379 | const struct keyspan_device_details *d_details; | 1378 | const struct keyspan_device_details *d_details; |
| 1380 | struct usb_serial_port *port; | ||
| 1381 | struct keyspan_port_private *p_priv; | ||
| 1382 | struct callbacks *cback; | 1379 | struct callbacks *cback; |
| 1383 | int endp; | ||
| 1384 | 1380 | ||
| 1385 | s_priv = usb_get_serial_data(serial); | 1381 | s_priv = usb_get_serial_data(serial); |
| 1386 | d_details = s_priv->device_details; | 1382 | d_details = s_priv->device_details; |
| @@ -1404,45 +1400,6 @@ static void keyspan_setup_urbs(struct usb_serial *serial) | |||
| 1404 | (serial, d_details->glocont_endpoint, USB_DIR_OUT, | 1400 | (serial, d_details->glocont_endpoint, USB_DIR_OUT, |
| 1405 | serial, s_priv->glocont_buf, GLOCONT_BUFLEN, | 1401 | serial, s_priv->glocont_buf, GLOCONT_BUFLEN, |
| 1406 | cback->glocont_callback); | 1402 | cback->glocont_callback); |
| 1407 | |||
| 1408 | /* Setup endpoints for each port specific thing */ | ||
| 1409 | for (i = 0; i < d_details->num_ports; i++) { | ||
| 1410 | port = serial->port[i]; | ||
| 1411 | p_priv = usb_get_serial_port_data(port); | ||
| 1412 | |||
| 1413 | /* Do indat endpoints first, once for each flip */ | ||
| 1414 | endp = d_details->indat_endpoints[i]; | ||
| 1415 | for (j = 0; j <= d_details->indat_endp_flip; ++j, ++endp) { | ||
| 1416 | p_priv->in_urbs[j] = keyspan_setup_urb | ||
| 1417 | (serial, endp, USB_DIR_IN, port, | ||
| 1418 | p_priv->in_buffer[j], 64, | ||
| 1419 | cback->indat_callback); | ||
| 1420 | } | ||
| 1421 | for (; j < 2; ++j) | ||
| 1422 | p_priv->in_urbs[j] = NULL; | ||
| 1423 | |||
| 1424 | /* outdat endpoints also have flip */ | ||
| 1425 | endp = d_details->outdat_endpoints[i]; | ||
| 1426 | for (j = 0; j <= d_details->outdat_endp_flip; ++j, ++endp) { | ||
| 1427 | p_priv->out_urbs[j] = keyspan_setup_urb | ||
| 1428 | (serial, endp, USB_DIR_OUT, port, | ||
| 1429 | p_priv->out_buffer[j], 64, | ||
| 1430 | cback->outdat_callback); | ||
| 1431 | } | ||
| 1432 | for (; j < 2; ++j) | ||
| 1433 | p_priv->out_urbs[j] = NULL; | ||
| 1434 | |||
| 1435 | /* inack endpoint */ | ||
| 1436 | p_priv->inack_urb = keyspan_setup_urb | ||
| 1437 | (serial, d_details->inack_endpoints[i], USB_DIR_IN, | ||
| 1438 | port, p_priv->inack_buffer, 1, cback->inack_callback); | ||
| 1439 | |||
| 1440 | /* outcont endpoint */ | ||
| 1441 | p_priv->outcont_urb = keyspan_setup_urb | ||
| 1442 | (serial, d_details->outcont_endpoints[i], USB_DIR_OUT, | ||
| 1443 | port, p_priv->outcont_buffer, 64, | ||
| 1444 | cback->outcont_callback); | ||
| 1445 | } | ||
| 1446 | } | 1403 | } |
| 1447 | 1404 | ||
| 1448 | /* usa19 function doesn't require prescaler */ | 1405 | /* usa19 function doesn't require prescaler */ |
| @@ -2407,9 +2364,7 @@ static void keyspan_send_setup(struct usb_serial_port *port, int reset_port) | |||
| 2407 | static int keyspan_startup(struct usb_serial *serial) | 2364 | static int keyspan_startup(struct usb_serial *serial) |
| 2408 | { | 2365 | { |
| 2409 | int i, err; | 2366 | int i, err; |
| 2410 | struct usb_serial_port *port; | ||
| 2411 | struct keyspan_serial_private *s_priv; | 2367 | struct keyspan_serial_private *s_priv; |
| 2412 | struct keyspan_port_private *p_priv; | ||
| 2413 | const struct keyspan_device_details *d_details; | 2368 | const struct keyspan_device_details *d_details; |
| 2414 | 2369 | ||
| 2415 | for (i = 0; (d_details = keyspan_devices[i]) != NULL; ++i) | 2370 | for (i = 0; (d_details = keyspan_devices[i]) != NULL; ++i) |
| @@ -2432,19 +2387,6 @@ static int keyspan_startup(struct usb_serial *serial) | |||
| 2432 | s_priv->device_details = d_details; | 2387 | s_priv->device_details = d_details; |
| 2433 | usb_set_serial_data(serial, s_priv); | 2388 | usb_set_serial_data(serial, s_priv); |
| 2434 | 2389 | ||
| 2435 | /* Now setup per port private data */ | ||
| 2436 | for (i = 0; i < serial->num_ports; i++) { | ||
| 2437 | port = serial->port[i]; | ||
| 2438 | p_priv = kzalloc(sizeof(struct keyspan_port_private), | ||
| 2439 | GFP_KERNEL); | ||
| 2440 | if (!p_priv) { | ||
| 2441 | dev_dbg(&port->dev, "%s - kmalloc for keyspan_port_private (%d) failed!.\n", __func__, i); | ||
| 2442 | return 1; | ||
| 2443 | } | ||
| 2444 | p_priv->device_details = d_details; | ||
| 2445 | usb_set_serial_port_data(port, p_priv); | ||
| 2446 | } | ||
| 2447 | |||
| 2448 | keyspan_setup_urbs(serial); | 2390 | keyspan_setup_urbs(serial); |
| 2449 | 2391 | ||
| 2450 | if (s_priv->instat_urb != NULL) { | 2392 | if (s_priv->instat_urb != NULL) { |
| @@ -2463,59 +2405,111 @@ static int keyspan_startup(struct usb_serial *serial) | |||
| 2463 | 2405 | ||
| 2464 | static void keyspan_disconnect(struct usb_serial *serial) | 2406 | static void keyspan_disconnect(struct usb_serial *serial) |
| 2465 | { | 2407 | { |
| 2466 | int i, j; | 2408 | struct keyspan_serial_private *s_priv; |
| 2467 | struct usb_serial_port *port; | ||
| 2468 | struct keyspan_serial_private *s_priv; | ||
| 2469 | struct keyspan_port_private *p_priv; | ||
| 2470 | 2409 | ||
| 2471 | s_priv = usb_get_serial_data(serial); | 2410 | s_priv = usb_get_serial_data(serial); |
| 2472 | 2411 | ||
| 2473 | /* Stop reading/writing urbs */ | ||
| 2474 | stop_urb(s_priv->instat_urb); | 2412 | stop_urb(s_priv->instat_urb); |
| 2475 | stop_urb(s_priv->glocont_urb); | 2413 | stop_urb(s_priv->glocont_urb); |
| 2476 | stop_urb(s_priv->indat_urb); | 2414 | stop_urb(s_priv->indat_urb); |
| 2477 | for (i = 0; i < serial->num_ports; ++i) { | 2415 | } |
| 2478 | port = serial->port[i]; | 2416 | |
| 2479 | p_priv = usb_get_serial_port_data(port); | 2417 | static void keyspan_release(struct usb_serial *serial) |
| 2480 | stop_urb(p_priv->inack_urb); | 2418 | { |
| 2481 | stop_urb(p_priv->outcont_urb); | 2419 | struct keyspan_serial_private *s_priv; |
| 2482 | for (j = 0; j < 2; j++) { | 2420 | |
| 2483 | stop_urb(p_priv->in_urbs[j]); | 2421 | s_priv = usb_get_serial_data(serial); |
| 2484 | stop_urb(p_priv->out_urbs[j]); | ||
| 2485 | } | ||
| 2486 | } | ||
| 2487 | 2422 | ||
| 2488 | /* Now free them */ | ||
| 2489 | usb_free_urb(s_priv->instat_urb); | 2423 | usb_free_urb(s_priv->instat_urb); |
| 2490 | usb_free_urb(s_priv->indat_urb); | 2424 | usb_free_urb(s_priv->indat_urb); |
| 2491 | usb_free_urb(s_priv->glocont_urb); | 2425 | usb_free_urb(s_priv->glocont_urb); |
| 2492 | for (i = 0; i < serial->num_ports; ++i) { | 2426 | |
| 2493 | port = serial->port[i]; | 2427 | kfree(s_priv); |
| 2494 | p_priv = usb_get_serial_port_data(port); | ||
| 2495 | usb_free_urb(p_priv->inack_urb); | ||
| 2496 | usb_free_urb(p_priv->outcont_urb); | ||
| 2497 | for (j = 0; j < 2; j++) { | ||
| 2498 | usb_free_urb(p_priv->in_urbs[j]); | ||
| 2499 | usb_free_urb(p_priv->out_urbs[j]); | ||
| 2500 | } | ||
| 2501 | } | ||
| 2502 | } | 2428 | } |
| 2503 | 2429 | ||
| 2504 | static void keyspan_release(struct usb_serial *serial) | 2430 | static int keyspan_port_probe(struct usb_serial_port *port) |
| 2505 | { | 2431 | { |
| 2506 | int i; | 2432 | struct usb_serial *serial = port->serial; |
| 2507 | struct usb_serial_port *port; | 2433 | struct keyspan_serial_private *s_priv; |
| 2508 | struct keyspan_serial_private *s_priv; | 2434 | struct keyspan_port_private *p_priv; |
| 2435 | const struct keyspan_device_details *d_details; | ||
| 2436 | struct callbacks *cback; | ||
| 2437 | int endp; | ||
| 2438 | int port_num; | ||
| 2439 | int i; | ||
| 2509 | 2440 | ||
| 2510 | s_priv = usb_get_serial_data(serial); | 2441 | s_priv = usb_get_serial_data(serial); |
| 2442 | d_details = s_priv->device_details; | ||
| 2511 | 2443 | ||
| 2512 | kfree(s_priv); | 2444 | p_priv = kzalloc(sizeof(*p_priv), GFP_KERNEL); |
| 2445 | if (!p_priv) | ||
| 2446 | return -ENOMEM; | ||
| 2513 | 2447 | ||
| 2514 | /* Now free per port private data */ | 2448 | p_priv->device_details = d_details; |
| 2515 | for (i = 0; i < serial->num_ports; i++) { | 2449 | |
| 2516 | port = serial->port[i]; | 2450 | /* Setup values for the various callback routines */ |
| 2517 | kfree(usb_get_serial_port_data(port)); | 2451 | cback = &keyspan_callbacks[d_details->msg_format]; |
| 2452 | |||
| 2453 | port_num = port->number - port->serial->minor; | ||
| 2454 | |||
| 2455 | /* Do indat endpoints first, once for each flip */ | ||
| 2456 | endp = d_details->indat_endpoints[port_num]; | ||
| 2457 | for (i = 0; i <= d_details->indat_endp_flip; ++i, ++endp) { | ||
| 2458 | p_priv->in_urbs[i] = keyspan_setup_urb(serial, endp, | ||
| 2459 | USB_DIR_IN, port, | ||
| 2460 | p_priv->in_buffer[i], 64, | ||
| 2461 | cback->indat_callback); | ||
| 2462 | } | ||
| 2463 | /* outdat endpoints also have flip */ | ||
| 2464 | endp = d_details->outdat_endpoints[port_num]; | ||
| 2465 | for (i = 0; i <= d_details->outdat_endp_flip; ++i, ++endp) { | ||
| 2466 | p_priv->out_urbs[i] = keyspan_setup_urb(serial, endp, | ||
| 2467 | USB_DIR_OUT, port, | ||
| 2468 | p_priv->out_buffer[i], 64, | ||
| 2469 | cback->outdat_callback); | ||
| 2470 | } | ||
| 2471 | /* inack endpoint */ | ||
| 2472 | p_priv->inack_urb = keyspan_setup_urb(serial, | ||
| 2473 | d_details->inack_endpoints[port_num], | ||
| 2474 | USB_DIR_IN, port, | ||
| 2475 | p_priv->inack_buffer, 1, | ||
| 2476 | cback->inack_callback); | ||
| 2477 | /* outcont endpoint */ | ||
| 2478 | p_priv->outcont_urb = keyspan_setup_urb(serial, | ||
| 2479 | d_details->outcont_endpoints[port_num], | ||
| 2480 | USB_DIR_OUT, port, | ||
| 2481 | p_priv->outcont_buffer, 64, | ||
| 2482 | cback->outcont_callback); | ||
| 2483 | |||
| 2484 | usb_set_serial_port_data(port, p_priv); | ||
| 2485 | |||
| 2486 | return 0; | ||
| 2487 | } | ||
| 2488 | |||
| 2489 | static int keyspan_port_remove(struct usb_serial_port *port) | ||
| 2490 | { | ||
| 2491 | struct keyspan_port_private *p_priv; | ||
| 2492 | int i; | ||
| 2493 | |||
| 2494 | p_priv = usb_get_serial_port_data(port); | ||
| 2495 | |||
| 2496 | stop_urb(p_priv->inack_urb); | ||
| 2497 | stop_urb(p_priv->outcont_urb); | ||
| 2498 | for (i = 0; i < 2; i++) { | ||
| 2499 | stop_urb(p_priv->in_urbs[i]); | ||
| 2500 | stop_urb(p_priv->out_urbs[i]); | ||
| 2501 | } | ||
| 2502 | |||
| 2503 | usb_free_urb(p_priv->inack_urb); | ||
| 2504 | usb_free_urb(p_priv->outcont_urb); | ||
| 2505 | for (i = 0; i < 2; i++) { | ||
| 2506 | usb_free_urb(p_priv->in_urbs[i]); | ||
| 2507 | usb_free_urb(p_priv->out_urbs[i]); | ||
| 2518 | } | 2508 | } |
| 2509 | |||
| 2510 | kfree(p_priv); | ||
| 2511 | |||
| 2512 | return 0; | ||
| 2519 | } | 2513 | } |
| 2520 | 2514 | ||
| 2521 | MODULE_AUTHOR(DRIVER_AUTHOR); | 2515 | MODULE_AUTHOR(DRIVER_AUTHOR); |
diff --git a/drivers/usb/serial/keyspan.h b/drivers/usb/serial/keyspan.h index 0a8a40b5711e..0273dda303a4 100644 --- a/drivers/usb/serial/keyspan.h +++ b/drivers/usb/serial/keyspan.h | |||
| @@ -42,6 +42,8 @@ static void keyspan_dtr_rts (struct usb_serial_port *port, int on); | |||
| 42 | static int keyspan_startup (struct usb_serial *serial); | 42 | static int keyspan_startup (struct usb_serial *serial); |
| 43 | static void keyspan_disconnect (struct usb_serial *serial); | 43 | static void keyspan_disconnect (struct usb_serial *serial); |
| 44 | static void keyspan_release (struct usb_serial *serial); | 44 | static void keyspan_release (struct usb_serial *serial); |
| 45 | static int keyspan_port_probe(struct usb_serial_port *port); | ||
| 46 | static int keyspan_port_remove(struct usb_serial_port *port); | ||
| 45 | static int keyspan_write_room (struct tty_struct *tty); | 47 | static int keyspan_write_room (struct tty_struct *tty); |
| 46 | 48 | ||
| 47 | static int keyspan_write (struct tty_struct *tty, | 49 | static int keyspan_write (struct tty_struct *tty, |
| @@ -567,6 +569,8 @@ static struct usb_serial_driver keyspan_1port_device = { | |||
| 567 | .attach = keyspan_startup, | 569 | .attach = keyspan_startup, |
| 568 | .disconnect = keyspan_disconnect, | 570 | .disconnect = keyspan_disconnect, |
| 569 | .release = keyspan_release, | 571 | .release = keyspan_release, |
| 572 | .port_probe = keyspan_port_probe, | ||
| 573 | .port_remove = keyspan_port_remove, | ||
| 570 | }; | 574 | }; |
| 571 | 575 | ||
| 572 | static struct usb_serial_driver keyspan_2port_device = { | 576 | static struct usb_serial_driver keyspan_2port_device = { |
| @@ -589,6 +593,8 @@ static struct usb_serial_driver keyspan_2port_device = { | |||
| 589 | .attach = keyspan_startup, | 593 | .attach = keyspan_startup, |
| 590 | .disconnect = keyspan_disconnect, | 594 | .disconnect = keyspan_disconnect, |
| 591 | .release = keyspan_release, | 595 | .release = keyspan_release, |
| 596 | .port_probe = keyspan_port_probe, | ||
| 597 | .port_remove = keyspan_port_remove, | ||
| 592 | }; | 598 | }; |
| 593 | 599 | ||
| 594 | static struct usb_serial_driver keyspan_4port_device = { | 600 | static struct usb_serial_driver keyspan_4port_device = { |
| @@ -611,6 +617,8 @@ static struct usb_serial_driver keyspan_4port_device = { | |||
| 611 | .attach = keyspan_startup, | 617 | .attach = keyspan_startup, |
| 612 | .disconnect = keyspan_disconnect, | 618 | .disconnect = keyspan_disconnect, |
| 613 | .release = keyspan_release, | 619 | .release = keyspan_release, |
| 620 | .port_probe = keyspan_port_probe, | ||
| 621 | .port_remove = keyspan_port_remove, | ||
| 614 | }; | 622 | }; |
| 615 | 623 | ||
| 616 | static struct usb_serial_driver * const serial_drivers[] = { | 624 | static struct usb_serial_driver * const serial_drivers[] = { |
diff --git a/drivers/usb/serial/keyspan_pda.c b/drivers/usb/serial/keyspan_pda.c index ca43ecb4a2bd..bb87e29c4ac2 100644 --- a/drivers/usb/serial/keyspan_pda.c +++ b/drivers/usb/serial/keyspan_pda.c | |||
| @@ -713,29 +713,33 @@ MODULE_FIRMWARE("keyspan_pda/keyspan_pda.fw"); | |||
| 713 | MODULE_FIRMWARE("keyspan_pda/xircom_pgs.fw"); | 713 | MODULE_FIRMWARE("keyspan_pda/xircom_pgs.fw"); |
| 714 | #endif | 714 | #endif |
| 715 | 715 | ||
| 716 | static int keyspan_pda_startup(struct usb_serial *serial) | 716 | static int keyspan_pda_port_probe(struct usb_serial_port *port) |
| 717 | { | 717 | { |
| 718 | 718 | ||
| 719 | struct keyspan_pda_private *priv; | 719 | struct keyspan_pda_private *priv; |
| 720 | 720 | ||
| 721 | /* allocate the private data structures for all ports. Well, for all | ||
| 722 | one ports. */ | ||
| 723 | |||
| 724 | priv = kmalloc(sizeof(struct keyspan_pda_private), GFP_KERNEL); | 721 | priv = kmalloc(sizeof(struct keyspan_pda_private), GFP_KERNEL); |
| 725 | if (!priv) | 722 | if (!priv) |
| 726 | return 1; /* error */ | 723 | return -ENOMEM; |
| 727 | usb_set_serial_port_data(serial->port[0], priv); | 724 | |
| 728 | init_waitqueue_head(&serial->port[0]->write_wait); | ||
| 729 | INIT_WORK(&priv->wakeup_work, keyspan_pda_wakeup_write); | 725 | INIT_WORK(&priv->wakeup_work, keyspan_pda_wakeup_write); |
| 730 | INIT_WORK(&priv->unthrottle_work, keyspan_pda_request_unthrottle); | 726 | INIT_WORK(&priv->unthrottle_work, keyspan_pda_request_unthrottle); |
| 731 | priv->serial = serial; | 727 | priv->serial = port->serial; |
| 732 | priv->port = serial->port[0]; | 728 | priv->port = port; |
| 729 | |||
| 730 | usb_set_serial_port_data(port, priv); | ||
| 731 | |||
| 733 | return 0; | 732 | return 0; |
| 734 | } | 733 | } |
| 735 | 734 | ||
| 736 | static void keyspan_pda_release(struct usb_serial *serial) | 735 | static int keyspan_pda_port_remove(struct usb_serial_port *port) |
| 737 | { | 736 | { |
| 738 | kfree(usb_get_serial_port_data(serial->port[0])); | 737 | struct keyspan_pda_private *priv; |
| 738 | |||
| 739 | priv = usb_get_serial_port_data(port); | ||
| 740 | kfree(priv); | ||
| 741 | |||
| 742 | return 0; | ||
| 739 | } | 743 | } |
| 740 | 744 | ||
| 741 | #ifdef KEYSPAN | 745 | #ifdef KEYSPAN |
| @@ -786,8 +790,8 @@ static struct usb_serial_driver keyspan_pda_device = { | |||
| 786 | .break_ctl = keyspan_pda_break_ctl, | 790 | .break_ctl = keyspan_pda_break_ctl, |
| 787 | .tiocmget = keyspan_pda_tiocmget, | 791 | .tiocmget = keyspan_pda_tiocmget, |
| 788 | .tiocmset = keyspan_pda_tiocmset, | 792 | .tiocmset = keyspan_pda_tiocmset, |
| 789 | .attach = keyspan_pda_startup, | 793 | .port_probe = keyspan_pda_port_probe, |
| 790 | .release = keyspan_pda_release, | 794 | .port_remove = keyspan_pda_port_remove, |
| 791 | }; | 795 | }; |
| 792 | 796 | ||
| 793 | static struct usb_serial_driver * const serial_drivers[] = { | 797 | static struct usb_serial_driver * const serial_drivers[] = { |
diff --git a/drivers/usb/serial/kl5kusb105.c b/drivers/usb/serial/kl5kusb105.c index 3f6d7376c02d..1f4517864cd2 100644 --- a/drivers/usb/serial/kl5kusb105.c +++ b/drivers/usb/serial/kl5kusb105.c | |||
| @@ -60,8 +60,8 @@ | |||
| 60 | /* | 60 | /* |
| 61 | * Function prototypes | 61 | * Function prototypes |
| 62 | */ | 62 | */ |
| 63 | static int klsi_105_startup(struct usb_serial *serial); | 63 | static int klsi_105_port_probe(struct usb_serial_port *port); |
| 64 | static void klsi_105_release(struct usb_serial *serial); | 64 | static int klsi_105_port_remove(struct usb_serial_port *port); |
| 65 | static int klsi_105_open(struct tty_struct *tty, struct usb_serial_port *port); | 65 | static int klsi_105_open(struct tty_struct *tty, struct usb_serial_port *port); |
| 66 | static void klsi_105_close(struct usb_serial_port *port); | 66 | static void klsi_105_close(struct usb_serial_port *port); |
| 67 | static void klsi_105_set_termios(struct tty_struct *tty, | 67 | static void klsi_105_set_termios(struct tty_struct *tty, |
| @@ -99,8 +99,8 @@ static struct usb_serial_driver kl5kusb105d_device = { | |||
| 99 | /*.break_ctl = klsi_105_break_ctl,*/ | 99 | /*.break_ctl = klsi_105_break_ctl,*/ |
| 100 | .tiocmget = klsi_105_tiocmget, | 100 | .tiocmget = klsi_105_tiocmget, |
| 101 | .tiocmset = klsi_105_tiocmset, | 101 | .tiocmset = klsi_105_tiocmset, |
| 102 | .attach = klsi_105_startup, | 102 | .port_probe = klsi_105_port_probe, |
| 103 | .release = klsi_105_release, | 103 | .port_remove = klsi_105_port_remove, |
| 104 | .throttle = usb_serial_generic_throttle, | 104 | .throttle = usb_serial_generic_throttle, |
| 105 | .unthrottle = usb_serial_generic_unthrottle, | 105 | .unthrottle = usb_serial_generic_unthrottle, |
| 106 | .process_read_urb = klsi_105_process_read_urb, | 106 | .process_read_urb = klsi_105_process_read_urb, |
| @@ -223,60 +223,40 @@ static int klsi_105_get_line_state(struct usb_serial_port *port, | |||
| 223 | * Driver's tty interface functions | 223 | * Driver's tty interface functions |
| 224 | */ | 224 | */ |
| 225 | 225 | ||
| 226 | static int klsi_105_startup(struct usb_serial *serial) | 226 | static int klsi_105_port_probe(struct usb_serial_port *port) |
| 227 | { | 227 | { |
| 228 | struct klsi_105_private *priv; | 228 | struct klsi_105_private *priv; |
| 229 | int i; | ||
| 230 | 229 | ||
| 231 | /* check if we support the product id (see keyspan.c) | 230 | priv = kmalloc(sizeof(*priv), GFP_KERNEL); |
| 232 | * FIXME | 231 | if (!priv) |
| 233 | */ | 232 | return -ENOMEM; |
| 234 | 233 | ||
| 235 | /* allocate the private data structure */ | 234 | /* set initial values for control structures */ |
| 236 | for (i = 0; i < serial->num_ports; i++) { | 235 | priv->cfg.pktlen = 5; |
| 237 | priv = kmalloc(sizeof(struct klsi_105_private), | 236 | priv->cfg.baudrate = kl5kusb105a_sio_b9600; |
| 238 | GFP_KERNEL); | 237 | priv->cfg.databits = kl5kusb105a_dtb_8; |
| 239 | if (!priv) { | 238 | priv->cfg.unknown1 = 0; |
| 240 | dev_dbg(&serial->interface->dev, | 239 | priv->cfg.unknown2 = 1; |
| 241 | "%s - kmalloc for klsi_105_private failed.\n", | ||
| 242 | __func__); | ||
| 243 | i--; | ||
| 244 | goto err_cleanup; | ||
| 245 | } | ||
| 246 | /* set initial values for control structures */ | ||
| 247 | priv->cfg.pktlen = 5; | ||
| 248 | priv->cfg.baudrate = kl5kusb105a_sio_b9600; | ||
| 249 | priv->cfg.databits = kl5kusb105a_dtb_8; | ||
| 250 | priv->cfg.unknown1 = 0; | ||
| 251 | priv->cfg.unknown2 = 1; | ||
| 252 | 240 | ||
| 253 | priv->line_state = 0; | 241 | priv->line_state = 0; |
| 254 | 242 | ||
| 255 | usb_set_serial_port_data(serial->port[i], priv); | 243 | spin_lock_init(&priv->lock); |
| 256 | 244 | ||
| 257 | spin_lock_init(&priv->lock); | 245 | /* priv->termios is left uninitialized until port opening */ |
| 258 | 246 | ||
| 259 | /* priv->termios is left uninitialized until port opening */ | 247 | usb_set_serial_port_data(port, priv); |
| 260 | init_waitqueue_head(&serial->port[i]->write_wait); | ||
| 261 | } | ||
| 262 | 248 | ||
| 263 | return 0; | 249 | return 0; |
| 264 | |||
| 265 | err_cleanup: | ||
| 266 | for (; i >= 0; i--) { | ||
| 267 | priv = usb_get_serial_port_data(serial->port[i]); | ||
| 268 | kfree(priv); | ||
| 269 | usb_set_serial_port_data(serial->port[i], NULL); | ||
| 270 | } | ||
| 271 | return -ENOMEM; | ||
| 272 | } | 250 | } |
| 273 | 251 | ||
| 274 | static void klsi_105_release(struct usb_serial *serial) | 252 | static int klsi_105_port_remove(struct usb_serial_port *port) |
| 275 | { | 253 | { |
| 276 | int i; | 254 | struct klsi_105_private *priv; |
| 255 | |||
| 256 | priv = usb_get_serial_port_data(port); | ||
| 257 | kfree(priv); | ||
| 277 | 258 | ||
| 278 | for (i = 0; i < serial->num_ports; ++i) | 259 | return 0; |
| 279 | kfree(usb_get_serial_port_data(serial->port[i])); | ||
| 280 | } | 260 | } |
| 281 | 261 | ||
| 282 | static int klsi_105_open(struct tty_struct *tty, struct usb_serial_port *port) | 262 | static int klsi_105_open(struct tty_struct *tty, struct usb_serial_port *port) |
diff --git a/drivers/usb/serial/kobil_sct.c b/drivers/usb/serial/kobil_sct.c index 5c4d2fbd4e11..c9ca7a5b12e0 100644 --- a/drivers/usb/serial/kobil_sct.c +++ b/drivers/usb/serial/kobil_sct.c | |||
| @@ -54,8 +54,8 @@ | |||
| 54 | 54 | ||
| 55 | 55 | ||
| 56 | /* Function prototypes */ | 56 | /* Function prototypes */ |
| 57 | static int kobil_startup(struct usb_serial *serial); | 57 | static int kobil_port_probe(struct usb_serial_port *probe); |
| 58 | static void kobil_release(struct usb_serial *serial); | 58 | static int kobil_port_remove(struct usb_serial_port *probe); |
| 59 | static int kobil_open(struct tty_struct *tty, struct usb_serial_port *port); | 59 | static int kobil_open(struct tty_struct *tty, struct usb_serial_port *port); |
| 60 | static void kobil_close(struct usb_serial_port *port); | 60 | static void kobil_close(struct usb_serial_port *port); |
| 61 | static int kobil_write(struct tty_struct *tty, struct usb_serial_port *port, | 61 | static int kobil_write(struct tty_struct *tty, struct usb_serial_port *port, |
| @@ -89,8 +89,8 @@ static struct usb_serial_driver kobil_device = { | |||
| 89 | .description = "KOBIL USB smart card terminal", | 89 | .description = "KOBIL USB smart card terminal", |
| 90 | .id_table = id_table, | 90 | .id_table = id_table, |
| 91 | .num_ports = 1, | 91 | .num_ports = 1, |
| 92 | .attach = kobil_startup, | 92 | .port_probe = kobil_port_probe, |
| 93 | .release = kobil_release, | 93 | .port_remove = kobil_port_remove, |
| 94 | .ioctl = kobil_ioctl, | 94 | .ioctl = kobil_ioctl, |
| 95 | .set_termios = kobil_set_termios, | 95 | .set_termios = kobil_set_termios, |
| 96 | .init_termios = kobil_init_termios, | 96 | .init_termios = kobil_init_termios, |
| @@ -117,9 +117,10 @@ struct kobil_private { | |||
| 117 | }; | 117 | }; |
| 118 | 118 | ||
| 119 | 119 | ||
| 120 | static int kobil_startup(struct usb_serial *serial) | 120 | static int kobil_port_probe(struct usb_serial_port *port) |
| 121 | { | 121 | { |
| 122 | int i; | 122 | int i; |
| 123 | struct usb_serial *serial = port->serial; | ||
| 123 | struct kobil_private *priv; | 124 | struct kobil_private *priv; |
| 124 | struct usb_device *pdev; | 125 | struct usb_device *pdev; |
| 125 | struct usb_host_config *actconfig; | 126 | struct usb_host_config *actconfig; |
| @@ -149,7 +150,7 @@ static int kobil_startup(struct usb_serial *serial) | |||
| 149 | dev_dbg(&serial->dev->dev, "KOBIL KAAN SIM detected\n"); | 150 | dev_dbg(&serial->dev->dev, "KOBIL KAAN SIM detected\n"); |
| 150 | break; | 151 | break; |
| 151 | } | 152 | } |
| 152 | usb_set_serial_port_data(serial->port[0], priv); | 153 | usb_set_serial_port_data(port, priv); |
| 153 | 154 | ||
| 154 | /* search for the necessary endpoints */ | 155 | /* search for the necessary endpoints */ |
| 155 | pdev = serial->dev; | 156 | pdev = serial->dev; |
| @@ -179,12 +180,14 @@ static int kobil_startup(struct usb_serial *serial) | |||
| 179 | } | 180 | } |
| 180 | 181 | ||
| 181 | 182 | ||
| 182 | static void kobil_release(struct usb_serial *serial) | 183 | static int kobil_port_remove(struct usb_serial_port *port) |
| 183 | { | 184 | { |
| 184 | int i; | 185 | struct kobil_private *priv; |
| 185 | 186 | ||
| 186 | for (i = 0; i < serial->num_ports; ++i) | 187 | priv = usb_get_serial_port_data(port); |
| 187 | kfree(usb_get_serial_port_data(serial->port[i])); | 188 | kfree(priv); |
| 189 | |||
| 190 | return 0; | ||
| 188 | } | 191 | } |
| 189 | 192 | ||
| 190 | static void kobil_init_termios(struct tty_struct *tty) | 193 | static void kobil_init_termios(struct tty_struct *tty) |
diff --git a/drivers/usb/serial/mct_u232.c b/drivers/usb/serial/mct_u232.c index f3947712e137..8a2081004107 100644 --- a/drivers/usb/serial/mct_u232.c +++ b/drivers/usb/serial/mct_u232.c | |||
| @@ -49,7 +49,8 @@ | |||
| 49 | * Function prototypes | 49 | * Function prototypes |
| 50 | */ | 50 | */ |
| 51 | static int mct_u232_startup(struct usb_serial *serial); | 51 | static int mct_u232_startup(struct usb_serial *serial); |
| 52 | static void mct_u232_release(struct usb_serial *serial); | 52 | static int mct_u232_port_probe(struct usb_serial_port *port); |
| 53 | static int mct_u232_port_remove(struct usb_serial_port *remove); | ||
| 53 | static int mct_u232_open(struct tty_struct *tty, struct usb_serial_port *port); | 54 | static int mct_u232_open(struct tty_struct *tty, struct usb_serial_port *port); |
| 54 | static void mct_u232_close(struct usb_serial_port *port); | 55 | static void mct_u232_close(struct usb_serial_port *port); |
| 55 | static void mct_u232_dtr_rts(struct usb_serial_port *port, int on); | 56 | static void mct_u232_dtr_rts(struct usb_serial_port *port, int on); |
| @@ -99,7 +100,8 @@ static struct usb_serial_driver mct_u232_device = { | |||
| 99 | .tiocmget = mct_u232_tiocmget, | 100 | .tiocmget = mct_u232_tiocmget, |
| 100 | .tiocmset = mct_u232_tiocmset, | 101 | .tiocmset = mct_u232_tiocmset, |
| 101 | .attach = mct_u232_startup, | 102 | .attach = mct_u232_startup, |
| 102 | .release = mct_u232_release, | 103 | .port_probe = mct_u232_port_probe, |
| 104 | .port_remove = mct_u232_port_remove, | ||
| 103 | .ioctl = mct_u232_ioctl, | 105 | .ioctl = mct_u232_ioctl, |
| 104 | .get_icount = mct_u232_get_icount, | 106 | .get_icount = mct_u232_get_icount, |
| 105 | }; | 107 | }; |
| @@ -388,18 +390,8 @@ static void mct_u232_msr_to_state(struct usb_serial_port *port, | |||
| 388 | 390 | ||
| 389 | static int mct_u232_startup(struct usb_serial *serial) | 391 | static int mct_u232_startup(struct usb_serial *serial) |
| 390 | { | 392 | { |
| 391 | struct mct_u232_private *priv; | ||
| 392 | struct usb_serial_port *port, *rport; | 393 | struct usb_serial_port *port, *rport; |
| 393 | 394 | ||
| 394 | priv = kzalloc(sizeof(struct mct_u232_private), GFP_KERNEL); | ||
| 395 | if (!priv) | ||
| 396 | return -ENOMEM; | ||
| 397 | spin_lock_init(&priv->lock); | ||
| 398 | init_waitqueue_head(&priv->msr_wait); | ||
| 399 | usb_set_serial_port_data(serial->port[0], priv); | ||
| 400 | |||
| 401 | init_waitqueue_head(&serial->port[0]->write_wait); | ||
| 402 | |||
| 403 | /* Puh, that's dirty */ | 395 | /* Puh, that's dirty */ |
| 404 | port = serial->port[0]; | 396 | port = serial->port[0]; |
| 405 | rport = serial->port[1]; | 397 | rport = serial->port[1]; |
| @@ -412,18 +404,31 @@ static int mct_u232_startup(struct usb_serial *serial) | |||
| 412 | return 0; | 404 | return 0; |
| 413 | } /* mct_u232_startup */ | 405 | } /* mct_u232_startup */ |
| 414 | 406 | ||
| 407 | static int mct_u232_port_probe(struct usb_serial_port *port) | ||
| 408 | { | ||
| 409 | struct mct_u232_private *priv; | ||
| 410 | |||
| 411 | priv = kzalloc(sizeof(*priv), GFP_KERNEL); | ||
| 412 | if (!priv) | ||
| 413 | return -ENOMEM; | ||
| 414 | |||
| 415 | spin_lock_init(&priv->lock); | ||
| 416 | init_waitqueue_head(&priv->msr_wait); | ||
| 417 | |||
| 418 | usb_set_serial_port_data(port, priv); | ||
| 415 | 419 | ||
| 416 | static void mct_u232_release(struct usb_serial *serial) | 420 | return 0; |
| 421 | } | ||
| 422 | |||
| 423 | static int mct_u232_port_remove(struct usb_serial_port *port) | ||
| 417 | { | 424 | { |
| 418 | struct mct_u232_private *priv; | 425 | struct mct_u232_private *priv; |
| 419 | int i; | ||
| 420 | 426 | ||
| 421 | for (i = 0; i < serial->num_ports; ++i) { | 427 | priv = usb_get_serial_port_data(port); |
| 422 | /* My special items, the standard routines free my urbs */ | 428 | kfree(priv); |
| 423 | priv = usb_get_serial_port_data(serial->port[i]); | 429 | |
| 424 | kfree(priv); | 430 | return 0; |
| 425 | } | 431 | } |
| 426 | } /* mct_u232_release */ | ||
| 427 | 432 | ||
| 428 | static int mct_u232_open(struct tty_struct *tty, struct usb_serial_port *port) | 433 | static int mct_u232_open(struct tty_struct *tty, struct usb_serial_port *port) |
| 429 | { | 434 | { |
| @@ -515,12 +520,14 @@ static void mct_u232_dtr_rts(struct usb_serial_port *port, int on) | |||
| 515 | 520 | ||
| 516 | static void mct_u232_close(struct usb_serial_port *port) | 521 | static void mct_u232_close(struct usb_serial_port *port) |
| 517 | { | 522 | { |
| 518 | if (port->serial->dev) { | 523 | /* |
| 519 | /* shutdown our urbs */ | 524 | * Must kill the read urb as it is actually an interrupt urb, which |
| 520 | usb_kill_urb(port->write_urb); | 525 | * generic close thus fails to kill. |
| 521 | usb_kill_urb(port->read_urb); | 526 | */ |
| 522 | usb_kill_urb(port->interrupt_in_urb); | 527 | usb_kill_urb(port->read_urb); |
| 523 | } | 528 | usb_kill_urb(port->interrupt_in_urb); |
| 529 | |||
| 530 | usb_serial_generic_close(port); | ||
| 524 | } /* mct_u232_close */ | 531 | } /* mct_u232_close */ |
| 525 | 532 | ||
| 526 | 533 | ||
diff --git a/drivers/usb/serial/metro-usb.c b/drivers/usb/serial/metro-usb.c index 0b257ddffbdb..6f29c74eb769 100644 --- a/drivers/usb/serial/metro-usb.c +++ b/drivers/usb/serial/metro-usb.c | |||
| @@ -179,16 +179,13 @@ static void metrousb_cleanup(struct usb_serial_port *port) | |||
| 179 | { | 179 | { |
| 180 | dev_dbg(&port->dev, "%s\n", __func__); | 180 | dev_dbg(&port->dev, "%s\n", __func__); |
| 181 | 181 | ||
| 182 | if (port->serial->dev) { | 182 | usb_unlink_urb(port->interrupt_in_urb); |
| 183 | /* Shutdown any interrupt in urbs. */ | 183 | usb_kill_urb(port->interrupt_in_urb); |
| 184 | if (port->interrupt_in_urb) { | 184 | |
| 185 | usb_unlink_urb(port->interrupt_in_urb); | 185 | mutex_lock(&port->serial->disc_mutex); |
| 186 | usb_kill_urb(port->interrupt_in_urb); | 186 | if (!port->serial->disconnected) |
| 187 | } | ||
| 188 | |||
| 189 | /* Send deactivate cmd to device */ | ||
| 190 | metrousb_send_unidirectional_cmd(UNI_CMD_CLOSE, port); | 187 | metrousb_send_unidirectional_cmd(UNI_CMD_CLOSE, port); |
| 191 | } | 188 | mutex_unlock(&port->serial->disc_mutex); |
| 192 | } | 189 | } |
| 193 | 190 | ||
| 194 | static int metrousb_open(struct tty_struct *tty, struct usb_serial_port *port) | 191 | static int metrousb_open(struct tty_struct *tty, struct usb_serial_port *port) |
| @@ -271,51 +268,27 @@ static int metrousb_set_modem_ctrl(struct usb_serial *serial, unsigned int contr | |||
| 271 | return retval; | 268 | return retval; |
| 272 | } | 269 | } |
| 273 | 270 | ||
| 274 | static void metrousb_shutdown(struct usb_serial *serial) | 271 | static int metrousb_port_probe(struct usb_serial_port *port) |
| 275 | { | 272 | { |
| 276 | int i = 0; | 273 | struct metrousb_private *metro_priv; |
| 277 | 274 | ||
| 278 | dev_dbg(&serial->dev->dev, "%s\n", __func__); | 275 | metro_priv = kzalloc(sizeof(*metro_priv), GFP_KERNEL); |
| 276 | if (!metro_priv) | ||
| 277 | return -ENOMEM; | ||
| 279 | 278 | ||
| 280 | /* Stop reading and writing on all ports. */ | 279 | spin_lock_init(&metro_priv->lock); |
| 281 | for (i = 0; i < serial->num_ports; ++i) { | ||
| 282 | /* Close any open urbs. */ | ||
| 283 | metrousb_cleanup(serial->port[i]); | ||
| 284 | 280 | ||
| 285 | /* Free memory. */ | 281 | usb_set_serial_port_data(port, metro_priv); |
| 286 | kfree(usb_get_serial_port_data(serial->port[i])); | ||
| 287 | usb_set_serial_port_data(serial->port[i], NULL); | ||
| 288 | 282 | ||
| 289 | dev_dbg(&serial->dev->dev, "%s - freed port number=%d\n", | 283 | return 0; |
| 290 | __func__, serial->port[i]->number); | ||
| 291 | } | ||
| 292 | } | 284 | } |
| 293 | 285 | ||
| 294 | static int metrousb_startup(struct usb_serial *serial) | 286 | static int metrousb_port_remove(struct usb_serial_port *port) |
| 295 | { | 287 | { |
| 296 | struct metrousb_private *metro_priv; | 288 | struct metrousb_private *metro_priv; |
| 297 | struct usb_serial_port *port; | ||
| 298 | int i = 0; | ||
| 299 | 289 | ||
| 300 | dev_dbg(&serial->dev->dev, "%s\n", __func__); | 290 | metro_priv = usb_get_serial_port_data(port); |
| 301 | 291 | kfree(metro_priv); | |
| 302 | /* Loop through the serial ports setting up the private structures. | ||
| 303 | * Currently we only use one port. */ | ||
| 304 | for (i = 0; i < serial->num_ports; ++i) { | ||
| 305 | port = serial->port[i]; | ||
| 306 | |||
| 307 | /* Declare memory. */ | ||
| 308 | metro_priv = kzalloc(sizeof(struct metrousb_private), GFP_KERNEL); | ||
| 309 | if (!metro_priv) | ||
| 310 | return -ENOMEM; | ||
| 311 | |||
| 312 | /* Initialize memory. */ | ||
| 313 | spin_lock_init(&metro_priv->lock); | ||
| 314 | usb_set_serial_port_data(port, metro_priv); | ||
| 315 | |||
| 316 | dev_dbg(&serial->dev->dev, "%s - port number=%d\n ", | ||
| 317 | __func__, port->number); | ||
| 318 | } | ||
| 319 | 292 | ||
| 320 | return 0; | 293 | return 0; |
| 321 | } | 294 | } |
| @@ -414,8 +387,8 @@ static struct usb_serial_driver metrousb_device = { | |||
| 414 | .close = metrousb_cleanup, | 387 | .close = metrousb_cleanup, |
| 415 | .read_int_callback = metrousb_read_int_callback, | 388 | .read_int_callback = metrousb_read_int_callback, |
| 416 | .write_int_callback = metrousb_write_int_callback, | 389 | .write_int_callback = metrousb_write_int_callback, |
| 417 | .attach = metrousb_startup, | 390 | .port_probe = metrousb_port_probe, |
| 418 | .release = metrousb_shutdown, | 391 | .port_remove = metrousb_port_remove, |
| 419 | .throttle = metrousb_throttle, | 392 | .throttle = metrousb_throttle, |
| 420 | .unthrottle = metrousb_unthrottle, | 393 | .unthrottle = metrousb_unthrottle, |
| 421 | .tiocmget = metrousb_tiocmget, | 394 | .tiocmget = metrousb_tiocmget, |
diff --git a/drivers/usb/serial/mos7720.c b/drivers/usb/serial/mos7720.c index 1bf1ad066666..75267421aad8 100644 --- a/drivers/usb/serial/mos7720.c +++ b/drivers/usb/serial/mos7720.c | |||
| @@ -1966,9 +1966,7 @@ static int mos7720_ioctl(struct tty_struct *tty, | |||
| 1966 | 1966 | ||
| 1967 | static int mos7720_startup(struct usb_serial *serial) | 1967 | static int mos7720_startup(struct usb_serial *serial) |
| 1968 | { | 1968 | { |
| 1969 | struct moschip_port *mos7720_port; | ||
| 1970 | struct usb_device *dev; | 1969 | struct usb_device *dev; |
| 1971 | int i; | ||
| 1972 | char data; | 1970 | char data; |
| 1973 | u16 product; | 1971 | u16 product; |
| 1974 | int ret_val; | 1972 | int ret_val; |
| @@ -1999,29 +1997,6 @@ static int mos7720_startup(struct usb_serial *serial) | |||
| 1999 | serial->port[1]->interrupt_in_buffer = NULL; | 1997 | serial->port[1]->interrupt_in_buffer = NULL; |
| 2000 | } | 1998 | } |
| 2001 | 1999 | ||
| 2002 | |||
| 2003 | /* set up serial port private structures */ | ||
| 2004 | for (i = 0; i < serial->num_ports; ++i) { | ||
| 2005 | mos7720_port = kzalloc(sizeof(struct moschip_port), GFP_KERNEL); | ||
| 2006 | if (mos7720_port == NULL) { | ||
| 2007 | dev_err(&dev->dev, "%s - Out of memory\n", __func__); | ||
| 2008 | return -ENOMEM; | ||
| 2009 | } | ||
| 2010 | |||
| 2011 | /* Initialize all port interrupt end point to port 0 int | ||
| 2012 | * endpoint. Our device has only one interrupt endpoint | ||
| 2013 | * common to all ports */ | ||
| 2014 | serial->port[i]->interrupt_in_endpointAddress = | ||
| 2015 | serial->port[0]->interrupt_in_endpointAddress; | ||
| 2016 | |||
| 2017 | mos7720_port->port = serial->port[i]; | ||
| 2018 | usb_set_serial_port_data(serial->port[i], mos7720_port); | ||
| 2019 | |||
| 2020 | dev_dbg(&dev->dev, "port number is %d\n", serial->port[i]->number); | ||
| 2021 | dev_dbg(&dev->dev, "serial number is %d\n", serial->minor); | ||
| 2022 | } | ||
| 2023 | |||
| 2024 | |||
| 2025 | /* setting configuration feature to one */ | 2000 | /* setting configuration feature to one */ |
| 2026 | usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0), | 2001 | usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0), |
| 2027 | (__u8)0x03, 0x00, 0x01, 0x00, NULL, 0x00, 5*HZ); | 2002 | (__u8)0x03, 0x00, 0x01, 0x00, NULL, 0x00, 5*HZ); |
| @@ -2049,8 +2024,6 @@ static int mos7720_startup(struct usb_serial *serial) | |||
| 2049 | 2024 | ||
| 2050 | static void mos7720_release(struct usb_serial *serial) | 2025 | static void mos7720_release(struct usb_serial *serial) |
| 2051 | { | 2026 | { |
| 2052 | int i; | ||
| 2053 | |||
| 2054 | #ifdef CONFIG_USB_SERIAL_MOS7715_PARPORT | 2027 | #ifdef CONFIG_USB_SERIAL_MOS7715_PARPORT |
| 2055 | /* close the parallel port */ | 2028 | /* close the parallel port */ |
| 2056 | 2029 | ||
| @@ -2089,9 +2062,36 @@ static void mos7720_release(struct usb_serial *serial) | |||
| 2089 | kref_put(&mos_parport->ref_count, destroy_mos_parport); | 2062 | kref_put(&mos_parport->ref_count, destroy_mos_parport); |
| 2090 | } | 2063 | } |
| 2091 | #endif | 2064 | #endif |
| 2092 | /* free private structure allocated for serial port */ | 2065 | } |
| 2093 | for (i = 0; i < serial->num_ports; ++i) | 2066 | |
| 2094 | kfree(usb_get_serial_port_data(serial->port[i])); | 2067 | static int mos7720_port_probe(struct usb_serial_port *port) |
| 2068 | { | ||
| 2069 | struct moschip_port *mos7720_port; | ||
| 2070 | |||
| 2071 | mos7720_port = kzalloc(sizeof(*mos7720_port), GFP_KERNEL); | ||
| 2072 | if (!mos7720_port) | ||
| 2073 | return -ENOMEM; | ||
| 2074 | |||
| 2075 | /* Initialize all port interrupt end point to port 0 int endpoint. | ||
| 2076 | * Our device has only one interrupt endpoint common to all ports. | ||
| 2077 | */ | ||
| 2078 | port->interrupt_in_endpointAddress = | ||
| 2079 | port->serial->port[0]->interrupt_in_endpointAddress; | ||
| 2080 | mos7720_port->port = port; | ||
| 2081 | |||
| 2082 | usb_set_serial_port_data(port, mos7720_port); | ||
| 2083 | |||
| 2084 | return 0; | ||
| 2085 | } | ||
| 2086 | |||
| 2087 | static int mos7720_port_remove(struct usb_serial_port *port) | ||
| 2088 | { | ||
| 2089 | struct moschip_port *mos7720_port; | ||
| 2090 | |||
| 2091 | mos7720_port = usb_get_serial_port_data(port); | ||
| 2092 | kfree(mos7720_port); | ||
| 2093 | |||
| 2094 | return 0; | ||
| 2095 | } | 2095 | } |
| 2096 | 2096 | ||
| 2097 | static struct usb_serial_driver moschip7720_2port_driver = { | 2097 | static struct usb_serial_driver moschip7720_2port_driver = { |
| @@ -2109,6 +2109,8 @@ static struct usb_serial_driver moschip7720_2port_driver = { | |||
| 2109 | .probe = mos77xx_probe, | 2109 | .probe = mos77xx_probe, |
| 2110 | .attach = mos7720_startup, | 2110 | .attach = mos7720_startup, |
| 2111 | .release = mos7720_release, | 2111 | .release = mos7720_release, |
| 2112 | .port_probe = mos7720_port_probe, | ||
| 2113 | .port_remove = mos7720_port_remove, | ||
| 2112 | .ioctl = mos7720_ioctl, | 2114 | .ioctl = mos7720_ioctl, |
| 2113 | .tiocmget = mos7720_tiocmget, | 2115 | .tiocmget = mos7720_tiocmget, |
| 2114 | .tiocmset = mos7720_tiocmset, | 2116 | .tiocmset = mos7720_tiocmset, |
diff --git a/drivers/usb/serial/mos7840.c b/drivers/usb/serial/mos7840.c index d6d4eeca8c68..1cf3375ec1af 100644 --- a/drivers/usb/serial/mos7840.c +++ b/drivers/usb/serial/mos7840.c | |||
| @@ -218,12 +218,10 @@ struct moschip_port { | |||
| 218 | int port_num; /*Actual port number in the device(1,2,etc) */ | 218 | int port_num; /*Actual port number in the device(1,2,etc) */ |
| 219 | struct urb *write_urb; /* write URB for this port */ | 219 | struct urb *write_urb; /* write URB for this port */ |
| 220 | struct urb *read_urb; /* read URB for this port */ | 220 | struct urb *read_urb; /* read URB for this port */ |
| 221 | struct urb *int_urb; | ||
| 222 | __u8 shadowLCR; /* last LCR value received */ | 221 | __u8 shadowLCR; /* last LCR value received */ |
| 223 | __u8 shadowMCR; /* last MCR value received */ | 222 | __u8 shadowMCR; /* last MCR value received */ |
| 224 | char open; | 223 | char open; |
| 225 | char open_ports; | 224 | char open_ports; |
| 226 | char zombie; | ||
| 227 | wait_queue_head_t wait_chase; /* for handling sleeping while waiting for chase to finish */ | 225 | wait_queue_head_t wait_chase; /* for handling sleeping while waiting for chase to finish */ |
| 228 | wait_queue_head_t delta_msr_wait; /* for handling sleeping while waiting for msr change to happen */ | 226 | wait_queue_head_t delta_msr_wait; /* for handling sleeping while waiting for msr change to happen */ |
| 229 | int delta_msr_cond; | 227 | int delta_msr_cond; |
| @@ -478,7 +476,6 @@ static void mos7840_control_callback(struct urb *urb) | |||
| 478 | struct moschip_port *mos7840_port; | 476 | struct moschip_port *mos7840_port; |
| 479 | struct device *dev = &urb->dev->dev; | 477 | struct device *dev = &urb->dev->dev; |
| 480 | __u8 regval = 0x0; | 478 | __u8 regval = 0x0; |
| 481 | int result = 0; | ||
| 482 | int status = urb->status; | 479 | int status = urb->status; |
| 483 | 480 | ||
| 484 | mos7840_port = urb->context; | 481 | mos7840_port = urb->context; |
| @@ -495,7 +492,7 @@ static void mos7840_control_callback(struct urb *urb) | |||
| 495 | return; | 492 | return; |
| 496 | default: | 493 | default: |
| 497 | dev_dbg(dev, "%s - nonzero urb status received: %d\n", __func__, status); | 494 | dev_dbg(dev, "%s - nonzero urb status received: %d\n", __func__, status); |
| 498 | goto exit; | 495 | return; |
| 499 | } | 496 | } |
| 500 | 497 | ||
| 501 | dev_dbg(dev, "%s urb buffer size is %d\n", __func__, urb->actual_length); | 498 | dev_dbg(dev, "%s urb buffer size is %d\n", __func__, urb->actual_length); |
| @@ -508,16 +505,6 @@ static void mos7840_control_callback(struct urb *urb) | |||
| 508 | mos7840_handle_new_msr(mos7840_port, regval); | 505 | mos7840_handle_new_msr(mos7840_port, regval); |
| 509 | else if (mos7840_port->MsrLsr == 1) | 506 | else if (mos7840_port->MsrLsr == 1) |
| 510 | mos7840_handle_new_lsr(mos7840_port, regval); | 507 | mos7840_handle_new_lsr(mos7840_port, regval); |
| 511 | |||
| 512 | exit: | ||
| 513 | spin_lock(&mos7840_port->pool_lock); | ||
| 514 | if (!mos7840_port->zombie) | ||
| 515 | result = usb_submit_urb(mos7840_port->int_urb, GFP_ATOMIC); | ||
| 516 | spin_unlock(&mos7840_port->pool_lock); | ||
| 517 | if (result) { | ||
| 518 | dev_err(dev, "%s - Error %d submitting interrupt urb\n", | ||
| 519 | __func__, result); | ||
| 520 | } | ||
| 521 | } | 508 | } |
| 522 | 509 | ||
| 523 | static int mos7840_get_reg(struct moschip_port *mcs, __u16 Wval, __u16 reg, | 510 | static int mos7840_get_reg(struct moschip_port *mcs, __u16 Wval, __u16 reg, |
| @@ -686,14 +673,7 @@ static void mos7840_interrupt_callback(struct urb *urb) | |||
| 686 | wreg = MODEM_STATUS_REGISTER; | 673 | wreg = MODEM_STATUS_REGISTER; |
| 687 | break; | 674 | break; |
| 688 | } | 675 | } |
| 689 | spin_lock(&mos7840_port->pool_lock); | 676 | rv = mos7840_get_reg(mos7840_port, wval, wreg, &Data); |
| 690 | if (!mos7840_port->zombie) { | ||
| 691 | rv = mos7840_get_reg(mos7840_port, wval, wreg, &Data); | ||
| 692 | } else { | ||
| 693 | spin_unlock(&mos7840_port->pool_lock); | ||
| 694 | return; | ||
| 695 | } | ||
| 696 | spin_unlock(&mos7840_port->pool_lock); | ||
| 697 | } | 677 | } |
| 698 | } | 678 | } |
| 699 | } | 679 | } |
| @@ -2347,309 +2327,249 @@ static int mos7840_calc_num_ports(struct usb_serial *serial) | |||
| 2347 | return mos7840_num_ports; | 2327 | return mos7840_num_ports; |
| 2348 | } | 2328 | } |
| 2349 | 2329 | ||
| 2350 | /**************************************************************************** | 2330 | static int mos7840_port_probe(struct usb_serial_port *port) |
| 2351 | * mos7840_startup | ||
| 2352 | ****************************************************************************/ | ||
| 2353 | |||
| 2354 | static int mos7840_startup(struct usb_serial *serial) | ||
| 2355 | { | 2331 | { |
| 2332 | struct usb_serial *serial = port->serial; | ||
| 2356 | struct moschip_port *mos7840_port; | 2333 | struct moschip_port *mos7840_port; |
| 2357 | struct usb_device *dev; | 2334 | int status; |
| 2358 | int i, status; | 2335 | int pnum; |
| 2359 | __u16 Data; | 2336 | __u16 Data; |
| 2360 | 2337 | ||
| 2361 | dev = serial->dev; | ||
| 2362 | |||
| 2363 | /* we set up the pointers to the endpoints in the mos7840_open * | 2338 | /* we set up the pointers to the endpoints in the mos7840_open * |
| 2364 | * function, as the structures aren't created yet. */ | 2339 | * function, as the structures aren't created yet. */ |
| 2365 | 2340 | ||
| 2366 | /* set up port private structures */ | 2341 | pnum = port->number - serial->minor; |
| 2367 | for (i = 0; i < serial->num_ports; ++i) { | ||
| 2368 | dev_dbg(&dev->dev, "mos7840_startup: configuring port %d............\n", i); | ||
| 2369 | mos7840_port = kzalloc(sizeof(struct moschip_port), GFP_KERNEL); | ||
| 2370 | if (mos7840_port == NULL) { | ||
| 2371 | dev_err(&dev->dev, "%s - Out of memory\n", __func__); | ||
| 2372 | status = -ENOMEM; | ||
| 2373 | i--; /* don't follow NULL pointer cleaning up */ | ||
| 2374 | goto error; | ||
| 2375 | } | ||
| 2376 | |||
| 2377 | /* Initialize all port interrupt end point to port 0 int | ||
| 2378 | * endpoint. Our device has only one interrupt end point | ||
| 2379 | * common to all port */ | ||
| 2380 | |||
| 2381 | mos7840_port->port = serial->port[i]; | ||
| 2382 | mos7840_set_port_private(serial->port[i], mos7840_port); | ||
| 2383 | spin_lock_init(&mos7840_port->pool_lock); | ||
| 2384 | |||
| 2385 | /* minor is not initialised until later by | ||
| 2386 | * usb-serial.c:get_free_serial() and cannot therefore be used | ||
| 2387 | * to index device instances */ | ||
| 2388 | mos7840_port->port_num = i + 1; | ||
| 2389 | dev_dbg(&dev->dev, "serial->port[i]->number = %d\n", serial->port[i]->number); | ||
| 2390 | dev_dbg(&dev->dev, "serial->port[i]->serial->minor = %d\n", serial->port[i]->serial->minor); | ||
| 2391 | dev_dbg(&dev->dev, "mos7840_port->port_num = %d\n", mos7840_port->port_num); | ||
| 2392 | dev_dbg(&dev->dev, "serial->minor = %d\n", serial->minor); | ||
| 2393 | |||
| 2394 | if (mos7840_port->port_num == 1) { | ||
| 2395 | mos7840_port->SpRegOffset = 0x0; | ||
| 2396 | mos7840_port->ControlRegOffset = 0x1; | ||
| 2397 | mos7840_port->DcrRegOffset = 0x4; | ||
| 2398 | } else if ((mos7840_port->port_num == 2) | ||
| 2399 | && (serial->num_ports == 4)) { | ||
| 2400 | mos7840_port->SpRegOffset = 0x8; | ||
| 2401 | mos7840_port->ControlRegOffset = 0x9; | ||
| 2402 | mos7840_port->DcrRegOffset = 0x16; | ||
| 2403 | } else if ((mos7840_port->port_num == 2) | ||
| 2404 | && (serial->num_ports == 2)) { | ||
| 2405 | mos7840_port->SpRegOffset = 0xa; | ||
| 2406 | mos7840_port->ControlRegOffset = 0xb; | ||
| 2407 | mos7840_port->DcrRegOffset = 0x19; | ||
| 2408 | } else if ((mos7840_port->port_num == 3) | ||
| 2409 | && (serial->num_ports == 4)) { | ||
| 2410 | mos7840_port->SpRegOffset = 0xa; | ||
| 2411 | mos7840_port->ControlRegOffset = 0xb; | ||
| 2412 | mos7840_port->DcrRegOffset = 0x19; | ||
| 2413 | } else if ((mos7840_port->port_num == 4) | ||
| 2414 | && (serial->num_ports == 4)) { | ||
| 2415 | mos7840_port->SpRegOffset = 0xc; | ||
| 2416 | mos7840_port->ControlRegOffset = 0xd; | ||
| 2417 | mos7840_port->DcrRegOffset = 0x1c; | ||
| 2418 | } | ||
| 2419 | mos7840_dump_serial_port(serial->port[i], mos7840_port); | ||
| 2420 | mos7840_set_port_private(serial->port[i], mos7840_port); | ||
| 2421 | 2342 | ||
| 2422 | /* enable rx_disable bit in control register */ | 2343 | dev_dbg(&port->dev, "mos7840_startup: configuring port %d\n", pnum); |
| 2423 | status = mos7840_get_reg_sync(serial->port[i], | 2344 | mos7840_port = kzalloc(sizeof(struct moschip_port), GFP_KERNEL); |
| 2424 | mos7840_port->ControlRegOffset, &Data); | 2345 | if (mos7840_port == NULL) { |
| 2425 | if (status < 0) { | 2346 | dev_err(&port->dev, "%s - Out of memory\n", __func__); |
| 2426 | dev_dbg(&dev->dev, "Reading ControlReg failed status-0x%x\n", status); | 2347 | return -ENOMEM; |
| 2427 | break; | 2348 | } |
| 2428 | } else | ||
| 2429 | dev_dbg(&dev->dev, "ControlReg Reading success val is %x, status%d\n", Data, status); | ||
| 2430 | Data |= 0x08; /* setting driver done bit */ | ||
| 2431 | Data |= 0x04; /* sp1_bit to have cts change reflect in | ||
| 2432 | modem status reg */ | ||
| 2433 | |||
| 2434 | /* Data |= 0x20; //rx_disable bit */ | ||
| 2435 | status = mos7840_set_reg_sync(serial->port[i], | ||
| 2436 | mos7840_port->ControlRegOffset, Data); | ||
| 2437 | if (status < 0) { | ||
| 2438 | dev_dbg(&dev->dev, "Writing ControlReg failed(rx_disable) status-0x%x\n", status); | ||
| 2439 | break; | ||
| 2440 | } else | ||
| 2441 | dev_dbg(&dev->dev, "ControlReg Writing success(rx_disable) status%d\n", status); | ||
| 2442 | 2349 | ||
| 2443 | /* Write default values in DCR (i.e 0x01 in DCR0, 0x05 in DCR2 | 2350 | /* Initialize all port interrupt end point to port 0 int |
| 2444 | and 0x24 in DCR3 */ | 2351 | * endpoint. Our device has only one interrupt end point |
| 2445 | Data = 0x01; | 2352 | * common to all port */ |
| 2446 | status = mos7840_set_reg_sync(serial->port[i], | 2353 | |
| 2447 | (__u16) (mos7840_port->DcrRegOffset + 0), Data); | 2354 | mos7840_port->port = port; |
| 2448 | if (status < 0) { | 2355 | mos7840_set_port_private(port, mos7840_port); |
| 2449 | dev_dbg(&dev->dev, "Writing DCR0 failed status-0x%x\n", status); | 2356 | spin_lock_init(&mos7840_port->pool_lock); |
| 2450 | break; | 2357 | |
| 2451 | } else | 2358 | /* minor is not initialised until later by |
| 2452 | dev_dbg(&dev->dev, "DCR0 Writing success status%d\n", status); | 2359 | * usb-serial.c:get_free_serial() and cannot therefore be used |
| 2360 | * to index device instances */ | ||
| 2361 | mos7840_port->port_num = pnum + 1; | ||
| 2362 | dev_dbg(&port->dev, "port->number = %d\n", port->number); | ||
| 2363 | dev_dbg(&port->dev, "port->serial->minor = %d\n", port->serial->minor); | ||
| 2364 | dev_dbg(&port->dev, "mos7840_port->port_num = %d\n", mos7840_port->port_num); | ||
| 2365 | dev_dbg(&port->dev, "serial->minor = %d\n", serial->minor); | ||
| 2366 | |||
| 2367 | if (mos7840_port->port_num == 1) { | ||
| 2368 | mos7840_port->SpRegOffset = 0x0; | ||
| 2369 | mos7840_port->ControlRegOffset = 0x1; | ||
| 2370 | mos7840_port->DcrRegOffset = 0x4; | ||
| 2371 | } else if ((mos7840_port->port_num == 2) && (serial->num_ports == 4)) { | ||
| 2372 | mos7840_port->SpRegOffset = 0x8; | ||
| 2373 | mos7840_port->ControlRegOffset = 0x9; | ||
| 2374 | mos7840_port->DcrRegOffset = 0x16; | ||
| 2375 | } else if ((mos7840_port->port_num == 2) && (serial->num_ports == 2)) { | ||
| 2376 | mos7840_port->SpRegOffset = 0xa; | ||
| 2377 | mos7840_port->ControlRegOffset = 0xb; | ||
| 2378 | mos7840_port->DcrRegOffset = 0x19; | ||
| 2379 | } else if ((mos7840_port->port_num == 3) && (serial->num_ports == 4)) { | ||
| 2380 | mos7840_port->SpRegOffset = 0xa; | ||
| 2381 | mos7840_port->ControlRegOffset = 0xb; | ||
| 2382 | mos7840_port->DcrRegOffset = 0x19; | ||
| 2383 | } else if ((mos7840_port->port_num == 4) && (serial->num_ports == 4)) { | ||
| 2384 | mos7840_port->SpRegOffset = 0xc; | ||
| 2385 | mos7840_port->ControlRegOffset = 0xd; | ||
| 2386 | mos7840_port->DcrRegOffset = 0x1c; | ||
| 2387 | } | ||
| 2388 | mos7840_dump_serial_port(port, mos7840_port); | ||
| 2389 | mos7840_set_port_private(port, mos7840_port); | ||
| 2390 | |||
| 2391 | /* enable rx_disable bit in control register */ | ||
| 2392 | status = mos7840_get_reg_sync(port, | ||
| 2393 | mos7840_port->ControlRegOffset, &Data); | ||
| 2394 | if (status < 0) { | ||
| 2395 | dev_dbg(&port->dev, "Reading ControlReg failed status-0x%x\n", status); | ||
| 2396 | goto out; | ||
| 2397 | } else | ||
| 2398 | dev_dbg(&port->dev, "ControlReg Reading success val is %x, status%d\n", Data, status); | ||
| 2399 | Data |= 0x08; /* setting driver done bit */ | ||
| 2400 | Data |= 0x04; /* sp1_bit to have cts change reflect in | ||
| 2401 | modem status reg */ | ||
| 2453 | 2402 | ||
| 2454 | Data = 0x05; | 2403 | /* Data |= 0x20; //rx_disable bit */ |
| 2455 | status = mos7840_set_reg_sync(serial->port[i], | 2404 | status = mos7840_set_reg_sync(port, |
| 2456 | (__u16) (mos7840_port->DcrRegOffset + 1), Data); | 2405 | mos7840_port->ControlRegOffset, Data); |
| 2457 | if (status < 0) { | 2406 | if (status < 0) { |
| 2458 | dev_dbg(&dev->dev, "Writing DCR1 failed status-0x%x\n", status); | 2407 | dev_dbg(&port->dev, "Writing ControlReg failed(rx_disable) status-0x%x\n", status); |
| 2459 | break; | 2408 | goto out; |
| 2460 | } else | 2409 | } else |
| 2461 | dev_dbg(&dev->dev, "DCR1 Writing success status%d\n", status); | 2410 | dev_dbg(&port->dev, "ControlReg Writing success(rx_disable) status%d\n", status); |
| 2462 | 2411 | ||
| 2463 | Data = 0x24; | 2412 | /* Write default values in DCR (i.e 0x01 in DCR0, 0x05 in DCR2 |
| 2464 | status = mos7840_set_reg_sync(serial->port[i], | 2413 | and 0x24 in DCR3 */ |
| 2465 | (__u16) (mos7840_port->DcrRegOffset + 2), Data); | 2414 | Data = 0x01; |
| 2466 | if (status < 0) { | 2415 | status = mos7840_set_reg_sync(port, |
| 2467 | dev_dbg(&dev->dev, "Writing DCR2 failed status-0x%x\n", status); | 2416 | (__u16) (mos7840_port->DcrRegOffset + 0), Data); |
| 2468 | break; | 2417 | if (status < 0) { |
| 2469 | } else | 2418 | dev_dbg(&port->dev, "Writing DCR0 failed status-0x%x\n", status); |
| 2470 | dev_dbg(&dev->dev, "DCR2 Writing success status%d\n", status); | 2419 | goto out; |
| 2420 | } else | ||
| 2421 | dev_dbg(&port->dev, "DCR0 Writing success status%d\n", status); | ||
| 2471 | 2422 | ||
| 2472 | /* write values in clkstart0x0 and clkmulti 0x20 */ | 2423 | Data = 0x05; |
| 2473 | Data = 0x0; | 2424 | status = mos7840_set_reg_sync(port, |
| 2474 | status = mos7840_set_reg_sync(serial->port[i], | 2425 | (__u16) (mos7840_port->DcrRegOffset + 1), Data); |
| 2475 | CLK_START_VALUE_REGISTER, Data); | 2426 | if (status < 0) { |
| 2476 | if (status < 0) { | 2427 | dev_dbg(&port->dev, "Writing DCR1 failed status-0x%x\n", status); |
| 2477 | dev_dbg(&dev->dev, "Writing CLK_START_VALUE_REGISTER failed status-0x%x\n", status); | 2428 | goto out; |
| 2478 | break; | 2429 | } else |
| 2479 | } else | 2430 | dev_dbg(&port->dev, "DCR1 Writing success status%d\n", status); |
| 2480 | dev_dbg(&dev->dev, "CLK_START_VALUE_REGISTER Writing success status%d\n", status); | ||
| 2481 | 2431 | ||
| 2482 | Data = 0x20; | 2432 | Data = 0x24; |
| 2483 | status = mos7840_set_reg_sync(serial->port[i], | 2433 | status = mos7840_set_reg_sync(port, |
| 2484 | CLK_MULTI_REGISTER, Data); | 2434 | (__u16) (mos7840_port->DcrRegOffset + 2), Data); |
| 2485 | if (status < 0) { | 2435 | if (status < 0) { |
| 2486 | dev_dbg(&dev->dev, "Writing CLK_MULTI_REGISTER failed status-0x%x\n", status); | 2436 | dev_dbg(&port->dev, "Writing DCR2 failed status-0x%x\n", status); |
| 2487 | goto error; | 2437 | goto out; |
| 2488 | } else | 2438 | } else |
| 2489 | dev_dbg(&dev->dev, "CLK_MULTI_REGISTER Writing success status%d\n", status); | 2439 | dev_dbg(&port->dev, "DCR2 Writing success status%d\n", status); |
| 2490 | 2440 | ||
| 2491 | /* write value 0x0 to scratchpad register */ | 2441 | /* write values in clkstart0x0 and clkmulti 0x20 */ |
| 2492 | Data = 0x00; | 2442 | Data = 0x0; |
| 2493 | status = mos7840_set_uart_reg(serial->port[i], | 2443 | status = mos7840_set_reg_sync(port, CLK_START_VALUE_REGISTER, Data); |
| 2494 | SCRATCH_PAD_REGISTER, Data); | 2444 | if (status < 0) { |
| 2495 | if (status < 0) { | 2445 | dev_dbg(&port->dev, "Writing CLK_START_VALUE_REGISTER failed status-0x%x\n", status); |
| 2496 | dev_dbg(&dev->dev, "Writing SCRATCH_PAD_REGISTER failed status-0x%x\n", status); | 2446 | goto out; |
| 2497 | break; | 2447 | } else |
| 2498 | } else | 2448 | dev_dbg(&port->dev, "CLK_START_VALUE_REGISTER Writing success status%d\n", status); |
| 2499 | dev_dbg(&dev->dev, "SCRATCH_PAD_REGISTER Writing success status%d\n", status); | ||
| 2500 | 2449 | ||
| 2501 | /* Zero Length flag register */ | 2450 | Data = 0x20; |
| 2502 | if ((mos7840_port->port_num != 1) | 2451 | status = mos7840_set_reg_sync(port, CLK_MULTI_REGISTER, Data); |
| 2503 | && (serial->num_ports == 2)) { | 2452 | if (status < 0) { |
| 2453 | dev_dbg(&port->dev, "Writing CLK_MULTI_REGISTER failed status-0x%x\n", status); | ||
| 2454 | goto error; | ||
| 2455 | } else | ||
| 2456 | dev_dbg(&port->dev, "CLK_MULTI_REGISTER Writing success status%d\n", status); | ||
| 2504 | 2457 | ||
| 2505 | Data = 0xff; | 2458 | /* write value 0x0 to scratchpad register */ |
| 2506 | status = mos7840_set_reg_sync(serial->port[i], | 2459 | Data = 0x00; |
| 2507 | (__u16) (ZLP_REG1 + | 2460 | status = mos7840_set_uart_reg(port, SCRATCH_PAD_REGISTER, Data); |
| 2508 | ((__u16)mos7840_port->port_num)), Data); | 2461 | if (status < 0) { |
| 2509 | dev_dbg(&dev->dev, "ZLIP offset %x\n", | 2462 | dev_dbg(&port->dev, "Writing SCRATCH_PAD_REGISTER failed status-0x%x\n", status); |
| 2463 | goto out; | ||
| 2464 | } else | ||
| 2465 | dev_dbg(&port->dev, "SCRATCH_PAD_REGISTER Writing success status%d\n", status); | ||
| 2466 | |||
| 2467 | /* Zero Length flag register */ | ||
| 2468 | if ((mos7840_port->port_num != 1) && (serial->num_ports == 2)) { | ||
| 2469 | Data = 0xff; | ||
| 2470 | status = mos7840_set_reg_sync(port, | ||
| 2471 | (__u16) (ZLP_REG1 + | ||
| 2472 | ((__u16)mos7840_port->port_num)), Data); | ||
| 2473 | dev_dbg(&port->dev, "ZLIP offset %x\n", | ||
| 2510 | (__u16)(ZLP_REG1 + ((__u16) mos7840_port->port_num))); | 2474 | (__u16)(ZLP_REG1 + ((__u16) mos7840_port->port_num))); |
| 2511 | if (status < 0) { | 2475 | if (status < 0) { |
| 2512 | dev_dbg(&dev->dev, "Writing ZLP_REG%d failed status-0x%x\n", i + 2, status); | 2476 | dev_dbg(&port->dev, "Writing ZLP_REG%d failed status-0x%x\n", pnum + 2, status); |
| 2513 | break; | 2477 | goto out; |
| 2514 | } else | 2478 | } else |
| 2515 | dev_dbg(&dev->dev, "ZLP_REG%d Writing success status%d\n", i + 2, status); | 2479 | dev_dbg(&port->dev, "ZLP_REG%d Writing success status%d\n", pnum + 2, status); |
| 2516 | } else { | 2480 | } else { |
| 2517 | Data = 0xff; | 2481 | Data = 0xff; |
| 2518 | status = mos7840_set_reg_sync(serial->port[i], | 2482 | status = mos7840_set_reg_sync(port, |
| 2519 | (__u16) (ZLP_REG1 + | 2483 | (__u16) (ZLP_REG1 + |
| 2520 | ((__u16)mos7840_port->port_num) - 0x1), Data); | 2484 | ((__u16)mos7840_port->port_num) - 0x1), Data); |
| 2521 | dev_dbg(&dev->dev, "ZLIP offset %x\n", | 2485 | dev_dbg(&port->dev, "ZLIP offset %x\n", |
| 2522 | (__u16)(ZLP_REG1 + ((__u16) mos7840_port->port_num) - 0x1)); | 2486 | (__u16)(ZLP_REG1 + ((__u16) mos7840_port->port_num) - 0x1)); |
| 2523 | if (status < 0) { | 2487 | if (status < 0) { |
| 2524 | dev_dbg(&dev->dev, "Writing ZLP_REG%d failed status-0x%x\n", i + 1, status); | 2488 | dev_dbg(&port->dev, "Writing ZLP_REG%d failed status-0x%x\n", pnum + 1, status); |
| 2525 | break; | 2489 | goto out; |
| 2526 | } else | 2490 | } else |
| 2527 | dev_dbg(&dev->dev, "ZLP_REG%d Writing success status%d\n", i + 1, status); | 2491 | dev_dbg(&port->dev, "ZLP_REG%d Writing success status%d\n", pnum + 1, status); |
| 2528 | 2492 | ||
| 2529 | } | 2493 | } |
| 2530 | mos7840_port->control_urb = usb_alloc_urb(0, GFP_KERNEL); | 2494 | mos7840_port->control_urb = usb_alloc_urb(0, GFP_KERNEL); |
| 2531 | mos7840_port->ctrl_buf = kmalloc(16, GFP_KERNEL); | 2495 | mos7840_port->ctrl_buf = kmalloc(16, GFP_KERNEL); |
| 2532 | mos7840_port->dr = kmalloc(sizeof(struct usb_ctrlrequest), | 2496 | mos7840_port->dr = kmalloc(sizeof(struct usb_ctrlrequest), |
| 2533 | GFP_KERNEL); | 2497 | GFP_KERNEL); |
| 2534 | if (!mos7840_port->control_urb || !mos7840_port->ctrl_buf || | 2498 | if (!mos7840_port->control_urb || !mos7840_port->ctrl_buf || |
| 2535 | !mos7840_port->dr) { | 2499 | !mos7840_port->dr) { |
| 2536 | status = -ENOMEM; | 2500 | status = -ENOMEM; |
| 2537 | goto error; | 2501 | goto error; |
| 2538 | } | 2502 | } |
| 2539 | 2503 | ||
| 2540 | mos7840_port->has_led = false; | 2504 | mos7840_port->has_led = false; |
| 2541 | 2505 | ||
| 2542 | /* Initialize LED timers */ | 2506 | /* Initialize LED timers */ |
| 2543 | if (device_type == MOSCHIP_DEVICE_ID_7810) { | 2507 | if (device_type == MOSCHIP_DEVICE_ID_7810) { |
| 2544 | mos7840_port->has_led = true; | 2508 | mos7840_port->has_led = true; |
| 2545 | 2509 | ||
| 2546 | init_timer(&mos7840_port->led_timer1); | 2510 | init_timer(&mos7840_port->led_timer1); |
| 2547 | mos7840_port->led_timer1.function = mos7840_led_off; | 2511 | mos7840_port->led_timer1.function = mos7840_led_off; |
| 2548 | mos7840_port->led_timer1.expires = | 2512 | mos7840_port->led_timer1.expires = |
| 2549 | jiffies + msecs_to_jiffies(LED_ON_MS); | 2513 | jiffies + msecs_to_jiffies(LED_ON_MS); |
| 2550 | mos7840_port->led_timer1.data = | 2514 | mos7840_port->led_timer1.data = (unsigned long)mos7840_port; |
| 2551 | (unsigned long)mos7840_port; | ||
| 2552 | 2515 | ||
| 2553 | init_timer(&mos7840_port->led_timer2); | 2516 | init_timer(&mos7840_port->led_timer2); |
| 2554 | mos7840_port->led_timer2.function = | 2517 | mos7840_port->led_timer2.function = mos7840_led_flag_off; |
| 2555 | mos7840_led_flag_off; | 2518 | mos7840_port->led_timer2.expires = |
| 2556 | mos7840_port->led_timer2.expires = | 2519 | jiffies + msecs_to_jiffies(LED_OFF_MS); |
| 2557 | jiffies + msecs_to_jiffies(LED_OFF_MS); | 2520 | mos7840_port->led_timer2.data = (unsigned long)mos7840_port; |
| 2558 | mos7840_port->led_timer2.data = | ||
| 2559 | (unsigned long)mos7840_port; | ||
| 2560 | 2521 | ||
| 2561 | mos7840_port->led_flag = false; | 2522 | mos7840_port->led_flag = false; |
| 2562 | 2523 | ||
| 2563 | /* Turn off LED */ | 2524 | /* Turn off LED */ |
| 2564 | mos7840_set_led_sync(serial->port[i], | 2525 | mos7840_set_led_sync(port, MODEM_CONTROL_REGISTER, 0x0300); |
| 2565 | MODEM_CONTROL_REGISTER, 0x0300); | ||
| 2566 | } | ||
| 2567 | } | 2526 | } |
| 2527 | out: | ||
| 2528 | if (pnum == serial->num_ports - 1) { | ||
| 2529 | /* Zero Length flag enable */ | ||
| 2530 | Data = 0x0f; | ||
| 2531 | status = mos7840_set_reg_sync(serial->port[0], ZLP_REG5, Data); | ||
| 2532 | if (status < 0) { | ||
| 2533 | dev_dbg(&port->dev, "Writing ZLP_REG5 failed status-0x%x\n", status); | ||
| 2534 | goto error; | ||
| 2535 | } else | ||
| 2536 | dev_dbg(&port->dev, "ZLP_REG5 Writing success status%d\n", status); | ||
| 2568 | 2537 | ||
| 2569 | /* Zero Length flag enable */ | 2538 | /* setting configuration feature to one */ |
| 2570 | Data = 0x0f; | 2539 | usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0), |
| 2571 | status = mos7840_set_reg_sync(serial->port[0], ZLP_REG5, Data); | 2540 | 0x03, 0x00, 0x01, 0x00, NULL, 0x00, |
| 2572 | if (status < 0) { | 2541 | MOS_WDR_TIMEOUT); |
| 2573 | dev_dbg(&dev->dev, "Writing ZLP_REG5 failed status-0x%x\n", status); | 2542 | } |
| 2574 | goto error; | ||
| 2575 | } else | ||
| 2576 | dev_dbg(&dev->dev, "ZLP_REG5 Writing success status%d\n", status); | ||
| 2577 | |||
| 2578 | /* setting configuration feature to one */ | ||
| 2579 | usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0), | ||
| 2580 | (__u8) 0x03, 0x00, 0x01, 0x00, NULL, 0x00, MOS_WDR_TIMEOUT); | ||
| 2581 | return 0; | 2543 | return 0; |
| 2582 | error: | 2544 | error: |
| 2583 | for (/* nothing */; i >= 0; i--) { | 2545 | kfree(mos7840_port->dr); |
| 2584 | mos7840_port = mos7840_get_port_private(serial->port[i]); | 2546 | kfree(mos7840_port->ctrl_buf); |
| 2547 | usb_free_urb(mos7840_port->control_urb); | ||
| 2548 | kfree(mos7840_port); | ||
| 2585 | 2549 | ||
| 2586 | kfree(mos7840_port->dr); | ||
| 2587 | kfree(mos7840_port->ctrl_buf); | ||
| 2588 | usb_free_urb(mos7840_port->control_urb); | ||
| 2589 | kfree(mos7840_port); | ||
| 2590 | serial->port[i] = NULL; | ||
| 2591 | } | ||
| 2592 | return status; | 2550 | return status; |
| 2593 | } | 2551 | } |
| 2594 | 2552 | ||
| 2595 | /**************************************************************************** | 2553 | static int mos7840_port_remove(struct usb_serial_port *port) |
| 2596 | * mos7840_disconnect | ||
| 2597 | * This function is called whenever the device is removed from the usb bus. | ||
| 2598 | ****************************************************************************/ | ||
| 2599 | |||
| 2600 | static void mos7840_disconnect(struct usb_serial *serial) | ||
| 2601 | { | 2554 | { |
| 2602 | int i; | ||
| 2603 | unsigned long flags; | ||
| 2604 | struct moschip_port *mos7840_port; | 2555 | struct moschip_port *mos7840_port; |
| 2605 | 2556 | ||
| 2606 | /* check for the ports to be closed,close the ports and disconnect */ | 2557 | mos7840_port = mos7840_get_port_private(port); |
| 2607 | 2558 | ||
| 2608 | /* free private structure allocated for serial port * | 2559 | if (mos7840_port->has_led) { |
| 2609 | * stop reads and writes on all ports */ | 2560 | /* Turn off LED */ |
| 2561 | mos7840_set_led_sync(port, MODEM_CONTROL_REGISTER, 0x0300); | ||
| 2610 | 2562 | ||
| 2611 | for (i = 0; i < serial->num_ports; ++i) { | 2563 | del_timer_sync(&mos7840_port->led_timer1); |
| 2612 | mos7840_port = mos7840_get_port_private(serial->port[i]); | 2564 | del_timer_sync(&mos7840_port->led_timer2); |
| 2613 | if (mos7840_port) { | ||
| 2614 | spin_lock_irqsave(&mos7840_port->pool_lock, flags); | ||
| 2615 | mos7840_port->zombie = 1; | ||
| 2616 | spin_unlock_irqrestore(&mos7840_port->pool_lock, flags); | ||
| 2617 | usb_kill_urb(mos7840_port->control_urb); | ||
| 2618 | } | ||
| 2619 | } | 2565 | } |
| 2620 | } | 2566 | usb_kill_urb(mos7840_port->control_urb); |
| 2621 | 2567 | usb_free_urb(mos7840_port->control_urb); | |
| 2622 | /**************************************************************************** | 2568 | kfree(mos7840_port->ctrl_buf); |
| 2623 | * mos7840_release | 2569 | kfree(mos7840_port->dr); |
| 2624 | * This function is called when the usb_serial structure is freed. | 2570 | kfree(mos7840_port); |
| 2625 | ****************************************************************************/ | ||
| 2626 | |||
| 2627 | static void mos7840_release(struct usb_serial *serial) | ||
| 2628 | { | ||
| 2629 | int i; | ||
| 2630 | struct moschip_port *mos7840_port; | ||
| 2631 | |||
| 2632 | /* check for the ports to be closed,close the ports and disconnect */ | ||
| 2633 | 2571 | ||
| 2634 | /* free private structure allocated for serial port * | 2572 | return 0; |
| 2635 | * stop reads and writes on all ports */ | ||
| 2636 | |||
| 2637 | for (i = 0; i < serial->num_ports; ++i) { | ||
| 2638 | mos7840_port = mos7840_get_port_private(serial->port[i]); | ||
| 2639 | if (mos7840_port) { | ||
| 2640 | if (mos7840_port->has_led) { | ||
| 2641 | /* Turn off LED */ | ||
| 2642 | mos7840_set_led_sync(mos7840_port->port, | ||
| 2643 | MODEM_CONTROL_REGISTER, 0x0300); | ||
| 2644 | |||
| 2645 | del_timer_sync(&mos7840_port->led_timer1); | ||
| 2646 | del_timer_sync(&mos7840_port->led_timer2); | ||
| 2647 | } | ||
| 2648 | kfree(mos7840_port->ctrl_buf); | ||
| 2649 | kfree(mos7840_port->dr); | ||
| 2650 | kfree(mos7840_port); | ||
| 2651 | } | ||
| 2652 | } | ||
| 2653 | } | 2573 | } |
| 2654 | 2574 | ||
| 2655 | static struct usb_serial_driver moschip7840_4port_device = { | 2575 | static struct usb_serial_driver moschip7840_4port_device = { |
| @@ -2677,9 +2597,8 @@ static struct usb_serial_driver moschip7840_4port_device = { | |||
| 2677 | .tiocmget = mos7840_tiocmget, | 2597 | .tiocmget = mos7840_tiocmget, |
| 2678 | .tiocmset = mos7840_tiocmset, | 2598 | .tiocmset = mos7840_tiocmset, |
| 2679 | .get_icount = mos7840_get_icount, | 2599 | .get_icount = mos7840_get_icount, |
| 2680 | .attach = mos7840_startup, | 2600 | .port_probe = mos7840_port_probe, |
| 2681 | .disconnect = mos7840_disconnect, | 2601 | .port_remove = mos7840_port_remove, |
| 2682 | .release = mos7840_release, | ||
| 2683 | .read_bulk_callback = mos7840_bulk_in_callback, | 2602 | .read_bulk_callback = mos7840_bulk_in_callback, |
| 2684 | .read_int_callback = mos7840_interrupt_callback, | 2603 | .read_int_callback = mos7840_interrupt_callback, |
| 2685 | }; | 2604 | }; |
diff --git a/drivers/usb/serial/omninet.c b/drivers/usb/serial/omninet.c index 6def58b79382..9ab73d295774 100644 --- a/drivers/usb/serial/omninet.c +++ b/drivers/usb/serial/omninet.c | |||
| @@ -44,8 +44,8 @@ static int omninet_write(struct tty_struct *tty, struct usb_serial_port *port, | |||
| 44 | const unsigned char *buf, int count); | 44 | const unsigned char *buf, int count); |
| 45 | static int omninet_write_room(struct tty_struct *tty); | 45 | static int omninet_write_room(struct tty_struct *tty); |
| 46 | static void omninet_disconnect(struct usb_serial *serial); | 46 | static void omninet_disconnect(struct usb_serial *serial); |
| 47 | static void omninet_release(struct usb_serial *serial); | 47 | static int omninet_port_probe(struct usb_serial_port *port); |
| 48 | static int omninet_attach(struct usb_serial *serial); | 48 | static int omninet_port_remove(struct usb_serial_port *port); |
| 49 | 49 | ||
| 50 | static const struct usb_device_id id_table[] = { | 50 | static const struct usb_device_id id_table[] = { |
| 51 | { USB_DEVICE(ZYXEL_VENDOR_ID, ZYXEL_OMNINET_ID) }, | 51 | { USB_DEVICE(ZYXEL_VENDOR_ID, ZYXEL_OMNINET_ID) }, |
| @@ -62,7 +62,8 @@ static struct usb_serial_driver zyxel_omninet_device = { | |||
| 62 | .description = "ZyXEL - omni.net lcd plus usb", | 62 | .description = "ZyXEL - omni.net lcd plus usb", |
| 63 | .id_table = id_table, | 63 | .id_table = id_table, |
| 64 | .num_ports = 1, | 64 | .num_ports = 1, |
| 65 | .attach = omninet_attach, | 65 | .port_probe = omninet_port_probe, |
| 66 | .port_remove = omninet_port_remove, | ||
| 66 | .open = omninet_open, | 67 | .open = omninet_open, |
| 67 | .close = omninet_close, | 68 | .close = omninet_close, |
| 68 | .write = omninet_write, | 69 | .write = omninet_write, |
| @@ -70,7 +71,6 @@ static struct usb_serial_driver zyxel_omninet_device = { | |||
| 70 | .read_bulk_callback = omninet_read_bulk_callback, | 71 | .read_bulk_callback = omninet_read_bulk_callback, |
| 71 | .write_bulk_callback = omninet_write_bulk_callback, | 72 | .write_bulk_callback = omninet_write_bulk_callback, |
| 72 | .disconnect = omninet_disconnect, | 73 | .disconnect = omninet_disconnect, |
| 73 | .release = omninet_release, | ||
| 74 | }; | 74 | }; |
| 75 | 75 | ||
| 76 | static struct usb_serial_driver * const serial_drivers[] = { | 76 | static struct usb_serial_driver * const serial_drivers[] = { |
| @@ -112,18 +112,26 @@ struct omninet_data { | |||
| 112 | __u8 od_outseq; /* Sequence number for bulk_out URBs */ | 112 | __u8 od_outseq; /* Sequence number for bulk_out URBs */ |
| 113 | }; | 113 | }; |
| 114 | 114 | ||
| 115 | static int omninet_attach(struct usb_serial *serial) | 115 | static int omninet_port_probe(struct usb_serial_port *port) |
| 116 | { | 116 | { |
| 117 | struct omninet_data *od; | 117 | struct omninet_data *od; |
| 118 | struct usb_serial_port *port = serial->port[0]; | ||
| 119 | 118 | ||
| 120 | od = kmalloc(sizeof(struct omninet_data), GFP_KERNEL); | 119 | od = kmalloc(sizeof(struct omninet_data), GFP_KERNEL); |
| 121 | if (!od) { | 120 | if (!od) |
| 122 | dev_err(&port->dev, "%s- kmalloc(%Zd) failed.\n", | ||
| 123 | __func__, sizeof(struct omninet_data)); | ||
| 124 | return -ENOMEM; | 121 | return -ENOMEM; |
| 125 | } | 122 | |
| 126 | usb_set_serial_port_data(port, od); | 123 | usb_set_serial_port_data(port, od); |
| 124 | |||
| 125 | return 0; | ||
| 126 | } | ||
| 127 | |||
| 128 | static int omninet_port_remove(struct usb_serial_port *port) | ||
| 129 | { | ||
| 130 | struct omninet_data *od; | ||
| 131 | |||
| 132 | od = usb_get_serial_port_data(port); | ||
| 133 | kfree(od); | ||
| 134 | |||
| 127 | return 0; | 135 | return 0; |
| 128 | } | 136 | } |
| 129 | 137 | ||
| @@ -279,14 +287,6 @@ static void omninet_disconnect(struct usb_serial *serial) | |||
| 279 | usb_kill_urb(wport->write_urb); | 287 | usb_kill_urb(wport->write_urb); |
| 280 | } | 288 | } |
| 281 | 289 | ||
| 282 | |||
| 283 | static void omninet_release(struct usb_serial *serial) | ||
| 284 | { | ||
| 285 | struct usb_serial_port *port = serial->port[0]; | ||
| 286 | |||
| 287 | kfree(usb_get_serial_port_data(port)); | ||
| 288 | } | ||
| 289 | |||
| 290 | module_usb_serial_driver(serial_drivers, id_table); | 290 | module_usb_serial_driver(serial_drivers, id_table); |
| 291 | 291 | ||
| 292 | MODULE_AUTHOR(DRIVER_AUTHOR); | 292 | MODULE_AUTHOR(DRIVER_AUTHOR); |
diff --git a/drivers/usb/serial/opticon.c b/drivers/usb/serial/opticon.c index 41b1647306eb..6aba731d4864 100644 --- a/drivers/usb/serial/opticon.c +++ b/drivers/usb/serial/opticon.c | |||
| @@ -155,7 +155,11 @@ static int send_control_msg(struct usb_serial_port *port, u8 requesttype, | |||
| 155 | { | 155 | { |
| 156 | struct usb_serial *serial = port->serial; | 156 | struct usb_serial *serial = port->serial; |
| 157 | int retval; | 157 | int retval; |
| 158 | u8 buffer[2]; | 158 | u8 *buffer; |
| 159 | |||
| 160 | buffer = kzalloc(1, GFP_KERNEL); | ||
| 161 | if (!buffer) | ||
| 162 | return -ENOMEM; | ||
| 159 | 163 | ||
| 160 | buffer[0] = val; | 164 | buffer[0] = val; |
| 161 | /* Send the message to the vendor control endpoint | 165 | /* Send the message to the vendor control endpoint |
| @@ -164,6 +168,7 @@ static int send_control_msg(struct usb_serial_port *port, u8 requesttype, | |||
| 164 | requesttype, | 168 | requesttype, |
| 165 | USB_DIR_OUT|USB_TYPE_VENDOR|USB_RECIP_INTERFACE, | 169 | USB_DIR_OUT|USB_TYPE_VENDOR|USB_RECIP_INTERFACE, |
| 166 | 0, 0, buffer, 1, 0); | 170 | 0, 0, buffer, 1, 0); |
| 171 | kfree(buffer); | ||
| 167 | 172 | ||
| 168 | return retval; | 173 | return retval; |
| 169 | } | 174 | } |
| @@ -281,7 +286,7 @@ static int opticon_write(struct tty_struct *tty, struct usb_serial_port *port, | |||
| 281 | if (!dr) { | 286 | if (!dr) { |
| 282 | dev_err(&port->dev, "out of memory\n"); | 287 | dev_err(&port->dev, "out of memory\n"); |
| 283 | count = -ENOMEM; | 288 | count = -ENOMEM; |
| 284 | goto error; | 289 | goto error_no_dr; |
| 285 | } | 290 | } |
| 286 | 291 | ||
| 287 | dr->bRequestType = USB_TYPE_VENDOR | USB_RECIP_INTERFACE | USB_DIR_OUT; | 292 | dr->bRequestType = USB_TYPE_VENDOR | USB_RECIP_INTERFACE | USB_DIR_OUT; |
| @@ -311,6 +316,8 @@ static int opticon_write(struct tty_struct *tty, struct usb_serial_port *port, | |||
| 311 | 316 | ||
| 312 | return count; | 317 | return count; |
| 313 | error: | 318 | error: |
| 319 | kfree(dr); | ||
| 320 | error_no_dr: | ||
| 314 | usb_free_urb(urb); | 321 | usb_free_urb(urb); |
| 315 | error_no_urb: | 322 | error_no_urb: |
| 316 | kfree(buffer); | 323 | kfree(buffer); |
diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index 30cff03e9f01..edc64bb6f457 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c | |||
| @@ -47,6 +47,7 @@ | |||
| 47 | /* Function prototypes */ | 47 | /* Function prototypes */ |
| 48 | static int option_probe(struct usb_serial *serial, | 48 | static int option_probe(struct usb_serial *serial, |
| 49 | const struct usb_device_id *id); | 49 | const struct usb_device_id *id); |
| 50 | static int option_attach(struct usb_serial *serial); | ||
| 50 | static void option_release(struct usb_serial *serial); | 51 | static void option_release(struct usb_serial *serial); |
| 51 | static int option_send_setup(struct usb_serial_port *port); | 52 | static int option_send_setup(struct usb_serial_port *port); |
| 52 | static void option_instat_callback(struct urb *urb); | 53 | static void option_instat_callback(struct urb *urb); |
| @@ -157,6 +158,7 @@ static void option_instat_callback(struct urb *urb); | |||
| 157 | #define NOVATELWIRELESS_PRODUCT_EVDO_EMBEDDED_HIGHSPEED 0x8001 | 158 | #define NOVATELWIRELESS_PRODUCT_EVDO_EMBEDDED_HIGHSPEED 0x8001 |
| 158 | #define NOVATELWIRELESS_PRODUCT_HSPA_EMBEDDED_FULLSPEED 0x9000 | 159 | #define NOVATELWIRELESS_PRODUCT_HSPA_EMBEDDED_FULLSPEED 0x9000 |
| 159 | #define NOVATELWIRELESS_PRODUCT_HSPA_EMBEDDED_HIGHSPEED 0x9001 | 160 | #define NOVATELWIRELESS_PRODUCT_HSPA_EMBEDDED_HIGHSPEED 0x9001 |
| 161 | #define NOVATELWIRELESS_PRODUCT_E362 0x9010 | ||
| 160 | #define NOVATELWIRELESS_PRODUCT_G1 0xA001 | 162 | #define NOVATELWIRELESS_PRODUCT_G1 0xA001 |
| 161 | #define NOVATELWIRELESS_PRODUCT_G1_M 0xA002 | 163 | #define NOVATELWIRELESS_PRODUCT_G1_M 0xA002 |
| 162 | #define NOVATELWIRELESS_PRODUCT_G2 0xA010 | 164 | #define NOVATELWIRELESS_PRODUCT_G2 0xA010 |
| @@ -192,6 +194,9 @@ static void option_instat_callback(struct urb *urb); | |||
| 192 | #define DELL_PRODUCT_5730_MINICARD_TELUS 0x8181 | 194 | #define DELL_PRODUCT_5730_MINICARD_TELUS 0x8181 |
| 193 | #define DELL_PRODUCT_5730_MINICARD_VZW 0x8182 | 195 | #define DELL_PRODUCT_5730_MINICARD_VZW 0x8182 |
| 194 | 196 | ||
| 197 | #define DELL_PRODUCT_5800_MINICARD_VZW 0x8195 /* Novatel E362 */ | ||
| 198 | #define DELL_PRODUCT_5800_V2_MINICARD_VZW 0x8196 /* Novatel E362 */ | ||
| 199 | |||
| 195 | #define KYOCERA_VENDOR_ID 0x0c88 | 200 | #define KYOCERA_VENDOR_ID 0x0c88 |
| 196 | #define KYOCERA_PRODUCT_KPC650 0x17da | 201 | #define KYOCERA_PRODUCT_KPC650 0x17da |
| 197 | #define KYOCERA_PRODUCT_KPC680 0x180a | 202 | #define KYOCERA_PRODUCT_KPC680 0x180a |
| @@ -282,6 +287,7 @@ static void option_instat_callback(struct urb *urb); | |||
| 282 | /* ALCATEL PRODUCTS */ | 287 | /* ALCATEL PRODUCTS */ |
| 283 | #define ALCATEL_VENDOR_ID 0x1bbb | 288 | #define ALCATEL_VENDOR_ID 0x1bbb |
| 284 | #define ALCATEL_PRODUCT_X060S_X200 0x0000 | 289 | #define ALCATEL_PRODUCT_X060S_X200 0x0000 |
| 290 | #define ALCATEL_PRODUCT_X220_X500D 0x0017 | ||
| 285 | 291 | ||
| 286 | #define PIRELLI_VENDOR_ID 0x1266 | 292 | #define PIRELLI_VENDOR_ID 0x1266 |
| 287 | #define PIRELLI_PRODUCT_C100_1 0x1002 | 293 | #define PIRELLI_PRODUCT_C100_1 0x1002 |
| @@ -503,11 +509,19 @@ static const struct option_blacklist_info net_intf5_blacklist = { | |||
| 503 | .reserved = BIT(5), | 509 | .reserved = BIT(5), |
| 504 | }; | 510 | }; |
| 505 | 511 | ||
| 512 | static const struct option_blacklist_info net_intf6_blacklist = { | ||
| 513 | .reserved = BIT(6), | ||
| 514 | }; | ||
| 515 | |||
| 506 | static const struct option_blacklist_info zte_mf626_blacklist = { | 516 | static const struct option_blacklist_info zte_mf626_blacklist = { |
| 507 | .sendsetup = BIT(0) | BIT(1), | 517 | .sendsetup = BIT(0) | BIT(1), |
| 508 | .reserved = BIT(4), | 518 | .reserved = BIT(4), |
| 509 | }; | 519 | }; |
| 510 | 520 | ||
| 521 | static const struct option_blacklist_info zte_1255_blacklist = { | ||
| 522 | .reserved = BIT(3) | BIT(4), | ||
| 523 | }; | ||
| 524 | |||
| 511 | static const struct usb_device_id option_ids[] = { | 525 | static const struct usb_device_id option_ids[] = { |
| 512 | { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_COLT) }, | 526 | { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_COLT) }, |
| 513 | { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_RICOLA) }, | 527 | { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_RICOLA) }, |
| @@ -697,6 +711,7 @@ static const struct usb_device_id option_ids[] = { | |||
| 697 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_G2) }, | 711 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_G2) }, |
| 698 | /* Novatel Ovation MC551 a.k.a. Verizon USB551L */ | 712 | /* Novatel Ovation MC551 a.k.a. Verizon USB551L */ |
| 699 | { USB_DEVICE_AND_INTERFACE_INFO(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_MC551, 0xff, 0xff, 0xff) }, | 713 | { USB_DEVICE_AND_INTERFACE_INFO(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_MC551, 0xff, 0xff, 0xff) }, |
| 714 | { USB_DEVICE_AND_INTERFACE_INFO(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_E362, 0xff, 0xff, 0xff) }, | ||
| 700 | 715 | ||
| 701 | { USB_DEVICE(AMOI_VENDOR_ID, AMOI_PRODUCT_H01) }, | 716 | { USB_DEVICE(AMOI_VENDOR_ID, AMOI_PRODUCT_H01) }, |
| 702 | { USB_DEVICE(AMOI_VENDOR_ID, AMOI_PRODUCT_H01A) }, | 717 | { USB_DEVICE(AMOI_VENDOR_ID, AMOI_PRODUCT_H01A) }, |
| @@ -719,6 +734,8 @@ static const struct usb_device_id option_ids[] = { | |||
| 719 | { USB_DEVICE(DELL_VENDOR_ID, DELL_PRODUCT_5730_MINICARD_SPRINT) }, /* Dell Wireless 5730 Mobile Broadband EVDO/HSPA Mini-Card */ | 734 | { USB_DEVICE(DELL_VENDOR_ID, DELL_PRODUCT_5730_MINICARD_SPRINT) }, /* Dell Wireless 5730 Mobile Broadband EVDO/HSPA Mini-Card */ |
| 720 | { USB_DEVICE(DELL_VENDOR_ID, DELL_PRODUCT_5730_MINICARD_TELUS) }, /* Dell Wireless 5730 Mobile Broadband EVDO/HSPA Mini-Card */ | 735 | { USB_DEVICE(DELL_VENDOR_ID, DELL_PRODUCT_5730_MINICARD_TELUS) }, /* Dell Wireless 5730 Mobile Broadband EVDO/HSPA Mini-Card */ |
| 721 | { USB_DEVICE(DELL_VENDOR_ID, DELL_PRODUCT_5730_MINICARD_VZW) }, /* Dell Wireless 5730 Mobile Broadband EVDO/HSPA Mini-Card */ | 736 | { USB_DEVICE(DELL_VENDOR_ID, DELL_PRODUCT_5730_MINICARD_VZW) }, /* Dell Wireless 5730 Mobile Broadband EVDO/HSPA Mini-Card */ |
| 737 | { USB_DEVICE_AND_INTERFACE_INFO(DELL_VENDOR_ID, DELL_PRODUCT_5800_MINICARD_VZW, 0xff, 0xff, 0xff) }, | ||
| 738 | { USB_DEVICE_AND_INTERFACE_INFO(DELL_VENDOR_ID, DELL_PRODUCT_5800_V2_MINICARD_VZW, 0xff, 0xff, 0xff) }, | ||
| 722 | { USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ADU_E100A) }, /* ADU-E100, ADU-310 */ | 739 | { USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ADU_E100A) }, /* ADU-E100, ADU-310 */ |
| 723 | { USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ADU_500A) }, | 740 | { USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ADU_500A) }, |
| 724 | { USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ADU_620UW) }, | 741 | { USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ADU_620UW) }, |
| @@ -853,13 +870,19 @@ static const struct usb_device_id option_ids[] = { | |||
| 853 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0113, 0xff, 0xff, 0xff), | 870 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0113, 0xff, 0xff, 0xff), |
| 854 | .driver_info = (kernel_ulong_t)&net_intf5_blacklist }, | 871 | .driver_info = (kernel_ulong_t)&net_intf5_blacklist }, |
| 855 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0117, 0xff, 0xff, 0xff) }, | 872 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0117, 0xff, 0xff, 0xff) }, |
| 856 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0118, 0xff, 0xff, 0xff) }, | 873 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0118, 0xff, 0xff, 0xff), |
| 857 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0121, 0xff, 0xff, 0xff) }, | 874 | .driver_info = (kernel_ulong_t)&net_intf5_blacklist }, |
| 875 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0121, 0xff, 0xff, 0xff), | ||
| 876 | .driver_info = (kernel_ulong_t)&net_intf5_blacklist }, | ||
| 858 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0122, 0xff, 0xff, 0xff) }, | 877 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0122, 0xff, 0xff, 0xff) }, |
| 859 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0123, 0xff, 0xff, 0xff) }, | 878 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0123, 0xff, 0xff, 0xff), |
| 860 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0124, 0xff, 0xff, 0xff) }, | 879 | .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, |
| 861 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0125, 0xff, 0xff, 0xff) }, | 880 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0124, 0xff, 0xff, 0xff), |
| 862 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0126, 0xff, 0xff, 0xff) }, | 881 | .driver_info = (kernel_ulong_t)&net_intf5_blacklist }, |
| 882 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0125, 0xff, 0xff, 0xff), | ||
| 883 | .driver_info = (kernel_ulong_t)&net_intf6_blacklist }, | ||
| 884 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0126, 0xff, 0xff, 0xff), | ||
| 885 | .driver_info = (kernel_ulong_t)&net_intf5_blacklist }, | ||
| 863 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0128, 0xff, 0xff, 0xff) }, | 886 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0128, 0xff, 0xff, 0xff) }, |
| 864 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0142, 0xff, 0xff, 0xff) }, | 887 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0142, 0xff, 0xff, 0xff) }, |
| 865 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0143, 0xff, 0xff, 0xff) }, | 888 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0143, 0xff, 0xff, 0xff) }, |
| @@ -872,7 +895,8 @@ static const struct usb_device_id option_ids[] = { | |||
| 872 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0156, 0xff, 0xff, 0xff) }, | 895 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0156, 0xff, 0xff, 0xff) }, |
| 873 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0157, 0xff, 0xff, 0xff), | 896 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0157, 0xff, 0xff, 0xff), |
| 874 | .driver_info = (kernel_ulong_t)&net_intf5_blacklist }, | 897 | .driver_info = (kernel_ulong_t)&net_intf5_blacklist }, |
| 875 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0158, 0xff, 0xff, 0xff) }, | 898 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0158, 0xff, 0xff, 0xff), |
| 899 | .driver_info = (kernel_ulong_t)&net_intf3_blacklist }, | ||
| 876 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0159, 0xff, 0xff, 0xff) }, | 900 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0159, 0xff, 0xff, 0xff) }, |
| 877 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0161, 0xff, 0xff, 0xff) }, | 901 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0161, 0xff, 0xff, 0xff) }, |
| 878 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0162, 0xff, 0xff, 0xff) }, | 902 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0162, 0xff, 0xff, 0xff) }, |
| @@ -880,13 +904,22 @@ static const struct usb_device_id option_ids[] = { | |||
| 880 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0165, 0xff, 0xff, 0xff) }, | 904 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0165, 0xff, 0xff, 0xff) }, |
| 881 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0167, 0xff, 0xff, 0xff), | 905 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0167, 0xff, 0xff, 0xff), |
| 882 | .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, | 906 | .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, |
| 907 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0191, 0xff, 0xff, 0xff), /* ZTE EuFi890 */ | ||
| 908 | .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, | ||
| 909 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0199, 0xff, 0xff, 0xff), /* ZTE MF820S */ | ||
| 910 | .driver_info = (kernel_ulong_t)&net_intf1_blacklist }, | ||
| 911 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0257, 0xff, 0xff, 0xff), /* ZTE MF821 */ | ||
| 912 | .driver_info = (kernel_ulong_t)&net_intf3_blacklist }, | ||
| 883 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0326, 0xff, 0xff, 0xff), | 913 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0326, 0xff, 0xff, 0xff), |
| 884 | .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, | 914 | .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, |
| 885 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1008, 0xff, 0xff, 0xff), | 915 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1008, 0xff, 0xff, 0xff), |
| 886 | .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, | 916 | .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, |
| 887 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1010, 0xff, 0xff, 0xff), | 917 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1010, 0xff, 0xff, 0xff), |
| 888 | .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, | 918 | .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, |
| 889 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1012, 0xff, 0xff, 0xff) }, | 919 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1012, 0xff, 0xff, 0xff), |
| 920 | .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, | ||
| 921 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1021, 0xff, 0xff, 0xff), | ||
| 922 | .driver_info = (kernel_ulong_t)&net_intf2_blacklist }, | ||
| 890 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1057, 0xff, 0xff, 0xff) }, | 923 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1057, 0xff, 0xff, 0xff) }, |
| 891 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1058, 0xff, 0xff, 0xff) }, | 924 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1058, 0xff, 0xff, 0xff) }, |
| 892 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1059, 0xff, 0xff, 0xff) }, | 925 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1059, 0xff, 0xff, 0xff) }, |
| @@ -1002,18 +1035,24 @@ static const struct usb_device_id option_ids[] = { | |||
| 1002 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1169, 0xff, 0xff, 0xff) }, | 1035 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1169, 0xff, 0xff, 0xff) }, |
| 1003 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1170, 0xff, 0xff, 0xff) }, | 1036 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1170, 0xff, 0xff, 0xff) }, |
| 1004 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1244, 0xff, 0xff, 0xff) }, | 1037 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1244, 0xff, 0xff, 0xff) }, |
| 1005 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1245, 0xff, 0xff, 0xff) }, | 1038 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1245, 0xff, 0xff, 0xff), |
| 1039 | .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, | ||
| 1006 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1246, 0xff, 0xff, 0xff) }, | 1040 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1246, 0xff, 0xff, 0xff) }, |
| 1007 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1247, 0xff, 0xff, 0xff) }, | 1041 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1247, 0xff, 0xff, 0xff), |
| 1042 | .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, | ||
| 1008 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1248, 0xff, 0xff, 0xff) }, | 1043 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1248, 0xff, 0xff, 0xff) }, |
| 1009 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1249, 0xff, 0xff, 0xff) }, | 1044 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1249, 0xff, 0xff, 0xff) }, |
| 1010 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1250, 0xff, 0xff, 0xff) }, | 1045 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1250, 0xff, 0xff, 0xff) }, |
| 1011 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1251, 0xff, 0xff, 0xff) }, | 1046 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1251, 0xff, 0xff, 0xff) }, |
| 1012 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1252, 0xff, 0xff, 0xff) }, | 1047 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1252, 0xff, 0xff, 0xff), |
| 1048 | .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, | ||
| 1013 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1253, 0xff, 0xff, 0xff) }, | 1049 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1253, 0xff, 0xff, 0xff) }, |
| 1014 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1254, 0xff, 0xff, 0xff) }, | 1050 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1254, 0xff, 0xff, 0xff), |
| 1015 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1255, 0xff, 0xff, 0xff) }, | 1051 | .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, |
| 1016 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1256, 0xff, 0xff, 0xff) }, | 1052 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1255, 0xff, 0xff, 0xff), |
| 1053 | .driver_info = (kernel_ulong_t)&zte_1255_blacklist }, | ||
| 1054 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1256, 0xff, 0xff, 0xff), | ||
| 1055 | .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, | ||
| 1017 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1257, 0xff, 0xff, 0xff) }, | 1056 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1257, 0xff, 0xff, 0xff) }, |
| 1018 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1258, 0xff, 0xff, 0xff) }, | 1057 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1258, 0xff, 0xff, 0xff) }, |
| 1019 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1259, 0xff, 0xff, 0xff) }, | 1058 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1259, 0xff, 0xff, 0xff) }, |
| @@ -1058,8 +1097,16 @@ static const struct usb_device_id option_ids[] = { | |||
| 1058 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1298, 0xff, 0xff, 0xff) }, | 1097 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1298, 0xff, 0xff, 0xff) }, |
| 1059 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1299, 0xff, 0xff, 0xff) }, | 1098 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1299, 0xff, 0xff, 0xff) }, |
| 1060 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1300, 0xff, 0xff, 0xff) }, | 1099 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1300, 0xff, 0xff, 0xff) }, |
| 1100 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1401, 0xff, 0xff, 0xff), | ||
| 1101 | .driver_info = (kernel_ulong_t)&net_intf2_blacklist }, | ||
| 1061 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1402, 0xff, 0xff, 0xff), | 1102 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1402, 0xff, 0xff, 0xff), |
| 1062 | .driver_info = (kernel_ulong_t)&net_intf2_blacklist }, | 1103 | .driver_info = (kernel_ulong_t)&net_intf2_blacklist }, |
| 1104 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1424, 0xff, 0xff, 0xff), | ||
| 1105 | .driver_info = (kernel_ulong_t)&net_intf2_blacklist }, | ||
| 1106 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1425, 0xff, 0xff, 0xff), | ||
| 1107 | .driver_info = (kernel_ulong_t)&net_intf2_blacklist }, | ||
| 1108 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1426, 0xff, 0xff, 0xff), /* ZTE MF91 */ | ||
| 1109 | .driver_info = (kernel_ulong_t)&net_intf2_blacklist }, | ||
| 1063 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x2002, 0xff, | 1110 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x2002, 0xff, |
| 1064 | 0xff, 0xff), .driver_info = (kernel_ulong_t)&zte_k3765_z_blacklist }, | 1111 | 0xff, 0xff), .driver_info = (kernel_ulong_t)&zte_k3765_z_blacklist }, |
| 1065 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x2003, 0xff, 0xff, 0xff) }, | 1112 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x2003, 0xff, 0xff, 0xff) }, |
| @@ -1071,15 +1118,21 @@ static const struct usb_device_id option_ids[] = { | |||
| 1071 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0070, 0xff, 0xff, 0xff) }, | 1118 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0070, 0xff, 0xff, 0xff) }, |
| 1072 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0073, 0xff, 0xff, 0xff) }, | 1119 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0073, 0xff, 0xff, 0xff) }, |
| 1073 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0094, 0xff, 0xff, 0xff) }, | 1120 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0094, 0xff, 0xff, 0xff) }, |
| 1074 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0130, 0xff, 0xff, 0xff) }, | 1121 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0130, 0xff, 0xff, 0xff), |
| 1075 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0133, 0xff, 0xff, 0xff) }, | 1122 | .driver_info = (kernel_ulong_t)&net_intf1_blacklist }, |
| 1076 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0141, 0xff, 0xff, 0xff) }, | 1123 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0133, 0xff, 0xff, 0xff), |
| 1124 | .driver_info = (kernel_ulong_t)&net_intf3_blacklist }, | ||
| 1125 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0141, 0xff, 0xff, 0xff), | ||
| 1126 | .driver_info = (kernel_ulong_t)&net_intf5_blacklist }, | ||
| 1077 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0147, 0xff, 0xff, 0xff) }, | 1127 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0147, 0xff, 0xff, 0xff) }, |
| 1078 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0152, 0xff, 0xff, 0xff) }, | 1128 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0152, 0xff, 0xff, 0xff) }, |
| 1079 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0168, 0xff, 0xff, 0xff) }, | 1129 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0168, 0xff, 0xff, 0xff), |
| 1130 | .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, | ||
| 1080 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0170, 0xff, 0xff, 0xff) }, | 1131 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0170, 0xff, 0xff, 0xff) }, |
| 1081 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0176, 0xff, 0xff, 0xff) }, | 1132 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0176, 0xff, 0xff, 0xff), |
| 1082 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0178, 0xff, 0xff, 0xff) }, | 1133 | .driver_info = (kernel_ulong_t)&net_intf3_blacklist }, |
| 1134 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0178, 0xff, 0xff, 0xff), | ||
| 1135 | .driver_info = (kernel_ulong_t)&net_intf3_blacklist }, | ||
| 1083 | 1136 | ||
| 1084 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_CDMA_TECH, 0xff, 0xff, 0xff) }, | 1137 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_CDMA_TECH, 0xff, 0xff, 0xff) }, |
| 1085 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_AC8710, 0xff, 0xff, 0xff) }, | 1138 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_AC8710, 0xff, 0xff, 0xff) }, |
| @@ -1112,6 +1165,7 @@ static const struct usb_device_id option_ids[] = { | |||
| 1112 | { USB_DEVICE(ALCATEL_VENDOR_ID, ALCATEL_PRODUCT_X060S_X200), | 1165 | { USB_DEVICE(ALCATEL_VENDOR_ID, ALCATEL_PRODUCT_X060S_X200), |
| 1113 | .driver_info = (kernel_ulong_t)&alcatel_x200_blacklist | 1166 | .driver_info = (kernel_ulong_t)&alcatel_x200_blacklist |
| 1114 | }, | 1167 | }, |
| 1168 | { USB_DEVICE(ALCATEL_VENDOR_ID, ALCATEL_PRODUCT_X220_X500D) }, | ||
| 1115 | { USB_DEVICE(AIRPLUS_VENDOR_ID, AIRPLUS_PRODUCT_MCD650) }, | 1169 | { USB_DEVICE(AIRPLUS_VENDOR_ID, AIRPLUS_PRODUCT_MCD650) }, |
| 1116 | { USB_DEVICE(TLAYTECH_VENDOR_ID, TLAYTECH_PRODUCT_TEU800) }, | 1170 | { USB_DEVICE(TLAYTECH_VENDOR_ID, TLAYTECH_PRODUCT_TEU800) }, |
| 1117 | { USB_DEVICE(LONGCHEER_VENDOR_ID, FOUR_G_SYSTEMS_PRODUCT_W14), | 1171 | { USB_DEVICE(LONGCHEER_VENDOR_ID, FOUR_G_SYSTEMS_PRODUCT_W14), |
| @@ -1244,8 +1298,9 @@ static struct usb_serial_driver option_1port_device = { | |||
| 1244 | .tiocmget = usb_wwan_tiocmget, | 1298 | .tiocmget = usb_wwan_tiocmget, |
| 1245 | .tiocmset = usb_wwan_tiocmset, | 1299 | .tiocmset = usb_wwan_tiocmset, |
| 1246 | .ioctl = usb_wwan_ioctl, | 1300 | .ioctl = usb_wwan_ioctl, |
| 1247 | .attach = usb_wwan_startup, | 1301 | .attach = option_attach, |
| 1248 | .release = option_release, | 1302 | .release = option_release, |
| 1303 | .port_probe = usb_wwan_port_probe, | ||
| 1249 | .port_remove = usb_wwan_port_remove, | 1304 | .port_remove = usb_wwan_port_remove, |
| 1250 | .read_int_callback = option_instat_callback, | 1305 | .read_int_callback = option_instat_callback, |
| 1251 | #ifdef CONFIG_PM | 1306 | #ifdef CONFIG_PM |
| @@ -1291,8 +1346,6 @@ static bool is_blacklisted(const u8 ifnum, enum option_blacklist_reason reason, | |||
| 1291 | static int option_probe(struct usb_serial *serial, | 1346 | static int option_probe(struct usb_serial *serial, |
| 1292 | const struct usb_device_id *id) | 1347 | const struct usb_device_id *id) |
| 1293 | { | 1348 | { |
| 1294 | struct usb_wwan_intf_private *data; | ||
| 1295 | struct option_private *priv; | ||
| 1296 | struct usb_interface_descriptor *iface_desc = | 1349 | struct usb_interface_descriptor *iface_desc = |
| 1297 | &serial->interface->cur_altsetting->desc; | 1350 | &serial->interface->cur_altsetting->desc; |
| 1298 | struct usb_device_descriptor *dev_desc = &serial->dev->descriptor; | 1351 | struct usb_device_descriptor *dev_desc = &serial->dev->descriptor; |
| @@ -1330,6 +1383,19 @@ static int option_probe(struct usb_serial *serial, | |||
| 1330 | iface_desc->bInterfaceClass != USB_CLASS_CDC_DATA) | 1383 | iface_desc->bInterfaceClass != USB_CLASS_CDC_DATA) |
| 1331 | return -ENODEV; | 1384 | return -ENODEV; |
| 1332 | 1385 | ||
| 1386 | /* Store device id so we can use it during attach. */ | ||
| 1387 | usb_set_serial_data(serial, (void *)id); | ||
| 1388 | |||
| 1389 | return 0; | ||
| 1390 | } | ||
| 1391 | |||
| 1392 | static int option_attach(struct usb_serial *serial) | ||
| 1393 | { | ||
| 1394 | struct usb_interface_descriptor *iface_desc; | ||
| 1395 | const struct usb_device_id *id; | ||
| 1396 | struct usb_wwan_intf_private *data; | ||
| 1397 | struct option_private *priv; | ||
| 1398 | |||
| 1333 | data = kzalloc(sizeof(struct usb_wwan_intf_private), GFP_KERNEL); | 1399 | data = kzalloc(sizeof(struct usb_wwan_intf_private), GFP_KERNEL); |
| 1334 | if (!data) | 1400 | if (!data) |
| 1335 | return -ENOMEM; | 1401 | return -ENOMEM; |
| @@ -1340,6 +1406,10 @@ static int option_probe(struct usb_serial *serial, | |||
| 1340 | return -ENOMEM; | 1406 | return -ENOMEM; |
| 1341 | } | 1407 | } |
| 1342 | 1408 | ||
| 1409 | /* Retrieve device id stored at probe. */ | ||
| 1410 | id = usb_get_serial_data(serial); | ||
| 1411 | iface_desc = &serial->interface->cur_altsetting->desc; | ||
| 1412 | |||
| 1343 | priv->bInterfaceNumber = iface_desc->bInterfaceNumber; | 1413 | priv->bInterfaceNumber = iface_desc->bInterfaceNumber; |
| 1344 | data->private = priv; | 1414 | data->private = priv; |
| 1345 | 1415 | ||
diff --git a/drivers/usb/serial/oti6858.c b/drivers/usb/serial/oti6858.c index 933241f03fd8..cee9a52ca891 100644 --- a/drivers/usb/serial/oti6858.c +++ b/drivers/usb/serial/oti6858.c | |||
| @@ -137,8 +137,8 @@ static int oti6858_chars_in_buffer(struct tty_struct *tty); | |||
| 137 | static int oti6858_tiocmget(struct tty_struct *tty); | 137 | static int oti6858_tiocmget(struct tty_struct *tty); |
| 138 | static int oti6858_tiocmset(struct tty_struct *tty, | 138 | static int oti6858_tiocmset(struct tty_struct *tty, |
| 139 | unsigned int set, unsigned int clear); | 139 | unsigned int set, unsigned int clear); |
| 140 | static int oti6858_startup(struct usb_serial *serial); | 140 | static int oti6858_port_probe(struct usb_serial_port *port); |
| 141 | static void oti6858_release(struct usb_serial *serial); | 141 | static int oti6858_port_remove(struct usb_serial_port *port); |
| 142 | 142 | ||
| 143 | /* device info */ | 143 | /* device info */ |
| 144 | static struct usb_serial_driver oti6858_device = { | 144 | static struct usb_serial_driver oti6858_device = { |
| @@ -161,8 +161,8 @@ static struct usb_serial_driver oti6858_device = { | |||
| 161 | .write_bulk_callback = oti6858_write_bulk_callback, | 161 | .write_bulk_callback = oti6858_write_bulk_callback, |
| 162 | .write_room = oti6858_write_room, | 162 | .write_room = oti6858_write_room, |
| 163 | .chars_in_buffer = oti6858_chars_in_buffer, | 163 | .chars_in_buffer = oti6858_chars_in_buffer, |
| 164 | .attach = oti6858_startup, | 164 | .port_probe = oti6858_port_probe, |
| 165 | .release = oti6858_release, | 165 | .port_remove = oti6858_port_remove, |
| 166 | }; | 166 | }; |
| 167 | 167 | ||
| 168 | static struct usb_serial_driver * const serial_drivers[] = { | 168 | static struct usb_serial_driver * const serial_drivers[] = { |
| @@ -331,36 +331,33 @@ static void send_data(struct work_struct *work) | |||
| 331 | usb_serial_port_softint(port); | 331 | usb_serial_port_softint(port); |
| 332 | } | 332 | } |
| 333 | 333 | ||
| 334 | static int oti6858_startup(struct usb_serial *serial) | 334 | static int oti6858_port_probe(struct usb_serial_port *port) |
| 335 | { | 335 | { |
| 336 | struct usb_serial_port *port = serial->port[0]; | ||
| 337 | struct oti6858_private *priv; | 336 | struct oti6858_private *priv; |
| 338 | int i; | ||
| 339 | |||
| 340 | for (i = 0; i < serial->num_ports; ++i) { | ||
| 341 | priv = kzalloc(sizeof(struct oti6858_private), GFP_KERNEL); | ||
| 342 | if (!priv) | ||
| 343 | break; | ||
| 344 | |||
| 345 | spin_lock_init(&priv->lock); | ||
| 346 | init_waitqueue_head(&priv->intr_wait); | ||
| 347 | /* INIT_WORK(&priv->setup_work, setup_line, serial->port[i]); */ | ||
| 348 | /* INIT_WORK(&priv->write_work, send_data, serial->port[i]); */ | ||
| 349 | priv->port = port; | ||
| 350 | INIT_DELAYED_WORK(&priv->delayed_setup_work, setup_line); | ||
| 351 | INIT_DELAYED_WORK(&priv->delayed_write_work, send_data); | ||
| 352 | |||
| 353 | usb_set_serial_port_data(serial->port[i], priv); | ||
| 354 | } | ||
| 355 | if (i == serial->num_ports) | ||
| 356 | return 0; | ||
| 357 | 337 | ||
| 358 | for (--i; i >= 0; --i) { | 338 | priv = kzalloc(sizeof(*priv), GFP_KERNEL); |
| 359 | priv = usb_get_serial_port_data(serial->port[i]); | 339 | if (!priv) |
| 360 | kfree(priv); | 340 | return -ENOMEM; |
| 361 | usb_set_serial_port_data(serial->port[i], NULL); | 341 | |
| 362 | } | 342 | spin_lock_init(&priv->lock); |
| 363 | return -ENOMEM; | 343 | init_waitqueue_head(&priv->intr_wait); |
| 344 | priv->port = port; | ||
| 345 | INIT_DELAYED_WORK(&priv->delayed_setup_work, setup_line); | ||
| 346 | INIT_DELAYED_WORK(&priv->delayed_write_work, send_data); | ||
| 347 | |||
| 348 | usb_set_serial_port_data(port, priv); | ||
| 349 | |||
| 350 | return 0; | ||
| 351 | } | ||
| 352 | |||
| 353 | static int oti6858_port_remove(struct usb_serial_port *port) | ||
| 354 | { | ||
| 355 | struct oti6858_private *priv; | ||
| 356 | |||
| 357 | priv = usb_get_serial_port_data(port); | ||
| 358 | kfree(priv); | ||
| 359 | |||
| 360 | return 0; | ||
| 364 | } | 361 | } |
| 365 | 362 | ||
| 366 | static int oti6858_write(struct tty_struct *tty, struct usb_serial_port *port, | 363 | static int oti6858_write(struct tty_struct *tty, struct usb_serial_port *port, |
| @@ -709,15 +706,6 @@ static int oti6858_ioctl(struct tty_struct *tty, | |||
| 709 | return -ENOIOCTLCMD; | 706 | return -ENOIOCTLCMD; |
| 710 | } | 707 | } |
| 711 | 708 | ||
| 712 | |||
| 713 | static void oti6858_release(struct usb_serial *serial) | ||
| 714 | { | ||
| 715 | int i; | ||
| 716 | |||
| 717 | for (i = 0; i < serial->num_ports; ++i) | ||
| 718 | kfree(usb_get_serial_port_data(serial->port[i])); | ||
| 719 | } | ||
| 720 | |||
| 721 | static void oti6858_read_int_callback(struct urb *urb) | 709 | static void oti6858_read_int_callback(struct urb *urb) |
| 722 | { | 710 | { |
| 723 | struct usb_serial_port *port = urb->context; | 711 | struct usb_serial_port *port = urb->context; |
diff --git a/drivers/usb/serial/pl2303.c b/drivers/usb/serial/pl2303.c index 892ebdc7a364..600241901361 100644 --- a/drivers/usb/serial/pl2303.c +++ b/drivers/usb/serial/pl2303.c | |||
| @@ -133,12 +133,15 @@ enum pl2303_type { | |||
| 133 | HX, /* HX version of the pl2303 chip */ | 133 | HX, /* HX version of the pl2303 chip */ |
| 134 | }; | 134 | }; |
| 135 | 135 | ||
| 136 | struct pl2303_serial_private { | ||
| 137 | enum pl2303_type type; | ||
| 138 | }; | ||
| 139 | |||
| 136 | struct pl2303_private { | 140 | struct pl2303_private { |
| 137 | spinlock_t lock; | 141 | spinlock_t lock; |
| 138 | wait_queue_head_t delta_msr_wait; | 142 | wait_queue_head_t delta_msr_wait; |
| 139 | u8 line_control; | 143 | u8 line_control; |
| 140 | u8 line_status; | 144 | u8 line_status; |
| 141 | enum pl2303_type type; | ||
| 142 | }; | 145 | }; |
| 143 | 146 | ||
| 144 | static int pl2303_vendor_read(__u16 value, __u16 index, | 147 | static int pl2303_vendor_read(__u16 value, __u16 index, |
| @@ -167,14 +170,19 @@ static int pl2303_vendor_write(__u16 value, __u16 index, | |||
| 167 | 170 | ||
| 168 | static int pl2303_startup(struct usb_serial *serial) | 171 | static int pl2303_startup(struct usb_serial *serial) |
| 169 | { | 172 | { |
| 170 | struct pl2303_private *priv; | 173 | struct pl2303_serial_private *spriv; |
| 171 | enum pl2303_type type = type_0; | 174 | enum pl2303_type type = type_0; |
| 172 | unsigned char *buf; | 175 | unsigned char *buf; |
| 173 | int i; | 176 | |
| 177 | spriv = kzalloc(sizeof(*spriv), GFP_KERNEL); | ||
| 178 | if (!spriv) | ||
| 179 | return -ENOMEM; | ||
| 174 | 180 | ||
| 175 | buf = kmalloc(10, GFP_KERNEL); | 181 | buf = kmalloc(10, GFP_KERNEL); |
| 176 | if (buf == NULL) | 182 | if (!buf) { |
| 183 | kfree(spriv); | ||
| 177 | return -ENOMEM; | 184 | return -ENOMEM; |
| 185 | } | ||
| 178 | 186 | ||
| 179 | if (serial->dev->descriptor.bDeviceClass == 0x02) | 187 | if (serial->dev->descriptor.bDeviceClass == 0x02) |
| 180 | type = type_0; | 188 | type = type_0; |
| @@ -186,15 +194,8 @@ static int pl2303_startup(struct usb_serial *serial) | |||
| 186 | type = type_1; | 194 | type = type_1; |
| 187 | dev_dbg(&serial->interface->dev, "device type: %d\n", type); | 195 | dev_dbg(&serial->interface->dev, "device type: %d\n", type); |
| 188 | 196 | ||
| 189 | for (i = 0; i < serial->num_ports; ++i) { | 197 | spriv->type = type; |
| 190 | priv = kzalloc(sizeof(struct pl2303_private), GFP_KERNEL); | 198 | usb_set_serial_data(serial, spriv); |
| 191 | if (!priv) | ||
| 192 | goto cleanup; | ||
| 193 | spin_lock_init(&priv->lock); | ||
| 194 | init_waitqueue_head(&priv->delta_msr_wait); | ||
| 195 | priv->type = type; | ||
| 196 | usb_set_serial_port_data(serial->port[i], priv); | ||
| 197 | } | ||
| 198 | 199 | ||
| 199 | pl2303_vendor_read(0x8484, 0, serial, buf); | 200 | pl2303_vendor_read(0x8484, 0, serial, buf); |
| 200 | pl2303_vendor_write(0x0404, 0, serial); | 201 | pl2303_vendor_write(0x0404, 0, serial); |
| @@ -213,15 +214,40 @@ static int pl2303_startup(struct usb_serial *serial) | |||
| 213 | 214 | ||
| 214 | kfree(buf); | 215 | kfree(buf); |
| 215 | return 0; | 216 | return 0; |
| 217 | } | ||
| 216 | 218 | ||
| 217 | cleanup: | 219 | static void pl2303_release(struct usb_serial *serial) |
| 218 | kfree(buf); | 220 | { |
| 219 | for (--i; i >= 0; --i) { | 221 | struct pl2303_serial_private *spriv; |
| 220 | priv = usb_get_serial_port_data(serial->port[i]); | 222 | |
| 221 | kfree(priv); | 223 | spriv = usb_get_serial_data(serial); |
| 222 | usb_set_serial_port_data(serial->port[i], NULL); | 224 | kfree(spriv); |
| 223 | } | 225 | } |
| 224 | return -ENOMEM; | 226 | |
| 227 | static int pl2303_port_probe(struct usb_serial_port *port) | ||
| 228 | { | ||
| 229 | struct pl2303_private *priv; | ||
| 230 | |||
| 231 | priv = kzalloc(sizeof(*priv), GFP_KERNEL); | ||
| 232 | if (!priv) | ||
| 233 | return -ENOMEM; | ||
| 234 | |||
| 235 | spin_lock_init(&priv->lock); | ||
| 236 | init_waitqueue_head(&priv->delta_msr_wait); | ||
| 237 | |||
| 238 | usb_set_serial_port_data(port, priv); | ||
| 239 | |||
| 240 | return 0; | ||
| 241 | } | ||
| 242 | |||
| 243 | static int pl2303_port_remove(struct usb_serial_port *port) | ||
| 244 | { | ||
| 245 | struct pl2303_private *priv; | ||
| 246 | |||
| 247 | priv = usb_get_serial_port_data(port); | ||
| 248 | kfree(priv); | ||
| 249 | |||
| 250 | return 0; | ||
| 225 | } | 251 | } |
| 226 | 252 | ||
| 227 | static int set_control_lines(struct usb_device *dev, u8 value) | 253 | static int set_control_lines(struct usb_device *dev, u8 value) |
| @@ -240,6 +266,7 @@ static void pl2303_set_termios(struct tty_struct *tty, | |||
| 240 | struct usb_serial_port *port, struct ktermios *old_termios) | 266 | struct usb_serial_port *port, struct ktermios *old_termios) |
| 241 | { | 267 | { |
| 242 | struct usb_serial *serial = port->serial; | 268 | struct usb_serial *serial = port->serial; |
| 269 | struct pl2303_serial_private *spriv = usb_get_serial_data(serial); | ||
| 243 | struct pl2303_private *priv = usb_get_serial_port_data(port); | 270 | struct pl2303_private *priv = usb_get_serial_port_data(port); |
| 244 | unsigned long flags; | 271 | unsigned long flags; |
| 245 | unsigned int cflag; | 272 | unsigned int cflag; |
| @@ -323,7 +350,7 @@ static void pl2303_set_termios(struct tty_struct *tty, | |||
| 323 | } | 350 | } |
| 324 | if (baud > 1228800) { | 351 | if (baud > 1228800) { |
| 325 | /* type_0, type_1 only support up to 1228800 baud */ | 352 | /* type_0, type_1 only support up to 1228800 baud */ |
| 326 | if (priv->type != HX) | 353 | if (spriv->type != HX) |
| 327 | baud = 1228800; | 354 | baud = 1228800; |
| 328 | else if (baud > 6000000) | 355 | else if (baud > 6000000) |
| 329 | baud = 6000000; | 356 | baud = 6000000; |
| @@ -426,7 +453,7 @@ static void pl2303_set_termios(struct tty_struct *tty, | |||
| 426 | buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], buf[6]); | 453 | buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], buf[6]); |
| 427 | 454 | ||
| 428 | if (cflag & CRTSCTS) { | 455 | if (cflag & CRTSCTS) { |
| 429 | if (priv->type == HX) | 456 | if (spriv->type == HX) |
| 430 | pl2303_vendor_write(0x0, 0x61, serial); | 457 | pl2303_vendor_write(0x0, 0x61, serial); |
| 431 | else | 458 | else |
| 432 | pl2303_vendor_write(0x0, 0x41, serial); | 459 | pl2303_vendor_write(0x0, 0x41, serial); |
| @@ -468,10 +495,10 @@ static int pl2303_open(struct tty_struct *tty, struct usb_serial_port *port) | |||
| 468 | { | 495 | { |
| 469 | struct ktermios tmp_termios; | 496 | struct ktermios tmp_termios; |
| 470 | struct usb_serial *serial = port->serial; | 497 | struct usb_serial *serial = port->serial; |
| 471 | struct pl2303_private *priv = usb_get_serial_port_data(port); | 498 | struct pl2303_serial_private *spriv = usb_get_serial_data(serial); |
| 472 | int result; | 499 | int result; |
| 473 | 500 | ||
| 474 | if (priv->type != HX) { | 501 | if (spriv->type != HX) { |
| 475 | usb_clear_halt(serial->dev, port->write_urb->pipe); | 502 | usb_clear_halt(serial->dev, port->write_urb->pipe); |
| 476 | usb_clear_halt(serial->dev, port->read_urb->pipe); | 503 | usb_clear_halt(serial->dev, port->read_urb->pipe); |
| 477 | } else { | 504 | } else { |
| @@ -655,17 +682,6 @@ static void pl2303_break_ctl(struct tty_struct *tty, int break_state) | |||
| 655 | dev_err(&port->dev, "error sending break = %d\n", result); | 682 | dev_err(&port->dev, "error sending break = %d\n", result); |
| 656 | } | 683 | } |
| 657 | 684 | ||
| 658 | static void pl2303_release(struct usb_serial *serial) | ||
| 659 | { | ||
| 660 | int i; | ||
| 661 | struct pl2303_private *priv; | ||
| 662 | |||
| 663 | for (i = 0; i < serial->num_ports; ++i) { | ||
| 664 | priv = usb_get_serial_port_data(serial->port[i]); | ||
| 665 | kfree(priv); | ||
| 666 | } | ||
| 667 | } | ||
| 668 | |||
| 669 | static void pl2303_update_line_status(struct usb_serial_port *port, | 685 | static void pl2303_update_line_status(struct usb_serial_port *port, |
| 670 | unsigned char *data, | 686 | unsigned char *data, |
| 671 | unsigned int actual_length) | 687 | unsigned int actual_length) |
| @@ -827,6 +843,8 @@ static struct usb_serial_driver pl2303_device = { | |||
| 827 | .read_int_callback = pl2303_read_int_callback, | 843 | .read_int_callback = pl2303_read_int_callback, |
| 828 | .attach = pl2303_startup, | 844 | .attach = pl2303_startup, |
| 829 | .release = pl2303_release, | 845 | .release = pl2303_release, |
| 846 | .port_probe = pl2303_port_probe, | ||
| 847 | .port_remove = pl2303_port_remove, | ||
| 830 | }; | 848 | }; |
| 831 | 849 | ||
| 832 | static struct usb_serial_driver * const serial_drivers[] = { | 850 | static struct usb_serial_driver * const serial_drivers[] = { |
diff --git a/drivers/usb/serial/qcserial.c b/drivers/usb/serial/qcserial.c index c3ddb65c05f2..aa148c21ea40 100644 --- a/drivers/usb/serial/qcserial.c +++ b/drivers/usb/serial/qcserial.c | |||
| @@ -138,7 +138,6 @@ MODULE_DEVICE_TABLE(usb, id_table); | |||
| 138 | 138 | ||
| 139 | static int qcprobe(struct usb_serial *serial, const struct usb_device_id *id) | 139 | static int qcprobe(struct usb_serial *serial, const struct usb_device_id *id) |
| 140 | { | 140 | { |
| 141 | struct usb_wwan_intf_private *data; | ||
| 142 | struct usb_host_interface *intf = serial->interface->cur_altsetting; | 141 | struct usb_host_interface *intf = serial->interface->cur_altsetting; |
| 143 | struct device *dev = &serial->dev->dev; | 142 | struct device *dev = &serial->dev->dev; |
| 144 | int retval = -ENODEV; | 143 | int retval = -ENODEV; |
| @@ -154,13 +153,6 @@ static int qcprobe(struct usb_serial *serial, const struct usb_device_id *id) | |||
| 154 | ifnum = intf->desc.bInterfaceNumber; | 153 | ifnum = intf->desc.bInterfaceNumber; |
| 155 | dev_dbg(dev, "This Interface = %d\n", ifnum); | 154 | dev_dbg(dev, "This Interface = %d\n", ifnum); |
| 156 | 155 | ||
| 157 | data = kzalloc(sizeof(struct usb_wwan_intf_private), | ||
| 158 | GFP_KERNEL); | ||
| 159 | if (!data) | ||
| 160 | return -ENOMEM; | ||
| 161 | |||
| 162 | spin_lock_init(&data->susp_lock); | ||
| 163 | |||
| 164 | if (nintf == 1) { | 156 | if (nintf == 1) { |
| 165 | /* QDL mode */ | 157 | /* QDL mode */ |
| 166 | /* Gobi 2000 has a single altsetting, older ones have two */ | 158 | /* Gobi 2000 has a single altsetting, older ones have two */ |
| @@ -253,20 +245,28 @@ done: | |||
| 253 | } | 245 | } |
| 254 | } | 246 | } |
| 255 | 247 | ||
| 256 | /* Set serial->private if not returning error */ | ||
| 257 | if (retval == 0) | ||
| 258 | usb_set_serial_data(serial, data); | ||
| 259 | else | ||
| 260 | kfree(data); | ||
| 261 | |||
| 262 | return retval; | 248 | return retval; |
| 263 | } | 249 | } |
| 264 | 250 | ||
| 251 | static int qc_attach(struct usb_serial *serial) | ||
| 252 | { | ||
| 253 | struct usb_wwan_intf_private *data; | ||
| 254 | |||
| 255 | data = kzalloc(sizeof(*data), GFP_KERNEL); | ||
| 256 | if (!data) | ||
| 257 | return -ENOMEM; | ||
| 258 | |||
| 259 | spin_lock_init(&data->susp_lock); | ||
| 260 | |||
| 261 | usb_set_serial_data(serial, data); | ||
| 262 | |||
| 263 | return 0; | ||
| 264 | } | ||
| 265 | |||
| 265 | static void qc_release(struct usb_serial *serial) | 266 | static void qc_release(struct usb_serial *serial) |
| 266 | { | 267 | { |
| 267 | struct usb_wwan_intf_private *priv = usb_get_serial_data(serial); | 268 | struct usb_wwan_intf_private *priv = usb_get_serial_data(serial); |
| 268 | 269 | ||
| 269 | /* Free the private data allocated in qcprobe */ | ||
| 270 | usb_set_serial_data(serial, NULL); | 270 | usb_set_serial_data(serial, NULL); |
| 271 | kfree(priv); | 271 | kfree(priv); |
| 272 | } | 272 | } |
| @@ -285,8 +285,9 @@ static struct usb_serial_driver qcdevice = { | |||
| 285 | .write = usb_wwan_write, | 285 | .write = usb_wwan_write, |
| 286 | .write_room = usb_wwan_write_room, | 286 | .write_room = usb_wwan_write_room, |
| 287 | .chars_in_buffer = usb_wwan_chars_in_buffer, | 287 | .chars_in_buffer = usb_wwan_chars_in_buffer, |
| 288 | .attach = usb_wwan_startup, | 288 | .attach = qc_attach, |
| 289 | .release = qc_release, | 289 | .release = qc_release, |
| 290 | .port_probe = usb_wwan_port_probe, | ||
| 290 | .port_remove = usb_wwan_port_remove, | 291 | .port_remove = usb_wwan_port_remove, |
| 291 | #ifdef CONFIG_PM | 292 | #ifdef CONFIG_PM |
| 292 | .suspend = usb_wwan_suspend, | 293 | .suspend = usb_wwan_suspend, |
diff --git a/drivers/usb/serial/quatech2.c b/drivers/usb/serial/quatech2.c index 2cdfdcc90b37..ffcfc962ab10 100644 --- a/drivers/usb/serial/quatech2.c +++ b/drivers/usb/serial/quatech2.c | |||
| @@ -143,12 +143,12 @@ static void qt2_read_bulk_callback(struct urb *urb); | |||
| 143 | 143 | ||
| 144 | static void qt2_release(struct usb_serial *serial) | 144 | static void qt2_release(struct usb_serial *serial) |
| 145 | { | 145 | { |
| 146 | int i; | 146 | struct qt2_serial_private *serial_priv; |
| 147 | 147 | ||
| 148 | kfree(usb_get_serial_data(serial)); | 148 | serial_priv = usb_get_serial_data(serial); |
| 149 | 149 | ||
| 150 | for (i = 0; i < serial->num_ports; i++) | 150 | usb_free_urb(serial_priv->read_urb); |
| 151 | kfree(usb_get_serial_port_data(serial->port[i])); | 151 | kfree(serial_priv); |
| 152 | } | 152 | } |
| 153 | 153 | ||
| 154 | static inline int calc_baud_divisor(int baudrate) | 154 | static inline int calc_baud_divisor(int baudrate) |
| @@ -423,11 +423,16 @@ static void qt2_close(struct usb_serial_port *port) | |||
| 423 | port_priv->is_open = false; | 423 | port_priv->is_open = false; |
| 424 | 424 | ||
| 425 | spin_lock_irqsave(&port_priv->urb_lock, flags); | 425 | spin_lock_irqsave(&port_priv->urb_lock, flags); |
| 426 | if (port_priv->write_urb->status == -EINPROGRESS) | 426 | usb_kill_urb(port_priv->write_urb); |
| 427 | usb_kill_urb(port_priv->write_urb); | ||
| 428 | port_priv->urb_in_use = false; | 427 | port_priv->urb_in_use = false; |
| 429 | spin_unlock_irqrestore(&port_priv->urb_lock, flags); | 428 | spin_unlock_irqrestore(&port_priv->urb_lock, flags); |
| 430 | 429 | ||
| 430 | mutex_lock(&port->serial->disc_mutex); | ||
| 431 | if (port->serial->disconnected) { | ||
| 432 | mutex_unlock(&port->serial->disc_mutex); | ||
| 433 | return; | ||
| 434 | } | ||
| 435 | |||
| 431 | /* flush the port transmit buffer */ | 436 | /* flush the port transmit buffer */ |
| 432 | i = usb_control_msg(serial->dev, | 437 | i = usb_control_msg(serial->dev, |
| 433 | usb_rcvctrlpipe(serial->dev, 0), | 438 | usb_rcvctrlpipe(serial->dev, 0), |
| @@ -459,26 +464,14 @@ static void qt2_close(struct usb_serial_port *port) | |||
| 459 | dev_err(&port->dev, "%s - close port failed %i\n", | 464 | dev_err(&port->dev, "%s - close port failed %i\n", |
| 460 | __func__, i); | 465 | __func__, i); |
| 461 | 466 | ||
| 467 | mutex_unlock(&port->serial->disc_mutex); | ||
| 462 | } | 468 | } |
| 463 | 469 | ||
| 464 | static void qt2_disconnect(struct usb_serial *serial) | 470 | static void qt2_disconnect(struct usb_serial *serial) |
| 465 | { | 471 | { |
| 466 | struct qt2_serial_private *serial_priv = usb_get_serial_data(serial); | 472 | struct qt2_serial_private *serial_priv = usb_get_serial_data(serial); |
| 467 | struct qt2_port_private *port_priv; | ||
| 468 | int i; | ||
| 469 | |||
| 470 | if (serial_priv->read_urb->status == -EINPROGRESS) | ||
| 471 | usb_kill_urb(serial_priv->read_urb); | ||
| 472 | |||
| 473 | usb_free_urb(serial_priv->read_urb); | ||
| 474 | 473 | ||
| 475 | for (i = 0; i < serial->num_ports; i++) { | 474 | usb_kill_urb(serial_priv->read_urb); |
| 476 | port_priv = usb_get_serial_port_data(serial->port[i]); | ||
| 477 | |||
| 478 | if (port_priv->write_urb->status == -EINPROGRESS) | ||
| 479 | usb_kill_urb(port_priv->write_urb); | ||
| 480 | usb_free_urb(port_priv->write_urb); | ||
| 481 | } | ||
| 482 | } | 475 | } |
| 483 | 476 | ||
| 484 | static int get_serial_info(struct usb_serial_port *port, | 477 | static int get_serial_info(struct usb_serial_port *port, |
| @@ -773,11 +766,9 @@ static void qt2_read_bulk_callback(struct urb *urb) | |||
| 773 | 766 | ||
| 774 | static int qt2_setup_urbs(struct usb_serial *serial) | 767 | static int qt2_setup_urbs(struct usb_serial *serial) |
| 775 | { | 768 | { |
| 776 | struct usb_serial_port *port; | ||
| 777 | struct usb_serial_port *port0; | 769 | struct usb_serial_port *port0; |
| 778 | struct qt2_serial_private *serial_priv; | 770 | struct qt2_serial_private *serial_priv; |
| 779 | struct qt2_port_private *port_priv; | 771 | int status; |
| 780 | int pcount, status; | ||
| 781 | 772 | ||
| 782 | port0 = serial->port[0]; | 773 | port0 = serial->port[0]; |
| 783 | 774 | ||
| @@ -795,46 +786,21 @@ static int qt2_setup_urbs(struct usb_serial *serial) | |||
| 795 | sizeof(serial_priv->read_buffer), | 786 | sizeof(serial_priv->read_buffer), |
| 796 | qt2_read_bulk_callback, serial); | 787 | qt2_read_bulk_callback, serial); |
| 797 | 788 | ||
| 798 | /* setup write_urb for each port */ | ||
| 799 | for (pcount = 0; pcount < serial->num_ports; pcount++) { | ||
| 800 | |||
| 801 | port = serial->port[pcount]; | ||
| 802 | port_priv = usb_get_serial_port_data(port); | ||
| 803 | |||
| 804 | port_priv->write_urb = usb_alloc_urb(0, GFP_KERNEL); | ||
| 805 | if (!port_priv->write_urb) { | ||
| 806 | dev_err(&serial->dev->dev, | ||
| 807 | "failed to alloc write_urb for port %i\n", | ||
| 808 | pcount); | ||
| 809 | return -ENOMEM; | ||
| 810 | } | ||
| 811 | |||
| 812 | usb_fill_bulk_urb(port_priv->write_urb, | ||
| 813 | serial->dev, | ||
| 814 | usb_sndbulkpipe(serial->dev, | ||
| 815 | port0-> | ||
| 816 | bulk_out_endpointAddress), | ||
| 817 | port_priv->write_buffer, | ||
| 818 | sizeof(port_priv->write_buffer), | ||
| 819 | qt2_write_bulk_callback, port); | ||
| 820 | } | ||
| 821 | |||
| 822 | status = usb_submit_urb(serial_priv->read_urb, GFP_KERNEL); | 789 | status = usb_submit_urb(serial_priv->read_urb, GFP_KERNEL); |
| 823 | if (status != 0) { | 790 | if (status != 0) { |
| 824 | dev_err(&serial->dev->dev, | 791 | dev_err(&serial->dev->dev, |
| 825 | "%s - submit read urb failed %i\n", __func__, status); | 792 | "%s - submit read urb failed %i\n", __func__, status); |
| 793 | usb_free_urb(serial_priv->read_urb); | ||
| 826 | return status; | 794 | return status; |
| 827 | } | 795 | } |
| 828 | 796 | ||
| 829 | return 0; | 797 | return 0; |
| 830 | |||
| 831 | } | 798 | } |
| 832 | 799 | ||
| 833 | static int qt2_attach(struct usb_serial *serial) | 800 | static int qt2_attach(struct usb_serial *serial) |
| 834 | { | 801 | { |
| 835 | struct qt2_serial_private *serial_priv; | 802 | struct qt2_serial_private *serial_priv; |
| 836 | struct qt2_port_private *port_priv; | 803 | int status; |
| 837 | int status, pcount; | ||
| 838 | 804 | ||
| 839 | /* power on unit */ | 805 | /* power on unit */ |
| 840 | status = usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0), | 806 | status = usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0), |
| @@ -854,26 +820,6 @@ static int qt2_attach(struct usb_serial *serial) | |||
| 854 | 820 | ||
| 855 | usb_set_serial_data(serial, serial_priv); | 821 | usb_set_serial_data(serial, serial_priv); |
| 856 | 822 | ||
| 857 | for (pcount = 0; pcount < serial->num_ports; pcount++) { | ||
| 858 | port_priv = kzalloc(sizeof(*port_priv), GFP_KERNEL); | ||
| 859 | if (!port_priv) { | ||
| 860 | dev_err(&serial->dev->dev, | ||
| 861 | "%s- kmalloc(%Zd) failed.\n", __func__, | ||
| 862 | sizeof(*port_priv)); | ||
| 863 | pcount--; | ||
| 864 | status = -ENOMEM; | ||
| 865 | goto attach_failed; | ||
| 866 | } | ||
| 867 | |||
| 868 | spin_lock_init(&port_priv->lock); | ||
| 869 | spin_lock_init(&port_priv->urb_lock); | ||
| 870 | init_waitqueue_head(&port_priv->delta_msr_wait); | ||
| 871 | |||
| 872 | port_priv->port = serial->port[pcount]; | ||
| 873 | |||
| 874 | usb_set_serial_port_data(serial->port[pcount], port_priv); | ||
| 875 | } | ||
| 876 | |||
| 877 | status = qt2_setup_urbs(serial); | 823 | status = qt2_setup_urbs(serial); |
| 878 | if (status != 0) | 824 | if (status != 0) |
| 879 | goto attach_failed; | 825 | goto attach_failed; |
| @@ -881,14 +827,53 @@ static int qt2_attach(struct usb_serial *serial) | |||
| 881 | return 0; | 827 | return 0; |
| 882 | 828 | ||
| 883 | attach_failed: | 829 | attach_failed: |
| 884 | for (/* empty */; pcount >= 0; pcount--) { | ||
| 885 | port_priv = usb_get_serial_port_data(serial->port[pcount]); | ||
| 886 | kfree(port_priv); | ||
| 887 | } | ||
| 888 | kfree(serial_priv); | 830 | kfree(serial_priv); |
| 889 | return status; | 831 | return status; |
| 890 | } | 832 | } |
| 891 | 833 | ||
| 834 | static int qt2_port_probe(struct usb_serial_port *port) | ||
| 835 | { | ||
| 836 | struct usb_serial *serial = port->serial; | ||
| 837 | struct qt2_port_private *port_priv; | ||
| 838 | u8 bEndpointAddress; | ||
| 839 | |||
| 840 | port_priv = kzalloc(sizeof(*port_priv), GFP_KERNEL); | ||
| 841 | if (!port_priv) | ||
| 842 | return -ENOMEM; | ||
| 843 | |||
| 844 | spin_lock_init(&port_priv->lock); | ||
| 845 | spin_lock_init(&port_priv->urb_lock); | ||
| 846 | init_waitqueue_head(&port_priv->delta_msr_wait); | ||
| 847 | port_priv->port = port; | ||
| 848 | |||
| 849 | port_priv->write_urb = usb_alloc_urb(0, GFP_KERNEL); | ||
| 850 | if (!port_priv->write_urb) { | ||
| 851 | kfree(port_priv); | ||
| 852 | return -ENOMEM; | ||
| 853 | } | ||
| 854 | bEndpointAddress = serial->port[0]->bulk_out_endpointAddress; | ||
| 855 | usb_fill_bulk_urb(port_priv->write_urb, serial->dev, | ||
| 856 | usb_sndbulkpipe(serial->dev, bEndpointAddress), | ||
| 857 | port_priv->write_buffer, | ||
| 858 | sizeof(port_priv->write_buffer), | ||
| 859 | qt2_write_bulk_callback, port); | ||
| 860 | |||
| 861 | usb_set_serial_port_data(port, port_priv); | ||
| 862 | |||
| 863 | return 0; | ||
| 864 | } | ||
| 865 | |||
| 866 | static int qt2_port_remove(struct usb_serial_port *port) | ||
| 867 | { | ||
| 868 | struct qt2_port_private *port_priv; | ||
| 869 | |||
| 870 | port_priv = usb_get_serial_port_data(port); | ||
| 871 | usb_free_urb(port_priv->write_urb); | ||
| 872 | kfree(port_priv); | ||
| 873 | |||
| 874 | return 0; | ||
| 875 | } | ||
| 876 | |||
| 892 | static int qt2_tiocmget(struct tty_struct *tty) | 877 | static int qt2_tiocmget(struct tty_struct *tty) |
| 893 | { | 878 | { |
| 894 | struct usb_serial_port *port = tty->driver_data; | 879 | struct usb_serial_port *port = tty->driver_data; |
| @@ -1127,6 +1112,8 @@ static struct usb_serial_driver qt2_device = { | |||
| 1127 | .attach = qt2_attach, | 1112 | .attach = qt2_attach, |
| 1128 | .release = qt2_release, | 1113 | .release = qt2_release, |
| 1129 | .disconnect = qt2_disconnect, | 1114 | .disconnect = qt2_disconnect, |
| 1115 | .port_probe = qt2_port_probe, | ||
| 1116 | .port_remove = qt2_port_remove, | ||
| 1130 | .dtr_rts = qt2_dtr_rts, | 1117 | .dtr_rts = qt2_dtr_rts, |
| 1131 | .break_ctl = qt2_break_ctl, | 1118 | .break_ctl = qt2_break_ctl, |
| 1132 | .tiocmget = qt2_tiocmget, | 1119 | .tiocmget = qt2_tiocmget, |
diff --git a/drivers/usb/serial/sierra.c b/drivers/usb/serial/sierra.c index 01d882cf3775..270860f6bb2a 100644 --- a/drivers/usb/serial/sierra.c +++ b/drivers/usb/serial/sierra.c | |||
| @@ -161,7 +161,6 @@ static int sierra_probe(struct usb_serial *serial, | |||
| 161 | { | 161 | { |
| 162 | int result = 0; | 162 | int result = 0; |
| 163 | struct usb_device *udev; | 163 | struct usb_device *udev; |
| 164 | struct sierra_intf_private *data; | ||
| 165 | u8 ifnum; | 164 | u8 ifnum; |
| 166 | 165 | ||
| 167 | udev = serial->dev; | 166 | udev = serial->dev; |
| @@ -188,11 +187,6 @@ static int sierra_probe(struct usb_serial *serial, | |||
| 188 | return -ENODEV; | 187 | return -ENODEV; |
| 189 | } | 188 | } |
| 190 | 189 | ||
| 191 | data = serial->private = kzalloc(sizeof(struct sierra_intf_private), GFP_KERNEL); | ||
| 192 | if (!data) | ||
| 193 | return -ENOMEM; | ||
| 194 | spin_lock_init(&data->susp_lock); | ||
| 195 | |||
| 196 | return result; | 190 | return result; |
| 197 | } | 191 | } |
| 198 | 192 | ||
| @@ -884,11 +878,15 @@ static void sierra_dtr_rts(struct usb_serial_port *port, int on) | |||
| 884 | 878 | ||
| 885 | static int sierra_startup(struct usb_serial *serial) | 879 | static int sierra_startup(struct usb_serial *serial) |
| 886 | { | 880 | { |
| 887 | struct usb_serial_port *port; | 881 | struct sierra_intf_private *intfdata; |
| 888 | struct sierra_port_private *portdata; | 882 | |
| 889 | struct sierra_iface_info *himemoryp = NULL; | 883 | intfdata = kzalloc(sizeof(*intfdata), GFP_KERNEL); |
| 890 | int i; | 884 | if (!intfdata) |
| 891 | u8 ifnum; | 885 | return -ENOMEM; |
| 886 | |||
| 887 | spin_lock_init(&intfdata->susp_lock); | ||
| 888 | |||
| 889 | usb_set_serial_data(serial, intfdata); | ||
| 892 | 890 | ||
| 893 | /* Set Device mode to D0 */ | 891 | /* Set Device mode to D0 */ |
| 894 | sierra_set_power_state(serial->dev, 0x0000); | 892 | sierra_set_power_state(serial->dev, 0x0000); |
| @@ -897,68 +895,71 @@ static int sierra_startup(struct usb_serial *serial) | |||
| 897 | if (nmea) | 895 | if (nmea) |
| 898 | sierra_vsc_set_nmea(serial->dev, 1); | 896 | sierra_vsc_set_nmea(serial->dev, 1); |
| 899 | 897 | ||
| 900 | /* Now setup per port private data */ | ||
| 901 | for (i = 0; i < serial->num_ports; i++) { | ||
| 902 | port = serial->port[i]; | ||
| 903 | portdata = kzalloc(sizeof(*portdata), GFP_KERNEL); | ||
| 904 | if (!portdata) { | ||
| 905 | dev_dbg(&port->dev, "%s: kmalloc for " | ||
| 906 | "sierra_port_private (%d) failed!\n", | ||
| 907 | __func__, i); | ||
| 908 | return -ENOMEM; | ||
| 909 | } | ||
| 910 | spin_lock_init(&portdata->lock); | ||
| 911 | init_usb_anchor(&portdata->active); | ||
| 912 | init_usb_anchor(&portdata->delayed); | ||
| 913 | ifnum = i; | ||
| 914 | /* Assume low memory requirements */ | ||
| 915 | portdata->num_out_urbs = N_OUT_URB; | ||
| 916 | portdata->num_in_urbs = N_IN_URB; | ||
| 917 | |||
| 918 | /* Determine actual memory requirements */ | ||
| 919 | if (serial->num_ports == 1) { | ||
| 920 | /* Get interface number for composite device */ | ||
| 921 | ifnum = sierra_calc_interface(serial); | ||
| 922 | himemoryp = | ||
| 923 | (struct sierra_iface_info *)&typeB_interface_list; | ||
| 924 | if (is_himemory(ifnum, himemoryp)) { | ||
| 925 | portdata->num_out_urbs = N_OUT_URB_HM; | ||
| 926 | portdata->num_in_urbs = N_IN_URB_HM; | ||
| 927 | } | ||
| 928 | } | ||
| 929 | else { | ||
| 930 | himemoryp = | ||
| 931 | (struct sierra_iface_info *)&typeA_interface_list; | ||
| 932 | if (is_himemory(i, himemoryp)) { | ||
| 933 | portdata->num_out_urbs = N_OUT_URB_HM; | ||
| 934 | portdata->num_in_urbs = N_IN_URB_HM; | ||
| 935 | } | ||
| 936 | } | ||
| 937 | dev_dbg(&serial->dev->dev, | ||
| 938 | "Memory usage (urbs) interface #%d, in=%d, out=%d\n", | ||
| 939 | ifnum,portdata->num_in_urbs, portdata->num_out_urbs ); | ||
| 940 | /* Set the port private data pointer */ | ||
| 941 | usb_set_serial_port_data(port, portdata); | ||
| 942 | } | ||
| 943 | |||
| 944 | return 0; | 898 | return 0; |
| 945 | } | 899 | } |
| 946 | 900 | ||
| 947 | static void sierra_release(struct usb_serial *serial) | 901 | static void sierra_release(struct usb_serial *serial) |
| 948 | { | 902 | { |
| 949 | int i; | 903 | struct sierra_intf_private *intfdata; |
| 950 | struct usb_serial_port *port; | 904 | |
| 905 | intfdata = usb_get_serial_data(serial); | ||
| 906 | kfree(intfdata); | ||
| 907 | } | ||
| 908 | |||
| 909 | static int sierra_port_probe(struct usb_serial_port *port) | ||
| 910 | { | ||
| 911 | struct usb_serial *serial = port->serial; | ||
| 951 | struct sierra_port_private *portdata; | 912 | struct sierra_port_private *portdata; |
| 913 | const struct sierra_iface_info *himemoryp; | ||
| 914 | u8 ifnum; | ||
| 952 | 915 | ||
| 953 | for (i = 0; i < serial->num_ports; ++i) { | 916 | portdata = kzalloc(sizeof(*portdata), GFP_KERNEL); |
| 954 | port = serial->port[i]; | 917 | if (!portdata) |
| 955 | if (!port) | 918 | return -ENOMEM; |
| 956 | continue; | 919 | |
| 957 | portdata = usb_get_serial_port_data(port); | 920 | spin_lock_init(&portdata->lock); |
| 958 | if (!portdata) | 921 | init_usb_anchor(&portdata->active); |
| 959 | continue; | 922 | init_usb_anchor(&portdata->delayed); |
| 960 | kfree(portdata); | 923 | |
| 924 | /* Assume low memory requirements */ | ||
| 925 | portdata->num_out_urbs = N_OUT_URB; | ||
| 926 | portdata->num_in_urbs = N_IN_URB; | ||
| 927 | |||
| 928 | /* Determine actual memory requirements */ | ||
| 929 | if (serial->num_ports == 1) { | ||
| 930 | /* Get interface number for composite device */ | ||
| 931 | ifnum = sierra_calc_interface(serial); | ||
| 932 | himemoryp = &typeB_interface_list; | ||
| 933 | } else { | ||
| 934 | /* This is really the usb-serial port number of the interface | ||
| 935 | * rather than the interface number. | ||
| 936 | */ | ||
| 937 | ifnum = port->number - serial->minor; | ||
| 938 | himemoryp = &typeA_interface_list; | ||
| 961 | } | 939 | } |
| 940 | |||
| 941 | if (is_himemory(ifnum, himemoryp)) { | ||
| 942 | portdata->num_out_urbs = N_OUT_URB_HM; | ||
| 943 | portdata->num_in_urbs = N_IN_URB_HM; | ||
| 944 | } | ||
| 945 | |||
| 946 | dev_dbg(&port->dev, | ||
| 947 | "Memory usage (urbs) interface #%d, in=%d, out=%d\n", | ||
| 948 | ifnum, portdata->num_in_urbs, portdata->num_out_urbs); | ||
| 949 | |||
| 950 | usb_set_serial_port_data(port, portdata); | ||
| 951 | |||
| 952 | return 0; | ||
| 953 | } | ||
| 954 | |||
| 955 | static int sierra_port_remove(struct usb_serial_port *port) | ||
| 956 | { | ||
| 957 | struct sierra_port_private *portdata; | ||
| 958 | |||
| 959 | portdata = usb_get_serial_port_data(port); | ||
| 960 | kfree(portdata); | ||
| 961 | |||
| 962 | return 0; | ||
| 962 | } | 963 | } |
| 963 | 964 | ||
| 964 | #ifdef CONFIG_PM | 965 | #ifdef CONFIG_PM |
| @@ -1062,6 +1063,8 @@ static struct usb_serial_driver sierra_device = { | |||
| 1062 | .tiocmset = sierra_tiocmset, | 1063 | .tiocmset = sierra_tiocmset, |
| 1063 | .attach = sierra_startup, | 1064 | .attach = sierra_startup, |
| 1064 | .release = sierra_release, | 1065 | .release = sierra_release, |
| 1066 | .port_probe = sierra_port_probe, | ||
| 1067 | .port_remove = sierra_port_remove, | ||
| 1065 | .suspend = sierra_suspend, | 1068 | .suspend = sierra_suspend, |
| 1066 | .resume = sierra_resume, | 1069 | .resume = sierra_resume, |
| 1067 | .read_int_callback = sierra_instat_callback, | 1070 | .read_int_callback = sierra_instat_callback, |
diff --git a/drivers/usb/serial/spcp8x5.c b/drivers/usb/serial/spcp8x5.c index 9716efe92955..769c137f8975 100644 --- a/drivers/usb/serial/spcp8x5.c +++ b/drivers/usb/serial/spcp8x5.c | |||
| @@ -157,13 +157,10 @@ struct spcp8x5_private { | |||
| 157 | u8 line_status; | 157 | u8 line_status; |
| 158 | }; | 158 | }; |
| 159 | 159 | ||
| 160 | /* desc : when device plug in,this function would be called. | 160 | static int spcp8x5_port_probe(struct usb_serial_port *port) |
| 161 | * thanks to usb_serial subsystem,then do almost every things for us. And what | ||
| 162 | * we should do just alloc the buffer */ | ||
| 163 | static int spcp8x5_startup(struct usb_serial *serial) | ||
| 164 | { | 161 | { |
| 162 | struct usb_serial *serial = port->serial; | ||
| 165 | struct spcp8x5_private *priv; | 163 | struct spcp8x5_private *priv; |
| 166 | int i; | ||
| 167 | enum spcp8x5_type type = SPCP825_007_TYPE; | 164 | enum spcp8x5_type type = SPCP825_007_TYPE; |
| 168 | u16 product = le16_to_cpu(serial->dev->descriptor.idProduct); | 165 | u16 product = le16_to_cpu(serial->dev->descriptor.idProduct); |
| 169 | 166 | ||
| @@ -180,34 +177,27 @@ static int spcp8x5_startup(struct usb_serial *serial) | |||
| 180 | type = SPCP825_PHILIP_TYPE; | 177 | type = SPCP825_PHILIP_TYPE; |
| 181 | dev_dbg(&serial->dev->dev, "device type = %d\n", (int)type); | 178 | dev_dbg(&serial->dev->dev, "device type = %d\n", (int)type); |
| 182 | 179 | ||
| 183 | for (i = 0; i < serial->num_ports; ++i) { | 180 | priv = kzalloc(sizeof(*priv), GFP_KERNEL); |
| 184 | priv = kzalloc(sizeof(struct spcp8x5_private), GFP_KERNEL); | 181 | if (!priv) |
| 185 | if (!priv) | 182 | return -ENOMEM; |
| 186 | goto cleanup; | ||
| 187 | 183 | ||
| 188 | spin_lock_init(&priv->lock); | 184 | spin_lock_init(&priv->lock); |
| 189 | init_waitqueue_head(&priv->delta_msr_wait); | 185 | init_waitqueue_head(&priv->delta_msr_wait); |
| 190 | priv->type = type; | 186 | priv->type = type; |
| 191 | usb_set_serial_port_data(serial->port[i] , priv); | 187 | |
| 192 | } | 188 | usb_set_serial_port_data(port , priv); |
| 193 | 189 | ||
| 194 | return 0; | 190 | return 0; |
| 195 | cleanup: | ||
| 196 | for (--i; i >= 0; --i) { | ||
| 197 | priv = usb_get_serial_port_data(serial->port[i]); | ||
| 198 | kfree(priv); | ||
| 199 | usb_set_serial_port_data(serial->port[i] , NULL); | ||
| 200 | } | ||
| 201 | return -ENOMEM; | ||
| 202 | } | 191 | } |
| 203 | 192 | ||
| 204 | /* call when the device plug out. free all the memory alloced by probe */ | 193 | static int spcp8x5_port_remove(struct usb_serial_port *port) |
| 205 | static void spcp8x5_release(struct usb_serial *serial) | ||
| 206 | { | 194 | { |
| 207 | int i; | 195 | struct spcp8x5_private *priv; |
| 208 | 196 | ||
| 209 | for (i = 0; i < serial->num_ports; i++) | 197 | priv = usb_get_serial_port_data(port); |
| 210 | kfree(usb_get_serial_port_data(serial->port[i])); | 198 | kfree(priv); |
| 199 | |||
| 200 | return 0; | ||
| 211 | } | 201 | } |
| 212 | 202 | ||
| 213 | /* set the modem control line of the device. | 203 | /* set the modem control line of the device. |
| @@ -649,8 +639,8 @@ static struct usb_serial_driver spcp8x5_device = { | |||
| 649 | .ioctl = spcp8x5_ioctl, | 639 | .ioctl = spcp8x5_ioctl, |
| 650 | .tiocmget = spcp8x5_tiocmget, | 640 | .tiocmget = spcp8x5_tiocmget, |
| 651 | .tiocmset = spcp8x5_tiocmset, | 641 | .tiocmset = spcp8x5_tiocmset, |
| 652 | .attach = spcp8x5_startup, | 642 | .port_probe = spcp8x5_port_probe, |
| 653 | .release = spcp8x5_release, | 643 | .port_remove = spcp8x5_port_remove, |
| 654 | .process_read_urb = spcp8x5_process_read_urb, | 644 | .process_read_urb = spcp8x5_process_read_urb, |
| 655 | }; | 645 | }; |
| 656 | 646 | ||
diff --git a/drivers/usb/serial/ssu100.c b/drivers/usb/serial/ssu100.c index 015810b3785b..868d1e6852e2 100644 --- a/drivers/usb/serial/ssu100.c +++ b/drivers/usb/serial/ssu100.c | |||
| @@ -67,13 +67,6 @@ struct ssu100_port_private { | |||
| 67 | struct async_icount icount; | 67 | struct async_icount icount; |
| 68 | }; | 68 | }; |
| 69 | 69 | ||
| 70 | static void ssu100_release(struct usb_serial *serial) | ||
| 71 | { | ||
| 72 | struct ssu100_port_private *priv = usb_get_serial_port_data(*serial->port); | ||
| 73 | |||
| 74 | kfree(priv); | ||
| 75 | } | ||
| 76 | |||
| 77 | static inline int ssu100_control_msg(struct usb_device *dev, | 70 | static inline int ssu100_control_msg(struct usb_device *dev, |
| 78 | u8 request, u16 data, u16 index) | 71 | u8 request, u16 data, u16 index) |
| 79 | { | 72 | { |
| @@ -442,21 +435,33 @@ static int ssu100_ioctl(struct tty_struct *tty, | |||
| 442 | 435 | ||
| 443 | static int ssu100_attach(struct usb_serial *serial) | 436 | static int ssu100_attach(struct usb_serial *serial) |
| 444 | { | 437 | { |
| 438 | return ssu100_initdevice(serial->dev); | ||
| 439 | } | ||
| 440 | |||
| 441 | static int ssu100_port_probe(struct usb_serial_port *port) | ||
| 442 | { | ||
| 445 | struct ssu100_port_private *priv; | 443 | struct ssu100_port_private *priv; |
| 446 | struct usb_serial_port *port = *serial->port; | ||
| 447 | 444 | ||
| 448 | priv = kzalloc(sizeof(*priv), GFP_KERNEL); | 445 | priv = kzalloc(sizeof(*priv), GFP_KERNEL); |
| 449 | if (!priv) { | 446 | if (!priv) |
| 450 | dev_err(&port->dev, "%s- kmalloc(%Zd) failed.\n", __func__, | ||
| 451 | sizeof(*priv)); | ||
| 452 | return -ENOMEM; | 447 | return -ENOMEM; |
| 453 | } | ||
| 454 | 448 | ||
| 455 | spin_lock_init(&priv->status_lock); | 449 | spin_lock_init(&priv->status_lock); |
| 456 | init_waitqueue_head(&priv->delta_msr_wait); | 450 | init_waitqueue_head(&priv->delta_msr_wait); |
| 451 | |||
| 457 | usb_set_serial_port_data(port, priv); | 452 | usb_set_serial_port_data(port, priv); |
| 458 | 453 | ||
| 459 | return ssu100_initdevice(serial->dev); | 454 | return 0; |
| 455 | } | ||
| 456 | |||
| 457 | static int ssu100_port_remove(struct usb_serial_port *port) | ||
| 458 | { | ||
| 459 | struct ssu100_port_private *priv; | ||
| 460 | |||
| 461 | priv = usb_get_serial_port_data(port); | ||
| 462 | kfree(priv); | ||
| 463 | |||
| 464 | return 0; | ||
| 460 | } | 465 | } |
| 461 | 466 | ||
| 462 | static int ssu100_tiocmget(struct tty_struct *tty) | 467 | static int ssu100_tiocmget(struct tty_struct *tty) |
| @@ -647,7 +652,8 @@ static struct usb_serial_driver ssu100_device = { | |||
| 647 | .open = ssu100_open, | 652 | .open = ssu100_open, |
| 648 | .close = ssu100_close, | 653 | .close = ssu100_close, |
| 649 | .attach = ssu100_attach, | 654 | .attach = ssu100_attach, |
| 650 | .release = ssu100_release, | 655 | .port_probe = ssu100_port_probe, |
| 656 | .port_remove = ssu100_port_remove, | ||
| 651 | .dtr_rts = ssu100_dtr_rts, | 657 | .dtr_rts = ssu100_dtr_rts, |
| 652 | .process_read_urb = ssu100_process_read_urb, | 658 | .process_read_urb = ssu100_process_read_urb, |
| 653 | .tiocmget = ssu100_tiocmget, | 659 | .tiocmget = ssu100_tiocmget, |
diff --git a/drivers/usb/serial/ti_usb_3410_5052.c b/drivers/usb/serial/ti_usb_3410_5052.c index 6f49392cda5b..f2530d2ef3c4 100644 --- a/drivers/usb/serial/ti_usb_3410_5052.c +++ b/drivers/usb/serial/ti_usb_3410_5052.c | |||
| @@ -97,6 +97,8 @@ struct ti_device { | |||
| 97 | 97 | ||
| 98 | static int ti_startup(struct usb_serial *serial); | 98 | static int ti_startup(struct usb_serial *serial); |
| 99 | static void ti_release(struct usb_serial *serial); | 99 | static void ti_release(struct usb_serial *serial); |
| 100 | static int ti_port_probe(struct usb_serial_port *port); | ||
| 101 | static int ti_port_remove(struct usb_serial_port *port); | ||
| 100 | static int ti_open(struct tty_struct *tty, struct usb_serial_port *port); | 102 | static int ti_open(struct tty_struct *tty, struct usb_serial_port *port); |
| 101 | static void ti_close(struct usb_serial_port *port); | 103 | static void ti_close(struct usb_serial_port *port); |
| 102 | static int ti_write(struct tty_struct *tty, struct usb_serial_port *port, | 104 | static int ti_write(struct tty_struct *tty, struct usb_serial_port *port, |
| @@ -221,6 +223,8 @@ static struct usb_serial_driver ti_1port_device = { | |||
| 221 | .num_ports = 1, | 223 | .num_ports = 1, |
| 222 | .attach = ti_startup, | 224 | .attach = ti_startup, |
| 223 | .release = ti_release, | 225 | .release = ti_release, |
| 226 | .port_probe = ti_port_probe, | ||
| 227 | .port_remove = ti_port_remove, | ||
| 224 | .open = ti_open, | 228 | .open = ti_open, |
| 225 | .close = ti_close, | 229 | .close = ti_close, |
| 226 | .write = ti_write, | 230 | .write = ti_write, |
| @@ -249,6 +253,8 @@ static struct usb_serial_driver ti_2port_device = { | |||
| 249 | .num_ports = 2, | 253 | .num_ports = 2, |
| 250 | .attach = ti_startup, | 254 | .attach = ti_startup, |
| 251 | .release = ti_release, | 255 | .release = ti_release, |
| 256 | .port_probe = ti_port_probe, | ||
| 257 | .port_remove = ti_port_remove, | ||
| 252 | .open = ti_open, | 258 | .open = ti_open, |
| 253 | .close = ti_close, | 259 | .close = ti_close, |
| 254 | .write = ti_write, | 260 | .write = ti_write, |
| @@ -347,11 +353,8 @@ module_exit(ti_exit); | |||
| 347 | static int ti_startup(struct usb_serial *serial) | 353 | static int ti_startup(struct usb_serial *serial) |
| 348 | { | 354 | { |
| 349 | struct ti_device *tdev; | 355 | struct ti_device *tdev; |
| 350 | struct ti_port *tport; | ||
| 351 | struct usb_device *dev = serial->dev; | 356 | struct usb_device *dev = serial->dev; |
| 352 | int status; | 357 | int status; |
| 353 | int i; | ||
| 354 | |||
| 355 | 358 | ||
| 356 | dev_dbg(&dev->dev, | 359 | dev_dbg(&dev->dev, |
| 357 | "%s - product 0x%4X, num configurations %d, configuration value %d", | 360 | "%s - product 0x%4X, num configurations %d, configuration value %d", |
| @@ -399,42 +402,8 @@ static int ti_startup(struct usb_serial *serial) | |||
| 399 | goto free_tdev; | 402 | goto free_tdev; |
| 400 | } | 403 | } |
| 401 | 404 | ||
| 402 | /* set up port structures */ | ||
| 403 | for (i = 0; i < serial->num_ports; ++i) { | ||
| 404 | tport = kzalloc(sizeof(struct ti_port), GFP_KERNEL); | ||
| 405 | if (tport == NULL) { | ||
| 406 | dev_err(&dev->dev, "%s - out of memory\n", __func__); | ||
| 407 | status = -ENOMEM; | ||
| 408 | goto free_tports; | ||
| 409 | } | ||
| 410 | spin_lock_init(&tport->tp_lock); | ||
| 411 | tport->tp_uart_base_addr = (i == 0 ? | ||
| 412 | TI_UART1_BASE_ADDR : TI_UART2_BASE_ADDR); | ||
| 413 | tport->tp_closing_wait = closing_wait; | ||
| 414 | init_waitqueue_head(&tport->tp_msr_wait); | ||
| 415 | init_waitqueue_head(&tport->tp_write_wait); | ||
| 416 | if (kfifo_alloc(&tport->write_fifo, TI_WRITE_BUF_SIZE, | ||
| 417 | GFP_KERNEL)) { | ||
| 418 | dev_err(&dev->dev, "%s - out of memory\n", __func__); | ||
| 419 | kfree(tport); | ||
| 420 | status = -ENOMEM; | ||
| 421 | goto free_tports; | ||
| 422 | } | ||
| 423 | tport->tp_port = serial->port[i]; | ||
| 424 | tport->tp_tdev = tdev; | ||
| 425 | usb_set_serial_port_data(serial->port[i], tport); | ||
| 426 | tport->tp_uart_mode = 0; /* default is RS232 */ | ||
| 427 | } | ||
| 428 | |||
| 429 | return 0; | 405 | return 0; |
| 430 | 406 | ||
| 431 | free_tports: | ||
| 432 | for (--i; i >= 0; --i) { | ||
| 433 | tport = usb_get_serial_port_data(serial->port[i]); | ||
| 434 | kfifo_free(&tport->write_fifo); | ||
| 435 | kfree(tport); | ||
| 436 | usb_set_serial_port_data(serial->port[i], NULL); | ||
| 437 | } | ||
| 438 | free_tdev: | 407 | free_tdev: |
| 439 | kfree(tdev); | 408 | kfree(tdev); |
| 440 | usb_set_serial_data(serial, NULL); | 409 | usb_set_serial_data(serial, NULL); |
| @@ -444,21 +413,50 @@ free_tdev: | |||
| 444 | 413 | ||
| 445 | static void ti_release(struct usb_serial *serial) | 414 | static void ti_release(struct usb_serial *serial) |
| 446 | { | 415 | { |
| 447 | int i; | ||
| 448 | struct ti_device *tdev = usb_get_serial_data(serial); | 416 | struct ti_device *tdev = usb_get_serial_data(serial); |
| 417 | |||
| 418 | kfree(tdev); | ||
| 419 | } | ||
| 420 | |||
| 421 | static int ti_port_probe(struct usb_serial_port *port) | ||
| 422 | { | ||
| 449 | struct ti_port *tport; | 423 | struct ti_port *tport; |
| 450 | 424 | ||
| 451 | for (i = 0; i < serial->num_ports; ++i) { | 425 | tport = kzalloc(sizeof(*tport), GFP_KERNEL); |
| 452 | tport = usb_get_serial_port_data(serial->port[i]); | 426 | if (!tport) |
| 453 | if (tport) { | 427 | return -ENOMEM; |
| 454 | kfifo_free(&tport->write_fifo); | 428 | |
| 455 | kfree(tport); | 429 | spin_lock_init(&tport->tp_lock); |
| 456 | } | 430 | if (port == port->serial->port[0]) |
| 431 | tport->tp_uart_base_addr = TI_UART1_BASE_ADDR; | ||
| 432 | else | ||
| 433 | tport->tp_uart_base_addr = TI_UART2_BASE_ADDR; | ||
| 434 | tport->tp_closing_wait = closing_wait; | ||
| 435 | init_waitqueue_head(&tport->tp_msr_wait); | ||
| 436 | init_waitqueue_head(&tport->tp_write_wait); | ||
| 437 | if (kfifo_alloc(&tport->write_fifo, TI_WRITE_BUF_SIZE, GFP_KERNEL)) { | ||
| 438 | kfree(tport); | ||
| 439 | return -ENOMEM; | ||
| 457 | } | 440 | } |
| 441 | tport->tp_port = port; | ||
| 442 | tport->tp_tdev = usb_get_serial_data(port->serial); | ||
| 443 | tport->tp_uart_mode = 0; /* default is RS232 */ | ||
| 458 | 444 | ||
| 459 | kfree(tdev); | 445 | usb_set_serial_port_data(port, tport); |
| 446 | |||
| 447 | return 0; | ||
| 460 | } | 448 | } |
| 461 | 449 | ||
| 450 | static int ti_port_remove(struct usb_serial_port *port) | ||
| 451 | { | ||
| 452 | struct ti_port *tport; | ||
| 453 | |||
| 454 | tport = usb_get_serial_port_data(port); | ||
| 455 | kfifo_free(&tport->write_fifo); | ||
| 456 | kfree(tport); | ||
| 457 | |||
| 458 | return 0; | ||
| 459 | } | ||
| 462 | 460 | ||
| 463 | static int ti_open(struct tty_struct *tty, struct usb_serial_port *port) | 461 | static int ti_open(struct tty_struct *tty, struct usb_serial_port *port) |
| 464 | { | 462 | { |
diff --git a/drivers/usb/serial/usb-wwan.h b/drivers/usb/serial/usb-wwan.h index 1f034d2397c6..684739b8efd0 100644 --- a/drivers/usb/serial/usb-wwan.h +++ b/drivers/usb/serial/usb-wwan.h | |||
| @@ -8,7 +8,7 @@ | |||
| 8 | extern void usb_wwan_dtr_rts(struct usb_serial_port *port, int on); | 8 | extern void usb_wwan_dtr_rts(struct usb_serial_port *port, int on); |
| 9 | extern int usb_wwan_open(struct tty_struct *tty, struct usb_serial_port *port); | 9 | extern int usb_wwan_open(struct tty_struct *tty, struct usb_serial_port *port); |
| 10 | extern void usb_wwan_close(struct usb_serial_port *port); | 10 | extern void usb_wwan_close(struct usb_serial_port *port); |
| 11 | extern int usb_wwan_startup(struct usb_serial *serial); | 11 | extern int usb_wwan_port_probe(struct usb_serial_port *port); |
| 12 | extern int usb_wwan_port_remove(struct usb_serial_port *port); | 12 | extern int usb_wwan_port_remove(struct usb_serial_port *port); |
| 13 | extern int usb_wwan_write_room(struct tty_struct *tty); | 13 | extern int usb_wwan_write_room(struct tty_struct *tty); |
| 14 | extern void usb_wwan_set_termios(struct tty_struct *tty, | 14 | extern void usb_wwan_set_termios(struct tty_struct *tty, |
diff --git a/drivers/usb/serial/usb_wwan.c b/drivers/usb/serial/usb_wwan.c index e42aa398ed37..a3e9c095f0d8 100644 --- a/drivers/usb/serial/usb_wwan.c +++ b/drivers/usb/serial/usb_wwan.c | |||
| @@ -447,15 +447,14 @@ void usb_wwan_close(struct usb_serial_port *port) | |||
| 447 | EXPORT_SYMBOL(usb_wwan_close); | 447 | EXPORT_SYMBOL(usb_wwan_close); |
| 448 | 448 | ||
| 449 | /* Helper functions used by usb_wwan_setup_urbs */ | 449 | /* Helper functions used by usb_wwan_setup_urbs */ |
| 450 | static struct urb *usb_wwan_setup_urb(struct usb_serial *serial, int endpoint, | 450 | static struct urb *usb_wwan_setup_urb(struct usb_serial_port *port, |
| 451 | int endpoint, | ||
| 451 | int dir, void *ctx, char *buf, int len, | 452 | int dir, void *ctx, char *buf, int len, |
| 452 | void (*callback) (struct urb *)) | 453 | void (*callback) (struct urb *)) |
| 453 | { | 454 | { |
| 455 | struct usb_serial *serial = port->serial; | ||
| 454 | struct urb *urb; | 456 | struct urb *urb; |
| 455 | 457 | ||
| 456 | if (endpoint == -1) | ||
| 457 | return NULL; /* endpoint not needed */ | ||
| 458 | |||
| 459 | urb = usb_alloc_urb(0, GFP_KERNEL); /* No ISO */ | 458 | urb = usb_alloc_urb(0, GFP_KERNEL); /* No ISO */ |
| 460 | if (urb == NULL) { | 459 | if (urb == NULL) { |
| 461 | dev_dbg(&serial->interface->dev, | 460 | dev_dbg(&serial->interface->dev, |
| @@ -472,101 +471,78 @@ static struct urb *usb_wwan_setup_urb(struct usb_serial *serial, int endpoint, | |||
| 472 | return urb; | 471 | return urb; |
| 473 | } | 472 | } |
| 474 | 473 | ||
| 475 | /* Setup urbs */ | 474 | int usb_wwan_port_probe(struct usb_serial_port *port) |
| 476 | static void usb_wwan_setup_urbs(struct usb_serial *serial) | ||
| 477 | { | 475 | { |
| 478 | int i, j; | ||
| 479 | struct usb_serial_port *port; | ||
| 480 | struct usb_wwan_port_private *portdata; | 476 | struct usb_wwan_port_private *portdata; |
| 477 | struct urb *urb; | ||
| 478 | u8 *buffer; | ||
| 479 | int err; | ||
| 480 | int i; | ||
| 481 | 481 | ||
| 482 | for (i = 0; i < serial->num_ports; i++) { | 482 | portdata = kzalloc(sizeof(*portdata), GFP_KERNEL); |
| 483 | port = serial->port[i]; | 483 | if (!portdata) |
| 484 | portdata = usb_get_serial_port_data(port); | 484 | return -ENOMEM; |
| 485 | 485 | ||
| 486 | /* Do indat endpoints first */ | 486 | init_usb_anchor(&portdata->delayed); |
| 487 | for (j = 0; j < N_IN_URB; ++j) { | ||
| 488 | portdata->in_urbs[j] = usb_wwan_setup_urb(serial, | ||
| 489 | port-> | ||
| 490 | bulk_in_endpointAddress, | ||
| 491 | USB_DIR_IN, | ||
| 492 | port, | ||
| 493 | portdata-> | ||
| 494 | in_buffer[j], | ||
| 495 | IN_BUFLEN, | ||
| 496 | usb_wwan_indat_callback); | ||
| 497 | } | ||
| 498 | 487 | ||
| 499 | /* outdat endpoints */ | 488 | for (i = 0; i < N_IN_URB; i++) { |
| 500 | for (j = 0; j < N_OUT_URB; ++j) { | 489 | if (!port->bulk_in_size) |
| 501 | portdata->out_urbs[j] = usb_wwan_setup_urb(serial, | 490 | break; |
| 502 | port-> | ||
| 503 | bulk_out_endpointAddress, | ||
| 504 | USB_DIR_OUT, | ||
| 505 | port, | ||
| 506 | portdata-> | ||
| 507 | out_buffer | ||
| 508 | [j], | ||
| 509 | OUT_BUFLEN, | ||
| 510 | usb_wwan_outdat_callback); | ||
| 511 | } | ||
| 512 | } | ||
| 513 | } | ||
| 514 | 491 | ||
| 515 | int usb_wwan_startup(struct usb_serial *serial) | 492 | buffer = (u8 *)__get_free_page(GFP_KERNEL); |
| 516 | { | 493 | if (!buffer) |
| 517 | int i, j, err; | 494 | goto bail_out_error; |
| 518 | struct usb_serial_port *port; | 495 | portdata->in_buffer[i] = buffer; |
| 519 | struct usb_wwan_port_private *portdata; | ||
| 520 | u8 *buffer; | ||
| 521 | 496 | ||
| 522 | /* Now setup per port private data */ | 497 | urb = usb_wwan_setup_urb(port, port->bulk_in_endpointAddress, |
| 523 | for (i = 0; i < serial->num_ports; i++) { | 498 | USB_DIR_IN, port, |
| 524 | port = serial->port[i]; | 499 | buffer, IN_BUFLEN, |
| 525 | portdata = kzalloc(sizeof(*portdata), GFP_KERNEL); | 500 | usb_wwan_indat_callback); |
| 526 | if (!portdata) { | 501 | portdata->in_urbs[i] = urb; |
| 527 | dev_dbg(&port->dev, "%s: kmalloc for usb_wwan_port_private (%d) failed!.\n", | 502 | } |
| 528 | __func__, i); | ||
| 529 | return 1; | ||
| 530 | } | ||
| 531 | init_usb_anchor(&portdata->delayed); | ||
| 532 | 503 | ||
| 533 | for (j = 0; j < N_IN_URB; j++) { | 504 | for (i = 0; i < N_OUT_URB; i++) { |
| 534 | buffer = (u8 *) __get_free_page(GFP_KERNEL); | 505 | if (!port->bulk_out_size) |
| 535 | if (!buffer) | 506 | break; |
| 536 | goto bail_out_error; | ||
| 537 | portdata->in_buffer[j] = buffer; | ||
| 538 | } | ||
| 539 | 507 | ||
| 540 | for (j = 0; j < N_OUT_URB; j++) { | 508 | buffer = kmalloc(OUT_BUFLEN, GFP_KERNEL); |
| 541 | buffer = kmalloc(OUT_BUFLEN, GFP_KERNEL); | 509 | if (!buffer) |
| 542 | if (!buffer) | 510 | goto bail_out_error2; |
| 543 | goto bail_out_error2; | 511 | portdata->out_buffer[i] = buffer; |
| 544 | portdata->out_buffer[j] = buffer; | ||
| 545 | } | ||
| 546 | 512 | ||
| 547 | usb_set_serial_port_data(port, portdata); | 513 | urb = usb_wwan_setup_urb(port, port->bulk_out_endpointAddress, |
| 514 | USB_DIR_OUT, port, | ||
| 515 | buffer, OUT_BUFLEN, | ||
| 516 | usb_wwan_outdat_callback); | ||
| 517 | portdata->out_urbs[i] = urb; | ||
| 518 | } | ||
| 548 | 519 | ||
| 549 | if (!port->interrupt_in_urb) | 520 | usb_set_serial_port_data(port, portdata); |
| 550 | continue; | 521 | |
| 522 | if (port->interrupt_in_urb) { | ||
| 551 | err = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL); | 523 | err = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL); |
| 552 | if (err) | 524 | if (err) |
| 553 | dev_dbg(&port->dev, "%s: submit irq_in urb failed %d\n", | 525 | dev_dbg(&port->dev, "%s: submit irq_in urb failed %d\n", |
| 554 | __func__, err); | 526 | __func__, err); |
| 555 | } | 527 | } |
| 556 | usb_wwan_setup_urbs(serial); | 528 | |
| 557 | return 0; | 529 | return 0; |
| 558 | 530 | ||
| 559 | bail_out_error2: | 531 | bail_out_error2: |
| 560 | for (j = 0; j < N_OUT_URB; j++) | 532 | for (i = 0; i < N_OUT_URB; i++) { |
| 561 | kfree(portdata->out_buffer[j]); | 533 | usb_free_urb(portdata->out_urbs[i]); |
| 534 | kfree(portdata->out_buffer[i]); | ||
| 535 | } | ||
| 562 | bail_out_error: | 536 | bail_out_error: |
| 563 | for (j = 0; j < N_IN_URB; j++) | 537 | for (i = 0; i < N_IN_URB; i++) { |
| 564 | if (portdata->in_buffer[j]) | 538 | usb_free_urb(portdata->in_urbs[i]); |
| 565 | free_page((unsigned long)portdata->in_buffer[j]); | 539 | free_page((unsigned long)portdata->in_buffer[i]); |
| 540 | } | ||
| 566 | kfree(portdata); | 541 | kfree(portdata); |
| 567 | return 1; | 542 | |
| 543 | return -ENOMEM; | ||
| 568 | } | 544 | } |
| 569 | EXPORT_SYMBOL(usb_wwan_startup); | 545 | EXPORT_SYMBOL_GPL(usb_wwan_port_probe); |
| 570 | 546 | ||
| 571 | int usb_wwan_port_remove(struct usb_serial_port *port) | 547 | int usb_wwan_port_remove(struct usb_serial_port *port) |
| 572 | { | 548 | { |
diff --git a/drivers/usb/serial/whiteheat.c b/drivers/usb/serial/whiteheat.c index 346c7efc20b0..b9fca3586d74 100644 --- a/drivers/usb/serial/whiteheat.c +++ b/drivers/usb/serial/whiteheat.c | |||
| @@ -83,6 +83,8 @@ static int whiteheat_firmware_attach(struct usb_serial *serial); | |||
| 83 | /* function prototypes for the Connect Tech WhiteHEAT serial converter */ | 83 | /* function prototypes for the Connect Tech WhiteHEAT serial converter */ |
| 84 | static int whiteheat_attach(struct usb_serial *serial); | 84 | static int whiteheat_attach(struct usb_serial *serial); |
| 85 | static void whiteheat_release(struct usb_serial *serial); | 85 | static void whiteheat_release(struct usb_serial *serial); |
| 86 | static int whiteheat_port_probe(struct usb_serial_port *port); | ||
| 87 | static int whiteheat_port_remove(struct usb_serial_port *port); | ||
| 86 | static int whiteheat_open(struct tty_struct *tty, | 88 | static int whiteheat_open(struct tty_struct *tty, |
| 87 | struct usb_serial_port *port); | 89 | struct usb_serial_port *port); |
| 88 | static void whiteheat_close(struct usb_serial_port *port); | 90 | static void whiteheat_close(struct usb_serial_port *port); |
| @@ -117,6 +119,8 @@ static struct usb_serial_driver whiteheat_device = { | |||
| 117 | .num_ports = 4, | 119 | .num_ports = 4, |
| 118 | .attach = whiteheat_attach, | 120 | .attach = whiteheat_attach, |
| 119 | .release = whiteheat_release, | 121 | .release = whiteheat_release, |
| 122 | .port_probe = whiteheat_port_probe, | ||
| 123 | .port_remove = whiteheat_port_remove, | ||
| 120 | .open = whiteheat_open, | 124 | .open = whiteheat_open, |
| 121 | .close = whiteheat_close, | 125 | .close = whiteheat_close, |
| 122 | .ioctl = whiteheat_ioctl, | 126 | .ioctl = whiteheat_ioctl, |
| @@ -218,15 +222,12 @@ static int whiteheat_attach(struct usb_serial *serial) | |||
| 218 | { | 222 | { |
| 219 | struct usb_serial_port *command_port; | 223 | struct usb_serial_port *command_port; |
| 220 | struct whiteheat_command_private *command_info; | 224 | struct whiteheat_command_private *command_info; |
| 221 | struct usb_serial_port *port; | ||
| 222 | struct whiteheat_private *info; | ||
| 223 | struct whiteheat_hw_info *hw_info; | 225 | struct whiteheat_hw_info *hw_info; |
| 224 | int pipe; | 226 | int pipe; |
| 225 | int ret; | 227 | int ret; |
| 226 | int alen; | 228 | int alen; |
| 227 | __u8 *command; | 229 | __u8 *command; |
| 228 | __u8 *result; | 230 | __u8 *result; |
| 229 | int i; | ||
| 230 | 231 | ||
| 231 | command_port = serial->port[COMMAND_PORT]; | 232 | command_port = serial->port[COMMAND_PORT]; |
| 232 | 233 | ||
| @@ -285,22 +286,6 @@ static int whiteheat_attach(struct usb_serial *serial) | |||
| 285 | serial->type->description, | 286 | serial->type->description, |
| 286 | hw_info->sw_major_rev, hw_info->sw_minor_rev); | 287 | hw_info->sw_major_rev, hw_info->sw_minor_rev); |
| 287 | 288 | ||
| 288 | for (i = 0; i < serial->num_ports; i++) { | ||
| 289 | port = serial->port[i]; | ||
| 290 | |||
| 291 | info = kmalloc(sizeof(struct whiteheat_private), GFP_KERNEL); | ||
| 292 | if (info == NULL) { | ||
| 293 | dev_err(&port->dev, | ||
| 294 | "%s: Out of memory for port structures\n", | ||
| 295 | serial->type->description); | ||
| 296 | goto no_private; | ||
| 297 | } | ||
| 298 | |||
| 299 | info->mcr = 0; | ||
| 300 | |||
| 301 | usb_set_serial_port_data(port, info); | ||
| 302 | } | ||
| 303 | |||
| 304 | command_info = kmalloc(sizeof(struct whiteheat_command_private), | 289 | command_info = kmalloc(sizeof(struct whiteheat_command_private), |
| 305 | GFP_KERNEL); | 290 | GFP_KERNEL); |
| 306 | if (command_info == NULL) { | 291 | if (command_info == NULL) { |
| @@ -333,16 +318,10 @@ no_firmware: | |||
| 333 | "%s: please contact support@connecttech.com\n", | 318 | "%s: please contact support@connecttech.com\n", |
| 334 | serial->type->description); | 319 | serial->type->description); |
| 335 | kfree(result); | 320 | kfree(result); |
| 321 | kfree(command); | ||
| 336 | return -ENODEV; | 322 | return -ENODEV; |
| 337 | 323 | ||
| 338 | no_command_private: | 324 | no_command_private: |
| 339 | for (i = serial->num_ports - 1; i >= 0; i--) { | ||
| 340 | port = serial->port[i]; | ||
| 341 | info = usb_get_serial_port_data(port); | ||
| 342 | kfree(info); | ||
| 343 | no_private: | ||
| 344 | ; | ||
| 345 | } | ||
| 346 | kfree(result); | 325 | kfree(result); |
| 347 | no_result_buffer: | 326 | no_result_buffer: |
| 348 | kfree(command); | 327 | kfree(command); |
| @@ -350,21 +329,36 @@ no_command_buffer: | |||
| 350 | return -ENOMEM; | 329 | return -ENOMEM; |
| 351 | } | 330 | } |
| 352 | 331 | ||
| 353 | |||
| 354 | static void whiteheat_release(struct usb_serial *serial) | 332 | static void whiteheat_release(struct usb_serial *serial) |
| 355 | { | 333 | { |
| 356 | struct usb_serial_port *command_port; | 334 | struct usb_serial_port *command_port; |
| 357 | struct whiteheat_private *info; | ||
| 358 | int i; | ||
| 359 | 335 | ||
| 360 | /* free up our private data for our command port */ | 336 | /* free up our private data for our command port */ |
| 361 | command_port = serial->port[COMMAND_PORT]; | 337 | command_port = serial->port[COMMAND_PORT]; |
| 362 | kfree(usb_get_serial_port_data(command_port)); | 338 | kfree(usb_get_serial_port_data(command_port)); |
| 339 | } | ||
| 363 | 340 | ||
| 364 | for (i = 0; i < serial->num_ports; i++) { | 341 | static int whiteheat_port_probe(struct usb_serial_port *port) |
| 365 | info = usb_get_serial_port_data(serial->port[i]); | 342 | { |
| 366 | kfree(info); | 343 | struct whiteheat_private *info; |
| 367 | } | 344 | |
| 345 | info = kzalloc(sizeof(*info), GFP_KERNEL); | ||
| 346 | if (!info) | ||
| 347 | return -ENOMEM; | ||
| 348 | |||
| 349 | usb_set_serial_port_data(port, info); | ||
| 350 | |||
| 351 | return 0; | ||
| 352 | } | ||
| 353 | |||
| 354 | static int whiteheat_port_remove(struct usb_serial_port *port) | ||
| 355 | { | ||
| 356 | struct whiteheat_private *info; | ||
| 357 | |||
| 358 | info = usb_get_serial_port_data(port); | ||
| 359 | kfree(info); | ||
| 360 | |||
| 361 | return 0; | ||
| 368 | } | 362 | } |
| 369 | 363 | ||
| 370 | static int whiteheat_open(struct tty_struct *tty, struct usb_serial_port *port) | 364 | static int whiteheat_open(struct tty_struct *tty, struct usb_serial_port *port) |
diff --git a/drivers/usb/storage/scsiglue.c b/drivers/usb/storage/scsiglue.c index a3d54366afcc..92f35abee92d 100644 --- a/drivers/usb/storage/scsiglue.c +++ b/drivers/usb/storage/scsiglue.c | |||
| @@ -186,6 +186,12 @@ static int slave_configure(struct scsi_device *sdev) | |||
| 186 | /* Some devices don't handle VPD pages correctly */ | 186 | /* Some devices don't handle VPD pages correctly */ |
| 187 | sdev->skip_vpd_pages = 1; | 187 | sdev->skip_vpd_pages = 1; |
| 188 | 188 | ||
| 189 | /* Do not attempt to use REPORT SUPPORTED OPERATION CODES */ | ||
| 190 | sdev->no_report_opcodes = 1; | ||
| 191 | |||
| 192 | /* Do not attempt to use WRITE SAME */ | ||
| 193 | sdev->no_write_same = 1; | ||
| 194 | |||
| 189 | /* Some disks return the total number of blocks in response | 195 | /* Some disks return the total number of blocks in response |
| 190 | * to READ CAPACITY rather than the highest block number. | 196 | * to READ CAPACITY rather than the highest block number. |
| 191 | * If this device makes that mistake, tell the sd driver. */ | 197 | * If this device makes that mistake, tell the sd driver. */ |
diff --git a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h index 779cd954abcb..d305a5aa3a5d 100644 --- a/drivers/usb/storage/unusual_devs.h +++ b/drivers/usb/storage/unusual_devs.h | |||
| @@ -1004,6 +1004,12 @@ UNUSUAL_DEV( 0x07cf, 0x1001, 0x1000, 0x9999, | |||
| 1004 | USB_SC_8070, USB_PR_CB, NULL, | 1004 | USB_SC_8070, USB_PR_CB, NULL, |
| 1005 | US_FL_NEED_OVERRIDE | US_FL_FIX_INQUIRY ), | 1005 | US_FL_NEED_OVERRIDE | US_FL_FIX_INQUIRY ), |
| 1006 | 1006 | ||
| 1007 | /* Submitted by Oleksandr Chumachenko <ledest@gmail.com> */ | ||
| 1008 | UNUSUAL_DEV( 0x07cf, 0x1167, 0x0100, 0x0100, | ||
| 1009 | "Casio", | ||
| 1010 | "EX-N1 DigitalCamera", | ||
| 1011 | USB_SC_8070, USB_PR_DEVICE, NULL, 0), | ||
| 1012 | |||
| 1007 | /* Submitted by Hartmut Wahl <hwahl@hwahl.de>*/ | 1013 | /* Submitted by Hartmut Wahl <hwahl@hwahl.de>*/ |
| 1008 | UNUSUAL_DEV( 0x0839, 0x000a, 0x0001, 0x0001, | 1014 | UNUSUAL_DEV( 0x0839, 0x000a, 0x0001, 0x0001, |
| 1009 | "Samsung", | 1015 | "Samsung", |
diff --git a/drivers/vhost/net.c b/drivers/vhost/net.c index 072cbbadbc36..7f93f34b7f91 100644 --- a/drivers/vhost/net.c +++ b/drivers/vhost/net.c | |||
| @@ -379,7 +379,8 @@ static void handle_rx(struct vhost_net *net) | |||
| 379 | .hdr.gso_type = VIRTIO_NET_HDR_GSO_NONE | 379 | .hdr.gso_type = VIRTIO_NET_HDR_GSO_NONE |
| 380 | }; | 380 | }; |
| 381 | size_t total_len = 0; | 381 | size_t total_len = 0; |
| 382 | int err, headcount, mergeable; | 382 | int err, mergeable; |
| 383 | s16 headcount; | ||
| 383 | size_t vhost_hlen, sock_hlen; | 384 | size_t vhost_hlen, sock_hlen; |
| 384 | size_t vhost_len, sock_len; | 385 | size_t vhost_len, sock_len; |
| 385 | /* TODO: check that we are running from vhost_worker? */ | 386 | /* TODO: check that we are running from vhost_worker? */ |
diff --git a/drivers/vhost/vhost.c b/drivers/vhost/vhost.c index 99ac2cb08b43..dedaf81d8f36 100644 --- a/drivers/vhost/vhost.c +++ b/drivers/vhost/vhost.c | |||
| @@ -1076,7 +1076,7 @@ static int translate_desc(struct vhost_dev *dev, u64 addr, u32 len, | |||
| 1076 | } | 1076 | } |
| 1077 | _iov = iov + ret; | 1077 | _iov = iov + ret; |
| 1078 | size = reg->memory_size - addr + reg->guest_phys_addr; | 1078 | size = reg->memory_size - addr + reg->guest_phys_addr; |
| 1079 | _iov->iov_len = min((u64)len, size); | 1079 | _iov->iov_len = min((u64)len - s, size); |
| 1080 | _iov->iov_base = (void __user *)(unsigned long) | 1080 | _iov->iov_base = (void __user *)(unsigned long) |
| 1081 | (reg->userspace_addr + addr - reg->guest_phys_addr); | 1081 | (reg->userspace_addr + addr - reg->guest_phys_addr); |
| 1082 | s += size; | 1082 | s += size; |
diff --git a/drivers/video/backlight/Kconfig b/drivers/video/backlight/Kconfig index c101697a4ba7..765a945f8ea1 100644 --- a/drivers/video/backlight/Kconfig +++ b/drivers/video/backlight/Kconfig | |||
| @@ -60,7 +60,8 @@ config LCD_LTV350QV | |||
| 60 | The LTV350QV panel is present on all ATSTK1000 boards. | 60 | The LTV350QV panel is present on all ATSTK1000 boards. |
| 61 | 61 | ||
| 62 | config LCD_ILI9320 | 62 | config LCD_ILI9320 |
| 63 | tristate | 63 | tristate "ILI Technology ILI9320 controller support" |
| 64 | depends on SPI | ||
| 64 | help | 65 | help |
| 65 | If you have a panel based on the ILI9320 controller chip | 66 | If you have a panel based on the ILI9320 controller chip |
| 66 | then say y to include a power driver for it. | 67 | then say y to include a power driver for it. |
diff --git a/drivers/video/backlight/lm3639_bl.c b/drivers/video/backlight/lm3639_bl.c index c6915c6c3cd1..585949b57055 100644 --- a/drivers/video/backlight/lm3639_bl.c +++ b/drivers/video/backlight/lm3639_bl.c | |||
| @@ -206,11 +206,11 @@ static ssize_t lm3639_bled_mode_store(struct device *dev, | |||
| 206 | 206 | ||
| 207 | out: | 207 | out: |
| 208 | dev_err(pchip->dev, "%s:i2c access fail to register\n", __func__); | 208 | dev_err(pchip->dev, "%s:i2c access fail to register\n", __func__); |
| 209 | return size; | 209 | return ret; |
| 210 | 210 | ||
| 211 | out_input: | 211 | out_input: |
| 212 | dev_err(pchip->dev, "%s:input conversion fail\n", __func__); | 212 | dev_err(pchip->dev, "%s:input conversion fail\n", __func__); |
| 213 | return size; | 213 | return ret; |
| 214 | 214 | ||
| 215 | } | 215 | } |
| 216 | 216 | ||
diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c index d64ac3842884..bee92846cfab 100644 --- a/drivers/video/omap2/dss/dsi.c +++ b/drivers/video/omap2/dss/dsi.c | |||
| @@ -365,11 +365,20 @@ struct platform_device *dsi_get_dsidev_from_id(int module) | |||
| 365 | struct omap_dss_output *out; | 365 | struct omap_dss_output *out; |
| 366 | enum omap_dss_output_id id; | 366 | enum omap_dss_output_id id; |
| 367 | 367 | ||
| 368 | id = module == 0 ? OMAP_DSS_OUTPUT_DSI1 : OMAP_DSS_OUTPUT_DSI2; | 368 | switch (module) { |
| 369 | case 0: | ||
| 370 | id = OMAP_DSS_OUTPUT_DSI1; | ||
| 371 | break; | ||
| 372 | case 1: | ||
| 373 | id = OMAP_DSS_OUTPUT_DSI2; | ||
| 374 | break; | ||
| 375 | default: | ||
| 376 | return NULL; | ||
| 377 | } | ||
| 369 | 378 | ||
| 370 | out = omap_dss_get_output(id); | 379 | out = omap_dss_get_output(id); |
| 371 | 380 | ||
| 372 | return out->pdev; | 381 | return out ? out->pdev : NULL; |
| 373 | } | 382 | } |
| 374 | 383 | ||
| 375 | static inline void dsi_write_reg(struct platform_device *dsidev, | 384 | static inline void dsi_write_reg(struct platform_device *dsidev, |
diff --git a/drivers/video/omap2/dss/dss.c b/drivers/video/omap2/dss/dss.c index 2ab1c3e96553..5f6eea801b06 100644 --- a/drivers/video/omap2/dss/dss.c +++ b/drivers/video/omap2/dss/dss.c | |||
| @@ -697,11 +697,15 @@ static int dss_get_clocks(void) | |||
| 697 | 697 | ||
| 698 | dss.dss_clk = clk; | 698 | dss.dss_clk = clk; |
| 699 | 699 | ||
| 700 | clk = clk_get(NULL, dss.feat->clk_name); | 700 | if (dss.feat->clk_name) { |
| 701 | if (IS_ERR(clk)) { | 701 | clk = clk_get(NULL, dss.feat->clk_name); |
| 702 | DSSERR("Failed to get %s\n", dss.feat->clk_name); | 702 | if (IS_ERR(clk)) { |
| 703 | r = PTR_ERR(clk); | 703 | DSSERR("Failed to get %s\n", dss.feat->clk_name); |
| 704 | goto err; | 704 | r = PTR_ERR(clk); |
| 705 | goto err; | ||
| 706 | } | ||
| 707 | } else { | ||
| 708 | clk = NULL; | ||
| 705 | } | 709 | } |
| 706 | 710 | ||
| 707 | dss.dpll4_m4_ck = clk; | 711 | dss.dpll4_m4_ck = clk; |
| @@ -805,10 +809,10 @@ static int __init dss_init_features(struct device *dev) | |||
| 805 | 809 | ||
| 806 | if (cpu_is_omap24xx()) | 810 | if (cpu_is_omap24xx()) |
| 807 | src = &omap24xx_dss_feats; | 811 | src = &omap24xx_dss_feats; |
| 808 | else if (cpu_is_omap34xx()) | ||
| 809 | src = &omap34xx_dss_feats; | ||
| 810 | else if (cpu_is_omap3630()) | 812 | else if (cpu_is_omap3630()) |
| 811 | src = &omap3630_dss_feats; | 813 | src = &omap3630_dss_feats; |
| 814 | else if (cpu_is_omap34xx()) | ||
| 815 | src = &omap34xx_dss_feats; | ||
| 812 | else if (cpu_is_omap44xx()) | 816 | else if (cpu_is_omap44xx()) |
| 813 | src = &omap44xx_dss_feats; | 817 | src = &omap44xx_dss_feats; |
| 814 | else if (soc_is_omap54xx()) | 818 | else if (soc_is_omap54xx()) |
diff --git a/drivers/video/omap2/dss/hdmi.c b/drivers/video/omap2/dss/hdmi.c index a48a7dd75b33..8c9b8b3b7f77 100644 --- a/drivers/video/omap2/dss/hdmi.c +++ b/drivers/video/omap2/dss/hdmi.c | |||
| @@ -644,8 +644,10 @@ static void hdmi_dump_regs(struct seq_file *s) | |||
| 644 | { | 644 | { |
| 645 | mutex_lock(&hdmi.lock); | 645 | mutex_lock(&hdmi.lock); |
| 646 | 646 | ||
| 647 | if (hdmi_runtime_get()) | 647 | if (hdmi_runtime_get()) { |
| 648 | mutex_unlock(&hdmi.lock); | ||
| 648 | return; | 649 | return; |
| 650 | } | ||
| 649 | 651 | ||
| 650 | hdmi.ip_data.ops->dump_wrapper(&hdmi.ip_data, s); | 652 | hdmi.ip_data.ops->dump_wrapper(&hdmi.ip_data, s); |
| 651 | hdmi.ip_data.ops->dump_pll(&hdmi.ip_data, s); | 653 | hdmi.ip_data.ops->dump_pll(&hdmi.ip_data, s); |
diff --git a/drivers/video/omap2/omapfb/omapfb-ioctl.c b/drivers/video/omap2/omapfb/omapfb-ioctl.c index 606b89f12351..d630b26a005c 100644 --- a/drivers/video/omap2/omapfb/omapfb-ioctl.c +++ b/drivers/video/omap2/omapfb/omapfb-ioctl.c | |||
| @@ -787,7 +787,7 @@ int omapfb_ioctl(struct fb_info *fbi, unsigned int cmd, unsigned long arg) | |||
| 787 | 787 | ||
| 788 | case OMAPFB_WAITFORVSYNC: | 788 | case OMAPFB_WAITFORVSYNC: |
| 789 | DBG("ioctl WAITFORVSYNC\n"); | 789 | DBG("ioctl WAITFORVSYNC\n"); |
| 790 | if (!display && !display->output && !display->output->manager) { | 790 | if (!display || !display->output || !display->output->manager) { |
| 791 | r = -EINVAL; | 791 | r = -EINVAL; |
| 792 | break; | 792 | break; |
| 793 | } | 793 | } |
diff --git a/drivers/video/xen-fbfront.c b/drivers/video/xen-fbfront.c index b7f5173ff9e9..917bb5681684 100644 --- a/drivers/video/xen-fbfront.c +++ b/drivers/video/xen-fbfront.c | |||
| @@ -641,7 +641,6 @@ static void xenfb_backend_changed(struct xenbus_device *dev, | |||
| 641 | case XenbusStateReconfiguring: | 641 | case XenbusStateReconfiguring: |
| 642 | case XenbusStateReconfigured: | 642 | case XenbusStateReconfigured: |
| 643 | case XenbusStateUnknown: | 643 | case XenbusStateUnknown: |
| 644 | case XenbusStateClosed: | ||
| 645 | break; | 644 | break; |
| 646 | 645 | ||
| 647 | case XenbusStateInitWait: | 646 | case XenbusStateInitWait: |
| @@ -670,6 +669,10 @@ InitWait: | |||
| 670 | info->feature_resize = val; | 669 | info->feature_resize = val; |
| 671 | break; | 670 | break; |
| 672 | 671 | ||
| 672 | case XenbusStateClosed: | ||
| 673 | if (dev->state == XenbusStateClosed) | ||
| 674 | break; | ||
| 675 | /* Missed the backend's CLOSING state -- fallthrough */ | ||
| 673 | case XenbusStateClosing: | 676 | case XenbusStateClosing: |
| 674 | xenbus_frontend_closed(dev); | 677 | xenbus_frontend_closed(dev); |
| 675 | break; | 678 | break; |
diff --git a/drivers/virtio/virtio.c b/drivers/virtio/virtio.c index 1e8659ca27ef..809b0de59c09 100644 --- a/drivers/virtio/virtio.c +++ b/drivers/virtio/virtio.c | |||
| @@ -225,8 +225,10 @@ EXPORT_SYMBOL_GPL(register_virtio_device); | |||
| 225 | 225 | ||
| 226 | void unregister_virtio_device(struct virtio_device *dev) | 226 | void unregister_virtio_device(struct virtio_device *dev) |
| 227 | { | 227 | { |
| 228 | int index = dev->index; /* save for after device release */ | ||
| 229 | |||
| 228 | device_unregister(&dev->dev); | 230 | device_unregister(&dev->dev); |
| 229 | ida_simple_remove(&virtio_index_ida, dev->index); | 231 | ida_simple_remove(&virtio_index_ida, index); |
| 230 | } | 232 | } |
| 231 | EXPORT_SYMBOL_GPL(unregister_virtio_device); | 233 | EXPORT_SYMBOL_GPL(unregister_virtio_device); |
| 232 | 234 | ||
diff --git a/drivers/xen/Kconfig b/drivers/xen/Kconfig index d4dffcd52873..126d8ce591ce 100644 --- a/drivers/xen/Kconfig +++ b/drivers/xen/Kconfig | |||
| @@ -3,6 +3,7 @@ menu "Xen driver support" | |||
| 3 | 3 | ||
| 4 | config XEN_BALLOON | 4 | config XEN_BALLOON |
| 5 | bool "Xen memory balloon driver" | 5 | bool "Xen memory balloon driver" |
| 6 | depends on !ARM | ||
| 6 | default y | 7 | default y |
| 7 | help | 8 | help |
| 8 | The balloon driver allows the Xen domain to request more memory from | 9 | The balloon driver allows the Xen domain to request more memory from |
| @@ -145,6 +146,7 @@ config SWIOTLB_XEN | |||
| 145 | 146 | ||
| 146 | config XEN_TMEM | 147 | config XEN_TMEM |
| 147 | bool | 148 | bool |
| 149 | depends on !ARM | ||
| 148 | default y if (CLEANCACHE || FRONTSWAP) | 150 | default y if (CLEANCACHE || FRONTSWAP) |
| 149 | help | 151 | help |
| 150 | Shim to interface in-kernel Transcendent Memory hooks | 152 | Shim to interface in-kernel Transcendent Memory hooks |
diff --git a/drivers/xen/Makefile b/drivers/xen/Makefile index 0e8637035457..74354708c6c4 100644 --- a/drivers/xen/Makefile +++ b/drivers/xen/Makefile | |||
| @@ -2,6 +2,7 @@ ifneq ($(CONFIG_ARM),y) | |||
| 2 | obj-y += manage.o balloon.o | 2 | obj-y += manage.o balloon.o |
| 3 | obj-$(CONFIG_HOTPLUG_CPU) += cpu_hotplug.o | 3 | obj-$(CONFIG_HOTPLUG_CPU) += cpu_hotplug.o |
| 4 | endif | 4 | endif |
| 5 | obj-$(CONFIG_X86) += fallback.o | ||
| 5 | obj-y += grant-table.o features.o events.o | 6 | obj-y += grant-table.o features.o events.o |
| 6 | obj-y += xenbus/ | 7 | obj-y += xenbus/ |
| 7 | 8 | ||
diff --git a/drivers/xen/balloon.c b/drivers/xen/balloon.c index 31ab82fda38a..d6886d90ccfd 100644 --- a/drivers/xen/balloon.c +++ b/drivers/xen/balloon.c | |||
| @@ -55,7 +55,6 @@ | |||
| 55 | #include <asm/pgalloc.h> | 55 | #include <asm/pgalloc.h> |
| 56 | #include <asm/pgtable.h> | 56 | #include <asm/pgtable.h> |
| 57 | #include <asm/tlb.h> | 57 | #include <asm/tlb.h> |
| 58 | #include <asm/e820.h> | ||
| 59 | 58 | ||
| 60 | #include <asm/xen/hypervisor.h> | 59 | #include <asm/xen/hypervisor.h> |
| 61 | #include <asm/xen/hypercall.h> | 60 | #include <asm/xen/hypercall.h> |
| @@ -88,7 +87,7 @@ struct balloon_stats balloon_stats; | |||
| 88 | EXPORT_SYMBOL_GPL(balloon_stats); | 87 | EXPORT_SYMBOL_GPL(balloon_stats); |
| 89 | 88 | ||
| 90 | /* We increase/decrease in batches which fit in a page */ | 89 | /* We increase/decrease in batches which fit in a page */ |
| 91 | static unsigned long frame_list[PAGE_SIZE / sizeof(unsigned long)]; | 90 | static xen_pfn_t frame_list[PAGE_SIZE / sizeof(unsigned long)]; |
| 92 | 91 | ||
| 93 | #ifdef CONFIG_HIGHMEM | 92 | #ifdef CONFIG_HIGHMEM |
| 94 | #define inc_totalhigh_pages() (totalhigh_pages++) | 93 | #define inc_totalhigh_pages() (totalhigh_pages++) |
diff --git a/drivers/xen/dbgp.c b/drivers/xen/dbgp.c index 42569c77ccc8..f3ccc80a455f 100644 --- a/drivers/xen/dbgp.c +++ b/drivers/xen/dbgp.c | |||
| @@ -8,7 +8,9 @@ | |||
| 8 | 8 | ||
| 9 | static int xen_dbgp_op(struct usb_hcd *hcd, int op) | 9 | static int xen_dbgp_op(struct usb_hcd *hcd, int op) |
| 10 | { | 10 | { |
| 11 | #ifdef CONFIG_PCI | ||
| 11 | const struct device *ctrlr = hcd_to_bus(hcd)->controller; | 12 | const struct device *ctrlr = hcd_to_bus(hcd)->controller; |
| 13 | #endif | ||
| 12 | struct physdev_dbgp_op dbgp; | 14 | struct physdev_dbgp_op dbgp; |
| 13 | 15 | ||
| 14 | if (!xen_initial_domain()) | 16 | if (!xen_initial_domain()) |
diff --git a/drivers/xen/events.c b/drivers/xen/events.c index 59e10a1286d5..0be4df39e953 100644 --- a/drivers/xen/events.c +++ b/drivers/xen/events.c | |||
| @@ -115,7 +115,9 @@ struct irq_info { | |||
| 115 | #define PIRQ_SHAREABLE (1 << 1) | 115 | #define PIRQ_SHAREABLE (1 << 1) |
| 116 | 116 | ||
| 117 | static int *evtchn_to_irq; | 117 | static int *evtchn_to_irq; |
| 118 | #ifdef CONFIG_X86 | ||
| 118 | static unsigned long *pirq_eoi_map; | 119 | static unsigned long *pirq_eoi_map; |
| 120 | #endif | ||
| 119 | static bool (*pirq_needs_eoi)(unsigned irq); | 121 | static bool (*pirq_needs_eoi)(unsigned irq); |
| 120 | 122 | ||
| 121 | static DEFINE_PER_CPU(unsigned long [NR_EVENT_CHANNELS/BITS_PER_LONG], | 123 | static DEFINE_PER_CPU(unsigned long [NR_EVENT_CHANNELS/BITS_PER_LONG], |
| @@ -277,10 +279,12 @@ static unsigned int cpu_from_evtchn(unsigned int evtchn) | |||
| 277 | return ret; | 279 | return ret; |
| 278 | } | 280 | } |
| 279 | 281 | ||
| 282 | #ifdef CONFIG_X86 | ||
| 280 | static bool pirq_check_eoi_map(unsigned irq) | 283 | static bool pirq_check_eoi_map(unsigned irq) |
| 281 | { | 284 | { |
| 282 | return test_bit(pirq_from_irq(irq), pirq_eoi_map); | 285 | return test_bit(pirq_from_irq(irq), pirq_eoi_map); |
| 283 | } | 286 | } |
| 287 | #endif | ||
| 284 | 288 | ||
| 285 | static bool pirq_needs_eoi_flag(unsigned irq) | 289 | static bool pirq_needs_eoi_flag(unsigned irq) |
| 286 | { | 290 | { |
| @@ -1391,10 +1395,10 @@ void xen_evtchn_do_upcall(struct pt_regs *regs) | |||
| 1391 | { | 1395 | { |
| 1392 | struct pt_regs *old_regs = set_irq_regs(regs); | 1396 | struct pt_regs *old_regs = set_irq_regs(regs); |
| 1393 | 1397 | ||
| 1398 | irq_enter(); | ||
| 1394 | #ifdef CONFIG_X86 | 1399 | #ifdef CONFIG_X86 |
| 1395 | exit_idle(); | 1400 | exit_idle(); |
| 1396 | #endif | 1401 | #endif |
| 1397 | irq_enter(); | ||
| 1398 | 1402 | ||
| 1399 | __xen_evtchn_do_upcall(); | 1403 | __xen_evtchn_do_upcall(); |
| 1400 | 1404 | ||
diff --git a/drivers/xen/fallback.c b/drivers/xen/fallback.c new file mode 100644 index 000000000000..0ef7c4d40f86 --- /dev/null +++ b/drivers/xen/fallback.c | |||
| @@ -0,0 +1,80 @@ | |||
| 1 | #include <linux/kernel.h> | ||
| 2 | #include <linux/string.h> | ||
| 3 | #include <linux/bug.h> | ||
| 4 | #include <linux/export.h> | ||
| 5 | #include <asm/hypervisor.h> | ||
| 6 | #include <asm/xen/hypercall.h> | ||
| 7 | |||
| 8 | int xen_event_channel_op_compat(int cmd, void *arg) | ||
| 9 | { | ||
| 10 | struct evtchn_op op; | ||
| 11 | int rc; | ||
| 12 | |||
| 13 | op.cmd = cmd; | ||
| 14 | memcpy(&op.u, arg, sizeof(op.u)); | ||
| 15 | rc = _hypercall1(int, event_channel_op_compat, &op); | ||
| 16 | |||
| 17 | switch (cmd) { | ||
| 18 | case EVTCHNOP_close: | ||
| 19 | case EVTCHNOP_send: | ||
| 20 | case EVTCHNOP_bind_vcpu: | ||
| 21 | case EVTCHNOP_unmask: | ||
| 22 | /* no output */ | ||
| 23 | break; | ||
| 24 | |||
| 25 | #define COPY_BACK(eop) \ | ||
| 26 | case EVTCHNOP_##eop: \ | ||
| 27 | memcpy(arg, &op.u.eop, sizeof(op.u.eop)); \ | ||
| 28 | break | ||
| 29 | |||
| 30 | COPY_BACK(bind_interdomain); | ||
| 31 | COPY_BACK(bind_virq); | ||
| 32 | COPY_BACK(bind_pirq); | ||
| 33 | COPY_BACK(status); | ||
| 34 | COPY_BACK(alloc_unbound); | ||
| 35 | COPY_BACK(bind_ipi); | ||
| 36 | #undef COPY_BACK | ||
| 37 | |||
| 38 | default: | ||
| 39 | WARN_ON(rc != -ENOSYS); | ||
| 40 | break; | ||
| 41 | } | ||
| 42 | |||
| 43 | return rc; | ||
| 44 | } | ||
| 45 | EXPORT_SYMBOL_GPL(xen_event_channel_op_compat); | ||
| 46 | |||
| 47 | int HYPERVISOR_physdev_op_compat(int cmd, void *arg) | ||
| 48 | { | ||
| 49 | struct physdev_op op; | ||
| 50 | int rc; | ||
| 51 | |||
| 52 | op.cmd = cmd; | ||
| 53 | memcpy(&op.u, arg, sizeof(op.u)); | ||
| 54 | rc = _hypercall1(int, physdev_op_compat, &op); | ||
| 55 | |||
| 56 | switch (cmd) { | ||
| 57 | case PHYSDEVOP_IRQ_UNMASK_NOTIFY: | ||
| 58 | case PHYSDEVOP_set_iopl: | ||
| 59 | case PHYSDEVOP_set_iobitmap: | ||
| 60 | case PHYSDEVOP_apic_write: | ||
| 61 | /* no output */ | ||
| 62 | break; | ||
| 63 | |||
| 64 | #define COPY_BACK(pop, fld) \ | ||
| 65 | case PHYSDEVOP_##pop: \ | ||
| 66 | memcpy(arg, &op.u.fld, sizeof(op.u.fld)); \ | ||
| 67 | break | ||
| 68 | |||
| 69 | COPY_BACK(irq_status_query, irq_status_query); | ||
| 70 | COPY_BACK(apic_read, apic_op); | ||
| 71 | COPY_BACK(ASSIGN_VECTOR, irq_op); | ||
| 72 | #undef COPY_BACK | ||
| 73 | |||
| 74 | default: | ||
| 75 | WARN_ON(rc != -ENOSYS); | ||
| 76 | break; | ||
| 77 | } | ||
| 78 | |||
| 79 | return rc; | ||
| 80 | } | ||
diff --git a/drivers/xen/gntdev.c b/drivers/xen/gntdev.c index 610bfc6be177..2e22df2f7a3f 100644 --- a/drivers/xen/gntdev.c +++ b/drivers/xen/gntdev.c | |||
| @@ -105,6 +105,21 @@ static void gntdev_print_maps(struct gntdev_priv *priv, | |||
| 105 | #endif | 105 | #endif |
| 106 | } | 106 | } |
| 107 | 107 | ||
| 108 | static void gntdev_free_map(struct grant_map *map) | ||
| 109 | { | ||
| 110 | if (map == NULL) | ||
| 111 | return; | ||
| 112 | |||
| 113 | if (map->pages) | ||
| 114 | free_xenballooned_pages(map->count, map->pages); | ||
| 115 | kfree(map->pages); | ||
| 116 | kfree(map->grants); | ||
| 117 | kfree(map->map_ops); | ||
| 118 | kfree(map->unmap_ops); | ||
| 119 | kfree(map->kmap_ops); | ||
| 120 | kfree(map); | ||
| 121 | } | ||
| 122 | |||
| 108 | static struct grant_map *gntdev_alloc_map(struct gntdev_priv *priv, int count) | 123 | static struct grant_map *gntdev_alloc_map(struct gntdev_priv *priv, int count) |
| 109 | { | 124 | { |
| 110 | struct grant_map *add; | 125 | struct grant_map *add; |
| @@ -142,12 +157,7 @@ static struct grant_map *gntdev_alloc_map(struct gntdev_priv *priv, int count) | |||
| 142 | return add; | 157 | return add; |
| 143 | 158 | ||
| 144 | err: | 159 | err: |
| 145 | kfree(add->pages); | 160 | gntdev_free_map(add); |
| 146 | kfree(add->grants); | ||
| 147 | kfree(add->map_ops); | ||
| 148 | kfree(add->unmap_ops); | ||
| 149 | kfree(add->kmap_ops); | ||
| 150 | kfree(add); | ||
| 151 | return NULL; | 161 | return NULL; |
| 152 | } | 162 | } |
| 153 | 163 | ||
| @@ -198,17 +208,9 @@ static void gntdev_put_map(struct grant_map *map) | |||
| 198 | evtchn_put(map->notify.event); | 208 | evtchn_put(map->notify.event); |
| 199 | } | 209 | } |
| 200 | 210 | ||
| 201 | if (map->pages) { | 211 | if (map->pages && !use_ptemod) |
| 202 | if (!use_ptemod) | 212 | unmap_grant_pages(map, 0, map->count); |
| 203 | unmap_grant_pages(map, 0, map->count); | 213 | gntdev_free_map(map); |
| 204 | |||
| 205 | free_xenballooned_pages(map->count, map->pages); | ||
| 206 | } | ||
| 207 | kfree(map->pages); | ||
| 208 | kfree(map->grants); | ||
| 209 | kfree(map->map_ops); | ||
| 210 | kfree(map->unmap_ops); | ||
| 211 | kfree(map); | ||
| 212 | } | 214 | } |
| 213 | 215 | ||
| 214 | /* ------------------------------------------------------------------ */ | 216 | /* ------------------------------------------------------------------ */ |
diff --git a/drivers/xen/grant-table.c b/drivers/xen/grant-table.c index b2b0a375b348..b91f14e83164 100644 --- a/drivers/xen/grant-table.c +++ b/drivers/xen/grant-table.c | |||
| @@ -84,7 +84,7 @@ struct gnttab_ops { | |||
| 84 | * nr_gframes is the number of frames to map grant table. Returning | 84 | * nr_gframes is the number of frames to map grant table. Returning |
| 85 | * GNTST_okay means success and negative value means failure. | 85 | * GNTST_okay means success and negative value means failure. |
| 86 | */ | 86 | */ |
| 87 | int (*map_frames)(unsigned long *frames, unsigned int nr_gframes); | 87 | int (*map_frames)(xen_pfn_t *frames, unsigned int nr_gframes); |
| 88 | /* | 88 | /* |
| 89 | * Release a list of frames which are mapped in map_frames for grant | 89 | * Release a list of frames which are mapped in map_frames for grant |
| 90 | * entry status. | 90 | * entry status. |
| @@ -960,7 +960,7 @@ static unsigned nr_status_frames(unsigned nr_grant_frames) | |||
| 960 | return (nr_grant_frames * GREFS_PER_GRANT_FRAME + SPP - 1) / SPP; | 960 | return (nr_grant_frames * GREFS_PER_GRANT_FRAME + SPP - 1) / SPP; |
| 961 | } | 961 | } |
| 962 | 962 | ||
| 963 | static int gnttab_map_frames_v1(unsigned long *frames, unsigned int nr_gframes) | 963 | static int gnttab_map_frames_v1(xen_pfn_t *frames, unsigned int nr_gframes) |
| 964 | { | 964 | { |
| 965 | int rc; | 965 | int rc; |
| 966 | 966 | ||
| @@ -977,7 +977,7 @@ static void gnttab_unmap_frames_v1(void) | |||
| 977 | arch_gnttab_unmap(gnttab_shared.addr, nr_grant_frames); | 977 | arch_gnttab_unmap(gnttab_shared.addr, nr_grant_frames); |
| 978 | } | 978 | } |
| 979 | 979 | ||
| 980 | static int gnttab_map_frames_v2(unsigned long *frames, unsigned int nr_gframes) | 980 | static int gnttab_map_frames_v2(xen_pfn_t *frames, unsigned int nr_gframes) |
| 981 | { | 981 | { |
| 982 | uint64_t *sframes; | 982 | uint64_t *sframes; |
| 983 | unsigned int nr_sframes; | 983 | unsigned int nr_sframes; |
| @@ -1029,7 +1029,7 @@ static void gnttab_unmap_frames_v2(void) | |||
| 1029 | static int gnttab_map(unsigned int start_idx, unsigned int end_idx) | 1029 | static int gnttab_map(unsigned int start_idx, unsigned int end_idx) |
| 1030 | { | 1030 | { |
| 1031 | struct gnttab_setup_table setup; | 1031 | struct gnttab_setup_table setup; |
| 1032 | unsigned long *frames; | 1032 | xen_pfn_t *frames; |
| 1033 | unsigned int nr_gframes = end_idx + 1; | 1033 | unsigned int nr_gframes = end_idx + 1; |
| 1034 | int rc; | 1034 | int rc; |
| 1035 | 1035 | ||
diff --git a/drivers/xen/privcmd.c b/drivers/xen/privcmd.c index 8adb9cc267f9..71f5c459b088 100644 --- a/drivers/xen/privcmd.c +++ b/drivers/xen/privcmd.c | |||
| @@ -361,13 +361,13 @@ static long privcmd_ioctl_mmap_batch(void __user *udata, int version) | |||
| 361 | down_write(&mm->mmap_sem); | 361 | down_write(&mm->mmap_sem); |
| 362 | 362 | ||
| 363 | vma = find_vma(mm, m.addr); | 363 | vma = find_vma(mm, m.addr); |
| 364 | ret = -EINVAL; | ||
| 365 | if (!vma || | 364 | if (!vma || |
| 366 | vma->vm_ops != &privcmd_vm_ops || | 365 | vma->vm_ops != &privcmd_vm_ops || |
| 367 | (m.addr != vma->vm_start) || | 366 | (m.addr != vma->vm_start) || |
| 368 | ((m.addr + (nr_pages << PAGE_SHIFT)) != vma->vm_end) || | 367 | ((m.addr + (nr_pages << PAGE_SHIFT)) != vma->vm_end) || |
| 369 | !privcmd_enforce_singleshot_mapping(vma)) { | 368 | !privcmd_enforce_singleshot_mapping(vma)) { |
| 370 | up_write(&mm->mmap_sem); | 369 | up_write(&mm->mmap_sem); |
| 370 | ret = -EINVAL; | ||
| 371 | goto out; | 371 | goto out; |
| 372 | } | 372 | } |
| 373 | 373 | ||
| @@ -383,12 +383,16 @@ static long privcmd_ioctl_mmap_batch(void __user *udata, int version) | |||
| 383 | 383 | ||
| 384 | up_write(&mm->mmap_sem); | 384 | up_write(&mm->mmap_sem); |
| 385 | 385 | ||
| 386 | if (state.global_error && (version == 1)) { | 386 | if (version == 1) { |
| 387 | /* Write back errors in second pass. */ | 387 | if (state.global_error) { |
| 388 | state.user_mfn = (xen_pfn_t *)m.arr; | 388 | /* Write back errors in second pass. */ |
| 389 | state.err = err_array; | 389 | state.user_mfn = (xen_pfn_t *)m.arr; |
| 390 | ret = traverse_pages(m.num, sizeof(xen_pfn_t), | 390 | state.err = err_array; |
| 391 | &pagelist, mmap_return_errors_v1, &state); | 391 | ret = traverse_pages(m.num, sizeof(xen_pfn_t), |
| 392 | &pagelist, mmap_return_errors_v1, &state); | ||
| 393 | } else | ||
| 394 | ret = 0; | ||
| 395 | |||
| 392 | } else if (version == 2) { | 396 | } else if (version == 2) { |
| 393 | ret = __copy_to_user(m.err, err_array, m.num * sizeof(int)); | 397 | ret = __copy_to_user(m.err, err_array, m.num * sizeof(int)); |
| 394 | if (ret) | 398 | if (ret) |
diff --git a/drivers/xen/sys-hypervisor.c b/drivers/xen/sys-hypervisor.c index 5e5ad7e28858..96453f8a85c5 100644 --- a/drivers/xen/sys-hypervisor.c +++ b/drivers/xen/sys-hypervisor.c | |||
| @@ -11,6 +11,7 @@ | |||
| 11 | #include <linux/kernel.h> | 11 | #include <linux/kernel.h> |
| 12 | #include <linux/module.h> | 12 | #include <linux/module.h> |
| 13 | #include <linux/kobject.h> | 13 | #include <linux/kobject.h> |
| 14 | #include <linux/err.h> | ||
| 14 | 15 | ||
| 15 | #include <asm/xen/hypervisor.h> | 16 | #include <asm/xen/hypervisor.h> |
| 16 | #include <asm/xen/hypercall.h> | 17 | #include <asm/xen/hypercall.h> |
| @@ -284,7 +285,8 @@ static ssize_t virtual_start_show(struct hyp_sysfs_attr *attr, char *buffer) | |||
| 284 | ret = HYPERVISOR_xen_version(XENVER_platform_parameters, | 285 | ret = HYPERVISOR_xen_version(XENVER_platform_parameters, |
| 285 | parms); | 286 | parms); |
| 286 | if (!ret) | 287 | if (!ret) |
| 287 | ret = sprintf(buffer, "%lx\n", parms->virt_start); | 288 | ret = sprintf(buffer, "%"PRI_xen_ulong"\n", |
| 289 | parms->virt_start); | ||
| 288 | kfree(parms); | 290 | kfree(parms); |
| 289 | } | 291 | } |
| 290 | 292 | ||
diff --git a/drivers/xen/xen-pciback/vpci.c b/drivers/xen/xen-pciback/vpci.c index 46d140baebd8..0f478ac483cd 100644 --- a/drivers/xen/xen-pciback/vpci.c +++ b/drivers/xen/xen-pciback/vpci.c | |||
| @@ -89,9 +89,15 @@ static int __xen_pcibk_add_pci_dev(struct xen_pcibk_device *pdev, | |||
| 89 | 89 | ||
| 90 | mutex_lock(&vpci_dev->lock); | 90 | mutex_lock(&vpci_dev->lock); |
| 91 | 91 | ||
| 92 | /* Keep multi-function devices together on the virtual PCI bus */ | 92 | /* |
| 93 | for (slot = 0; slot < PCI_SLOT_MAX; slot++) { | 93 | * Keep multi-function devices together on the virtual PCI bus, except |
| 94 | if (!list_empty(&vpci_dev->dev_list[slot])) { | 94 | * virtual functions. |
| 95 | */ | ||
| 96 | if (!dev->is_virtfn) { | ||
| 97 | for (slot = 0; slot < PCI_SLOT_MAX; slot++) { | ||
| 98 | if (list_empty(&vpci_dev->dev_list[slot])) | ||
| 99 | continue; | ||
| 100 | |||
| 95 | t = list_entry(list_first(&vpci_dev->dev_list[slot]), | 101 | t = list_entry(list_first(&vpci_dev->dev_list[slot]), |
| 96 | struct pci_dev_entry, list); | 102 | struct pci_dev_entry, list); |
| 97 | 103 | ||
| @@ -116,7 +122,7 @@ static int __xen_pcibk_add_pci_dev(struct xen_pcibk_device *pdev, | |||
| 116 | pci_name(dev), slot); | 122 | pci_name(dev), slot); |
| 117 | list_add_tail(&dev_entry->list, | 123 | list_add_tail(&dev_entry->list, |
| 118 | &vpci_dev->dev_list[slot]); | 124 | &vpci_dev->dev_list[slot]); |
| 119 | func = PCI_FUNC(dev->devfn); | 125 | func = dev->is_virtfn ? 0 : PCI_FUNC(dev->devfn); |
| 120 | goto unlock; | 126 | goto unlock; |
| 121 | } | 127 | } |
| 122 | } | 128 | } |
diff --git a/drivers/xen/xenbus/xenbus_dev_frontend.c b/drivers/xen/xenbus/xenbus_dev_frontend.c index 89f76252a16f..ac727028e658 100644 --- a/drivers/xen/xenbus/xenbus_dev_frontend.c +++ b/drivers/xen/xenbus/xenbus_dev_frontend.c | |||
| @@ -458,7 +458,7 @@ static ssize_t xenbus_file_write(struct file *filp, | |||
| 458 | goto out; | 458 | goto out; |
| 459 | 459 | ||
| 460 | /* Can't write a xenbus message larger we can buffer */ | 460 | /* Can't write a xenbus message larger we can buffer */ |
| 461 | if ((len + u->len) > sizeof(u->u.buffer)) { | 461 | if (len > sizeof(u->u.buffer) - u->len) { |
| 462 | /* On error, dump existing buffer */ | 462 | /* On error, dump existing buffer */ |
| 463 | u->len = 0; | 463 | u->len = 0; |
| 464 | rc = -EINVAL; | 464 | rc = -EINVAL; |
diff --git a/drivers/xen/xenbus/xenbus_xs.c b/drivers/xen/xenbus/xenbus_xs.c index 48220e129f85..acedeabe589c 100644 --- a/drivers/xen/xenbus/xenbus_xs.c +++ b/drivers/xen/xenbus/xenbus_xs.c | |||
| @@ -625,8 +625,9 @@ static struct xenbus_watch *find_watch(const char *token) | |||
| 625 | * so if we are running on anything older than 4 do not attempt to read | 625 | * so if we are running on anything older than 4 do not attempt to read |
| 626 | * control/platform-feature-xs_reset_watches. | 626 | * control/platform-feature-xs_reset_watches. |
| 627 | */ | 627 | */ |
| 628 | static bool xen_strict_xenbus_quirk() | 628 | static bool xen_strict_xenbus_quirk(void) |
| 629 | { | 629 | { |
| 630 | #ifdef CONFIG_X86 | ||
| 630 | uint32_t eax, ebx, ecx, edx, base; | 631 | uint32_t eax, ebx, ecx, edx, base; |
| 631 | 632 | ||
| 632 | base = xen_cpuid_base(); | 633 | base = xen_cpuid_base(); |
| @@ -634,6 +635,7 @@ static bool xen_strict_xenbus_quirk() | |||
| 634 | 635 | ||
| 635 | if ((eax >> 16) < 4) | 636 | if ((eax >> 16) < 4) |
| 636 | return true; | 637 | return true; |
| 638 | #endif | ||
| 637 | return false; | 639 | return false; |
| 638 | 640 | ||
| 639 | } | 641 | } |
