diff options
| author | David S. Miller <davem@davemloft.net> | 2015-07-23 03:41:16 -0400 |
|---|---|---|
| committer | David S. Miller <davem@davemloft.net> | 2015-07-23 03:41:16 -0400 |
| commit | c5e40ee287db61a79af1746954ee03ebbf1ff8a3 (patch) | |
| tree | 007da00e75e9b84766ac4868421705300e1e2e14 /drivers | |
| parent | 052831879945be0d9fad2216b127147c565ec1b1 (diff) | |
| parent | c5dfd654d0ec0a28fe81e7bd4d4fd984a9855e09 (diff) | |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net
Conflicts:
net/bridge/br_mdb.c
br_mdb.c conflict was a function call being removed to fix a bug in
'net' but whose signature was changed in 'net-next'.
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers')
222 files changed, 1937 insertions, 1698 deletions
diff --git a/drivers/acpi/resource.c b/drivers/acpi/resource.c index 8244f013f210..f1c966e05078 100644 --- a/drivers/acpi/resource.c +++ b/drivers/acpi/resource.c | |||
| @@ -193,6 +193,7 @@ static bool acpi_decode_space(struct resource_win *win, | |||
| 193 | u8 iodec = attr->granularity == 0xfff ? ACPI_DECODE_10 : ACPI_DECODE_16; | 193 | u8 iodec = attr->granularity == 0xfff ? ACPI_DECODE_10 : ACPI_DECODE_16; |
| 194 | bool wp = addr->info.mem.write_protect; | 194 | bool wp = addr->info.mem.write_protect; |
| 195 | u64 len = attr->address_length; | 195 | u64 len = attr->address_length; |
| 196 | u64 start, end, offset = 0; | ||
| 196 | struct resource *res = &win->res; | 197 | struct resource *res = &win->res; |
| 197 | 198 | ||
| 198 | /* | 199 | /* |
| @@ -204,9 +205,6 @@ static bool acpi_decode_space(struct resource_win *win, | |||
| 204 | pr_debug("ACPI: Invalid address space min_addr_fix %d, max_addr_fix %d, len %llx\n", | 205 | pr_debug("ACPI: Invalid address space min_addr_fix %d, max_addr_fix %d, len %llx\n", |
| 205 | addr->min_address_fixed, addr->max_address_fixed, len); | 206 | addr->min_address_fixed, addr->max_address_fixed, len); |
| 206 | 207 | ||
| 207 | res->start = attr->minimum; | ||
| 208 | res->end = attr->maximum; | ||
| 209 | |||
| 210 | /* | 208 | /* |
| 211 | * For bridges that translate addresses across the bridge, | 209 | * For bridges that translate addresses across the bridge, |
| 212 | * translation_offset is the offset that must be added to the | 210 | * translation_offset is the offset that must be added to the |
| @@ -214,12 +212,22 @@ static bool acpi_decode_space(struct resource_win *win, | |||
| 214 | * primary side. Non-bridge devices must list 0 for all Address | 212 | * primary side. Non-bridge devices must list 0 for all Address |
| 215 | * Translation offset bits. | 213 | * Translation offset bits. |
| 216 | */ | 214 | */ |
| 217 | if (addr->producer_consumer == ACPI_PRODUCER) { | 215 | if (addr->producer_consumer == ACPI_PRODUCER) |
| 218 | res->start += attr->translation_offset; | 216 | offset = attr->translation_offset; |
| 219 | res->end += attr->translation_offset; | 217 | else if (attr->translation_offset) |
| 220 | } else if (attr->translation_offset) { | ||
| 221 | pr_debug("ACPI: translation_offset(%lld) is invalid for non-bridge device.\n", | 218 | pr_debug("ACPI: translation_offset(%lld) is invalid for non-bridge device.\n", |
| 222 | attr->translation_offset); | 219 | attr->translation_offset); |
| 220 | start = attr->minimum + offset; | ||
| 221 | end = attr->maximum + offset; | ||
| 222 | |||
| 223 | win->offset = offset; | ||
| 224 | res->start = start; | ||
| 225 | res->end = end; | ||
| 226 | if (sizeof(resource_size_t) < sizeof(u64) && | ||
| 227 | (offset != win->offset || start != res->start || end != res->end)) { | ||
| 228 | pr_warn("acpi resource window ([%#llx-%#llx] ignored, not CPU addressable)\n", | ||
| 229 | attr->minimum, attr->maximum); | ||
| 230 | return false; | ||
| 223 | } | 231 | } |
| 224 | 232 | ||
| 225 | switch (addr->resource_type) { | 233 | switch (addr->resource_type) { |
| @@ -236,8 +244,6 @@ static bool acpi_decode_space(struct resource_win *win, | |||
| 236 | return false; | 244 | return false; |
| 237 | } | 245 | } |
| 238 | 246 | ||
| 239 | win->offset = attr->translation_offset; | ||
| 240 | |||
| 241 | if (addr->producer_consumer == ACPI_PRODUCER) | 247 | if (addr->producer_consumer == ACPI_PRODUCER) |
| 242 | res->flags |= IORESOURCE_WINDOW; | 248 | res->flags |= IORESOURCE_WINDOW; |
| 243 | 249 | ||
diff --git a/drivers/ata/pata_arasan_cf.c b/drivers/ata/pata_arasan_cf.c index a9b0c820f2eb..5d9ee99c2148 100644 --- a/drivers/ata/pata_arasan_cf.c +++ b/drivers/ata/pata_arasan_cf.c | |||
| @@ -4,7 +4,7 @@ | |||
| 4 | * Arasan Compact Flash host controller source file | 4 | * Arasan Compact Flash host controller source file |
| 5 | * | 5 | * |
| 6 | * Copyright (C) 2011 ST Microelectronics | 6 | * Copyright (C) 2011 ST Microelectronics |
| 7 | * Viresh Kumar <viresh.linux@gmail.com> | 7 | * Viresh Kumar <vireshk@kernel.org> |
| 8 | * | 8 | * |
| 9 | * This file is licensed under the terms of the GNU General Public | 9 | * This file is licensed under the terms of the GNU General Public |
| 10 | * License version 2. This program is licensed "as is" without any | 10 | * License version 2. This program is licensed "as is" without any |
| @@ -968,7 +968,7 @@ static struct platform_driver arasan_cf_driver = { | |||
| 968 | 968 | ||
| 969 | module_platform_driver(arasan_cf_driver); | 969 | module_platform_driver(arasan_cf_driver); |
| 970 | 970 | ||
| 971 | MODULE_AUTHOR("Viresh Kumar <viresh.linux@gmail.com>"); | 971 | MODULE_AUTHOR("Viresh Kumar <vireshk@kernel.org>"); |
| 972 | MODULE_DESCRIPTION("Arasan ATA Compact Flash driver"); | 972 | MODULE_DESCRIPTION("Arasan ATA Compact Flash driver"); |
| 973 | MODULE_LICENSE("GPL"); | 973 | MODULE_LICENSE("GPL"); |
| 974 | MODULE_ALIAS("platform:" DRIVER_NAME); | 974 | MODULE_ALIAS("platform:" DRIVER_NAME); |
diff --git a/drivers/block/nvme-core.c b/drivers/block/nvme-core.c index d1d6141920d3..7920c2741b47 100644 --- a/drivers/block/nvme-core.c +++ b/drivers/block/nvme-core.c | |||
| @@ -2108,8 +2108,17 @@ static void nvme_alloc_ns(struct nvme_dev *dev, unsigned nsid) | |||
| 2108 | goto out_free_disk; | 2108 | goto out_free_disk; |
| 2109 | 2109 | ||
| 2110 | add_disk(ns->disk); | 2110 | add_disk(ns->disk); |
| 2111 | if (ns->ms) | 2111 | if (ns->ms) { |
| 2112 | revalidate_disk(ns->disk); | 2112 | struct block_device *bd = bdget_disk(ns->disk, 0); |
| 2113 | if (!bd) | ||
| 2114 | return; | ||
| 2115 | if (blkdev_get(bd, FMODE_READ, NULL)) { | ||
| 2116 | bdput(bd); | ||
| 2117 | return; | ||
| 2118 | } | ||
| 2119 | blkdev_reread_part(bd); | ||
| 2120 | blkdev_put(bd, FMODE_READ); | ||
| 2121 | } | ||
| 2113 | return; | 2122 | return; |
| 2114 | out_free_disk: | 2123 | out_free_disk: |
| 2115 | kfree(disk); | 2124 | kfree(disk); |
diff --git a/drivers/bluetooth/btbcm.c b/drivers/bluetooth/btbcm.c index 1e1a4323a71f..9ceb8ac68fdc 100644 --- a/drivers/bluetooth/btbcm.c +++ b/drivers/bluetooth/btbcm.c | |||
| @@ -472,12 +472,11 @@ int btbcm_setup_apple(struct hci_dev *hdev) | |||
| 472 | 472 | ||
| 473 | /* Read Verbose Config Version Info */ | 473 | /* Read Verbose Config Version Info */ |
| 474 | skb = btbcm_read_verbose_config(hdev); | 474 | skb = btbcm_read_verbose_config(hdev); |
| 475 | if (IS_ERR(skb)) | 475 | if (!IS_ERR(skb)) { |
| 476 | return PTR_ERR(skb); | 476 | BT_INFO("%s: BCM: chip id %u build %4.4u", hdev->name, skb->data[1], |
| 477 | 477 | get_unaligned_le16(skb->data + 5)); | |
| 478 | BT_INFO("%s: BCM: chip id %u build %4.4u", hdev->name, skb->data[1], | 478 | kfree_skb(skb); |
| 479 | get_unaligned_le16(skb->data + 5)); | 479 | } |
| 480 | kfree_skb(skb); | ||
| 481 | 480 | ||
| 482 | set_bit(HCI_QUIRK_STRICT_DUPLICATE_FILTER, &hdev->quirks); | 481 | set_bit(HCI_QUIRK_STRICT_DUPLICATE_FILTER, &hdev->quirks); |
| 483 | 482 | ||
diff --git a/drivers/char/tpm/tpm-chip.c b/drivers/char/tpm/tpm-chip.c index 283f00a7f036..1082d4bb016a 100644 --- a/drivers/char/tpm/tpm-chip.c +++ b/drivers/char/tpm/tpm-chip.c | |||
| @@ -129,8 +129,9 @@ struct tpm_chip *tpmm_chip_alloc(struct device *dev, | |||
| 129 | 129 | ||
| 130 | device_initialize(&chip->dev); | 130 | device_initialize(&chip->dev); |
| 131 | 131 | ||
| 132 | chip->cdev.owner = chip->pdev->driver->owner; | ||
| 133 | cdev_init(&chip->cdev, &tpm_fops); | 132 | cdev_init(&chip->cdev, &tpm_fops); |
| 133 | chip->cdev.owner = chip->pdev->driver->owner; | ||
| 134 | chip->cdev.kobj.parent = &chip->dev.kobj; | ||
| 134 | 135 | ||
| 135 | return chip; | 136 | return chip; |
| 136 | } | 137 | } |
diff --git a/drivers/char/tpm/tpm_crb.c b/drivers/char/tpm/tpm_crb.c index 44f9d20c19ac..1267322595da 100644 --- a/drivers/char/tpm/tpm_crb.c +++ b/drivers/char/tpm/tpm_crb.c | |||
| @@ -233,6 +233,14 @@ static int crb_acpi_add(struct acpi_device *device) | |||
| 233 | return -ENODEV; | 233 | return -ENODEV; |
| 234 | } | 234 | } |
| 235 | 235 | ||
| 236 | /* At least some versions of AMI BIOS have a bug that TPM2 table has | ||
| 237 | * zero address for the control area and therefore we must fail. | ||
| 238 | */ | ||
| 239 | if (!buf->control_area_pa) { | ||
| 240 | dev_err(dev, "TPM2 ACPI table has a zero address for the control area\n"); | ||
| 241 | return -EINVAL; | ||
| 242 | } | ||
| 243 | |||
| 236 | if (buf->hdr.length < sizeof(struct acpi_tpm2)) { | 244 | if (buf->hdr.length < sizeof(struct acpi_tpm2)) { |
| 237 | dev_err(dev, "TPM2 ACPI table has wrong size"); | 245 | dev_err(dev, "TPM2 ACPI table has wrong size"); |
| 238 | return -EINVAL; | 246 | return -EINVAL; |
diff --git a/drivers/clk/spear/clk-aux-synth.c b/drivers/clk/spear/clk-aux-synth.c index bdfb4421c643..f271c350ef94 100644 --- a/drivers/clk/spear/clk-aux-synth.c +++ b/drivers/clk/spear/clk-aux-synth.c | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * Copyright (C) 2012 ST Microelectronics | 2 | * Copyright (C) 2012 ST Microelectronics |
| 3 | * Viresh Kumar <viresh.linux@gmail.com> | 3 | * Viresh Kumar <vireshk@kernel.org> |
| 4 | * | 4 | * |
| 5 | * This file is licensed under the terms of the GNU General Public | 5 | * This file is licensed under the terms of the GNU General Public |
| 6 | * License version 2. This program is licensed "as is" without any | 6 | * License version 2. This program is licensed "as is" without any |
diff --git a/drivers/clk/spear/clk-frac-synth.c b/drivers/clk/spear/clk-frac-synth.c index dffd4ce6c8b5..58d678b5b40a 100644 --- a/drivers/clk/spear/clk-frac-synth.c +++ b/drivers/clk/spear/clk-frac-synth.c | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * Copyright (C) 2012 ST Microelectronics | 2 | * Copyright (C) 2012 ST Microelectronics |
| 3 | * Viresh Kumar <viresh.linux@gmail.com> | 3 | * Viresh Kumar <vireshk@kernel.org> |
| 4 | * | 4 | * |
| 5 | * This file is licensed under the terms of the GNU General Public | 5 | * This file is licensed under the terms of the GNU General Public |
| 6 | * License version 2. This program is licensed "as is" without any | 6 | * License version 2. This program is licensed "as is" without any |
diff --git a/drivers/clk/spear/clk-gpt-synth.c b/drivers/clk/spear/clk-gpt-synth.c index 1afc18c4effc..1a722e99e76e 100644 --- a/drivers/clk/spear/clk-gpt-synth.c +++ b/drivers/clk/spear/clk-gpt-synth.c | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * Copyright (C) 2012 ST Microelectronics | 2 | * Copyright (C) 2012 ST Microelectronics |
| 3 | * Viresh Kumar <viresh.linux@gmail.com> | 3 | * Viresh Kumar <vireshk@kernel.org> |
| 4 | * | 4 | * |
| 5 | * This file is licensed under the terms of the GNU General Public | 5 | * This file is licensed under the terms of the GNU General Public |
| 6 | * License version 2. This program is licensed "as is" without any | 6 | * License version 2. This program is licensed "as is" without any |
diff --git a/drivers/clk/spear/clk-vco-pll.c b/drivers/clk/spear/clk-vco-pll.c index 1b9b65bca51e..5ebddc528145 100644 --- a/drivers/clk/spear/clk-vco-pll.c +++ b/drivers/clk/spear/clk-vco-pll.c | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * Copyright (C) 2012 ST Microelectronics | 2 | * Copyright (C) 2012 ST Microelectronics |
| 3 | * Viresh Kumar <viresh.linux@gmail.com> | 3 | * Viresh Kumar <vireshk@kernel.org> |
| 4 | * | 4 | * |
| 5 | * This file is licensed under the terms of the GNU General Public | 5 | * This file is licensed under the terms of the GNU General Public |
| 6 | * License version 2. This program is licensed "as is" without any | 6 | * License version 2. This program is licensed "as is" without any |
diff --git a/drivers/clk/spear/clk.c b/drivers/clk/spear/clk.c index 628b6d5ed3d9..157fe099ea6a 100644 --- a/drivers/clk/spear/clk.c +++ b/drivers/clk/spear/clk.c | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * Copyright (C) 2012 ST Microelectronics | 2 | * Copyright (C) 2012 ST Microelectronics |
| 3 | * Viresh Kumar <viresh.linux@gmail.com> | 3 | * Viresh Kumar <vireshk@kernel.org> |
| 4 | * | 4 | * |
| 5 | * This file is licensed under the terms of the GNU General Public | 5 | * This file is licensed under the terms of the GNU General Public |
| 6 | * License version 2. This program is licensed "as is" without any | 6 | * License version 2. This program is licensed "as is" without any |
diff --git a/drivers/clk/spear/clk.h b/drivers/clk/spear/clk.h index 931737677dfa..9834944f08b1 100644 --- a/drivers/clk/spear/clk.h +++ b/drivers/clk/spear/clk.h | |||
| @@ -2,7 +2,7 @@ | |||
| 2 | * Clock framework definitions for SPEAr platform | 2 | * Clock framework definitions for SPEAr platform |
| 3 | * | 3 | * |
| 4 | * Copyright (C) 2012 ST Microelectronics | 4 | * Copyright (C) 2012 ST Microelectronics |
| 5 | * Viresh Kumar <viresh.linux@gmail.com> | 5 | * Viresh Kumar <vireshk@kernel.org> |
| 6 | * | 6 | * |
| 7 | * This file is licensed under the terms of the GNU General Public | 7 | * This file is licensed under the terms of the GNU General Public |
| 8 | * License version 2. This program is licensed "as is" without any | 8 | * License version 2. This program is licensed "as is" without any |
diff --git a/drivers/clk/spear/spear1310_clock.c b/drivers/clk/spear/spear1310_clock.c index 4daa5977793a..222ce108b41a 100644 --- a/drivers/clk/spear/spear1310_clock.c +++ b/drivers/clk/spear/spear1310_clock.c | |||
| @@ -4,7 +4,7 @@ | |||
| 4 | * SPEAr1310 machine clock framework source file | 4 | * SPEAr1310 machine clock framework source file |
| 5 | * | 5 | * |
| 6 | * Copyright (C) 2012 ST Microelectronics | 6 | * Copyright (C) 2012 ST Microelectronics |
| 7 | * Viresh Kumar <viresh.linux@gmail.com> | 7 | * Viresh Kumar <vireshk@kernel.org> |
| 8 | * | 8 | * |
| 9 | * This file is licensed under the terms of the GNU General Public | 9 | * This file is licensed under the terms of the GNU General Public |
| 10 | * License version 2. This program is licensed "as is" without any | 10 | * License version 2. This program is licensed "as is" without any |
diff --git a/drivers/clk/spear/spear1340_clock.c b/drivers/clk/spear/spear1340_clock.c index 5a5c6648308d..973c9d3fbcf8 100644 --- a/drivers/clk/spear/spear1340_clock.c +++ b/drivers/clk/spear/spear1340_clock.c | |||
| @@ -4,7 +4,7 @@ | |||
| 4 | * SPEAr1340 machine clock framework source file | 4 | * SPEAr1340 machine clock framework source file |
| 5 | * | 5 | * |
| 6 | * Copyright (C) 2012 ST Microelectronics | 6 | * Copyright (C) 2012 ST Microelectronics |
| 7 | * Viresh Kumar <viresh.linux@gmail.com> | 7 | * Viresh Kumar <vireshk@kernel.org> |
| 8 | * | 8 | * |
| 9 | * This file is licensed under the terms of the GNU General Public | 9 | * This file is licensed under the terms of the GNU General Public |
| 10 | * License version 2. This program is licensed "as is" without any | 10 | * License version 2. This program is licensed "as is" without any |
diff --git a/drivers/clk/spear/spear3xx_clock.c b/drivers/clk/spear/spear3xx_clock.c index bb5f387774e2..404a55edd613 100644 --- a/drivers/clk/spear/spear3xx_clock.c +++ b/drivers/clk/spear/spear3xx_clock.c | |||
| @@ -2,7 +2,7 @@ | |||
| 2 | * SPEAr3xx machines clock framework source file | 2 | * SPEAr3xx machines clock framework source file |
| 3 | * | 3 | * |
| 4 | * Copyright (C) 2012 ST Microelectronics | 4 | * Copyright (C) 2012 ST Microelectronics |
| 5 | * Viresh Kumar <viresh.linux@gmail.com> | 5 | * Viresh Kumar <vireshk@kernel.org> |
| 6 | * | 6 | * |
| 7 | * This file is licensed under the terms of the GNU General Public | 7 | * This file is licensed under the terms of the GNU General Public |
| 8 | * License version 2. This program is licensed "as is" without any | 8 | * License version 2. This program is licensed "as is" without any |
diff --git a/drivers/clk/spear/spear6xx_clock.c b/drivers/clk/spear/spear6xx_clock.c index 4f649c9cb094..231061fa73a4 100644 --- a/drivers/clk/spear/spear6xx_clock.c +++ b/drivers/clk/spear/spear6xx_clock.c | |||
| @@ -2,7 +2,7 @@ | |||
| 2 | * SPEAr6xx machines clock framework source file | 2 | * SPEAr6xx machines clock framework source file |
| 3 | * | 3 | * |
| 4 | * Copyright (C) 2012 ST Microelectronics | 4 | * Copyright (C) 2012 ST Microelectronics |
| 5 | * Viresh Kumar <viresh.linux@gmail.com> | 5 | * Viresh Kumar <vireshk@kernel.org> |
| 6 | * | 6 | * |
| 7 | * This file is licensed under the terms of the GNU General Public | 7 | * This file is licensed under the terms of the GNU General Public |
| 8 | * License version 2. This program is licensed "as is" without any | 8 | * License version 2. This program is licensed "as is" without any |
diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c index b612411655f9..26063afb3eba 100644 --- a/drivers/cpufreq/cpufreq.c +++ b/drivers/cpufreq/cpufreq.c | |||
| @@ -169,6 +169,15 @@ struct kobject *get_governor_parent_kobj(struct cpufreq_policy *policy) | |||
| 169 | } | 169 | } |
| 170 | EXPORT_SYMBOL_GPL(get_governor_parent_kobj); | 170 | EXPORT_SYMBOL_GPL(get_governor_parent_kobj); |
| 171 | 171 | ||
| 172 | struct cpufreq_frequency_table *cpufreq_frequency_get_table(unsigned int cpu) | ||
| 173 | { | ||
| 174 | struct cpufreq_policy *policy = per_cpu(cpufreq_cpu_data, cpu); | ||
| 175 | |||
| 176 | return policy && !policy_is_inactive(policy) ? | ||
| 177 | policy->freq_table : NULL; | ||
| 178 | } | ||
| 179 | EXPORT_SYMBOL_GPL(cpufreq_frequency_get_table); | ||
| 180 | |||
| 172 | static inline u64 get_cpu_idle_time_jiffy(unsigned int cpu, u64 *wall) | 181 | static inline u64 get_cpu_idle_time_jiffy(unsigned int cpu, u64 *wall) |
| 173 | { | 182 | { |
| 174 | u64 idle_time; | 183 | u64 idle_time; |
| @@ -1132,6 +1141,7 @@ static struct cpufreq_policy *cpufreq_policy_restore(unsigned int cpu) | |||
| 1132 | 1141 | ||
| 1133 | down_write(&policy->rwsem); | 1142 | down_write(&policy->rwsem); |
| 1134 | policy->cpu = cpu; | 1143 | policy->cpu = cpu; |
| 1144 | policy->governor = NULL; | ||
| 1135 | up_write(&policy->rwsem); | 1145 | up_write(&policy->rwsem); |
| 1136 | } | 1146 | } |
| 1137 | 1147 | ||
diff --git a/drivers/cpufreq/freq_table.c b/drivers/cpufreq/freq_table.c index df14766a8e06..dfbbf981ed56 100644 --- a/drivers/cpufreq/freq_table.c +++ b/drivers/cpufreq/freq_table.c | |||
| @@ -297,15 +297,6 @@ int cpufreq_table_validate_and_show(struct cpufreq_policy *policy, | |||
| 297 | } | 297 | } |
| 298 | EXPORT_SYMBOL_GPL(cpufreq_table_validate_and_show); | 298 | EXPORT_SYMBOL_GPL(cpufreq_table_validate_and_show); |
| 299 | 299 | ||
| 300 | struct cpufreq_policy *cpufreq_cpu_get_raw(unsigned int cpu); | ||
| 301 | |||
| 302 | struct cpufreq_frequency_table *cpufreq_frequency_get_table(unsigned int cpu) | ||
| 303 | { | ||
| 304 | struct cpufreq_policy *policy = cpufreq_cpu_get_raw(cpu); | ||
| 305 | return policy ? policy->freq_table : NULL; | ||
| 306 | } | ||
| 307 | EXPORT_SYMBOL_GPL(cpufreq_frequency_get_table); | ||
| 308 | |||
| 309 | MODULE_AUTHOR("Dominik Brodowski <linux@brodo.de>"); | 300 | MODULE_AUTHOR("Dominik Brodowski <linux@brodo.de>"); |
| 310 | MODULE_DESCRIPTION("CPUfreq frequency table helpers"); | 301 | MODULE_DESCRIPTION("CPUfreq frequency table helpers"); |
| 311 | MODULE_LICENSE("GPL"); | 302 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/cpuidle/cpuidle.c b/drivers/cpuidle/cpuidle.c index e8e2775c3821..48b7228563ad 100644 --- a/drivers/cpuidle/cpuidle.c +++ b/drivers/cpuidle/cpuidle.c | |||
| @@ -112,7 +112,12 @@ int cpuidle_find_deepest_state(struct cpuidle_driver *drv, | |||
| 112 | static void enter_freeze_proper(struct cpuidle_driver *drv, | 112 | static void enter_freeze_proper(struct cpuidle_driver *drv, |
| 113 | struct cpuidle_device *dev, int index) | 113 | struct cpuidle_device *dev, int index) |
| 114 | { | 114 | { |
| 115 | tick_freeze(); | 115 | /* |
| 116 | * trace_suspend_resume() called by tick_freeze() for the last CPU | ||
| 117 | * executing it contains RCU usage regarded as invalid in the idle | ||
| 118 | * context, so tell RCU about that. | ||
| 119 | */ | ||
| 120 | RCU_NONIDLE(tick_freeze()); | ||
| 116 | /* | 121 | /* |
| 117 | * The state used here cannot be a "coupled" one, because the "coupled" | 122 | * The state used here cannot be a "coupled" one, because the "coupled" |
| 118 | * cpuidle mechanism enables interrupts and doing that with timekeeping | 123 | * cpuidle mechanism enables interrupts and doing that with timekeeping |
| @@ -122,7 +127,7 @@ static void enter_freeze_proper(struct cpuidle_driver *drv, | |||
| 122 | WARN_ON(!irqs_disabled()); | 127 | WARN_ON(!irqs_disabled()); |
| 123 | /* | 128 | /* |
| 124 | * timekeeping_resume() that will be called by tick_unfreeze() for the | 129 | * timekeeping_resume() that will be called by tick_unfreeze() for the |
| 125 | * last CPU executing it calls functions containing RCU read-side | 130 | * first CPU executing it calls functions containing RCU read-side |
| 126 | * critical sections, so tell RCU about that. | 131 | * critical sections, so tell RCU about that. |
| 127 | */ | 132 | */ |
| 128 | RCU_NONIDLE(tick_unfreeze()); | 133 | RCU_NONIDLE(tick_unfreeze()); |
diff --git a/drivers/dma/dw/core.c b/drivers/dma/dw/core.c index 1022c2e1a2b0..cf1c87fa1edd 100644 --- a/drivers/dma/dw/core.c +++ b/drivers/dma/dw/core.c | |||
| @@ -1746,4 +1746,4 @@ EXPORT_SYMBOL_GPL(dw_dma_enable); | |||
| 1746 | MODULE_LICENSE("GPL v2"); | 1746 | MODULE_LICENSE("GPL v2"); |
| 1747 | MODULE_DESCRIPTION("Synopsys DesignWare DMA Controller core driver"); | 1747 | MODULE_DESCRIPTION("Synopsys DesignWare DMA Controller core driver"); |
| 1748 | MODULE_AUTHOR("Haavard Skinnemoen (Atmel)"); | 1748 | MODULE_AUTHOR("Haavard Skinnemoen (Atmel)"); |
| 1749 | MODULE_AUTHOR("Viresh Kumar <viresh.linux@gmail.com>"); | 1749 | MODULE_AUTHOR("Viresh Kumar <vireshk@kernel.org>"); |
diff --git a/drivers/gpio/gpio-brcmstb.c b/drivers/gpio/gpio-brcmstb.c index 7a3cb1fa0a76..4630a8133ea6 100644 --- a/drivers/gpio/gpio-brcmstb.c +++ b/drivers/gpio/gpio-brcmstb.c | |||
| @@ -87,6 +87,15 @@ static int brcmstb_gpio_remove(struct platform_device *pdev) | |||
| 87 | struct brcmstb_gpio_bank *bank; | 87 | struct brcmstb_gpio_bank *bank; |
| 88 | int ret = 0; | 88 | int ret = 0; |
| 89 | 89 | ||
| 90 | if (!priv) { | ||
| 91 | dev_err(&pdev->dev, "called %s without drvdata!\n", __func__); | ||
| 92 | return -EFAULT; | ||
| 93 | } | ||
| 94 | |||
| 95 | /* | ||
| 96 | * You can lose return values below, but we report all errors, and it's | ||
| 97 | * more important to actually perform all of the steps. | ||
| 98 | */ | ||
| 90 | list_for_each(pos, &priv->bank_list) { | 99 | list_for_each(pos, &priv->bank_list) { |
| 91 | bank = list_entry(pos, struct brcmstb_gpio_bank, node); | 100 | bank = list_entry(pos, struct brcmstb_gpio_bank, node); |
| 92 | ret = bgpio_remove(&bank->bgc); | 101 | ret = bgpio_remove(&bank->bgc); |
| @@ -143,6 +152,8 @@ static int brcmstb_gpio_probe(struct platform_device *pdev) | |||
| 143 | priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); | 152 | priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); |
| 144 | if (!priv) | 153 | if (!priv) |
| 145 | return -ENOMEM; | 154 | return -ENOMEM; |
| 155 | platform_set_drvdata(pdev, priv); | ||
| 156 | INIT_LIST_HEAD(&priv->bank_list); | ||
| 146 | 157 | ||
| 147 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 158 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
| 148 | reg_base = devm_ioremap_resource(dev, res); | 159 | reg_base = devm_ioremap_resource(dev, res); |
| @@ -153,7 +164,6 @@ static int brcmstb_gpio_probe(struct platform_device *pdev) | |||
| 153 | priv->reg_base = reg_base; | 164 | priv->reg_base = reg_base; |
| 154 | priv->pdev = pdev; | 165 | priv->pdev = pdev; |
| 155 | 166 | ||
| 156 | INIT_LIST_HEAD(&priv->bank_list); | ||
| 157 | if (brcmstb_gpio_sanity_check_banks(dev, np, res)) | 167 | if (brcmstb_gpio_sanity_check_banks(dev, np, res)) |
| 158 | return -EINVAL; | 168 | return -EINVAL; |
| 159 | 169 | ||
| @@ -221,8 +231,6 @@ static int brcmstb_gpio_probe(struct platform_device *pdev) | |||
| 221 | dev_info(dev, "Registered %d banks (GPIO(s): %d-%d)\n", | 231 | dev_info(dev, "Registered %d banks (GPIO(s): %d-%d)\n", |
| 222 | priv->num_banks, priv->gpio_base, gpio_base - 1); | 232 | priv->num_banks, priv->gpio_base, gpio_base - 1); |
| 223 | 233 | ||
| 224 | platform_set_drvdata(pdev, priv); | ||
| 225 | |||
| 226 | return 0; | 234 | return 0; |
| 227 | 235 | ||
| 228 | fail: | 236 | fail: |
diff --git a/drivers/gpio/gpio-davinci.c b/drivers/gpio/gpio-davinci.c index c5e05c82d67c..c246ac3dda7c 100644 --- a/drivers/gpio/gpio-davinci.c +++ b/drivers/gpio/gpio-davinci.c | |||
| @@ -578,15 +578,13 @@ static int davinci_gpio_irq_setup(struct platform_device *pdev) | |||
| 578 | writel_relaxed(~0, &g->clr_falling); | 578 | writel_relaxed(~0, &g->clr_falling); |
| 579 | writel_relaxed(~0, &g->clr_rising); | 579 | writel_relaxed(~0, &g->clr_rising); |
| 580 | 580 | ||
| 581 | /* set up all irqs in this bank */ | ||
| 582 | irq_set_chained_handler(bank_irq, gpio_irq_handler); | ||
| 583 | |||
| 584 | /* | 581 | /* |
| 585 | * Each chip handles 32 gpios, and each irq bank consists of 16 | 582 | * Each chip handles 32 gpios, and each irq bank consists of 16 |
| 586 | * gpio irqs. Pass the irq bank's corresponding controller to | 583 | * gpio irqs. Pass the irq bank's corresponding controller to |
| 587 | * the chained irq handler. | 584 | * the chained irq handler. |
| 588 | */ | 585 | */ |
| 589 | irq_set_handler_data(bank_irq, &chips[gpio / 32]); | 586 | irq_set_chained_handler_and_data(bank_irq, gpio_irq_handler, |
| 587 | &chips[gpio / 32]); | ||
| 590 | 588 | ||
| 591 | binten |= BIT(bank); | 589 | binten |= BIT(bank); |
| 592 | } | 590 | } |
diff --git a/drivers/gpio/gpio-max732x.c b/drivers/gpio/gpio-max732x.c index aed4ca9338bc..7d3c90e9da71 100644 --- a/drivers/gpio/gpio-max732x.c +++ b/drivers/gpio/gpio-max732x.c | |||
| @@ -603,6 +603,7 @@ static int max732x_setup_gpio(struct max732x_chip *chip, | |||
| 603 | gc->base = gpio_start; | 603 | gc->base = gpio_start; |
| 604 | gc->ngpio = port; | 604 | gc->ngpio = port; |
| 605 | gc->label = chip->client->name; | 605 | gc->label = chip->client->name; |
| 606 | gc->dev = &chip->client->dev; | ||
| 606 | gc->owner = THIS_MODULE; | 607 | gc->owner = THIS_MODULE; |
| 607 | 608 | ||
| 608 | return port; | 609 | return port; |
diff --git a/drivers/gpio/gpio-omap.c b/drivers/gpio/gpio-omap.c index b0c57d505be7..61a731ff9a07 100644 --- a/drivers/gpio/gpio-omap.c +++ b/drivers/gpio/gpio-omap.c | |||
| @@ -500,8 +500,10 @@ static int omap_gpio_irq_type(struct irq_data *d, unsigned type) | |||
| 500 | 500 | ||
| 501 | spin_lock_irqsave(&bank->lock, flags); | 501 | spin_lock_irqsave(&bank->lock, flags); |
| 502 | retval = omap_set_gpio_triggering(bank, offset, type); | 502 | retval = omap_set_gpio_triggering(bank, offset, type); |
| 503 | if (retval) | 503 | if (retval) { |
| 504 | spin_unlock_irqrestore(&bank->lock, flags); | ||
| 504 | goto error; | 505 | goto error; |
| 506 | } | ||
| 505 | omap_gpio_init_irq(bank, offset); | 507 | omap_gpio_init_irq(bank, offset); |
| 506 | if (!omap_gpio_is_input(bank, offset)) { | 508 | if (!omap_gpio_is_input(bank, offset)) { |
| 507 | spin_unlock_irqrestore(&bank->lock, flags); | 509 | spin_unlock_irqrestore(&bank->lock, flags); |
| @@ -1185,6 +1187,7 @@ static int omap_gpio_probe(struct platform_device *pdev) | |||
| 1185 | bank->irq = res->start; | 1187 | bank->irq = res->start; |
| 1186 | bank->dev = dev; | 1188 | bank->dev = dev; |
| 1187 | bank->chip.dev = dev; | 1189 | bank->chip.dev = dev; |
| 1190 | bank->chip.owner = THIS_MODULE; | ||
| 1188 | bank->dbck_flag = pdata->dbck_flag; | 1191 | bank->dbck_flag = pdata->dbck_flag; |
| 1189 | bank->stride = pdata->bank_stride; | 1192 | bank->stride = pdata->bank_stride; |
| 1190 | bank->width = pdata->bank_width; | 1193 | bank->width = pdata->bank_width; |
diff --git a/drivers/gpio/gpio-pca953x.c b/drivers/gpio/gpio-pca953x.c index d233eb3b8132..50caeb1ee350 100644 --- a/drivers/gpio/gpio-pca953x.c +++ b/drivers/gpio/gpio-pca953x.c | |||
| @@ -570,6 +570,10 @@ static int pca953x_irq_setup(struct pca953x_chip *chip, | |||
| 570 | "could not connect irqchip to gpiochip\n"); | 570 | "could not connect irqchip to gpiochip\n"); |
| 571 | return ret; | 571 | return ret; |
| 572 | } | 572 | } |
| 573 | |||
| 574 | gpiochip_set_chained_irqchip(&chip->gpio_chip, | ||
| 575 | &pca953x_irq_chip, | ||
| 576 | client->irq, NULL); | ||
| 573 | } | 577 | } |
| 574 | 578 | ||
| 575 | return 0; | 579 | return 0; |
diff --git a/drivers/gpio/gpio-xilinx.c b/drivers/gpio/gpio-xilinx.c index 77fe5d3cb105..d5284dfe01fe 100644 --- a/drivers/gpio/gpio-xilinx.c +++ b/drivers/gpio/gpio-xilinx.c | |||
| @@ -220,9 +220,9 @@ static void xgpio_save_regs(struct of_mm_gpio_chip *mm_gc) | |||
| 220 | if (!chip->gpio_width[1]) | 220 | if (!chip->gpio_width[1]) |
| 221 | return; | 221 | return; |
| 222 | 222 | ||
| 223 | xgpio_writereg(mm_gc->regs + XGPIO_DATA_OFFSET + XGPIO_TRI_OFFSET, | 223 | xgpio_writereg(mm_gc->regs + XGPIO_DATA_OFFSET + XGPIO_CHANNEL_OFFSET, |
| 224 | chip->gpio_state[1]); | 224 | chip->gpio_state[1]); |
| 225 | xgpio_writereg(mm_gc->regs + XGPIO_TRI_OFFSET + XGPIO_TRI_OFFSET, | 225 | xgpio_writereg(mm_gc->regs + XGPIO_TRI_OFFSET + XGPIO_CHANNEL_OFFSET, |
| 226 | chip->gpio_dir[1]); | 226 | chip->gpio_dir[1]); |
| 227 | } | 227 | } |
| 228 | 228 | ||
diff --git a/drivers/gpio/gpio-zynq.c b/drivers/gpio/gpio-zynq.c index 2e87c4b8da26..a78882389836 100644 --- a/drivers/gpio/gpio-zynq.c +++ b/drivers/gpio/gpio-zynq.c | |||
| @@ -757,6 +757,7 @@ static int zynq_gpio_remove(struct platform_device *pdev) | |||
| 757 | gpiochip_remove(&gpio->chip); | 757 | gpiochip_remove(&gpio->chip); |
| 758 | clk_disable_unprepare(gpio->clk); | 758 | clk_disable_unprepare(gpio->clk); |
| 759 | device_set_wakeup_capable(&pdev->dev, 0); | 759 | device_set_wakeup_capable(&pdev->dev, 0); |
| 760 | pm_runtime_disable(&pdev->dev); | ||
| 760 | return 0; | 761 | return 0; |
| 761 | } | 762 | } |
| 762 | 763 | ||
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c index d63135bf29c0..1f040d85ac47 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c | |||
| @@ -669,6 +669,7 @@ static int amdgpu_cs_ib_fill(struct amdgpu_device *adev, | |||
| 669 | static int amdgpu_cs_dependencies(struct amdgpu_device *adev, | 669 | static int amdgpu_cs_dependencies(struct amdgpu_device *adev, |
| 670 | struct amdgpu_cs_parser *p) | 670 | struct amdgpu_cs_parser *p) |
| 671 | { | 671 | { |
| 672 | struct amdgpu_fpriv *fpriv = p->filp->driver_priv; | ||
| 672 | struct amdgpu_ib *ib; | 673 | struct amdgpu_ib *ib; |
| 673 | int i, j, r; | 674 | int i, j, r; |
| 674 | 675 | ||
| @@ -694,6 +695,7 @@ static int amdgpu_cs_dependencies(struct amdgpu_device *adev, | |||
| 694 | for (j = 0; j < num_deps; ++j) { | 695 | for (j = 0; j < num_deps; ++j) { |
| 695 | struct amdgpu_fence *fence; | 696 | struct amdgpu_fence *fence; |
| 696 | struct amdgpu_ring *ring; | 697 | struct amdgpu_ring *ring; |
| 698 | struct amdgpu_ctx *ctx; | ||
| 697 | 699 | ||
| 698 | r = amdgpu_cs_get_ring(adev, deps[j].ip_type, | 700 | r = amdgpu_cs_get_ring(adev, deps[j].ip_type, |
| 699 | deps[j].ip_instance, | 701 | deps[j].ip_instance, |
| @@ -701,14 +703,21 @@ static int amdgpu_cs_dependencies(struct amdgpu_device *adev, | |||
| 701 | if (r) | 703 | if (r) |
| 702 | return r; | 704 | return r; |
| 703 | 705 | ||
| 706 | ctx = amdgpu_ctx_get(fpriv, deps[j].ctx_id); | ||
| 707 | if (ctx == NULL) | ||
| 708 | return -EINVAL; | ||
| 709 | |||
| 704 | r = amdgpu_fence_recreate(ring, p->filp, | 710 | r = amdgpu_fence_recreate(ring, p->filp, |
| 705 | deps[j].handle, | 711 | deps[j].handle, |
| 706 | &fence); | 712 | &fence); |
| 707 | if (r) | 713 | if (r) { |
| 714 | amdgpu_ctx_put(ctx); | ||
| 708 | return r; | 715 | return r; |
| 716 | } | ||
| 709 | 717 | ||
| 710 | amdgpu_sync_fence(&ib->sync, fence); | 718 | amdgpu_sync_fence(&ib->sync, fence); |
| 711 | amdgpu_fence_unref(&fence); | 719 | amdgpu_fence_unref(&fence); |
| 720 | amdgpu_ctx_put(ctx); | ||
| 712 | } | 721 | } |
| 713 | } | 722 | } |
| 714 | 723 | ||
| @@ -808,12 +817,16 @@ int amdgpu_cs_wait_ioctl(struct drm_device *dev, void *data, | |||
| 808 | 817 | ||
| 809 | r = amdgpu_cs_get_ring(adev, wait->in.ip_type, wait->in.ip_instance, | 818 | r = amdgpu_cs_get_ring(adev, wait->in.ip_type, wait->in.ip_instance, |
| 810 | wait->in.ring, &ring); | 819 | wait->in.ring, &ring); |
| 811 | if (r) | 820 | if (r) { |
| 821 | amdgpu_ctx_put(ctx); | ||
| 812 | return r; | 822 | return r; |
| 823 | } | ||
| 813 | 824 | ||
| 814 | r = amdgpu_fence_recreate(ring, filp, wait->in.handle, &fence); | 825 | r = amdgpu_fence_recreate(ring, filp, wait->in.handle, &fence); |
| 815 | if (r) | 826 | if (r) { |
| 827 | amdgpu_ctx_put(ctx); | ||
| 816 | return r; | 828 | return r; |
| 829 | } | ||
| 817 | 830 | ||
| 818 | r = fence_wait_timeout(&fence->base, true, timeout); | 831 | r = fence_wait_timeout(&fence->base, true, timeout); |
| 819 | amdgpu_fence_unref(&fence); | 832 | amdgpu_fence_unref(&fence); |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c index ba46be361c9b..d79009b65867 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | |||
| @@ -1207,10 +1207,15 @@ static int amdgpu_early_init(struct amdgpu_device *adev) | |||
| 1207 | } else { | 1207 | } else { |
| 1208 | if (adev->ip_blocks[i].funcs->early_init) { | 1208 | if (adev->ip_blocks[i].funcs->early_init) { |
| 1209 | r = adev->ip_blocks[i].funcs->early_init((void *)adev); | 1209 | r = adev->ip_blocks[i].funcs->early_init((void *)adev); |
| 1210 | if (r) | 1210 | if (r == -ENOENT) |
| 1211 | adev->ip_block_enabled[i] = false; | ||
| 1212 | else if (r) | ||
| 1211 | return r; | 1213 | return r; |
| 1214 | else | ||
| 1215 | adev->ip_block_enabled[i] = true; | ||
| 1216 | } else { | ||
| 1217 | adev->ip_block_enabled[i] = true; | ||
| 1212 | } | 1218 | } |
| 1213 | adev->ip_block_enabled[i] = true; | ||
| 1214 | } | 1219 | } |
| 1215 | } | 1220 | } |
| 1216 | 1221 | ||
diff --git a/drivers/gpu/drm/amd/amdgpu/cz_dpm.c b/drivers/gpu/drm/amd/amdgpu/cz_dpm.c index f75a31df30bd..1a2d419cbf16 100644 --- a/drivers/gpu/drm/amd/amdgpu/cz_dpm.c +++ b/drivers/gpu/drm/amd/amdgpu/cz_dpm.c | |||
| @@ -1679,25 +1679,31 @@ static int cz_dpm_unforce_dpm_levels(struct amdgpu_device *adev) | |||
| 1679 | if (ret) | 1679 | if (ret) |
| 1680 | return ret; | 1680 | return ret; |
| 1681 | 1681 | ||
| 1682 | DRM_INFO("DPM unforce state min=%d, max=%d.\n", | 1682 | DRM_DEBUG("DPM unforce state min=%d, max=%d.\n", |
| 1683 | pi->sclk_dpm.soft_min_clk, | 1683 | pi->sclk_dpm.soft_min_clk, |
| 1684 | pi->sclk_dpm.soft_max_clk); | 1684 | pi->sclk_dpm.soft_max_clk); |
| 1685 | 1685 | ||
| 1686 | return 0; | 1686 | return 0; |
| 1687 | } | 1687 | } |
| 1688 | 1688 | ||
| 1689 | static int cz_dpm_force_dpm_level(struct amdgpu_device *adev, | 1689 | static int cz_dpm_force_dpm_level(struct amdgpu_device *adev, |
| 1690 | enum amdgpu_dpm_forced_level level) | 1690 | enum amdgpu_dpm_forced_level level) |
| 1691 | { | 1691 | { |
| 1692 | int ret = 0; | 1692 | int ret = 0; |
| 1693 | 1693 | ||
| 1694 | switch (level) { | 1694 | switch (level) { |
| 1695 | case AMDGPU_DPM_FORCED_LEVEL_HIGH: | 1695 | case AMDGPU_DPM_FORCED_LEVEL_HIGH: |
| 1696 | ret = cz_dpm_unforce_dpm_levels(adev); | ||
| 1697 | if (ret) | ||
| 1698 | return ret; | ||
| 1696 | ret = cz_dpm_force_highest(adev); | 1699 | ret = cz_dpm_force_highest(adev); |
| 1697 | if (ret) | 1700 | if (ret) |
| 1698 | return ret; | 1701 | return ret; |
| 1699 | break; | 1702 | break; |
| 1700 | case AMDGPU_DPM_FORCED_LEVEL_LOW: | 1703 | case AMDGPU_DPM_FORCED_LEVEL_LOW: |
| 1704 | ret = cz_dpm_unforce_dpm_levels(adev); | ||
| 1705 | if (ret) | ||
| 1706 | return ret; | ||
| 1701 | ret = cz_dpm_force_lowest(adev); | 1707 | ret = cz_dpm_force_lowest(adev); |
| 1702 | if (ret) | 1708 | if (ret) |
| 1703 | return ret; | 1709 | return ret; |
| @@ -1711,6 +1717,8 @@ static int cz_dpm_force_dpm_level(struct amdgpu_device *adev, | |||
| 1711 | break; | 1717 | break; |
| 1712 | } | 1718 | } |
| 1713 | 1719 | ||
| 1720 | adev->pm.dpm.forced_level = level; | ||
| 1721 | |||
| 1714 | return ret; | 1722 | return ret; |
| 1715 | } | 1723 | } |
| 1716 | 1724 | ||
diff --git a/drivers/gpu/drm/amd/amdgpu/dce_v8_0.c b/drivers/gpu/drm/amd/amdgpu/dce_v8_0.c index 08387dfd98a7..cc050a329c49 100644 --- a/drivers/gpu/drm/amd/amdgpu/dce_v8_0.c +++ b/drivers/gpu/drm/amd/amdgpu/dce_v8_0.c | |||
| @@ -2566,6 +2566,7 @@ static void dce_v8_0_crtc_dpms(struct drm_crtc *crtc, int mode) | |||
| 2566 | struct drm_device *dev = crtc->dev; | 2566 | struct drm_device *dev = crtc->dev; |
| 2567 | struct amdgpu_device *adev = dev->dev_private; | 2567 | struct amdgpu_device *adev = dev->dev_private; |
| 2568 | struct amdgpu_crtc *amdgpu_crtc = to_amdgpu_crtc(crtc); | 2568 | struct amdgpu_crtc *amdgpu_crtc = to_amdgpu_crtc(crtc); |
| 2569 | unsigned type; | ||
| 2569 | 2570 | ||
| 2570 | switch (mode) { | 2571 | switch (mode) { |
| 2571 | case DRM_MODE_DPMS_ON: | 2572 | case DRM_MODE_DPMS_ON: |
| @@ -2574,6 +2575,9 @@ static void dce_v8_0_crtc_dpms(struct drm_crtc *crtc, int mode) | |||
| 2574 | dce_v8_0_vga_enable(crtc, true); | 2575 | dce_v8_0_vga_enable(crtc, true); |
| 2575 | amdgpu_atombios_crtc_blank(crtc, ATOM_DISABLE); | 2576 | amdgpu_atombios_crtc_blank(crtc, ATOM_DISABLE); |
| 2576 | dce_v8_0_vga_enable(crtc, false); | 2577 | dce_v8_0_vga_enable(crtc, false); |
| 2578 | /* Make sure VBLANK interrupt is still enabled */ | ||
| 2579 | type = amdgpu_crtc_idx_to_irq_type(adev, amdgpu_crtc->crtc_id); | ||
| 2580 | amdgpu_irq_update(adev, &adev->crtc_irq, type); | ||
| 2577 | drm_vblank_post_modeset(dev, amdgpu_crtc->crtc_id); | 2581 | drm_vblank_post_modeset(dev, amdgpu_crtc->crtc_id); |
| 2578 | dce_v8_0_crtc_load_lut(crtc); | 2582 | dce_v8_0_crtc_load_lut(crtc); |
| 2579 | break; | 2583 | break; |
diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c index 7b683fb2173c..1c7c992dea37 100644 --- a/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c | |||
| @@ -1813,10 +1813,7 @@ static u32 gfx_v8_0_get_rb_disabled(struct amdgpu_device *adev, | |||
| 1813 | u32 data, mask; | 1813 | u32 data, mask; |
| 1814 | 1814 | ||
| 1815 | data = RREG32(mmCC_RB_BACKEND_DISABLE); | 1815 | data = RREG32(mmCC_RB_BACKEND_DISABLE); |
| 1816 | if (data & 1) | 1816 | data &= CC_RB_BACKEND_DISABLE__BACKEND_DISABLE_MASK; |
| 1817 | data &= CC_RB_BACKEND_DISABLE__BACKEND_DISABLE_MASK; | ||
| 1818 | else | ||
| 1819 | data = 0; | ||
| 1820 | 1817 | ||
| 1821 | data |= RREG32(mmGC_USER_RB_BACKEND_DISABLE); | 1818 | data |= RREG32(mmGC_USER_RB_BACKEND_DISABLE); |
| 1822 | 1819 | ||
diff --git a/drivers/gpu/drm/amd/amdgpu/vi.c b/drivers/gpu/drm/amd/amdgpu/vi.c index fa5a4448531d..68552da40287 100644 --- a/drivers/gpu/drm/amd/amdgpu/vi.c +++ b/drivers/gpu/drm/amd/amdgpu/vi.c | |||
| @@ -122,6 +122,32 @@ static void vi_smc_wreg(struct amdgpu_device *adev, u32 reg, u32 v) | |||
| 122 | spin_unlock_irqrestore(&adev->smc_idx_lock, flags); | 122 | spin_unlock_irqrestore(&adev->smc_idx_lock, flags); |
| 123 | } | 123 | } |
| 124 | 124 | ||
| 125 | /* smu_8_0_d.h */ | ||
| 126 | #define mmMP0PUB_IND_INDEX 0x180 | ||
| 127 | #define mmMP0PUB_IND_DATA 0x181 | ||
| 128 | |||
| 129 | static u32 cz_smc_rreg(struct amdgpu_device *adev, u32 reg) | ||
| 130 | { | ||
| 131 | unsigned long flags; | ||
| 132 | u32 r; | ||
| 133 | |||
| 134 | spin_lock_irqsave(&adev->smc_idx_lock, flags); | ||
| 135 | WREG32(mmMP0PUB_IND_INDEX, (reg)); | ||
| 136 | r = RREG32(mmMP0PUB_IND_DATA); | ||
| 137 | spin_unlock_irqrestore(&adev->smc_idx_lock, flags); | ||
| 138 | return r; | ||
| 139 | } | ||
| 140 | |||
| 141 | static void cz_smc_wreg(struct amdgpu_device *adev, u32 reg, u32 v) | ||
| 142 | { | ||
| 143 | unsigned long flags; | ||
| 144 | |||
| 145 | spin_lock_irqsave(&adev->smc_idx_lock, flags); | ||
| 146 | WREG32(mmMP0PUB_IND_INDEX, (reg)); | ||
| 147 | WREG32(mmMP0PUB_IND_DATA, (v)); | ||
| 148 | spin_unlock_irqrestore(&adev->smc_idx_lock, flags); | ||
| 149 | } | ||
| 150 | |||
| 125 | static u32 vi_uvd_ctx_rreg(struct amdgpu_device *adev, u32 reg) | 151 | static u32 vi_uvd_ctx_rreg(struct amdgpu_device *adev, u32 reg) |
| 126 | { | 152 | { |
| 127 | unsigned long flags; | 153 | unsigned long flags; |
| @@ -1222,8 +1248,13 @@ static int vi_common_early_init(void *handle) | |||
| 1222 | bool smc_enabled = false; | 1248 | bool smc_enabled = false; |
| 1223 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; | 1249 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; |
| 1224 | 1250 | ||
| 1225 | adev->smc_rreg = &vi_smc_rreg; | 1251 | if (adev->flags & AMDGPU_IS_APU) { |
| 1226 | adev->smc_wreg = &vi_smc_wreg; | 1252 | adev->smc_rreg = &cz_smc_rreg; |
| 1253 | adev->smc_wreg = &cz_smc_wreg; | ||
| 1254 | } else { | ||
| 1255 | adev->smc_rreg = &vi_smc_rreg; | ||
| 1256 | adev->smc_wreg = &vi_smc_wreg; | ||
| 1257 | } | ||
| 1227 | adev->pcie_rreg = &vi_pcie_rreg; | 1258 | adev->pcie_rreg = &vi_pcie_rreg; |
| 1228 | adev->pcie_wreg = &vi_pcie_wreg; | 1259 | adev->pcie_wreg = &vi_pcie_wreg; |
| 1229 | adev->uvd_ctx_rreg = &vi_uvd_ctx_rreg; | 1260 | adev->uvd_ctx_rreg = &vi_uvd_ctx_rreg; |
diff --git a/drivers/gpu/drm/armada/armada_crtc.c b/drivers/gpu/drm/armada/armada_crtc.c index 42d2ffa08716..01ffe9bffe38 100644 --- a/drivers/gpu/drm/armada/armada_crtc.c +++ b/drivers/gpu/drm/armada/armada_crtc.c | |||
| @@ -531,8 +531,6 @@ static int armada_drm_crtc_mode_set(struct drm_crtc *crtc, | |||
| 531 | 531 | ||
| 532 | drm_crtc_vblank_off(crtc); | 532 | drm_crtc_vblank_off(crtc); |
| 533 | 533 | ||
| 534 | crtc->mode = *adj; | ||
| 535 | |||
| 536 | val = dcrtc->dumb_ctrl & ~CFG_DUMB_ENA; | 534 | val = dcrtc->dumb_ctrl & ~CFG_DUMB_ENA; |
| 537 | if (val != dcrtc->dumb_ctrl) { | 535 | if (val != dcrtc->dumb_ctrl) { |
| 538 | dcrtc->dumb_ctrl = val; | 536 | dcrtc->dumb_ctrl = val; |
diff --git a/drivers/gpu/drm/armada/armada_gem.c b/drivers/gpu/drm/armada/armada_gem.c index 580e10acaa3a..60a688ef81c7 100644 --- a/drivers/gpu/drm/armada/armada_gem.c +++ b/drivers/gpu/drm/armada/armada_gem.c | |||
| @@ -69,8 +69,9 @@ void armada_gem_free_object(struct drm_gem_object *obj) | |||
| 69 | 69 | ||
| 70 | if (dobj->obj.import_attach) { | 70 | if (dobj->obj.import_attach) { |
| 71 | /* We only ever display imported data */ | 71 | /* We only ever display imported data */ |
| 72 | dma_buf_unmap_attachment(dobj->obj.import_attach, dobj->sgt, | 72 | if (dobj->sgt) |
| 73 | DMA_TO_DEVICE); | 73 | dma_buf_unmap_attachment(dobj->obj.import_attach, |
| 74 | dobj->sgt, DMA_TO_DEVICE); | ||
| 74 | drm_prime_gem_destroy(&dobj->obj, NULL); | 75 | drm_prime_gem_destroy(&dobj->obj, NULL); |
| 75 | } | 76 | } |
| 76 | 77 | ||
diff --git a/drivers/gpu/drm/armada/armada_overlay.c b/drivers/gpu/drm/armada/armada_overlay.c index c5b06fdb459c..e939faba7fcc 100644 --- a/drivers/gpu/drm/armada/armada_overlay.c +++ b/drivers/gpu/drm/armada/armada_overlay.c | |||
| @@ -7,6 +7,7 @@ | |||
| 7 | * published by the Free Software Foundation. | 7 | * published by the Free Software Foundation. |
| 8 | */ | 8 | */ |
| 9 | #include <drm/drmP.h> | 9 | #include <drm/drmP.h> |
| 10 | #include <drm/drm_plane_helper.h> | ||
| 10 | #include "armada_crtc.h" | 11 | #include "armada_crtc.h" |
| 11 | #include "armada_drm.h" | 12 | #include "armada_drm.h" |
| 12 | #include "armada_fb.h" | 13 | #include "armada_fb.h" |
| @@ -85,16 +86,8 @@ static void armada_plane_vbl(struct armada_crtc *dcrtc, void *data) | |||
| 85 | 86 | ||
| 86 | if (fb) | 87 | if (fb) |
| 87 | armada_drm_queue_unref_work(dcrtc->crtc.dev, fb); | 88 | armada_drm_queue_unref_work(dcrtc->crtc.dev, fb); |
| 88 | } | ||
| 89 | 89 | ||
| 90 | static unsigned armada_limit(int start, unsigned size, unsigned max) | 90 | wake_up(&dplane->vbl.wait); |
| 91 | { | ||
| 92 | int end = start + size; | ||
| 93 | if (end < 0) | ||
| 94 | return 0; | ||
| 95 | if (start < 0) | ||
| 96 | start = 0; | ||
| 97 | return (unsigned)end > max ? max - start : end - start; | ||
| 98 | } | 91 | } |
| 99 | 92 | ||
| 100 | static int | 93 | static int |
| @@ -105,26 +98,39 @@ armada_plane_update(struct drm_plane *plane, struct drm_crtc *crtc, | |||
| 105 | { | 98 | { |
| 106 | struct armada_plane *dplane = drm_to_armada_plane(plane); | 99 | struct armada_plane *dplane = drm_to_armada_plane(plane); |
| 107 | struct armada_crtc *dcrtc = drm_to_armada_crtc(crtc); | 100 | struct armada_crtc *dcrtc = drm_to_armada_crtc(crtc); |
| 101 | struct drm_rect src = { | ||
| 102 | .x1 = src_x, | ||
| 103 | .y1 = src_y, | ||
| 104 | .x2 = src_x + src_w, | ||
| 105 | .y2 = src_y + src_h, | ||
| 106 | }; | ||
| 107 | struct drm_rect dest = { | ||
| 108 | .x1 = crtc_x, | ||
| 109 | .y1 = crtc_y, | ||
| 110 | .x2 = crtc_x + crtc_w, | ||
| 111 | .y2 = crtc_y + crtc_h, | ||
| 112 | }; | ||
| 113 | const struct drm_rect clip = { | ||
| 114 | .x2 = crtc->mode.hdisplay, | ||
| 115 | .y2 = crtc->mode.vdisplay, | ||
| 116 | }; | ||
| 108 | uint32_t val, ctrl0; | 117 | uint32_t val, ctrl0; |
| 109 | unsigned idx = 0; | 118 | unsigned idx = 0; |
| 119 | bool visible; | ||
| 110 | int ret; | 120 | int ret; |
| 111 | 121 | ||
| 112 | crtc_w = armada_limit(crtc_x, crtc_w, dcrtc->crtc.mode.hdisplay); | 122 | ret = drm_plane_helper_check_update(plane, crtc, fb, &src, &dest, &clip, |
| 113 | crtc_h = armada_limit(crtc_y, crtc_h, dcrtc->crtc.mode.vdisplay); | 123 | 0, INT_MAX, true, false, &visible); |
| 124 | if (ret) | ||
| 125 | return ret; | ||
| 126 | |||
| 114 | ctrl0 = CFG_DMA_FMT(drm_fb_to_armada_fb(fb)->fmt) | | 127 | ctrl0 = CFG_DMA_FMT(drm_fb_to_armada_fb(fb)->fmt) | |
| 115 | CFG_DMA_MOD(drm_fb_to_armada_fb(fb)->mod) | | 128 | CFG_DMA_MOD(drm_fb_to_armada_fb(fb)->mod) | |
| 116 | CFG_CBSH_ENA | CFG_DMA_HSMOOTH | CFG_DMA_ENA; | 129 | CFG_CBSH_ENA | CFG_DMA_HSMOOTH | CFG_DMA_ENA; |
| 117 | 130 | ||
| 118 | /* Does the position/size result in nothing to display? */ | 131 | /* Does the position/size result in nothing to display? */ |
| 119 | if (crtc_w == 0 || crtc_h == 0) { | 132 | if (!visible) |
| 120 | ctrl0 &= ~CFG_DMA_ENA; | 133 | ctrl0 &= ~CFG_DMA_ENA; |
| 121 | } | ||
| 122 | |||
| 123 | /* | ||
| 124 | * FIXME: if the starting point is off screen, we need to | ||
| 125 | * adjust src_x, src_y, src_w, src_h appropriately, and | ||
| 126 | * according to the scale. | ||
| 127 | */ | ||
| 128 | 134 | ||
| 129 | if (!dcrtc->plane) { | 135 | if (!dcrtc->plane) { |
| 130 | dcrtc->plane = plane; | 136 | dcrtc->plane = plane; |
| @@ -134,15 +140,19 @@ armada_plane_update(struct drm_plane *plane, struct drm_crtc *crtc, | |||
| 134 | /* FIXME: overlay on an interlaced display */ | 140 | /* FIXME: overlay on an interlaced display */ |
| 135 | /* Just updating the position/size? */ | 141 | /* Just updating the position/size? */ |
| 136 | if (plane->fb == fb && dplane->ctrl0 == ctrl0) { | 142 | if (plane->fb == fb && dplane->ctrl0 == ctrl0) { |
| 137 | val = (src_h & 0xffff0000) | src_w >> 16; | 143 | val = (drm_rect_height(&src) & 0xffff0000) | |
| 144 | drm_rect_width(&src) >> 16; | ||
| 138 | dplane->src_hw = val; | 145 | dplane->src_hw = val; |
| 139 | writel_relaxed(val, dcrtc->base + LCD_SPU_DMA_HPXL_VLN); | 146 | writel_relaxed(val, dcrtc->base + LCD_SPU_DMA_HPXL_VLN); |
| 140 | val = crtc_h << 16 | crtc_w; | 147 | |
| 148 | val = drm_rect_height(&dest) << 16 | drm_rect_width(&dest); | ||
| 141 | dplane->dst_hw = val; | 149 | dplane->dst_hw = val; |
| 142 | writel_relaxed(val, dcrtc->base + LCD_SPU_DZM_HPXL_VLN); | 150 | writel_relaxed(val, dcrtc->base + LCD_SPU_DZM_HPXL_VLN); |
| 143 | val = crtc_y << 16 | crtc_x; | 151 | |
| 152 | val = dest.y1 << 16 | dest.x1; | ||
| 144 | dplane->dst_yx = val; | 153 | dplane->dst_yx = val; |
| 145 | writel_relaxed(val, dcrtc->base + LCD_SPU_DMA_OVSA_HPXL_VLN); | 154 | writel_relaxed(val, dcrtc->base + LCD_SPU_DMA_OVSA_HPXL_VLN); |
| 155 | |||
| 146 | return 0; | 156 | return 0; |
| 147 | } else if (~dplane->ctrl0 & ctrl0 & CFG_DMA_ENA) { | 157 | } else if (~dplane->ctrl0 & ctrl0 & CFG_DMA_ENA) { |
| 148 | /* Power up the Y/U/V FIFOs on ENA 0->1 transitions */ | 158 | /* Power up the Y/U/V FIFOs on ENA 0->1 transitions */ |
| @@ -150,15 +160,14 @@ armada_plane_update(struct drm_plane *plane, struct drm_crtc *crtc, | |||
| 150 | dcrtc->base + LCD_SPU_SRAM_PARA1); | 160 | dcrtc->base + LCD_SPU_SRAM_PARA1); |
| 151 | } | 161 | } |
| 152 | 162 | ||
| 153 | ret = wait_event_timeout(dplane->vbl.wait, | 163 | wait_event_timeout(dplane->vbl.wait, |
| 154 | list_empty(&dplane->vbl.update.node), | 164 | list_empty(&dplane->vbl.update.node), |
| 155 | HZ/25); | 165 | HZ/25); |
| 156 | if (ret < 0) | ||
| 157 | return ret; | ||
| 158 | 166 | ||
| 159 | if (plane->fb != fb) { | 167 | if (plane->fb != fb) { |
| 160 | struct armada_gem_object *obj = drm_fb_obj(fb); | 168 | struct armada_gem_object *obj = drm_fb_obj(fb); |
| 161 | uint32_t sy, su, sv; | 169 | uint32_t addr[3], pixel_format; |
| 170 | int i, num_planes, hsub; | ||
| 162 | 171 | ||
| 163 | /* | 172 | /* |
| 164 | * Take a reference on the new framebuffer - we want to | 173 | * Take a reference on the new framebuffer - we want to |
| @@ -178,26 +187,39 @@ armada_plane_update(struct drm_plane *plane, struct drm_crtc *crtc, | |||
| 178 | older_fb); | 187 | older_fb); |
| 179 | } | 188 | } |
| 180 | 189 | ||
| 181 | src_y >>= 16; | 190 | src_y = src.y1 >> 16; |
| 182 | src_x >>= 16; | 191 | src_x = src.x1 >> 16; |
| 183 | sy = obj->dev_addr + fb->offsets[0] + src_y * fb->pitches[0] + | ||
| 184 | src_x * fb->bits_per_pixel / 8; | ||
| 185 | su = obj->dev_addr + fb->offsets[1] + src_y * fb->pitches[1] + | ||
| 186 | src_x; | ||
| 187 | sv = obj->dev_addr + fb->offsets[2] + src_y * fb->pitches[2] + | ||
| 188 | src_x; | ||
| 189 | 192 | ||
| 190 | armada_reg_queue_set(dplane->vbl.regs, idx, sy, | 193 | pixel_format = fb->pixel_format; |
| 194 | hsub = drm_format_horz_chroma_subsampling(pixel_format); | ||
| 195 | num_planes = drm_format_num_planes(pixel_format); | ||
| 196 | |||
| 197 | /* | ||
| 198 | * Annoyingly, shifting a YUYV-format image by one pixel | ||
| 199 | * causes the U/V planes to toggle. Toggle the UV swap. | ||
| 200 | * (Unfortunately, this causes momentary colour flickering.) | ||
| 201 | */ | ||
| 202 | if (src_x & (hsub - 1) && num_planes == 1) | ||
| 203 | ctrl0 ^= CFG_DMA_MOD(CFG_SWAPUV); | ||
| 204 | |||
| 205 | for (i = 0; i < num_planes; i++) | ||
| 206 | addr[i] = obj->dev_addr + fb->offsets[i] + | ||
| 207 | src_y * fb->pitches[i] + | ||
| 208 | src_x * drm_format_plane_cpp(pixel_format, i); | ||
| 209 | for (; i < ARRAY_SIZE(addr); i++) | ||
| 210 | addr[i] = 0; | ||
| 211 | |||
| 212 | armada_reg_queue_set(dplane->vbl.regs, idx, addr[0], | ||
| 191 | LCD_SPU_DMA_START_ADDR_Y0); | 213 | LCD_SPU_DMA_START_ADDR_Y0); |
| 192 | armada_reg_queue_set(dplane->vbl.regs, idx, su, | 214 | armada_reg_queue_set(dplane->vbl.regs, idx, addr[1], |
| 193 | LCD_SPU_DMA_START_ADDR_U0); | 215 | LCD_SPU_DMA_START_ADDR_U0); |
| 194 | armada_reg_queue_set(dplane->vbl.regs, idx, sv, | 216 | armada_reg_queue_set(dplane->vbl.regs, idx, addr[2], |
| 195 | LCD_SPU_DMA_START_ADDR_V0); | 217 | LCD_SPU_DMA_START_ADDR_V0); |
| 196 | armada_reg_queue_set(dplane->vbl.regs, idx, sy, | 218 | armada_reg_queue_set(dplane->vbl.regs, idx, addr[0], |
| 197 | LCD_SPU_DMA_START_ADDR_Y1); | 219 | LCD_SPU_DMA_START_ADDR_Y1); |
| 198 | armada_reg_queue_set(dplane->vbl.regs, idx, su, | 220 | armada_reg_queue_set(dplane->vbl.regs, idx, addr[1], |
| 199 | LCD_SPU_DMA_START_ADDR_U1); | 221 | LCD_SPU_DMA_START_ADDR_U1); |
| 200 | armada_reg_queue_set(dplane->vbl.regs, idx, sv, | 222 | armada_reg_queue_set(dplane->vbl.regs, idx, addr[2], |
| 201 | LCD_SPU_DMA_START_ADDR_V1); | 223 | LCD_SPU_DMA_START_ADDR_V1); |
| 202 | 224 | ||
| 203 | val = fb->pitches[0] << 16 | fb->pitches[0]; | 225 | val = fb->pitches[0] << 16 | fb->pitches[0]; |
| @@ -208,24 +230,27 @@ armada_plane_update(struct drm_plane *plane, struct drm_crtc *crtc, | |||
| 208 | LCD_SPU_DMA_PITCH_UV); | 230 | LCD_SPU_DMA_PITCH_UV); |
| 209 | } | 231 | } |
| 210 | 232 | ||
| 211 | val = (src_h & 0xffff0000) | src_w >> 16; | 233 | val = (drm_rect_height(&src) & 0xffff0000) | drm_rect_width(&src) >> 16; |
| 212 | if (dplane->src_hw != val) { | 234 | if (dplane->src_hw != val) { |
| 213 | dplane->src_hw = val; | 235 | dplane->src_hw = val; |
| 214 | armada_reg_queue_set(dplane->vbl.regs, idx, val, | 236 | armada_reg_queue_set(dplane->vbl.regs, idx, val, |
| 215 | LCD_SPU_DMA_HPXL_VLN); | 237 | LCD_SPU_DMA_HPXL_VLN); |
| 216 | } | 238 | } |
| 217 | val = crtc_h << 16 | crtc_w; | 239 | |
| 240 | val = drm_rect_height(&dest) << 16 | drm_rect_width(&dest); | ||
| 218 | if (dplane->dst_hw != val) { | 241 | if (dplane->dst_hw != val) { |
| 219 | dplane->dst_hw = val; | 242 | dplane->dst_hw = val; |
| 220 | armada_reg_queue_set(dplane->vbl.regs, idx, val, | 243 | armada_reg_queue_set(dplane->vbl.regs, idx, val, |
| 221 | LCD_SPU_DZM_HPXL_VLN); | 244 | LCD_SPU_DZM_HPXL_VLN); |
| 222 | } | 245 | } |
| 223 | val = crtc_y << 16 | crtc_x; | 246 | |
| 247 | val = dest.y1 << 16 | dest.x1; | ||
| 224 | if (dplane->dst_yx != val) { | 248 | if (dplane->dst_yx != val) { |
| 225 | dplane->dst_yx = val; | 249 | dplane->dst_yx = val; |
| 226 | armada_reg_queue_set(dplane->vbl.regs, idx, val, | 250 | armada_reg_queue_set(dplane->vbl.regs, idx, val, |
| 227 | LCD_SPU_DMA_OVSA_HPXL_VLN); | 251 | LCD_SPU_DMA_OVSA_HPXL_VLN); |
| 228 | } | 252 | } |
| 253 | |||
| 229 | if (dplane->ctrl0 != ctrl0) { | 254 | if (dplane->ctrl0 != ctrl0) { |
| 230 | dplane->ctrl0 = ctrl0; | 255 | dplane->ctrl0 = ctrl0; |
| 231 | armada_reg_queue_mod(dplane->vbl.regs, idx, ctrl0, | 256 | armada_reg_queue_mod(dplane->vbl.regs, idx, ctrl0, |
| @@ -279,7 +304,11 @@ static int armada_plane_disable(struct drm_plane *plane) | |||
| 279 | 304 | ||
| 280 | static void armada_plane_destroy(struct drm_plane *plane) | 305 | static void armada_plane_destroy(struct drm_plane *plane) |
| 281 | { | 306 | { |
| 282 | kfree(plane); | 307 | struct armada_plane *dplane = drm_to_armada_plane(plane); |
| 308 | |||
| 309 | drm_plane_cleanup(plane); | ||
| 310 | |||
| 311 | kfree(dplane); | ||
| 283 | } | 312 | } |
| 284 | 313 | ||
| 285 | static int armada_plane_set_property(struct drm_plane *plane, | 314 | static int armada_plane_set_property(struct drm_plane *plane, |
diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c index b9ba06176eb1..357bd04a173b 100644 --- a/drivers/gpu/drm/drm_crtc.c +++ b/drivers/gpu/drm/drm_crtc.c | |||
| @@ -2706,8 +2706,11 @@ int drm_mode_setcrtc(struct drm_device *dev, void *data, | |||
| 2706 | if (!drm_core_check_feature(dev, DRIVER_MODESET)) | 2706 | if (!drm_core_check_feature(dev, DRIVER_MODESET)) |
| 2707 | return -EINVAL; | 2707 | return -EINVAL; |
| 2708 | 2708 | ||
| 2709 | /* For some reason crtc x/y offsets are signed internally. */ | 2709 | /* |
| 2710 | if (crtc_req->x > INT_MAX || crtc_req->y > INT_MAX) | 2710 | * Universal plane src offsets are only 16.16, prevent havoc for |
| 2711 | * drivers using universal plane code internally. | ||
| 2712 | */ | ||
| 2713 | if (crtc_req->x & 0xffff0000 || crtc_req->y & 0xffff0000) | ||
| 2711 | return -ERANGE; | 2714 | return -ERANGE; |
| 2712 | 2715 | ||
| 2713 | drm_modeset_lock_all(dev); | 2716 | drm_modeset_lock_all(dev); |
diff --git a/drivers/gpu/drm/drm_ioc32.c b/drivers/gpu/drm/drm_ioc32.c index aa8bbb460c57..9cfcd0aef0df 100644 --- a/drivers/gpu/drm/drm_ioc32.c +++ b/drivers/gpu/drm/drm_ioc32.c | |||
| @@ -70,6 +70,8 @@ | |||
| 70 | 70 | ||
| 71 | #define DRM_IOCTL_WAIT_VBLANK32 DRM_IOWR(0x3a, drm_wait_vblank32_t) | 71 | #define DRM_IOCTL_WAIT_VBLANK32 DRM_IOWR(0x3a, drm_wait_vblank32_t) |
| 72 | 72 | ||
| 73 | #define DRM_IOCTL_MODE_ADDFB232 DRM_IOWR(0xb8, drm_mode_fb_cmd232_t) | ||
| 74 | |||
| 73 | typedef struct drm_version_32 { | 75 | typedef struct drm_version_32 { |
| 74 | int version_major; /**< Major version */ | 76 | int version_major; /**< Major version */ |
| 75 | int version_minor; /**< Minor version */ | 77 | int version_minor; /**< Minor version */ |
| @@ -1016,6 +1018,63 @@ static int compat_drm_wait_vblank(struct file *file, unsigned int cmd, | |||
| 1016 | return 0; | 1018 | return 0; |
| 1017 | } | 1019 | } |
| 1018 | 1020 | ||
| 1021 | typedef struct drm_mode_fb_cmd232 { | ||
| 1022 | u32 fb_id; | ||
| 1023 | u32 width; | ||
| 1024 | u32 height; | ||
| 1025 | u32 pixel_format; | ||
| 1026 | u32 flags; | ||
| 1027 | u32 handles[4]; | ||
| 1028 | u32 pitches[4]; | ||
| 1029 | u32 offsets[4]; | ||
| 1030 | u64 modifier[4]; | ||
| 1031 | } __attribute__((packed)) drm_mode_fb_cmd232_t; | ||
| 1032 | |||
| 1033 | static int compat_drm_mode_addfb2(struct file *file, unsigned int cmd, | ||
| 1034 | unsigned long arg) | ||
| 1035 | { | ||
| 1036 | struct drm_mode_fb_cmd232 __user *argp = (void __user *)arg; | ||
| 1037 | struct drm_mode_fb_cmd232 req32; | ||
| 1038 | struct drm_mode_fb_cmd2 __user *req64; | ||
| 1039 | int i; | ||
| 1040 | int err; | ||
| 1041 | |||
| 1042 | if (copy_from_user(&req32, argp, sizeof(req32))) | ||
| 1043 | return -EFAULT; | ||
| 1044 | |||
| 1045 | req64 = compat_alloc_user_space(sizeof(*req64)); | ||
| 1046 | |||
| 1047 | if (!access_ok(VERIFY_WRITE, req64, sizeof(*req64)) | ||
| 1048 | || __put_user(req32.width, &req64->width) | ||
| 1049 | || __put_user(req32.height, &req64->height) | ||
| 1050 | || __put_user(req32.pixel_format, &req64->pixel_format) | ||
| 1051 | || __put_user(req32.flags, &req64->flags)) | ||
| 1052 | return -EFAULT; | ||
| 1053 | |||
| 1054 | for (i = 0; i < 4; i++) { | ||
| 1055 | if (__put_user(req32.handles[i], &req64->handles[i])) | ||
| 1056 | return -EFAULT; | ||
| 1057 | if (__put_user(req32.pitches[i], &req64->pitches[i])) | ||
| 1058 | return -EFAULT; | ||
| 1059 | if (__put_user(req32.offsets[i], &req64->offsets[i])) | ||
| 1060 | return -EFAULT; | ||
| 1061 | if (__put_user(req32.modifier[i], &req64->modifier[i])) | ||
| 1062 | return -EFAULT; | ||
| 1063 | } | ||
| 1064 | |||
| 1065 | err = drm_ioctl(file, DRM_IOCTL_MODE_ADDFB2, (unsigned long)req64); | ||
| 1066 | if (err) | ||
| 1067 | return err; | ||
| 1068 | |||
| 1069 | if (__get_user(req32.fb_id, &req64->fb_id)) | ||
| 1070 | return -EFAULT; | ||
| 1071 | |||
| 1072 | if (copy_to_user(argp, &req32, sizeof(req32))) | ||
| 1073 | return -EFAULT; | ||
| 1074 | |||
| 1075 | return 0; | ||
| 1076 | } | ||
| 1077 | |||
| 1019 | static drm_ioctl_compat_t *drm_compat_ioctls[] = { | 1078 | static drm_ioctl_compat_t *drm_compat_ioctls[] = { |
| 1020 | [DRM_IOCTL_NR(DRM_IOCTL_VERSION32)] = compat_drm_version, | 1079 | [DRM_IOCTL_NR(DRM_IOCTL_VERSION32)] = compat_drm_version, |
| 1021 | [DRM_IOCTL_NR(DRM_IOCTL_GET_UNIQUE32)] = compat_drm_getunique, | 1080 | [DRM_IOCTL_NR(DRM_IOCTL_GET_UNIQUE32)] = compat_drm_getunique, |
| @@ -1048,6 +1107,7 @@ static drm_ioctl_compat_t *drm_compat_ioctls[] = { | |||
| 1048 | [DRM_IOCTL_NR(DRM_IOCTL_UPDATE_DRAW32)] = compat_drm_update_draw, | 1107 | [DRM_IOCTL_NR(DRM_IOCTL_UPDATE_DRAW32)] = compat_drm_update_draw, |
| 1049 | #endif | 1108 | #endif |
| 1050 | [DRM_IOCTL_NR(DRM_IOCTL_WAIT_VBLANK32)] = compat_drm_wait_vblank, | 1109 | [DRM_IOCTL_NR(DRM_IOCTL_WAIT_VBLANK32)] = compat_drm_wait_vblank, |
| 1110 | [DRM_IOCTL_NR(DRM_IOCTL_MODE_ADDFB232)] = compat_drm_mode_addfb2, | ||
| 1051 | }; | 1111 | }; |
| 1052 | 1112 | ||
| 1053 | /** | 1113 | /** |
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 542fac628b28..5f27290201e0 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h | |||
| @@ -826,6 +826,7 @@ struct intel_context { | |||
| 826 | struct kref ref; | 826 | struct kref ref; |
| 827 | int user_handle; | 827 | int user_handle; |
| 828 | uint8_t remap_slice; | 828 | uint8_t remap_slice; |
| 829 | struct drm_i915_private *i915; | ||
| 829 | struct drm_i915_file_private *file_priv; | 830 | struct drm_i915_file_private *file_priv; |
| 830 | struct i915_ctx_hang_stats hang_stats; | 831 | struct i915_ctx_hang_stats hang_stats; |
| 831 | struct i915_hw_ppgtt *ppgtt; | 832 | struct i915_hw_ppgtt *ppgtt; |
| @@ -2036,8 +2037,6 @@ struct drm_i915_gem_object { | |||
| 2036 | unsigned int cache_level:3; | 2037 | unsigned int cache_level:3; |
| 2037 | unsigned int cache_dirty:1; | 2038 | unsigned int cache_dirty:1; |
| 2038 | 2039 | ||
| 2039 | unsigned int has_dma_mapping:1; | ||
| 2040 | |||
| 2041 | unsigned int frontbuffer_bits:INTEL_FRONTBUFFER_BITS; | 2040 | unsigned int frontbuffer_bits:INTEL_FRONTBUFFER_BITS; |
| 2042 | 2041 | ||
| 2043 | unsigned int pin_display; | 2042 | unsigned int pin_display; |
| @@ -3116,7 +3115,8 @@ void i915_debugfs_cleanup(struct drm_minor *minor); | |||
| 3116 | int i915_debugfs_connector_add(struct drm_connector *connector); | 3115 | int i915_debugfs_connector_add(struct drm_connector *connector); |
| 3117 | void intel_display_crc_init(struct drm_device *dev); | 3116 | void intel_display_crc_init(struct drm_device *dev); |
| 3118 | #else | 3117 | #else |
| 3119 | static inline int i915_debugfs_connector_add(struct drm_connector *connector) {} | 3118 | static inline int i915_debugfs_connector_add(struct drm_connector *connector) |
| 3119 | { return 0; } | ||
| 3120 | static inline void intel_display_crc_init(struct drm_device *dev) {} | 3120 | static inline void intel_display_crc_init(struct drm_device *dev) {} |
| 3121 | #endif | 3121 | #endif |
| 3122 | 3122 | ||
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 248fd1ac7b3a..52b446b27b4d 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c | |||
| @@ -213,7 +213,6 @@ i915_gem_object_get_pages_phys(struct drm_i915_gem_object *obj) | |||
| 213 | sg_dma_len(sg) = obj->base.size; | 213 | sg_dma_len(sg) = obj->base.size; |
| 214 | 214 | ||
| 215 | obj->pages = st; | 215 | obj->pages = st; |
| 216 | obj->has_dma_mapping = true; | ||
| 217 | return 0; | 216 | return 0; |
| 218 | } | 217 | } |
| 219 | 218 | ||
| @@ -265,8 +264,6 @@ i915_gem_object_put_pages_phys(struct drm_i915_gem_object *obj) | |||
| 265 | 264 | ||
| 266 | sg_free_table(obj->pages); | 265 | sg_free_table(obj->pages); |
| 267 | kfree(obj->pages); | 266 | kfree(obj->pages); |
| 268 | |||
| 269 | obj->has_dma_mapping = false; | ||
| 270 | } | 267 | } |
| 271 | 268 | ||
| 272 | static void | 269 | static void |
| @@ -2139,6 +2136,8 @@ i915_gem_object_put_pages_gtt(struct drm_i915_gem_object *obj) | |||
| 2139 | obj->base.read_domains = obj->base.write_domain = I915_GEM_DOMAIN_CPU; | 2136 | obj->base.read_domains = obj->base.write_domain = I915_GEM_DOMAIN_CPU; |
| 2140 | } | 2137 | } |
| 2141 | 2138 | ||
| 2139 | i915_gem_gtt_finish_object(obj); | ||
| 2140 | |||
| 2142 | if (i915_gem_object_needs_bit17_swizzle(obj)) | 2141 | if (i915_gem_object_needs_bit17_swizzle(obj)) |
| 2143 | i915_gem_object_save_bit_17_swizzle(obj); | 2142 | i915_gem_object_save_bit_17_swizzle(obj); |
| 2144 | 2143 | ||
| @@ -2199,6 +2198,7 @@ i915_gem_object_get_pages_gtt(struct drm_i915_gem_object *obj) | |||
| 2199 | struct sg_page_iter sg_iter; | 2198 | struct sg_page_iter sg_iter; |
| 2200 | struct page *page; | 2199 | struct page *page; |
| 2201 | unsigned long last_pfn = 0; /* suppress gcc warning */ | 2200 | unsigned long last_pfn = 0; /* suppress gcc warning */ |
| 2201 | int ret; | ||
| 2202 | gfp_t gfp; | 2202 | gfp_t gfp; |
| 2203 | 2203 | ||
| 2204 | /* Assert that the object is not currently in any GPU domain. As it | 2204 | /* Assert that the object is not currently in any GPU domain. As it |
| @@ -2246,8 +2246,10 @@ i915_gem_object_get_pages_gtt(struct drm_i915_gem_object *obj) | |||
| 2246 | */ | 2246 | */ |
| 2247 | i915_gem_shrink_all(dev_priv); | 2247 | i915_gem_shrink_all(dev_priv); |
| 2248 | page = shmem_read_mapping_page(mapping, i); | 2248 | page = shmem_read_mapping_page(mapping, i); |
| 2249 | if (IS_ERR(page)) | 2249 | if (IS_ERR(page)) { |
| 2250 | ret = PTR_ERR(page); | ||
| 2250 | goto err_pages; | 2251 | goto err_pages; |
| 2252 | } | ||
| 2251 | } | 2253 | } |
| 2252 | #ifdef CONFIG_SWIOTLB | 2254 | #ifdef CONFIG_SWIOTLB |
| 2253 | if (swiotlb_nr_tbl()) { | 2255 | if (swiotlb_nr_tbl()) { |
| @@ -2276,6 +2278,10 @@ i915_gem_object_get_pages_gtt(struct drm_i915_gem_object *obj) | |||
| 2276 | sg_mark_end(sg); | 2278 | sg_mark_end(sg); |
| 2277 | obj->pages = st; | 2279 | obj->pages = st; |
| 2278 | 2280 | ||
| 2281 | ret = i915_gem_gtt_prepare_object(obj); | ||
| 2282 | if (ret) | ||
| 2283 | goto err_pages; | ||
| 2284 | |||
| 2279 | if (i915_gem_object_needs_bit17_swizzle(obj)) | 2285 | if (i915_gem_object_needs_bit17_swizzle(obj)) |
| 2280 | i915_gem_object_do_bit_17_swizzle(obj); | 2286 | i915_gem_object_do_bit_17_swizzle(obj); |
| 2281 | 2287 | ||
| @@ -2300,10 +2306,10 @@ err_pages: | |||
| 2300 | * space and so want to translate the error from shmemfs back to our | 2306 | * space and so want to translate the error from shmemfs back to our |
| 2301 | * usual understanding of ENOMEM. | 2307 | * usual understanding of ENOMEM. |
| 2302 | */ | 2308 | */ |
| 2303 | if (PTR_ERR(page) == -ENOSPC) | 2309 | if (ret == -ENOSPC) |
| 2304 | return -ENOMEM; | 2310 | ret = -ENOMEM; |
| 2305 | else | 2311 | |
| 2306 | return PTR_ERR(page); | 2312 | return ret; |
| 2307 | } | 2313 | } |
| 2308 | 2314 | ||
| 2309 | /* Ensure that the associated pages are gathered from the backing storage | 2315 | /* Ensure that the associated pages are gathered from the backing storage |
| @@ -2542,6 +2548,7 @@ int __i915_add_request(struct intel_engine_cs *ring, | |||
| 2542 | } | 2548 | } |
| 2543 | 2549 | ||
| 2544 | request->emitted_jiffies = jiffies; | 2550 | request->emitted_jiffies = jiffies; |
| 2551 | ring->last_submitted_seqno = request->seqno; | ||
| 2545 | list_add_tail(&request->list, &ring->request_list); | 2552 | list_add_tail(&request->list, &ring->request_list); |
| 2546 | request->file_priv = NULL; | 2553 | request->file_priv = NULL; |
| 2547 | 2554 | ||
| @@ -3247,10 +3254,8 @@ int i915_vma_unbind(struct i915_vma *vma) | |||
| 3247 | 3254 | ||
| 3248 | /* Since the unbound list is global, only move to that list if | 3255 | /* Since the unbound list is global, only move to that list if |
| 3249 | * no more VMAs exist. */ | 3256 | * no more VMAs exist. */ |
| 3250 | if (list_empty(&obj->vma_list)) { | 3257 | if (list_empty(&obj->vma_list)) |
| 3251 | i915_gem_gtt_finish_object(obj); | ||
| 3252 | list_move_tail(&obj->global_list, &dev_priv->mm.unbound_list); | 3258 | list_move_tail(&obj->global_list, &dev_priv->mm.unbound_list); |
| 3253 | } | ||
| 3254 | 3259 | ||
| 3255 | /* And finally now the object is completely decoupled from this vma, | 3260 | /* And finally now the object is completely decoupled from this vma, |
| 3256 | * we can drop its hold on the backing storage and allow it to be | 3261 | * we can drop its hold on the backing storage and allow it to be |
| @@ -3768,22 +3773,16 @@ search_free: | |||
| 3768 | goto err_remove_node; | 3773 | goto err_remove_node; |
| 3769 | } | 3774 | } |
| 3770 | 3775 | ||
| 3771 | ret = i915_gem_gtt_prepare_object(obj); | ||
| 3772 | if (ret) | ||
| 3773 | goto err_remove_node; | ||
| 3774 | |||
| 3775 | trace_i915_vma_bind(vma, flags); | 3776 | trace_i915_vma_bind(vma, flags); |
| 3776 | ret = i915_vma_bind(vma, obj->cache_level, flags); | 3777 | ret = i915_vma_bind(vma, obj->cache_level, flags); |
| 3777 | if (ret) | 3778 | if (ret) |
| 3778 | goto err_finish_gtt; | 3779 | goto err_remove_node; |
| 3779 | 3780 | ||
| 3780 | list_move_tail(&obj->global_list, &dev_priv->mm.bound_list); | 3781 | list_move_tail(&obj->global_list, &dev_priv->mm.bound_list); |
| 3781 | list_add_tail(&vma->mm_list, &vm->inactive_list); | 3782 | list_add_tail(&vma->mm_list, &vm->inactive_list); |
| 3782 | 3783 | ||
| 3783 | return vma; | 3784 | return vma; |
| 3784 | 3785 | ||
| 3785 | err_finish_gtt: | ||
| 3786 | i915_gem_gtt_finish_object(obj); | ||
| 3787 | err_remove_node: | 3786 | err_remove_node: |
| 3788 | drm_mm_remove_node(&vma->node); | 3787 | drm_mm_remove_node(&vma->node); |
| 3789 | err_free_vma: | 3788 | err_free_vma: |
diff --git a/drivers/gpu/drm/i915/i915_gem_context.c b/drivers/gpu/drm/i915/i915_gem_context.c index d65cbe6afb92..48afa777e94a 100644 --- a/drivers/gpu/drm/i915/i915_gem_context.c +++ b/drivers/gpu/drm/i915/i915_gem_context.c | |||
| @@ -135,8 +135,7 @@ static int get_context_size(struct drm_device *dev) | |||
| 135 | 135 | ||
| 136 | void i915_gem_context_free(struct kref *ctx_ref) | 136 | void i915_gem_context_free(struct kref *ctx_ref) |
| 137 | { | 137 | { |
| 138 | struct intel_context *ctx = container_of(ctx_ref, | 138 | struct intel_context *ctx = container_of(ctx_ref, typeof(*ctx), ref); |
| 139 | typeof(*ctx), ref); | ||
| 140 | 139 | ||
| 141 | trace_i915_context_free(ctx); | 140 | trace_i915_context_free(ctx); |
| 142 | 141 | ||
| @@ -195,6 +194,7 @@ __create_hw_context(struct drm_device *dev, | |||
| 195 | 194 | ||
| 196 | kref_init(&ctx->ref); | 195 | kref_init(&ctx->ref); |
| 197 | list_add_tail(&ctx->link, &dev_priv->context_list); | 196 | list_add_tail(&ctx->link, &dev_priv->context_list); |
| 197 | ctx->i915 = dev_priv; | ||
| 198 | 198 | ||
| 199 | if (dev_priv->hw_context_size) { | 199 | if (dev_priv->hw_context_size) { |
| 200 | struct drm_i915_gem_object *obj = | 200 | struct drm_i915_gem_object *obj = |
diff --git a/drivers/gpu/drm/i915/i915_gem_dmabuf.c b/drivers/gpu/drm/i915/i915_gem_dmabuf.c index 7998da27c500..e9c2bfd85b52 100644 --- a/drivers/gpu/drm/i915/i915_gem_dmabuf.c +++ b/drivers/gpu/drm/i915/i915_gem_dmabuf.c | |||
| @@ -256,7 +256,6 @@ static int i915_gem_object_get_pages_dmabuf(struct drm_i915_gem_object *obj) | |||
| 256 | return PTR_ERR(sg); | 256 | return PTR_ERR(sg); |
| 257 | 257 | ||
| 258 | obj->pages = sg; | 258 | obj->pages = sg; |
| 259 | obj->has_dma_mapping = true; | ||
| 260 | return 0; | 259 | return 0; |
| 261 | } | 260 | } |
| 262 | 261 | ||
| @@ -264,7 +263,6 @@ static void i915_gem_object_put_pages_dmabuf(struct drm_i915_gem_object *obj) | |||
| 264 | { | 263 | { |
| 265 | dma_buf_unmap_attachment(obj->base.import_attach, | 264 | dma_buf_unmap_attachment(obj->base.import_attach, |
| 266 | obj->pages, DMA_BIDIRECTIONAL); | 265 | obj->pages, DMA_BIDIRECTIONAL); |
| 267 | obj->has_dma_mapping = false; | ||
| 268 | } | 266 | } |
| 269 | 267 | ||
| 270 | static const struct drm_i915_gem_object_ops i915_gem_object_dmabuf_ops = { | 268 | static const struct drm_i915_gem_object_ops i915_gem_object_dmabuf_ops = { |
diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c index dcc6a88c560e..56b52a4767d4 100644 --- a/drivers/gpu/drm/i915/i915_gem_gtt.c +++ b/drivers/gpu/drm/i915/i915_gem_gtt.c | |||
| @@ -1723,9 +1723,6 @@ void i915_gem_suspend_gtt_mappings(struct drm_device *dev) | |||
| 1723 | 1723 | ||
| 1724 | int i915_gem_gtt_prepare_object(struct drm_i915_gem_object *obj) | 1724 | int i915_gem_gtt_prepare_object(struct drm_i915_gem_object *obj) |
| 1725 | { | 1725 | { |
| 1726 | if (obj->has_dma_mapping) | ||
| 1727 | return 0; | ||
| 1728 | |||
| 1729 | if (!dma_map_sg(&obj->base.dev->pdev->dev, | 1726 | if (!dma_map_sg(&obj->base.dev->pdev->dev, |
| 1730 | obj->pages->sgl, obj->pages->nents, | 1727 | obj->pages->sgl, obj->pages->nents, |
| 1731 | PCI_DMA_BIDIRECTIONAL)) | 1728 | PCI_DMA_BIDIRECTIONAL)) |
| @@ -1972,10 +1969,8 @@ void i915_gem_gtt_finish_object(struct drm_i915_gem_object *obj) | |||
| 1972 | 1969 | ||
| 1973 | interruptible = do_idling(dev_priv); | 1970 | interruptible = do_idling(dev_priv); |
| 1974 | 1971 | ||
| 1975 | if (!obj->has_dma_mapping) | 1972 | dma_unmap_sg(&dev->pdev->dev, obj->pages->sgl, obj->pages->nents, |
| 1976 | dma_unmap_sg(&dev->pdev->dev, | 1973 | PCI_DMA_BIDIRECTIONAL); |
| 1977 | obj->pages->sgl, obj->pages->nents, | ||
| 1978 | PCI_DMA_BIDIRECTIONAL); | ||
| 1979 | 1974 | ||
| 1980 | undo_idling(dev_priv, interruptible); | 1975 | undo_idling(dev_priv, interruptible); |
| 1981 | } | 1976 | } |
diff --git a/drivers/gpu/drm/i915/i915_gem_stolen.c b/drivers/gpu/drm/i915/i915_gem_stolen.c index 348ed5abcdbf..8b5b784c62fe 100644 --- a/drivers/gpu/drm/i915/i915_gem_stolen.c +++ b/drivers/gpu/drm/i915/i915_gem_stolen.c | |||
| @@ -416,7 +416,6 @@ _i915_gem_object_create_stolen(struct drm_device *dev, | |||
| 416 | if (obj->pages == NULL) | 416 | if (obj->pages == NULL) |
| 417 | goto cleanup; | 417 | goto cleanup; |
| 418 | 418 | ||
| 419 | obj->has_dma_mapping = true; | ||
| 420 | i915_gem_object_pin_pages(obj); | 419 | i915_gem_object_pin_pages(obj); |
| 421 | obj->stolen = stolen; | 420 | obj->stolen = stolen; |
| 422 | 421 | ||
diff --git a/drivers/gpu/drm/i915/i915_gem_tiling.c b/drivers/gpu/drm/i915/i915_gem_tiling.c index d61e74a08f82..633bd1fcab69 100644 --- a/drivers/gpu/drm/i915/i915_gem_tiling.c +++ b/drivers/gpu/drm/i915/i915_gem_tiling.c | |||
| @@ -183,18 +183,8 @@ i915_gem_detect_bit_6_swizzle(struct drm_device *dev) | |||
| 183 | if (IS_GEN4(dev)) { | 183 | if (IS_GEN4(dev)) { |
| 184 | uint32_t ddc2 = I915_READ(DCC2); | 184 | uint32_t ddc2 = I915_READ(DCC2); |
| 185 | 185 | ||
| 186 | if (!(ddc2 & DCC2_MODIFIED_ENHANCED_DISABLE)) { | 186 | if (!(ddc2 & DCC2_MODIFIED_ENHANCED_DISABLE)) |
| 187 | /* Since the swizzling may vary within an | ||
| 188 | * object, we have no idea what the swizzling | ||
| 189 | * is for any page in particular. Thus we | ||
| 190 | * cannot migrate tiled pages using the GPU, | ||
| 191 | * nor can we tell userspace what the exact | ||
| 192 | * swizzling is for any object. | ||
| 193 | */ | ||
| 194 | dev_priv->quirks |= QUIRK_PIN_SWIZZLED_PAGES; | 187 | dev_priv->quirks |= QUIRK_PIN_SWIZZLED_PAGES; |
| 195 | swizzle_x = I915_BIT_6_SWIZZLE_UNKNOWN; | ||
| 196 | swizzle_y = I915_BIT_6_SWIZZLE_UNKNOWN; | ||
| 197 | } | ||
| 198 | } | 188 | } |
| 199 | 189 | ||
| 200 | if (dcc == 0xffffffff) { | 190 | if (dcc == 0xffffffff) { |
diff --git a/drivers/gpu/drm/i915/i915_gem_userptr.c b/drivers/gpu/drm/i915/i915_gem_userptr.c index 1f4e5a32a16e..8fd431bcdfd3 100644 --- a/drivers/gpu/drm/i915/i915_gem_userptr.c +++ b/drivers/gpu/drm/i915/i915_gem_userptr.c | |||
| @@ -545,6 +545,26 @@ err: | |||
| 545 | return ret; | 545 | return ret; |
| 546 | } | 546 | } |
| 547 | 547 | ||
| 548 | static int | ||
| 549 | __i915_gem_userptr_set_pages(struct drm_i915_gem_object *obj, | ||
| 550 | struct page **pvec, int num_pages) | ||
| 551 | { | ||
| 552 | int ret; | ||
| 553 | |||
| 554 | ret = st_set_pages(&obj->pages, pvec, num_pages); | ||
| 555 | if (ret) | ||
| 556 | return ret; | ||
| 557 | |||
| 558 | ret = i915_gem_gtt_prepare_object(obj); | ||
| 559 | if (ret) { | ||
| 560 | sg_free_table(obj->pages); | ||
| 561 | kfree(obj->pages); | ||
| 562 | obj->pages = NULL; | ||
| 563 | } | ||
| 564 | |||
| 565 | return ret; | ||
| 566 | } | ||
| 567 | |||
| 548 | static void | 568 | static void |
| 549 | __i915_gem_userptr_get_pages_worker(struct work_struct *_work) | 569 | __i915_gem_userptr_get_pages_worker(struct work_struct *_work) |
| 550 | { | 570 | { |
| @@ -584,9 +604,12 @@ __i915_gem_userptr_get_pages_worker(struct work_struct *_work) | |||
| 584 | if (obj->userptr.work != &work->work) { | 604 | if (obj->userptr.work != &work->work) { |
| 585 | ret = 0; | 605 | ret = 0; |
| 586 | } else if (pinned == num_pages) { | 606 | } else if (pinned == num_pages) { |
| 587 | ret = st_set_pages(&obj->pages, pvec, num_pages); | 607 | ret = __i915_gem_userptr_set_pages(obj, pvec, num_pages); |
| 588 | if (ret == 0) { | 608 | if (ret == 0) { |
| 589 | list_add_tail(&obj->global_list, &to_i915(dev)->mm.unbound_list); | 609 | list_add_tail(&obj->global_list, &to_i915(dev)->mm.unbound_list); |
| 610 | obj->get_page.sg = obj->pages->sgl; | ||
| 611 | obj->get_page.last = 0; | ||
| 612 | |||
| 590 | pinned = 0; | 613 | pinned = 0; |
| 591 | } | 614 | } |
| 592 | } | 615 | } |
| @@ -693,7 +716,7 @@ i915_gem_userptr_get_pages(struct drm_i915_gem_object *obj) | |||
| 693 | } | 716 | } |
| 694 | } | 717 | } |
| 695 | } else { | 718 | } else { |
| 696 | ret = st_set_pages(&obj->pages, pvec, num_pages); | 719 | ret = __i915_gem_userptr_set_pages(obj, pvec, num_pages); |
| 697 | if (ret == 0) { | 720 | if (ret == 0) { |
| 698 | obj->userptr.work = NULL; | 721 | obj->userptr.work = NULL; |
| 699 | pinned = 0; | 722 | pinned = 0; |
| @@ -715,6 +738,8 @@ i915_gem_userptr_put_pages(struct drm_i915_gem_object *obj) | |||
| 715 | if (obj->madv != I915_MADV_WILLNEED) | 738 | if (obj->madv != I915_MADV_WILLNEED) |
| 716 | obj->dirty = 0; | 739 | obj->dirty = 0; |
| 717 | 740 | ||
| 741 | i915_gem_gtt_finish_object(obj); | ||
| 742 | |||
| 718 | for_each_sg_page(obj->pages->sgl, &sg_iter, obj->pages->nents, 0) { | 743 | for_each_sg_page(obj->pages->sgl, &sg_iter, obj->pages->nents, 0) { |
| 719 | struct page *page = sg_page_iter_page(&sg_iter); | 744 | struct page *page = sg_page_iter_page(&sg_iter); |
| 720 | 745 | ||
diff --git a/drivers/gpu/drm/i915/i915_ioc32.c b/drivers/gpu/drm/i915/i915_ioc32.c index 176de6322e4d..23aa04cded6b 100644 --- a/drivers/gpu/drm/i915/i915_ioc32.c +++ b/drivers/gpu/drm/i915/i915_ioc32.c | |||
| @@ -204,7 +204,7 @@ long i915_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) | |||
| 204 | drm_ioctl_compat_t *fn = NULL; | 204 | drm_ioctl_compat_t *fn = NULL; |
| 205 | int ret; | 205 | int ret; |
| 206 | 206 | ||
| 207 | if (nr < DRM_COMMAND_BASE) | 207 | if (nr < DRM_COMMAND_BASE || nr >= DRM_COMMAND_END) |
| 208 | return drm_compat_ioctl(filp, cmd, arg); | 208 | return drm_compat_ioctl(filp, cmd, arg); |
| 209 | 209 | ||
| 210 | if (nr < DRM_COMMAND_BASE + ARRAY_SIZE(i915_compat_ioctls)) | 210 | if (nr < DRM_COMMAND_BASE + ARRAY_SIZE(i915_compat_ioctls)) |
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index e6bb72dca3ff..984e2fe6688c 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c | |||
| @@ -2706,18 +2706,11 @@ static void gen8_disable_vblank(struct drm_device *dev, int pipe) | |||
| 2706 | spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags); | 2706 | spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags); |
| 2707 | } | 2707 | } |
| 2708 | 2708 | ||
| 2709 | static struct drm_i915_gem_request * | ||
| 2710 | ring_last_request(struct intel_engine_cs *ring) | ||
| 2711 | { | ||
| 2712 | return list_entry(ring->request_list.prev, | ||
| 2713 | struct drm_i915_gem_request, list); | ||
| 2714 | } | ||
| 2715 | |||
| 2716 | static bool | 2709 | static bool |
| 2717 | ring_idle(struct intel_engine_cs *ring) | 2710 | ring_idle(struct intel_engine_cs *ring, u32 seqno) |
| 2718 | { | 2711 | { |
| 2719 | return (list_empty(&ring->request_list) || | 2712 | return (list_empty(&ring->request_list) || |
| 2720 | i915_gem_request_completed(ring_last_request(ring), false)); | 2713 | i915_seqno_passed(seqno, ring->last_submitted_seqno)); |
| 2721 | } | 2714 | } |
| 2722 | 2715 | ||
| 2723 | static bool | 2716 | static bool |
| @@ -2939,7 +2932,7 @@ static void i915_hangcheck_elapsed(struct work_struct *work) | |||
| 2939 | acthd = intel_ring_get_active_head(ring); | 2932 | acthd = intel_ring_get_active_head(ring); |
| 2940 | 2933 | ||
| 2941 | if (ring->hangcheck.seqno == seqno) { | 2934 | if (ring->hangcheck.seqno == seqno) { |
| 2942 | if (ring_idle(ring)) { | 2935 | if (ring_idle(ring, seqno)) { |
| 2943 | ring->hangcheck.action = HANGCHECK_IDLE; | 2936 | ring->hangcheck.action = HANGCHECK_IDLE; |
| 2944 | 2937 | ||
| 2945 | if (waitqueue_active(&ring->irq_queue)) { | 2938 | if (waitqueue_active(&ring->irq_queue)) { |
diff --git a/drivers/gpu/drm/i915/i915_trace.h b/drivers/gpu/drm/i915/i915_trace.h index 497cba5deb1e..849a2590e010 100644 --- a/drivers/gpu/drm/i915/i915_trace.h +++ b/drivers/gpu/drm/i915/i915_trace.h | |||
| @@ -727,7 +727,7 @@ DECLARE_EVENT_CLASS(i915_context, | |||
| 727 | TP_fast_assign( | 727 | TP_fast_assign( |
| 728 | __entry->ctx = ctx; | 728 | __entry->ctx = ctx; |
| 729 | __entry->vm = ctx->ppgtt ? &ctx->ppgtt->base : NULL; | 729 | __entry->vm = ctx->ppgtt ? &ctx->ppgtt->base : NULL; |
| 730 | __entry->dev = ctx->file_priv->dev_priv->dev->primary->index; | 730 | __entry->dev = ctx->i915->dev->primary->index; |
| 731 | ), | 731 | ), |
| 732 | 732 | ||
| 733 | TP_printk("dev=%u, ctx=%p, ctx_vm=%p", | 733 | TP_printk("dev=%u, ctx=%p, ctx_vm=%p", |
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 647b1404c441..30e0f54ba19d 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c | |||
| @@ -6315,9 +6315,6 @@ static void intel_crtc_disable(struct drm_crtc *crtc) | |||
| 6315 | struct drm_connector *connector; | 6315 | struct drm_connector *connector; |
| 6316 | struct drm_i915_private *dev_priv = dev->dev_private; | 6316 | struct drm_i915_private *dev_priv = dev->dev_private; |
| 6317 | 6317 | ||
| 6318 | /* crtc should still be enabled when we disable it. */ | ||
| 6319 | WARN_ON(!crtc->state->enable); | ||
| 6320 | |||
| 6321 | intel_crtc_disable_planes(crtc); | 6318 | intel_crtc_disable_planes(crtc); |
| 6322 | dev_priv->display.crtc_disable(crtc); | 6319 | dev_priv->display.crtc_disable(crtc); |
| 6323 | dev_priv->display.off(crtc); | 6320 | dev_priv->display.off(crtc); |
| @@ -12591,7 +12588,8 @@ static int __intel_set_mode(struct drm_crtc *modeset_crtc, | |||
| 12591 | continue; | 12588 | continue; |
| 12592 | 12589 | ||
| 12593 | if (!crtc_state->enable) { | 12590 | if (!crtc_state->enable) { |
| 12594 | intel_crtc_disable(crtc); | 12591 | if (crtc->state->enable) |
| 12592 | intel_crtc_disable(crtc); | ||
| 12595 | } else if (crtc->state->enable) { | 12593 | } else if (crtc->state->enable) { |
| 12596 | intel_crtc_disable_planes(crtc); | 12594 | intel_crtc_disable_planes(crtc); |
| 12597 | dev_priv->display.crtc_disable(crtc); | 12595 | dev_priv->display.crtc_disable(crtc); |
| @@ -13276,7 +13274,7 @@ intel_check_primary_plane(struct drm_plane *plane, | |||
| 13276 | if (ret) | 13274 | if (ret) |
| 13277 | return ret; | 13275 | return ret; |
| 13278 | 13276 | ||
| 13279 | if (intel_crtc->active) { | 13277 | if (crtc_state ? crtc_state->base.active : intel_crtc->active) { |
| 13280 | struct intel_plane_state *old_state = | 13278 | struct intel_plane_state *old_state = |
| 13281 | to_intel_plane_state(plane->state); | 13279 | to_intel_plane_state(plane->state); |
| 13282 | 13280 | ||
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h index e539314ae87e..4be66f60504d 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.h +++ b/drivers/gpu/drm/i915/intel_ringbuffer.h | |||
| @@ -275,6 +275,13 @@ struct intel_engine_cs { | |||
| 275 | * Do we have some not yet emitted requests outstanding? | 275 | * Do we have some not yet emitted requests outstanding? |
| 276 | */ | 276 | */ |
| 277 | struct drm_i915_gem_request *outstanding_lazy_request; | 277 | struct drm_i915_gem_request *outstanding_lazy_request; |
| 278 | /** | ||
| 279 | * Seqno of request most recently submitted to request_list. | ||
| 280 | * Used exclusively by hang checker to avoid grabbing lock while | ||
| 281 | * inspecting request list. | ||
| 282 | */ | ||
| 283 | u32 last_submitted_seqno; | ||
| 284 | |||
| 278 | bool gpu_caches_dirty; | 285 | bool gpu_caches_dirty; |
| 279 | 286 | ||
| 280 | wait_queue_head_t irq_queue; | 287 | wait_queue_head_t irq_queue; |
diff --git a/drivers/gpu/drm/imx/imx-tve.c b/drivers/gpu/drm/imx/imx-tve.c index 214eceefc981..e671ad369416 100644 --- a/drivers/gpu/drm/imx/imx-tve.c +++ b/drivers/gpu/drm/imx/imx-tve.c | |||
| @@ -301,7 +301,7 @@ static void imx_tve_encoder_prepare(struct drm_encoder *encoder) | |||
| 301 | 301 | ||
| 302 | switch (tve->mode) { | 302 | switch (tve->mode) { |
| 303 | case TVE_MODE_VGA: | 303 | case TVE_MODE_VGA: |
| 304 | imx_drm_set_bus_format_pins(encoder, MEDIA_BUS_FMT_YUV8_1X24, | 304 | imx_drm_set_bus_format_pins(encoder, MEDIA_BUS_FMT_GBR888_1X24, |
| 305 | tve->hsync_pin, tve->vsync_pin); | 305 | tve->hsync_pin, tve->vsync_pin); |
| 306 | break; | 306 | break; |
| 307 | case TVE_MODE_TVOUT: | 307 | case TVE_MODE_TVOUT: |
diff --git a/drivers/gpu/drm/imx/parallel-display.c b/drivers/gpu/drm/imx/parallel-display.c index 74a9ce40ddc4..b4deb9cf9d71 100644 --- a/drivers/gpu/drm/imx/parallel-display.c +++ b/drivers/gpu/drm/imx/parallel-display.c | |||
| @@ -21,6 +21,7 @@ | |||
| 21 | #include <drm/drm_panel.h> | 21 | #include <drm/drm_panel.h> |
| 22 | #include <linux/videodev2.h> | 22 | #include <linux/videodev2.h> |
| 23 | #include <video/of_display_timing.h> | 23 | #include <video/of_display_timing.h> |
| 24 | #include <linux/of_graph.h> | ||
| 24 | 25 | ||
| 25 | #include "imx-drm.h" | 26 | #include "imx-drm.h" |
| 26 | 27 | ||
| @@ -208,7 +209,7 @@ static int imx_pd_bind(struct device *dev, struct device *master, void *data) | |||
| 208 | { | 209 | { |
| 209 | struct drm_device *drm = data; | 210 | struct drm_device *drm = data; |
| 210 | struct device_node *np = dev->of_node; | 211 | struct device_node *np = dev->of_node; |
| 211 | struct device_node *panel_node; | 212 | struct device_node *port; |
| 212 | const u8 *edidp; | 213 | const u8 *edidp; |
| 213 | struct imx_parallel_display *imxpd; | 214 | struct imx_parallel_display *imxpd; |
| 214 | int ret; | 215 | int ret; |
| @@ -234,11 +235,19 @@ static int imx_pd_bind(struct device *dev, struct device *master, void *data) | |||
| 234 | imxpd->bus_format = MEDIA_BUS_FMT_RGB666_1X24_CPADHI; | 235 | imxpd->bus_format = MEDIA_BUS_FMT_RGB666_1X24_CPADHI; |
| 235 | } | 236 | } |
| 236 | 237 | ||
| 237 | panel_node = of_parse_phandle(np, "fsl,panel", 0); | 238 | /* port@1 is the output port */ |
| 238 | if (panel_node) { | 239 | port = of_graph_get_port_by_id(np, 1); |
| 239 | imxpd->panel = of_drm_find_panel(panel_node); | 240 | if (port) { |
| 240 | if (!imxpd->panel) | 241 | struct device_node *endpoint, *remote; |
| 241 | return -EPROBE_DEFER; | 242 | |
| 243 | endpoint = of_get_child_by_name(port, "endpoint"); | ||
| 244 | if (endpoint) { | ||
| 245 | remote = of_graph_get_remote_port_parent(endpoint); | ||
| 246 | if (remote) | ||
| 247 | imxpd->panel = of_drm_find_panel(remote); | ||
| 248 | if (!imxpd->panel) | ||
| 249 | return -EPROBE_DEFER; | ||
| 250 | } | ||
| 242 | } | 251 | } |
| 243 | 252 | ||
| 244 | imxpd->dev = dev; | 253 | imxpd->dev = dev; |
diff --git a/drivers/gpu/drm/radeon/ci_dpm.c b/drivers/gpu/drm/radeon/ci_dpm.c index 8730562323a8..4a09947be244 100644 --- a/drivers/gpu/drm/radeon/ci_dpm.c +++ b/drivers/gpu/drm/radeon/ci_dpm.c | |||
| @@ -5818,7 +5818,7 @@ int ci_dpm_init(struct radeon_device *rdev) | |||
| 5818 | tmp |= DPM_ENABLED; | 5818 | tmp |= DPM_ENABLED; |
| 5819 | break; | 5819 | break; |
| 5820 | default: | 5820 | default: |
| 5821 | DRM_ERROR("Invalid PCC GPIO: %u!\n", gpio.shift); | 5821 | DRM_DEBUG("Invalid PCC GPIO: %u!\n", gpio.shift); |
| 5822 | break; | 5822 | break; |
| 5823 | } | 5823 | } |
| 5824 | WREG32_SMC(CNB_PWRMGT_CNTL, tmp); | 5824 | WREG32_SMC(CNB_PWRMGT_CNTL, tmp); |
diff --git a/drivers/gpu/drm/radeon/radeon_gart.c b/drivers/gpu/drm/radeon/radeon_gart.c index 5450fa95a47e..c4777c8d0312 100644 --- a/drivers/gpu/drm/radeon/radeon_gart.c +++ b/drivers/gpu/drm/radeon/radeon_gart.c | |||
| @@ -260,8 +260,10 @@ void radeon_gart_unbind(struct radeon_device *rdev, unsigned offset, | |||
| 260 | } | 260 | } |
| 261 | } | 261 | } |
| 262 | } | 262 | } |
| 263 | mb(); | 263 | if (rdev->gart.ptr) { |
| 264 | radeon_gart_tlb_flush(rdev); | 264 | mb(); |
| 265 | radeon_gart_tlb_flush(rdev); | ||
| 266 | } | ||
| 265 | } | 267 | } |
| 266 | 268 | ||
| 267 | /** | 269 | /** |
| @@ -306,8 +308,10 @@ int radeon_gart_bind(struct radeon_device *rdev, unsigned offset, | |||
| 306 | page_base += RADEON_GPU_PAGE_SIZE; | 308 | page_base += RADEON_GPU_PAGE_SIZE; |
| 307 | } | 309 | } |
| 308 | } | 310 | } |
| 309 | mb(); | 311 | if (rdev->gart.ptr) { |
| 310 | radeon_gart_tlb_flush(rdev); | 312 | mb(); |
| 313 | radeon_gart_tlb_flush(rdev); | ||
| 314 | } | ||
| 311 | return 0; | 315 | return 0; |
| 312 | } | 316 | } |
| 313 | 317 | ||
diff --git a/drivers/gpu/drm/radeon/radeon_gem.c b/drivers/gpu/drm/radeon/radeon_gem.c index 013ec7106e55..3dcc5733ff69 100644 --- a/drivers/gpu/drm/radeon/radeon_gem.c +++ b/drivers/gpu/drm/radeon/radeon_gem.c | |||
| @@ -36,6 +36,7 @@ void radeon_gem_object_free(struct drm_gem_object *gobj) | |||
| 36 | if (robj) { | 36 | if (robj) { |
| 37 | if (robj->gem_base.import_attach) | 37 | if (robj->gem_base.import_attach) |
| 38 | drm_prime_gem_destroy(&robj->gem_base, robj->tbo.sg); | 38 | drm_prime_gem_destroy(&robj->gem_base, robj->tbo.sg); |
| 39 | radeon_mn_unregister(robj); | ||
| 39 | radeon_bo_unref(&robj); | 40 | radeon_bo_unref(&robj); |
| 40 | } | 41 | } |
| 41 | } | 42 | } |
diff --git a/drivers/gpu/drm/radeon/radeon_object.c b/drivers/gpu/drm/radeon/radeon_object.c index 318165d4855c..676362769b8d 100644 --- a/drivers/gpu/drm/radeon/radeon_object.c +++ b/drivers/gpu/drm/radeon/radeon_object.c | |||
| @@ -75,7 +75,6 @@ static void radeon_ttm_bo_destroy(struct ttm_buffer_object *tbo) | |||
| 75 | bo = container_of(tbo, struct radeon_bo, tbo); | 75 | bo = container_of(tbo, struct radeon_bo, tbo); |
| 76 | 76 | ||
| 77 | radeon_update_memory_usage(bo, bo->tbo.mem.mem_type, -1); | 77 | radeon_update_memory_usage(bo, bo->tbo.mem.mem_type, -1); |
| 78 | radeon_mn_unregister(bo); | ||
| 79 | 78 | ||
| 80 | mutex_lock(&bo->rdev->gem.mutex); | 79 | mutex_lock(&bo->rdev->gem.mutex); |
| 81 | list_del_init(&bo->list); | 80 | list_del_init(&bo->list); |
diff --git a/drivers/gpu/drm/radeon/si_dpm.c b/drivers/gpu/drm/radeon/si_dpm.c index 1dbdf3230dae..787cd8fd897f 100644 --- a/drivers/gpu/drm/radeon/si_dpm.c +++ b/drivers/gpu/drm/radeon/si_dpm.c | |||
| @@ -2926,6 +2926,7 @@ static struct si_dpm_quirk si_dpm_quirk_list[] = { | |||
| 2926 | /* PITCAIRN - https://bugs.freedesktop.org/show_bug.cgi?id=76490 */ | 2926 | /* PITCAIRN - https://bugs.freedesktop.org/show_bug.cgi?id=76490 */ |
| 2927 | { PCI_VENDOR_ID_ATI, 0x6810, 0x1462, 0x3036, 0, 120000 }, | 2927 | { PCI_VENDOR_ID_ATI, 0x6810, 0x1462, 0x3036, 0, 120000 }, |
| 2928 | { PCI_VENDOR_ID_ATI, 0x6811, 0x174b, 0xe271, 0, 120000 }, | 2928 | { PCI_VENDOR_ID_ATI, 0x6811, 0x174b, 0xe271, 0, 120000 }, |
| 2929 | { PCI_VENDOR_ID_ATI, 0x6810, 0x174b, 0xe271, 85000, 90000 }, | ||
| 2929 | { 0, 0, 0, 0 }, | 2930 | { 0, 0, 0, 0 }, |
| 2930 | }; | 2931 | }; |
| 2931 | 2932 | ||
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c index 01b558fe3695..9a0c2911272a 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c +++ b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c | |||
| @@ -555,7 +555,6 @@ static struct platform_driver rockchip_drm_platform_driver = { | |||
| 555 | .probe = rockchip_drm_platform_probe, | 555 | .probe = rockchip_drm_platform_probe, |
| 556 | .remove = rockchip_drm_platform_remove, | 556 | .remove = rockchip_drm_platform_remove, |
| 557 | .driver = { | 557 | .driver = { |
| 558 | .owner = THIS_MODULE, | ||
| 559 | .name = "rockchip-drm", | 558 | .name = "rockchip-drm", |
| 560 | .of_match_table = rockchip_drm_dt_ids, | 559 | .of_match_table = rockchip_drm_dt_ids, |
| 561 | .pm = &rockchip_drm_pm_ops, | 560 | .pm = &rockchip_drm_pm_ops, |
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_fb.c b/drivers/gpu/drm/rockchip/rockchip_drm_fb.c index 77d52893d40f..002645bb5bbf 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_fb.c +++ b/drivers/gpu/drm/rockchip/rockchip_drm_fb.c | |||
| @@ -162,7 +162,8 @@ static void rockchip_drm_output_poll_changed(struct drm_device *dev) | |||
| 162 | struct rockchip_drm_private *private = dev->dev_private; | 162 | struct rockchip_drm_private *private = dev->dev_private; |
| 163 | struct drm_fb_helper *fb_helper = &private->fbdev_helper; | 163 | struct drm_fb_helper *fb_helper = &private->fbdev_helper; |
| 164 | 164 | ||
| 165 | drm_fb_helper_hotplug_event(fb_helper); | 165 | if (fb_helper) |
| 166 | drm_fb_helper_hotplug_event(fb_helper); | ||
| 166 | } | 167 | } |
| 167 | 168 | ||
| 168 | static const struct drm_mode_config_funcs rockchip_drm_mode_config_funcs = { | 169 | static const struct drm_mode_config_funcs rockchip_drm_mode_config_funcs = { |
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_gem.c b/drivers/gpu/drm/rockchip/rockchip_drm_gem.c index eb2282cc4a56..eba5f8a52fbd 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_gem.c +++ b/drivers/gpu/drm/rockchip/rockchip_drm_gem.c | |||
| @@ -54,55 +54,56 @@ static void rockchip_gem_free_buf(struct rockchip_gem_object *rk_obj) | |||
| 54 | &rk_obj->dma_attrs); | 54 | &rk_obj->dma_attrs); |
| 55 | } | 55 | } |
| 56 | 56 | ||
| 57 | int rockchip_gem_mmap_buf(struct drm_gem_object *obj, | 57 | static int rockchip_drm_gem_object_mmap(struct drm_gem_object *obj, |
| 58 | struct vm_area_struct *vma) | 58 | struct vm_area_struct *vma) |
| 59 | |||
| 59 | { | 60 | { |
| 61 | int ret; | ||
| 60 | struct rockchip_gem_object *rk_obj = to_rockchip_obj(obj); | 62 | struct rockchip_gem_object *rk_obj = to_rockchip_obj(obj); |
| 61 | struct drm_device *drm = obj->dev; | 63 | struct drm_device *drm = obj->dev; |
| 62 | unsigned long vm_size; | ||
| 63 | 64 | ||
| 64 | vma->vm_flags |= VM_IO | VM_DONTEXPAND | VM_DONTDUMP; | 65 | /* |
| 65 | vm_size = vma->vm_end - vma->vm_start; | 66 | * dma_alloc_attrs() allocated a struct page table for rk_obj, so clear |
| 66 | 67 | * VM_PFNMAP flag that was set by drm_gem_mmap_obj()/drm_gem_mmap(). | |
| 67 | if (vm_size > obj->size) | 68 | */ |
| 68 | return -EINVAL; | 69 | vma->vm_flags &= ~VM_PFNMAP; |
| 69 | 70 | ||
| 70 | return dma_mmap_attrs(drm->dev, vma, rk_obj->kvaddr, rk_obj->dma_addr, | 71 | ret = dma_mmap_attrs(drm->dev, vma, rk_obj->kvaddr, rk_obj->dma_addr, |
| 71 | obj->size, &rk_obj->dma_attrs); | 72 | obj->size, &rk_obj->dma_attrs); |
| 73 | if (ret) | ||
| 74 | drm_gem_vm_close(vma); | ||
| 75 | |||
| 76 | return ret; | ||
| 72 | } | 77 | } |
| 73 | 78 | ||
| 74 | /* drm driver mmap file operations */ | 79 | int rockchip_gem_mmap_buf(struct drm_gem_object *obj, |
| 75 | int rockchip_gem_mmap(struct file *filp, struct vm_area_struct *vma) | 80 | struct vm_area_struct *vma) |
| 76 | { | 81 | { |
| 77 | struct drm_file *priv = filp->private_data; | 82 | struct drm_device *drm = obj->dev; |
| 78 | struct drm_device *dev = priv->minor->dev; | ||
| 79 | struct drm_gem_object *obj; | ||
| 80 | struct drm_vma_offset_node *node; | ||
| 81 | int ret; | 83 | int ret; |
| 82 | 84 | ||
| 83 | if (drm_device_is_unplugged(dev)) | 85 | mutex_lock(&drm->struct_mutex); |
| 84 | return -ENODEV; | 86 | ret = drm_gem_mmap_obj(obj, obj->size, vma); |
| 87 | mutex_unlock(&drm->struct_mutex); | ||
| 88 | if (ret) | ||
| 89 | return ret; | ||
| 85 | 90 | ||
| 86 | mutex_lock(&dev->struct_mutex); | 91 | return rockchip_drm_gem_object_mmap(obj, vma); |
| 92 | } | ||
| 87 | 93 | ||
| 88 | node = drm_vma_offset_exact_lookup(dev->vma_offset_manager, | 94 | /* drm driver mmap file operations */ |
| 89 | vma->vm_pgoff, | 95 | int rockchip_gem_mmap(struct file *filp, struct vm_area_struct *vma) |
| 90 | vma_pages(vma)); | 96 | { |
| 91 | if (!node) { | 97 | struct drm_gem_object *obj; |
| 92 | mutex_unlock(&dev->struct_mutex); | 98 | int ret; |
| 93 | DRM_ERROR("failed to find vma node.\n"); | ||
| 94 | return -EINVAL; | ||
| 95 | } else if (!drm_vma_node_is_allowed(node, filp)) { | ||
| 96 | mutex_unlock(&dev->struct_mutex); | ||
| 97 | return -EACCES; | ||
| 98 | } | ||
| 99 | 99 | ||
| 100 | obj = container_of(node, struct drm_gem_object, vma_node); | 100 | ret = drm_gem_mmap(filp, vma); |
| 101 | ret = rockchip_gem_mmap_buf(obj, vma); | 101 | if (ret) |
| 102 | return ret; | ||
| 102 | 103 | ||
| 103 | mutex_unlock(&dev->struct_mutex); | 104 | obj = vma->vm_private_data; |
| 104 | 105 | ||
| 105 | return ret; | 106 | return rockchip_drm_gem_object_mmap(obj, vma); |
| 106 | } | 107 | } |
| 107 | 108 | ||
| 108 | struct rockchip_gem_object * | 109 | struct rockchip_gem_object * |
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c index dc65161d7cad..34b78e736532 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c +++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c | |||
| @@ -170,6 +170,7 @@ struct vop_win_phy { | |||
| 170 | 170 | ||
| 171 | struct vop_reg enable; | 171 | struct vop_reg enable; |
| 172 | struct vop_reg format; | 172 | struct vop_reg format; |
| 173 | struct vop_reg rb_swap; | ||
| 173 | struct vop_reg act_info; | 174 | struct vop_reg act_info; |
| 174 | struct vop_reg dsp_info; | 175 | struct vop_reg dsp_info; |
| 175 | struct vop_reg dsp_st; | 176 | struct vop_reg dsp_st; |
| @@ -199,8 +200,12 @@ struct vop_data { | |||
| 199 | static const uint32_t formats_01[] = { | 200 | static const uint32_t formats_01[] = { |
| 200 | DRM_FORMAT_XRGB8888, | 201 | DRM_FORMAT_XRGB8888, |
| 201 | DRM_FORMAT_ARGB8888, | 202 | DRM_FORMAT_ARGB8888, |
| 203 | DRM_FORMAT_XBGR8888, | ||
| 204 | DRM_FORMAT_ABGR8888, | ||
| 202 | DRM_FORMAT_RGB888, | 205 | DRM_FORMAT_RGB888, |
| 206 | DRM_FORMAT_BGR888, | ||
| 203 | DRM_FORMAT_RGB565, | 207 | DRM_FORMAT_RGB565, |
| 208 | DRM_FORMAT_BGR565, | ||
| 204 | DRM_FORMAT_NV12, | 209 | DRM_FORMAT_NV12, |
| 205 | DRM_FORMAT_NV16, | 210 | DRM_FORMAT_NV16, |
| 206 | DRM_FORMAT_NV24, | 211 | DRM_FORMAT_NV24, |
| @@ -209,8 +214,12 @@ static const uint32_t formats_01[] = { | |||
| 209 | static const uint32_t formats_234[] = { | 214 | static const uint32_t formats_234[] = { |
| 210 | DRM_FORMAT_XRGB8888, | 215 | DRM_FORMAT_XRGB8888, |
| 211 | DRM_FORMAT_ARGB8888, | 216 | DRM_FORMAT_ARGB8888, |
| 217 | DRM_FORMAT_XBGR8888, | ||
| 218 | DRM_FORMAT_ABGR8888, | ||
| 212 | DRM_FORMAT_RGB888, | 219 | DRM_FORMAT_RGB888, |
| 220 | DRM_FORMAT_BGR888, | ||
| 213 | DRM_FORMAT_RGB565, | 221 | DRM_FORMAT_RGB565, |
| 222 | DRM_FORMAT_BGR565, | ||
| 214 | }; | 223 | }; |
| 215 | 224 | ||
| 216 | static const struct vop_win_phy win01_data = { | 225 | static const struct vop_win_phy win01_data = { |
| @@ -218,6 +227,7 @@ static const struct vop_win_phy win01_data = { | |||
| 218 | .nformats = ARRAY_SIZE(formats_01), | 227 | .nformats = ARRAY_SIZE(formats_01), |
| 219 | .enable = VOP_REG(WIN0_CTRL0, 0x1, 0), | 228 | .enable = VOP_REG(WIN0_CTRL0, 0x1, 0), |
| 220 | .format = VOP_REG(WIN0_CTRL0, 0x7, 1), | 229 | .format = VOP_REG(WIN0_CTRL0, 0x7, 1), |
| 230 | .rb_swap = VOP_REG(WIN0_CTRL0, 0x1, 12), | ||
| 221 | .act_info = VOP_REG(WIN0_ACT_INFO, 0x1fff1fff, 0), | 231 | .act_info = VOP_REG(WIN0_ACT_INFO, 0x1fff1fff, 0), |
| 222 | .dsp_info = VOP_REG(WIN0_DSP_INFO, 0x0fff0fff, 0), | 232 | .dsp_info = VOP_REG(WIN0_DSP_INFO, 0x0fff0fff, 0), |
| 223 | .dsp_st = VOP_REG(WIN0_DSP_ST, 0x1fff1fff, 0), | 233 | .dsp_st = VOP_REG(WIN0_DSP_ST, 0x1fff1fff, 0), |
| @@ -234,6 +244,7 @@ static const struct vop_win_phy win23_data = { | |||
| 234 | .nformats = ARRAY_SIZE(formats_234), | 244 | .nformats = ARRAY_SIZE(formats_234), |
| 235 | .enable = VOP_REG(WIN2_CTRL0, 0x1, 0), | 245 | .enable = VOP_REG(WIN2_CTRL0, 0x1, 0), |
| 236 | .format = VOP_REG(WIN2_CTRL0, 0x7, 1), | 246 | .format = VOP_REG(WIN2_CTRL0, 0x7, 1), |
| 247 | .rb_swap = VOP_REG(WIN2_CTRL0, 0x1, 12), | ||
| 237 | .dsp_info = VOP_REG(WIN2_DSP_INFO0, 0x0fff0fff, 0), | 248 | .dsp_info = VOP_REG(WIN2_DSP_INFO0, 0x0fff0fff, 0), |
| 238 | .dsp_st = VOP_REG(WIN2_DSP_ST0, 0x1fff1fff, 0), | 249 | .dsp_st = VOP_REG(WIN2_DSP_ST0, 0x1fff1fff, 0), |
| 239 | .yrgb_mst = VOP_REG(WIN2_MST0, 0xffffffff, 0), | 250 | .yrgb_mst = VOP_REG(WIN2_MST0, 0xffffffff, 0), |
| @@ -242,15 +253,6 @@ static const struct vop_win_phy win23_data = { | |||
| 242 | .dst_alpha_ctl = VOP_REG(WIN2_DST_ALPHA_CTRL, 0xff, 0), | 253 | .dst_alpha_ctl = VOP_REG(WIN2_DST_ALPHA_CTRL, 0xff, 0), |
| 243 | }; | 254 | }; |
| 244 | 255 | ||
| 245 | static const struct vop_win_phy cursor_data = { | ||
| 246 | .data_formats = formats_234, | ||
| 247 | .nformats = ARRAY_SIZE(formats_234), | ||
| 248 | .enable = VOP_REG(HWC_CTRL0, 0x1, 0), | ||
| 249 | .format = VOP_REG(HWC_CTRL0, 0x7, 1), | ||
| 250 | .dsp_st = VOP_REG(HWC_DSP_ST, 0x1fff1fff, 0), | ||
| 251 | .yrgb_mst = VOP_REG(HWC_MST, 0xffffffff, 0), | ||
| 252 | }; | ||
| 253 | |||
| 254 | static const struct vop_ctrl ctrl_data = { | 256 | static const struct vop_ctrl ctrl_data = { |
| 255 | .standby = VOP_REG(SYS_CTRL, 0x1, 22), | 257 | .standby = VOP_REG(SYS_CTRL, 0x1, 22), |
| 256 | .gate_en = VOP_REG(SYS_CTRL, 0x1, 23), | 258 | .gate_en = VOP_REG(SYS_CTRL, 0x1, 23), |
| @@ -282,14 +284,14 @@ static const struct vop_reg_data vop_init_reg_table[] = { | |||
| 282 | /* | 284 | /* |
| 283 | * Note: rk3288 has a dedicated 'cursor' window, however, that window requires | 285 | * Note: rk3288 has a dedicated 'cursor' window, however, that window requires |
| 284 | * special support to get alpha blending working. For now, just use overlay | 286 | * special support to get alpha blending working. For now, just use overlay |
| 285 | * window 1 for the drm cursor. | 287 | * window 3 for the drm cursor. |
| 288 | * | ||
| 286 | */ | 289 | */ |
| 287 | static const struct vop_win_data rk3288_vop_win_data[] = { | 290 | static const struct vop_win_data rk3288_vop_win_data[] = { |
| 288 | { .base = 0x00, .phy = &win01_data, .type = DRM_PLANE_TYPE_PRIMARY }, | 291 | { .base = 0x00, .phy = &win01_data, .type = DRM_PLANE_TYPE_PRIMARY }, |
| 289 | { .base = 0x40, .phy = &win01_data, .type = DRM_PLANE_TYPE_CURSOR }, | 292 | { .base = 0x40, .phy = &win01_data, .type = DRM_PLANE_TYPE_OVERLAY }, |
| 290 | { .base = 0x00, .phy = &win23_data, .type = DRM_PLANE_TYPE_OVERLAY }, | 293 | { .base = 0x00, .phy = &win23_data, .type = DRM_PLANE_TYPE_OVERLAY }, |
| 291 | { .base = 0x50, .phy = &win23_data, .type = DRM_PLANE_TYPE_OVERLAY }, | 294 | { .base = 0x50, .phy = &win23_data, .type = DRM_PLANE_TYPE_CURSOR }, |
| 292 | { .base = 0x00, .phy = &cursor_data, .type = DRM_PLANE_TYPE_OVERLAY }, | ||
| 293 | }; | 295 | }; |
| 294 | 296 | ||
| 295 | static const struct vop_data rk3288_vop = { | 297 | static const struct vop_data rk3288_vop = { |
| @@ -352,15 +354,32 @@ static inline void vop_mask_write_relaxed(struct vop *vop, uint32_t offset, | |||
| 352 | } | 354 | } |
| 353 | } | 355 | } |
| 354 | 356 | ||
| 357 | static bool has_rb_swapped(uint32_t format) | ||
| 358 | { | ||
| 359 | switch (format) { | ||
| 360 | case DRM_FORMAT_XBGR8888: | ||
| 361 | case DRM_FORMAT_ABGR8888: | ||
| 362 | case DRM_FORMAT_BGR888: | ||
| 363 | case DRM_FORMAT_BGR565: | ||
| 364 | return true; | ||
| 365 | default: | ||
| 366 | return false; | ||
| 367 | } | ||
| 368 | } | ||
| 369 | |||
| 355 | static enum vop_data_format vop_convert_format(uint32_t format) | 370 | static enum vop_data_format vop_convert_format(uint32_t format) |
| 356 | { | 371 | { |
| 357 | switch (format) { | 372 | switch (format) { |
| 358 | case DRM_FORMAT_XRGB8888: | 373 | case DRM_FORMAT_XRGB8888: |
| 359 | case DRM_FORMAT_ARGB8888: | 374 | case DRM_FORMAT_ARGB8888: |
| 375 | case DRM_FORMAT_XBGR8888: | ||
| 376 | case DRM_FORMAT_ABGR8888: | ||
| 360 | return VOP_FMT_ARGB8888; | 377 | return VOP_FMT_ARGB8888; |
| 361 | case DRM_FORMAT_RGB888: | 378 | case DRM_FORMAT_RGB888: |
| 379 | case DRM_FORMAT_BGR888: | ||
| 362 | return VOP_FMT_RGB888; | 380 | return VOP_FMT_RGB888; |
| 363 | case DRM_FORMAT_RGB565: | 381 | case DRM_FORMAT_RGB565: |
| 382 | case DRM_FORMAT_BGR565: | ||
| 364 | return VOP_FMT_RGB565; | 383 | return VOP_FMT_RGB565; |
| 365 | case DRM_FORMAT_NV12: | 384 | case DRM_FORMAT_NV12: |
| 366 | return VOP_FMT_YUV420SP; | 385 | return VOP_FMT_YUV420SP; |
| @@ -378,6 +397,7 @@ static bool is_alpha_support(uint32_t format) | |||
| 378 | { | 397 | { |
| 379 | switch (format) { | 398 | switch (format) { |
| 380 | case DRM_FORMAT_ARGB8888: | 399 | case DRM_FORMAT_ARGB8888: |
| 400 | case DRM_FORMAT_ABGR8888: | ||
| 381 | return true; | 401 | return true; |
| 382 | default: | 402 | default: |
| 383 | return false; | 403 | return false; |
| @@ -588,6 +608,7 @@ static int vop_update_plane_event(struct drm_plane *plane, | |||
| 588 | enum vop_data_format format; | 608 | enum vop_data_format format; |
| 589 | uint32_t val; | 609 | uint32_t val; |
| 590 | bool is_alpha; | 610 | bool is_alpha; |
| 611 | bool rb_swap; | ||
| 591 | bool visible; | 612 | bool visible; |
| 592 | int ret; | 613 | int ret; |
| 593 | struct drm_rect dest = { | 614 | struct drm_rect dest = { |
| @@ -621,6 +642,7 @@ static int vop_update_plane_event(struct drm_plane *plane, | |||
| 621 | return 0; | 642 | return 0; |
| 622 | 643 | ||
| 623 | is_alpha = is_alpha_support(fb->pixel_format); | 644 | is_alpha = is_alpha_support(fb->pixel_format); |
| 645 | rb_swap = has_rb_swapped(fb->pixel_format); | ||
| 624 | format = vop_convert_format(fb->pixel_format); | 646 | format = vop_convert_format(fb->pixel_format); |
| 625 | if (format < 0) | 647 | if (format < 0) |
| 626 | return format; | 648 | return format; |
| @@ -689,6 +711,7 @@ static int vop_update_plane_event(struct drm_plane *plane, | |||
| 689 | val = (dsp_sty - 1) << 16; | 711 | val = (dsp_sty - 1) << 16; |
| 690 | val |= (dsp_stx - 1) & 0xffff; | 712 | val |= (dsp_stx - 1) & 0xffff; |
| 691 | VOP_WIN_SET(vop, win, dsp_st, val); | 713 | VOP_WIN_SET(vop, win, dsp_st, val); |
| 714 | VOP_WIN_SET(vop, win, rb_swap, rb_swap); | ||
| 692 | 715 | ||
| 693 | if (is_alpha) { | 716 | if (is_alpha) { |
| 694 | VOP_WIN_SET(vop, win, dst_alpha_ctl, | 717 | VOP_WIN_SET(vop, win, dst_alpha_ctl, |
diff --git a/drivers/gpu/drm/ttm/ttm_page_alloc_dma.c b/drivers/gpu/drm/ttm/ttm_page_alloc_dma.c index 3077f1554099..624d941aaad1 100644 --- a/drivers/gpu/drm/ttm/ttm_page_alloc_dma.c +++ b/drivers/gpu/drm/ttm/ttm_page_alloc_dma.c | |||
| @@ -963,14 +963,13 @@ void ttm_dma_unpopulate(struct ttm_dma_tt *ttm_dma, struct device *dev) | |||
| 963 | } else { | 963 | } else { |
| 964 | pool->npages_free += count; | 964 | pool->npages_free += count; |
| 965 | list_splice(&ttm_dma->pages_list, &pool->free_list); | 965 | list_splice(&ttm_dma->pages_list, &pool->free_list); |
| 966 | npages = count; | 966 | /* |
| 967 | if (pool->npages_free > _manager->options.max_size) { | 967 | * Wait to have at at least NUM_PAGES_TO_ALLOC number of pages |
| 968 | * to free in order to minimize calls to set_memory_wb(). | ||
| 969 | */ | ||
| 970 | if (pool->npages_free >= (_manager->options.max_size + | ||
| 971 | NUM_PAGES_TO_ALLOC)) | ||
| 968 | npages = pool->npages_free - _manager->options.max_size; | 972 | npages = pool->npages_free - _manager->options.max_size; |
| 969 | /* free at least NUM_PAGES_TO_ALLOC number of pages | ||
| 970 | * to reduce calls to set_memory_wb */ | ||
| 971 | if (npages < NUM_PAGES_TO_ALLOC) | ||
| 972 | npages = NUM_PAGES_TO_ALLOC; | ||
| 973 | } | ||
| 974 | } | 973 | } |
| 975 | spin_unlock_irqrestore(&pool->lock, irq_flags); | 974 | spin_unlock_irqrestore(&pool->lock, irq_flags); |
| 976 | 975 | ||
diff --git a/drivers/gpu/ipu-v3/ipu-common.c b/drivers/gpu/ipu-v3/ipu-common.c index 6d2f39d36e44..00f2058944e5 100644 --- a/drivers/gpu/ipu-v3/ipu-common.c +++ b/drivers/gpu/ipu-v3/ipu-common.c | |||
| @@ -1107,6 +1107,9 @@ static int ipu_irq_init(struct ipu_soc *ipu) | |||
| 1107 | return ret; | 1107 | return ret; |
| 1108 | } | 1108 | } |
| 1109 | 1109 | ||
| 1110 | for (i = 0; i < IPU_NUM_IRQS; i += 32) | ||
| 1111 | ipu_cm_write(ipu, 0, IPU_INT_CTRL(i / 32)); | ||
| 1112 | |||
| 1110 | for (i = 0; i < IPU_NUM_IRQS; i += 32) { | 1113 | for (i = 0; i < IPU_NUM_IRQS; i += 32) { |
| 1111 | gc = irq_get_domain_generic_chip(ipu->domain, i); | 1114 | gc = irq_get_domain_generic_chip(ipu->domain, i); |
| 1112 | gc->reg_base = ipu->cm_reg; | 1115 | gc->reg_base = ipu->cm_reg; |
diff --git a/drivers/iio/accel/bmc150-accel.c b/drivers/iio/accel/bmc150-accel.c index 4e70f51c2370..cc5a35750b50 100644 --- a/drivers/iio/accel/bmc150-accel.c +++ b/drivers/iio/accel/bmc150-accel.c | |||
| @@ -1464,7 +1464,7 @@ static void bmc150_accel_unregister_triggers(struct bmc150_accel_data *data, | |||
| 1464 | { | 1464 | { |
| 1465 | int i; | 1465 | int i; |
| 1466 | 1466 | ||
| 1467 | for (i = from; i >= 0; i++) { | 1467 | for (i = from; i >= 0; i--) { |
| 1468 | if (data->triggers[i].indio_trig) { | 1468 | if (data->triggers[i].indio_trig) { |
| 1469 | iio_trigger_unregister(data->triggers[i].indio_trig); | 1469 | iio_trigger_unregister(data->triggers[i].indio_trig); |
| 1470 | data->triggers[i].indio_trig = NULL; | 1470 | data->triggers[i].indio_trig = NULL; |
diff --git a/drivers/iio/adc/Kconfig b/drivers/iio/adc/Kconfig index 7c5565891cb8..eb0cd897714a 100644 --- a/drivers/iio/adc/Kconfig +++ b/drivers/iio/adc/Kconfig | |||
| @@ -153,8 +153,7 @@ config DA9150_GPADC | |||
| 153 | 153 | ||
| 154 | config CC10001_ADC | 154 | config CC10001_ADC |
| 155 | tristate "Cosmic Circuits 10001 ADC driver" | 155 | tristate "Cosmic Circuits 10001 ADC driver" |
| 156 | depends on HAVE_CLK || REGULATOR | 156 | depends on HAS_IOMEM && HAVE_CLK && REGULATOR |
| 157 | depends on HAS_IOMEM | ||
| 158 | select IIO_BUFFER | 157 | select IIO_BUFFER |
| 159 | select IIO_TRIGGERED_BUFFER | 158 | select IIO_TRIGGERED_BUFFER |
| 160 | help | 159 | help |
diff --git a/drivers/iio/adc/at91_adc.c b/drivers/iio/adc/at91_adc.c index 8a0eb4a04fb5..7b40925dd4ff 100644 --- a/drivers/iio/adc/at91_adc.c +++ b/drivers/iio/adc/at91_adc.c | |||
| @@ -182,7 +182,7 @@ struct at91_adc_caps { | |||
| 182 | u8 ts_pen_detect_sensitivity; | 182 | u8 ts_pen_detect_sensitivity; |
| 183 | 183 | ||
| 184 | /* startup time calculate function */ | 184 | /* startup time calculate function */ |
| 185 | u32 (*calc_startup_ticks)(u8 startup_time, u32 adc_clk_khz); | 185 | u32 (*calc_startup_ticks)(u32 startup_time, u32 adc_clk_khz); |
| 186 | 186 | ||
| 187 | u8 num_channels; | 187 | u8 num_channels; |
| 188 | struct at91_adc_reg_desc registers; | 188 | struct at91_adc_reg_desc registers; |
| @@ -201,7 +201,7 @@ struct at91_adc_state { | |||
| 201 | u8 num_channels; | 201 | u8 num_channels; |
| 202 | void __iomem *reg_base; | 202 | void __iomem *reg_base; |
| 203 | struct at91_adc_reg_desc *registers; | 203 | struct at91_adc_reg_desc *registers; |
| 204 | u8 startup_time; | 204 | u32 startup_time; |
| 205 | u8 sample_hold_time; | 205 | u8 sample_hold_time; |
| 206 | bool sleep_mode; | 206 | bool sleep_mode; |
| 207 | struct iio_trigger **trig; | 207 | struct iio_trigger **trig; |
| @@ -779,7 +779,7 @@ ret: | |||
| 779 | return ret; | 779 | return ret; |
| 780 | } | 780 | } |
| 781 | 781 | ||
| 782 | static u32 calc_startup_ticks_9260(u8 startup_time, u32 adc_clk_khz) | 782 | static u32 calc_startup_ticks_9260(u32 startup_time, u32 adc_clk_khz) |
| 783 | { | 783 | { |
| 784 | /* | 784 | /* |
| 785 | * Number of ticks needed to cover the startup time of the ADC | 785 | * Number of ticks needed to cover the startup time of the ADC |
| @@ -790,7 +790,7 @@ static u32 calc_startup_ticks_9260(u8 startup_time, u32 adc_clk_khz) | |||
| 790 | return round_up((startup_time * adc_clk_khz / 1000) - 1, 8) / 8; | 790 | return round_up((startup_time * adc_clk_khz / 1000) - 1, 8) / 8; |
| 791 | } | 791 | } |
| 792 | 792 | ||
| 793 | static u32 calc_startup_ticks_9x5(u8 startup_time, u32 adc_clk_khz) | 793 | static u32 calc_startup_ticks_9x5(u32 startup_time, u32 adc_clk_khz) |
| 794 | { | 794 | { |
| 795 | /* | 795 | /* |
| 796 | * For sama5d3x and at91sam9x5, the formula changes to: | 796 | * For sama5d3x and at91sam9x5, the formula changes to: |
diff --git a/drivers/iio/adc/rockchip_saradc.c b/drivers/iio/adc/rockchip_saradc.c index 8d4e019ea4ca..9c311c1e1ac7 100644 --- a/drivers/iio/adc/rockchip_saradc.c +++ b/drivers/iio/adc/rockchip_saradc.c | |||
| @@ -349,3 +349,7 @@ static struct platform_driver rockchip_saradc_driver = { | |||
| 349 | }; | 349 | }; |
| 350 | 350 | ||
| 351 | module_platform_driver(rockchip_saradc_driver); | 351 | module_platform_driver(rockchip_saradc_driver); |
| 352 | |||
| 353 | MODULE_AUTHOR("Heiko Stuebner <heiko@sntech.de>"); | ||
| 354 | MODULE_DESCRIPTION("Rockchip SARADC driver"); | ||
| 355 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/iio/adc/twl4030-madc.c b/drivers/iio/adc/twl4030-madc.c index 06f4792240f0..ebe415f10640 100644 --- a/drivers/iio/adc/twl4030-madc.c +++ b/drivers/iio/adc/twl4030-madc.c | |||
| @@ -833,7 +833,8 @@ static int twl4030_madc_probe(struct platform_device *pdev) | |||
| 833 | irq = platform_get_irq(pdev, 0); | 833 | irq = platform_get_irq(pdev, 0); |
| 834 | ret = devm_request_threaded_irq(&pdev->dev, irq, NULL, | 834 | ret = devm_request_threaded_irq(&pdev->dev, irq, NULL, |
| 835 | twl4030_madc_threaded_irq_handler, | 835 | twl4030_madc_threaded_irq_handler, |
| 836 | IRQF_TRIGGER_RISING, "twl4030_madc", madc); | 836 | IRQF_TRIGGER_RISING | IRQF_ONESHOT, |
| 837 | "twl4030_madc", madc); | ||
| 837 | if (ret) { | 838 | if (ret) { |
| 838 | dev_err(&pdev->dev, "could not request irq\n"); | 839 | dev_err(&pdev->dev, "could not request irq\n"); |
| 839 | goto err_i2c; | 840 | goto err_i2c; |
diff --git a/drivers/iio/common/hid-sensors/hid-sensor-trigger.c b/drivers/iio/common/hid-sensors/hid-sensor-trigger.c index 610fc98f88ef..595511022795 100644 --- a/drivers/iio/common/hid-sensors/hid-sensor-trigger.c +++ b/drivers/iio/common/hid-sensors/hid-sensor-trigger.c | |||
| @@ -36,6 +36,8 @@ static int _hid_sensor_power_state(struct hid_sensor_common *st, bool state) | |||
| 36 | s32 poll_value = 0; | 36 | s32 poll_value = 0; |
| 37 | 37 | ||
| 38 | if (state) { | 38 | if (state) { |
| 39 | if (!atomic_read(&st->user_requested_state)) | ||
| 40 | return 0; | ||
| 39 | if (sensor_hub_device_open(st->hsdev)) | 41 | if (sensor_hub_device_open(st->hsdev)) |
| 40 | return -EIO; | 42 | return -EIO; |
| 41 | 43 | ||
| @@ -52,8 +54,12 @@ static int _hid_sensor_power_state(struct hid_sensor_common *st, bool state) | |||
| 52 | 54 | ||
| 53 | poll_value = hid_sensor_read_poll_value(st); | 55 | poll_value = hid_sensor_read_poll_value(st); |
| 54 | } else { | 56 | } else { |
| 55 | if (!atomic_dec_and_test(&st->data_ready)) | 57 | int val; |
| 58 | |||
| 59 | val = atomic_dec_if_positive(&st->data_ready); | ||
| 60 | if (val < 0) | ||
| 56 | return 0; | 61 | return 0; |
| 62 | |||
| 57 | sensor_hub_device_close(st->hsdev); | 63 | sensor_hub_device_close(st->hsdev); |
| 58 | state_val = hid_sensor_get_usage_index(st->hsdev, | 64 | state_val = hid_sensor_get_usage_index(st->hsdev, |
| 59 | st->power_state.report_id, | 65 | st->power_state.report_id, |
| @@ -92,9 +98,11 @@ EXPORT_SYMBOL(hid_sensor_power_state); | |||
| 92 | 98 | ||
| 93 | int hid_sensor_power_state(struct hid_sensor_common *st, bool state) | 99 | int hid_sensor_power_state(struct hid_sensor_common *st, bool state) |
| 94 | { | 100 | { |
| 101 | |||
| 95 | #ifdef CONFIG_PM | 102 | #ifdef CONFIG_PM |
| 96 | int ret; | 103 | int ret; |
| 97 | 104 | ||
| 105 | atomic_set(&st->user_requested_state, state); | ||
| 98 | if (state) | 106 | if (state) |
| 99 | ret = pm_runtime_get_sync(&st->pdev->dev); | 107 | ret = pm_runtime_get_sync(&st->pdev->dev); |
| 100 | else { | 108 | else { |
| @@ -109,6 +117,7 @@ int hid_sensor_power_state(struct hid_sensor_common *st, bool state) | |||
| 109 | 117 | ||
| 110 | return 0; | 118 | return 0; |
| 111 | #else | 119 | #else |
| 120 | atomic_set(&st->user_requested_state, state); | ||
| 112 | return _hid_sensor_power_state(st, state); | 121 | return _hid_sensor_power_state(st, state); |
| 113 | #endif | 122 | #endif |
| 114 | } | 123 | } |
diff --git a/drivers/iio/dac/ad5624r_spi.c b/drivers/iio/dac/ad5624r_spi.c index 61bb9d4239ea..e98428df0d44 100644 --- a/drivers/iio/dac/ad5624r_spi.c +++ b/drivers/iio/dac/ad5624r_spi.c | |||
| @@ -22,7 +22,7 @@ | |||
| 22 | #include "ad5624r.h" | 22 | #include "ad5624r.h" |
| 23 | 23 | ||
| 24 | static int ad5624r_spi_write(struct spi_device *spi, | 24 | static int ad5624r_spi_write(struct spi_device *spi, |
| 25 | u8 cmd, u8 addr, u16 val, u8 len) | 25 | u8 cmd, u8 addr, u16 val, u8 shift) |
| 26 | { | 26 | { |
| 27 | u32 data; | 27 | u32 data; |
| 28 | u8 msg[3]; | 28 | u8 msg[3]; |
| @@ -35,7 +35,7 @@ static int ad5624r_spi_write(struct spi_device *spi, | |||
| 35 | * 14-, 12-bit input code followed by 0, 2, or 4 don't care bits, | 35 | * 14-, 12-bit input code followed by 0, 2, or 4 don't care bits, |
| 36 | * for the AD5664R, AD5644R, and AD5624R, respectively. | 36 | * for the AD5664R, AD5644R, and AD5624R, respectively. |
| 37 | */ | 37 | */ |
| 38 | data = (0 << 22) | (cmd << 19) | (addr << 16) | (val << (16 - len)); | 38 | data = (0 << 22) | (cmd << 19) | (addr << 16) | (val << shift); |
| 39 | msg[0] = data >> 16; | 39 | msg[0] = data >> 16; |
| 40 | msg[1] = data >> 8; | 40 | msg[1] = data >> 8; |
| 41 | msg[2] = data; | 41 | msg[2] = data; |
diff --git a/drivers/iio/imu/inv_mpu6050/inv_mpu_core.c b/drivers/iio/imu/inv_mpu6050/inv_mpu_core.c index 17d4bb15be4d..65ce86837177 100644 --- a/drivers/iio/imu/inv_mpu6050/inv_mpu_core.c +++ b/drivers/iio/imu/inv_mpu6050/inv_mpu_core.c | |||
| @@ -431,6 +431,23 @@ static int inv_mpu6050_write_gyro_scale(struct inv_mpu6050_state *st, int val) | |||
| 431 | return -EINVAL; | 431 | return -EINVAL; |
| 432 | } | 432 | } |
| 433 | 433 | ||
| 434 | static int inv_write_raw_get_fmt(struct iio_dev *indio_dev, | ||
| 435 | struct iio_chan_spec const *chan, long mask) | ||
| 436 | { | ||
| 437 | switch (mask) { | ||
| 438 | case IIO_CHAN_INFO_SCALE: | ||
| 439 | switch (chan->type) { | ||
| 440 | case IIO_ANGL_VEL: | ||
| 441 | return IIO_VAL_INT_PLUS_NANO; | ||
| 442 | default: | ||
| 443 | return IIO_VAL_INT_PLUS_MICRO; | ||
| 444 | } | ||
| 445 | default: | ||
| 446 | return IIO_VAL_INT_PLUS_MICRO; | ||
| 447 | } | ||
| 448 | |||
| 449 | return -EINVAL; | ||
| 450 | } | ||
| 434 | static int inv_mpu6050_write_accel_scale(struct inv_mpu6050_state *st, int val) | 451 | static int inv_mpu6050_write_accel_scale(struct inv_mpu6050_state *st, int val) |
| 435 | { | 452 | { |
| 436 | int result, i; | 453 | int result, i; |
| @@ -696,6 +713,7 @@ static const struct iio_info mpu_info = { | |||
| 696 | .driver_module = THIS_MODULE, | 713 | .driver_module = THIS_MODULE, |
| 697 | .read_raw = &inv_mpu6050_read_raw, | 714 | .read_raw = &inv_mpu6050_read_raw, |
| 698 | .write_raw = &inv_mpu6050_write_raw, | 715 | .write_raw = &inv_mpu6050_write_raw, |
| 716 | .write_raw_get_fmt = &inv_write_raw_get_fmt, | ||
| 699 | .attrs = &inv_attribute_group, | 717 | .attrs = &inv_attribute_group, |
| 700 | .validate_trigger = inv_mpu6050_validate_trigger, | 718 | .validate_trigger = inv_mpu6050_validate_trigger, |
| 701 | }; | 719 | }; |
diff --git a/drivers/iio/light/Kconfig b/drivers/iio/light/Kconfig index e6198b7c9cbf..a5c59251ec0e 100644 --- a/drivers/iio/light/Kconfig +++ b/drivers/iio/light/Kconfig | |||
| @@ -188,6 +188,7 @@ config SENSORS_LM3533 | |||
| 188 | config LTR501 | 188 | config LTR501 |
| 189 | tristate "LTR-501ALS-01 light sensor" | 189 | tristate "LTR-501ALS-01 light sensor" |
| 190 | depends on I2C | 190 | depends on I2C |
| 191 | select REGMAP_I2C | ||
| 191 | select IIO_BUFFER | 192 | select IIO_BUFFER |
| 192 | select IIO_TRIGGERED_BUFFER | 193 | select IIO_TRIGGERED_BUFFER |
| 193 | help | 194 | help |
| @@ -201,6 +202,7 @@ config LTR501 | |||
| 201 | config STK3310 | 202 | config STK3310 |
| 202 | tristate "STK3310 ALS and proximity sensor" | 203 | tristate "STK3310 ALS and proximity sensor" |
| 203 | depends on I2C | 204 | depends on I2C |
| 205 | select REGMAP_I2C | ||
| 204 | help | 206 | help |
| 205 | Say yes here to get support for the Sensortek STK3310 ambient light | 207 | Say yes here to get support for the Sensortek STK3310 ambient light |
| 206 | and proximity sensor. The STK3311 model is also supported by this | 208 | and proximity sensor. The STK3311 model is also supported by this |
diff --git a/drivers/iio/light/cm3323.c b/drivers/iio/light/cm3323.c index 869033e48a1f..a1d4905cc9d2 100644 --- a/drivers/iio/light/cm3323.c +++ b/drivers/iio/light/cm3323.c | |||
| @@ -123,7 +123,7 @@ static int cm3323_set_it_bits(struct cm3323_data *data, int val, int val2) | |||
| 123 | for (i = 0; i < ARRAY_SIZE(cm3323_int_time); i++) { | 123 | for (i = 0; i < ARRAY_SIZE(cm3323_int_time); i++) { |
| 124 | if (val == cm3323_int_time[i].val && | 124 | if (val == cm3323_int_time[i].val && |
| 125 | val2 == cm3323_int_time[i].val2) { | 125 | val2 == cm3323_int_time[i].val2) { |
| 126 | reg_conf = data->reg_conf; | 126 | reg_conf = data->reg_conf & ~CM3323_CONF_IT_MASK; |
| 127 | reg_conf |= i << CM3323_CONF_IT_SHIFT; | 127 | reg_conf |= i << CM3323_CONF_IT_SHIFT; |
| 128 | 128 | ||
| 129 | ret = i2c_smbus_write_word_data(data->client, | 129 | ret = i2c_smbus_write_word_data(data->client, |
diff --git a/drivers/iio/light/ltr501.c b/drivers/iio/light/ltr501.c index 1ef7d3773ab9..b5a0e66b5f28 100644 --- a/drivers/iio/light/ltr501.c +++ b/drivers/iio/light/ltr501.c | |||
| @@ -1302,7 +1302,7 @@ static int ltr501_init(struct ltr501_data *data) | |||
| 1302 | if (ret < 0) | 1302 | if (ret < 0) |
| 1303 | return ret; | 1303 | return ret; |
| 1304 | 1304 | ||
| 1305 | data->als_contr = ret | data->chip_info->als_mode_active; | 1305 | data->als_contr = status | data->chip_info->als_mode_active; |
| 1306 | 1306 | ||
| 1307 | ret = regmap_read(data->regmap, LTR501_PS_CONTR, &status); | 1307 | ret = regmap_read(data->regmap, LTR501_PS_CONTR, &status); |
| 1308 | if (ret < 0) | 1308 | if (ret < 0) |
diff --git a/drivers/iio/light/stk3310.c b/drivers/iio/light/stk3310.c index fee4297d7c8f..c1a218236be5 100644 --- a/drivers/iio/light/stk3310.c +++ b/drivers/iio/light/stk3310.c | |||
| @@ -43,7 +43,6 @@ | |||
| 43 | #define STK3311_CHIP_ID_VAL 0x1D | 43 | #define STK3311_CHIP_ID_VAL 0x1D |
| 44 | #define STK3310_PSINT_EN 0x01 | 44 | #define STK3310_PSINT_EN 0x01 |
| 45 | #define STK3310_PS_MAX_VAL 0xFFFF | 45 | #define STK3310_PS_MAX_VAL 0xFFFF |
| 46 | #define STK3310_THRESH_MAX 0xFFFF | ||
| 47 | 46 | ||
| 48 | #define STK3310_DRIVER_NAME "stk3310" | 47 | #define STK3310_DRIVER_NAME "stk3310" |
| 49 | #define STK3310_REGMAP_NAME "stk3310_regmap" | 48 | #define STK3310_REGMAP_NAME "stk3310_regmap" |
| @@ -84,15 +83,13 @@ static const struct reg_field stk3310_reg_field_flag_psint = | |||
| 84 | REG_FIELD(STK3310_REG_FLAG, 4, 4); | 83 | REG_FIELD(STK3310_REG_FLAG, 4, 4); |
| 85 | static const struct reg_field stk3310_reg_field_flag_nf = | 84 | static const struct reg_field stk3310_reg_field_flag_nf = |
| 86 | REG_FIELD(STK3310_REG_FLAG, 0, 0); | 85 | REG_FIELD(STK3310_REG_FLAG, 0, 0); |
| 87 | /* | 86 | |
| 88 | * Maximum PS values with regard to scale. Used to export the 'inverse' | 87 | /* Estimate maximum proximity values with regard to measurement scale. */ |
| 89 | * PS value (high values for far objects, low values for near objects). | ||
| 90 | */ | ||
| 91 | static const int stk3310_ps_max[4] = { | 88 | static const int stk3310_ps_max[4] = { |
| 92 | STK3310_PS_MAX_VAL / 64, | 89 | STK3310_PS_MAX_VAL / 640, |
| 93 | STK3310_PS_MAX_VAL / 16, | 90 | STK3310_PS_MAX_VAL / 160, |
| 94 | STK3310_PS_MAX_VAL / 4, | 91 | STK3310_PS_MAX_VAL / 40, |
| 95 | STK3310_PS_MAX_VAL, | 92 | STK3310_PS_MAX_VAL / 10 |
| 96 | }; | 93 | }; |
| 97 | 94 | ||
| 98 | static const int stk3310_scale_table[][2] = { | 95 | static const int stk3310_scale_table[][2] = { |
| @@ -128,14 +125,14 @@ static const struct iio_event_spec stk3310_events[] = { | |||
| 128 | /* Proximity event */ | 125 | /* Proximity event */ |
| 129 | { | 126 | { |
| 130 | .type = IIO_EV_TYPE_THRESH, | 127 | .type = IIO_EV_TYPE_THRESH, |
| 131 | .dir = IIO_EV_DIR_FALLING, | 128 | .dir = IIO_EV_DIR_RISING, |
| 132 | .mask_separate = BIT(IIO_EV_INFO_VALUE) | | 129 | .mask_separate = BIT(IIO_EV_INFO_VALUE) | |
| 133 | BIT(IIO_EV_INFO_ENABLE), | 130 | BIT(IIO_EV_INFO_ENABLE), |
| 134 | }, | 131 | }, |
| 135 | /* Out-of-proximity event */ | 132 | /* Out-of-proximity event */ |
| 136 | { | 133 | { |
| 137 | .type = IIO_EV_TYPE_THRESH, | 134 | .type = IIO_EV_TYPE_THRESH, |
| 138 | .dir = IIO_EV_DIR_RISING, | 135 | .dir = IIO_EV_DIR_FALLING, |
| 139 | .mask_separate = BIT(IIO_EV_INFO_VALUE) | | 136 | .mask_separate = BIT(IIO_EV_INFO_VALUE) | |
| 140 | BIT(IIO_EV_INFO_ENABLE), | 137 | BIT(IIO_EV_INFO_ENABLE), |
| 141 | }, | 138 | }, |
| @@ -205,23 +202,16 @@ static int stk3310_read_event(struct iio_dev *indio_dev, | |||
| 205 | u8 reg; | 202 | u8 reg; |
| 206 | u16 buf; | 203 | u16 buf; |
| 207 | int ret; | 204 | int ret; |
| 208 | unsigned int index; | ||
| 209 | struct stk3310_data *data = iio_priv(indio_dev); | 205 | struct stk3310_data *data = iio_priv(indio_dev); |
| 210 | 206 | ||
| 211 | if (info != IIO_EV_INFO_VALUE) | 207 | if (info != IIO_EV_INFO_VALUE) |
| 212 | return -EINVAL; | 208 | return -EINVAL; |
| 213 | 209 | ||
| 214 | /* | 210 | /* Only proximity interrupts are implemented at the moment. */ |
| 215 | * Only proximity interrupts are implemented at the moment. | ||
| 216 | * Since we're inverting proximity values, the sensor's 'high' | ||
| 217 | * threshold will become our 'low' threshold, associated with | ||
| 218 | * 'near' events. Similarly, the sensor's 'low' threshold will | ||
| 219 | * be our 'high' threshold, associated with 'far' events. | ||
| 220 | */ | ||
| 221 | if (dir == IIO_EV_DIR_RISING) | 211 | if (dir == IIO_EV_DIR_RISING) |
| 222 | reg = STK3310_REG_THDL_PS; | ||
| 223 | else if (dir == IIO_EV_DIR_FALLING) | ||
| 224 | reg = STK3310_REG_THDH_PS; | 212 | reg = STK3310_REG_THDH_PS; |
| 213 | else if (dir == IIO_EV_DIR_FALLING) | ||
| 214 | reg = STK3310_REG_THDL_PS; | ||
| 225 | else | 215 | else |
| 226 | return -EINVAL; | 216 | return -EINVAL; |
| 227 | 217 | ||
| @@ -232,8 +222,7 @@ static int stk3310_read_event(struct iio_dev *indio_dev, | |||
| 232 | dev_err(&data->client->dev, "register read failed\n"); | 222 | dev_err(&data->client->dev, "register read failed\n"); |
| 233 | return ret; | 223 | return ret; |
| 234 | } | 224 | } |
| 235 | regmap_field_read(data->reg_ps_gain, &index); | 225 | *val = swab16(buf); |
| 236 | *val = swab16(stk3310_ps_max[index] - buf); | ||
| 237 | 226 | ||
| 238 | return IIO_VAL_INT; | 227 | return IIO_VAL_INT; |
| 239 | } | 228 | } |
| @@ -257,13 +246,13 @@ static int stk3310_write_event(struct iio_dev *indio_dev, | |||
| 257 | return -EINVAL; | 246 | return -EINVAL; |
| 258 | 247 | ||
| 259 | if (dir == IIO_EV_DIR_RISING) | 248 | if (dir == IIO_EV_DIR_RISING) |
| 260 | reg = STK3310_REG_THDL_PS; | ||
| 261 | else if (dir == IIO_EV_DIR_FALLING) | ||
| 262 | reg = STK3310_REG_THDH_PS; | 249 | reg = STK3310_REG_THDH_PS; |
| 250 | else if (dir == IIO_EV_DIR_FALLING) | ||
| 251 | reg = STK3310_REG_THDL_PS; | ||
| 263 | else | 252 | else |
| 264 | return -EINVAL; | 253 | return -EINVAL; |
| 265 | 254 | ||
| 266 | buf = swab16(stk3310_ps_max[index] - val); | 255 | buf = swab16(val); |
| 267 | ret = regmap_bulk_write(data->regmap, reg, &buf, 2); | 256 | ret = regmap_bulk_write(data->regmap, reg, &buf, 2); |
| 268 | if (ret < 0) | 257 | if (ret < 0) |
| 269 | dev_err(&client->dev, "failed to set PS threshold!\n"); | 258 | dev_err(&client->dev, "failed to set PS threshold!\n"); |
| @@ -334,14 +323,6 @@ static int stk3310_read_raw(struct iio_dev *indio_dev, | |||
| 334 | return ret; | 323 | return ret; |
| 335 | } | 324 | } |
| 336 | *val = swab16(buf); | 325 | *val = swab16(buf); |
| 337 | if (chan->type == IIO_PROXIMITY) { | ||
| 338 | /* | ||
| 339 | * Invert the proximity data so we return low values | ||
| 340 | * for close objects and high values for far ones. | ||
| 341 | */ | ||
| 342 | regmap_field_read(data->reg_ps_gain, &index); | ||
| 343 | *val = stk3310_ps_max[index] - *val; | ||
| 344 | } | ||
| 345 | mutex_unlock(&data->lock); | 326 | mutex_unlock(&data->lock); |
| 346 | return IIO_VAL_INT; | 327 | return IIO_VAL_INT; |
| 347 | case IIO_CHAN_INFO_INT_TIME: | 328 | case IIO_CHAN_INFO_INT_TIME: |
| @@ -581,8 +562,8 @@ static irqreturn_t stk3310_irq_event_handler(int irq, void *private) | |||
| 581 | } | 562 | } |
| 582 | event = IIO_UNMOD_EVENT_CODE(IIO_PROXIMITY, 1, | 563 | event = IIO_UNMOD_EVENT_CODE(IIO_PROXIMITY, 1, |
| 583 | IIO_EV_TYPE_THRESH, | 564 | IIO_EV_TYPE_THRESH, |
| 584 | (dir ? IIO_EV_DIR_RISING : | 565 | (dir ? IIO_EV_DIR_FALLING : |
| 585 | IIO_EV_DIR_FALLING)); | 566 | IIO_EV_DIR_RISING)); |
| 586 | iio_push_event(indio_dev, event, data->timestamp); | 567 | iio_push_event(indio_dev, event, data->timestamp); |
| 587 | 568 | ||
| 588 | /* Reset the interrupt flag */ | 569 | /* Reset the interrupt flag */ |
diff --git a/drivers/iio/light/tcs3414.c b/drivers/iio/light/tcs3414.c index 71c2bde275aa..f8b1df018abe 100644 --- a/drivers/iio/light/tcs3414.c +++ b/drivers/iio/light/tcs3414.c | |||
| @@ -185,7 +185,7 @@ static int tcs3414_write_raw(struct iio_dev *indio_dev, | |||
| 185 | if (val != 0) | 185 | if (val != 0) |
| 186 | return -EINVAL; | 186 | return -EINVAL; |
| 187 | for (i = 0; i < ARRAY_SIZE(tcs3414_times); i++) { | 187 | for (i = 0; i < ARRAY_SIZE(tcs3414_times); i++) { |
| 188 | if (val == tcs3414_times[i] * 1000) { | 188 | if (val2 == tcs3414_times[i] * 1000) { |
| 189 | data->timing &= ~TCS3414_INTEG_MASK; | 189 | data->timing &= ~TCS3414_INTEG_MASK; |
| 190 | data->timing |= i; | 190 | data->timing |= i; |
| 191 | return i2c_smbus_write_byte_data( | 191 | return i2c_smbus_write_byte_data( |
diff --git a/drivers/iio/magnetometer/mmc35240.c b/drivers/iio/magnetometer/mmc35240.c index 7a2ea71c659a..d927397a6ef7 100644 --- a/drivers/iio/magnetometer/mmc35240.c +++ b/drivers/iio/magnetometer/mmc35240.c | |||
| @@ -84,10 +84,10 @@ | |||
| 84 | #define MMC35240_OTP_START_ADDR 0x1B | 84 | #define MMC35240_OTP_START_ADDR 0x1B |
| 85 | 85 | ||
| 86 | enum mmc35240_resolution { | 86 | enum mmc35240_resolution { |
| 87 | MMC35240_16_BITS_SLOW = 0, /* 100 Hz */ | 87 | MMC35240_16_BITS_SLOW = 0, /* 7.92 ms */ |
| 88 | MMC35240_16_BITS_FAST, /* 200 Hz */ | 88 | MMC35240_16_BITS_FAST, /* 4.08 ms */ |
| 89 | MMC35240_14_BITS, /* 333 Hz */ | 89 | MMC35240_14_BITS, /* 2.16 ms */ |
| 90 | MMC35240_12_BITS, /* 666 Hz */ | 90 | MMC35240_12_BITS, /* 1.20 ms */ |
| 91 | }; | 91 | }; |
| 92 | 92 | ||
| 93 | enum mmc35240_axis { | 93 | enum mmc35240_axis { |
| @@ -100,22 +100,22 @@ static const struct { | |||
| 100 | int sens[3]; /* sensitivity per X, Y, Z axis */ | 100 | int sens[3]; /* sensitivity per X, Y, Z axis */ |
| 101 | int nfo; /* null field output */ | 101 | int nfo; /* null field output */ |
| 102 | } mmc35240_props_table[] = { | 102 | } mmc35240_props_table[] = { |
| 103 | /* 16 bits, 100Hz ODR */ | 103 | /* 16 bits, 125Hz ODR */ |
| 104 | { | 104 | { |
| 105 | {1024, 1024, 1024}, | 105 | {1024, 1024, 1024}, |
| 106 | 32768, | 106 | 32768, |
| 107 | }, | 107 | }, |
| 108 | /* 16 bits, 200Hz ODR */ | 108 | /* 16 bits, 250Hz ODR */ |
| 109 | { | 109 | { |
| 110 | {1024, 1024, 770}, | 110 | {1024, 1024, 770}, |
| 111 | 32768, | 111 | 32768, |
| 112 | }, | 112 | }, |
| 113 | /* 14 bits, 333Hz ODR */ | 113 | /* 14 bits, 450Hz ODR */ |
| 114 | { | 114 | { |
| 115 | {256, 256, 193}, | 115 | {256, 256, 193}, |
| 116 | 8192, | 116 | 8192, |
| 117 | }, | 117 | }, |
| 118 | /* 12 bits, 666Hz ODR */ | 118 | /* 12 bits, 800Hz ODR */ |
| 119 | { | 119 | { |
| 120 | {64, 64, 48}, | 120 | {64, 64, 48}, |
| 121 | 2048, | 121 | 2048, |
| @@ -133,9 +133,15 @@ struct mmc35240_data { | |||
| 133 | int axis_scale[3]; | 133 | int axis_scale[3]; |
| 134 | }; | 134 | }; |
| 135 | 135 | ||
| 136 | static const int mmc35240_samp_freq[] = {100, 200, 333, 666}; | 136 | static const struct { |
| 137 | int val; | ||
| 138 | int val2; | ||
| 139 | } mmc35240_samp_freq[] = { {1, 500000}, | ||
| 140 | {13, 0}, | ||
| 141 | {25, 0}, | ||
| 142 | {50, 0} }; | ||
| 137 | 143 | ||
| 138 | static IIO_CONST_ATTR_SAMP_FREQ_AVAIL("100 200 333 666"); | 144 | static IIO_CONST_ATTR_SAMP_FREQ_AVAIL("1.5 13 25 50"); |
| 139 | 145 | ||
| 140 | #define MMC35240_CHANNEL(_axis) { \ | 146 | #define MMC35240_CHANNEL(_axis) { \ |
| 141 | .type = IIO_MAGN, \ | 147 | .type = IIO_MAGN, \ |
| @@ -168,7 +174,8 @@ static int mmc35240_get_samp_freq_index(struct mmc35240_data *data, | |||
| 168 | int i; | 174 | int i; |
| 169 | 175 | ||
| 170 | for (i = 0; i < ARRAY_SIZE(mmc35240_samp_freq); i++) | 176 | for (i = 0; i < ARRAY_SIZE(mmc35240_samp_freq); i++) |
| 171 | if (mmc35240_samp_freq[i] == val) | 177 | if (mmc35240_samp_freq[i].val == val && |
| 178 | mmc35240_samp_freq[i].val2 == val2) | ||
| 172 | return i; | 179 | return i; |
| 173 | return -EINVAL; | 180 | return -EINVAL; |
| 174 | } | 181 | } |
| @@ -378,9 +385,9 @@ static int mmc35240_read_raw(struct iio_dev *indio_dev, | |||
| 378 | if (i < 0 || i >= ARRAY_SIZE(mmc35240_samp_freq)) | 385 | if (i < 0 || i >= ARRAY_SIZE(mmc35240_samp_freq)) |
| 379 | return -EINVAL; | 386 | return -EINVAL; |
| 380 | 387 | ||
| 381 | *val = mmc35240_samp_freq[i]; | 388 | *val = mmc35240_samp_freq[i].val; |
| 382 | *val2 = 0; | 389 | *val2 = mmc35240_samp_freq[i].val2; |
| 383 | return IIO_VAL_INT; | 390 | return IIO_VAL_INT_PLUS_MICRO; |
| 384 | default: | 391 | default: |
| 385 | return -EINVAL; | 392 | return -EINVAL; |
| 386 | } | 393 | } |
diff --git a/drivers/iio/proximity/sx9500.c b/drivers/iio/proximity/sx9500.c index 2042e375f835..3d756bd8c703 100644 --- a/drivers/iio/proximity/sx9500.c +++ b/drivers/iio/proximity/sx9500.c | |||
| @@ -80,6 +80,7 @@ | |||
| 80 | #define SX9500_COMPSTAT_MASK GENMASK(3, 0) | 80 | #define SX9500_COMPSTAT_MASK GENMASK(3, 0) |
| 81 | 81 | ||
| 82 | #define SX9500_NUM_CHANNELS 4 | 82 | #define SX9500_NUM_CHANNELS 4 |
| 83 | #define SX9500_CHAN_MASK GENMASK(SX9500_NUM_CHANNELS - 1, 0) | ||
| 83 | 84 | ||
| 84 | struct sx9500_data { | 85 | struct sx9500_data { |
| 85 | struct mutex mutex; | 86 | struct mutex mutex; |
| @@ -281,7 +282,7 @@ static int sx9500_read_prox_data(struct sx9500_data *data, | |||
| 281 | if (ret < 0) | 282 | if (ret < 0) |
| 282 | return ret; | 283 | return ret; |
| 283 | 284 | ||
| 284 | *val = 32767 - (s16)be16_to_cpu(regval); | 285 | *val = be16_to_cpu(regval); |
| 285 | 286 | ||
| 286 | return IIO_VAL_INT; | 287 | return IIO_VAL_INT; |
| 287 | } | 288 | } |
| @@ -329,27 +330,29 @@ static int sx9500_read_proximity(struct sx9500_data *data, | |||
| 329 | else | 330 | else |
| 330 | ret = sx9500_wait_for_sample(data); | 331 | ret = sx9500_wait_for_sample(data); |
| 331 | 332 | ||
| 332 | if (ret < 0) | ||
| 333 | return ret; | ||
| 334 | |||
| 335 | mutex_lock(&data->mutex); | 333 | mutex_lock(&data->mutex); |
| 336 | 334 | ||
| 337 | ret = sx9500_read_prox_data(data, chan, val); | ||
| 338 | if (ret < 0) | 335 | if (ret < 0) |
| 339 | goto out; | 336 | goto out_dec_data_rdy; |
| 340 | 337 | ||
| 341 | ret = sx9500_dec_chan_users(data, chan->channel); | 338 | ret = sx9500_read_prox_data(data, chan, val); |
| 342 | if (ret < 0) | 339 | if (ret < 0) |
| 343 | goto out; | 340 | goto out_dec_data_rdy; |
| 344 | 341 | ||
| 345 | ret = sx9500_dec_data_rdy_users(data); | 342 | ret = sx9500_dec_data_rdy_users(data); |
| 346 | if (ret < 0) | 343 | if (ret < 0) |
| 344 | goto out_dec_chan; | ||
| 345 | |||
| 346 | ret = sx9500_dec_chan_users(data, chan->channel); | ||
| 347 | if (ret < 0) | ||
| 347 | goto out; | 348 | goto out; |
| 348 | 349 | ||
| 349 | ret = IIO_VAL_INT; | 350 | ret = IIO_VAL_INT; |
| 350 | 351 | ||
| 351 | goto out; | 352 | goto out; |
| 352 | 353 | ||
| 354 | out_dec_data_rdy: | ||
| 355 | sx9500_dec_data_rdy_users(data); | ||
| 353 | out_dec_chan: | 356 | out_dec_chan: |
| 354 | sx9500_dec_chan_users(data, chan->channel); | 357 | sx9500_dec_chan_users(data, chan->channel); |
| 355 | out: | 358 | out: |
| @@ -679,7 +682,7 @@ out: | |||
| 679 | static int sx9500_buffer_preenable(struct iio_dev *indio_dev) | 682 | static int sx9500_buffer_preenable(struct iio_dev *indio_dev) |
| 680 | { | 683 | { |
| 681 | struct sx9500_data *data = iio_priv(indio_dev); | 684 | struct sx9500_data *data = iio_priv(indio_dev); |
| 682 | int ret, i; | 685 | int ret = 0, i; |
| 683 | 686 | ||
| 684 | mutex_lock(&data->mutex); | 687 | mutex_lock(&data->mutex); |
| 685 | 688 | ||
| @@ -703,7 +706,7 @@ static int sx9500_buffer_preenable(struct iio_dev *indio_dev) | |||
| 703 | static int sx9500_buffer_predisable(struct iio_dev *indio_dev) | 706 | static int sx9500_buffer_predisable(struct iio_dev *indio_dev) |
| 704 | { | 707 | { |
| 705 | struct sx9500_data *data = iio_priv(indio_dev); | 708 | struct sx9500_data *data = iio_priv(indio_dev); |
| 706 | int ret, i; | 709 | int ret = 0, i; |
| 707 | 710 | ||
| 708 | iio_triggered_buffer_predisable(indio_dev); | 711 | iio_triggered_buffer_predisable(indio_dev); |
| 709 | 712 | ||
| @@ -800,8 +803,7 @@ static int sx9500_init_compensation(struct iio_dev *indio_dev) | |||
| 800 | unsigned int val; | 803 | unsigned int val; |
| 801 | 804 | ||
| 802 | ret = regmap_update_bits(data->regmap, SX9500_REG_PROX_CTRL0, | 805 | ret = regmap_update_bits(data->regmap, SX9500_REG_PROX_CTRL0, |
| 803 | GENMASK(SX9500_NUM_CHANNELS, 0), | 806 | SX9500_CHAN_MASK, SX9500_CHAN_MASK); |
| 804 | GENMASK(SX9500_NUM_CHANNELS, 0)); | ||
| 805 | if (ret < 0) | 807 | if (ret < 0) |
| 806 | return ret; | 808 | return ret; |
| 807 | 809 | ||
| @@ -821,7 +823,7 @@ static int sx9500_init_compensation(struct iio_dev *indio_dev) | |||
| 821 | 823 | ||
| 822 | out: | 824 | out: |
| 823 | regmap_update_bits(data->regmap, SX9500_REG_PROX_CTRL0, | 825 | regmap_update_bits(data->regmap, SX9500_REG_PROX_CTRL0, |
| 824 | GENMASK(SX9500_NUM_CHANNELS, 0), 0); | 826 | SX9500_CHAN_MASK, 0); |
| 825 | return ret; | 827 | return ret; |
| 826 | } | 828 | } |
| 827 | 829 | ||
diff --git a/drivers/iio/temperature/tmp006.c b/drivers/iio/temperature/tmp006.c index fcc49f89b946..8f21f32f9739 100644 --- a/drivers/iio/temperature/tmp006.c +++ b/drivers/iio/temperature/tmp006.c | |||
| @@ -132,6 +132,9 @@ static int tmp006_write_raw(struct iio_dev *indio_dev, | |||
| 132 | struct tmp006_data *data = iio_priv(indio_dev); | 132 | struct tmp006_data *data = iio_priv(indio_dev); |
| 133 | int i; | 133 | int i; |
| 134 | 134 | ||
| 135 | if (mask != IIO_CHAN_INFO_SAMP_FREQ) | ||
| 136 | return -EINVAL; | ||
| 137 | |||
| 135 | for (i = 0; i < ARRAY_SIZE(tmp006_freqs); i++) | 138 | for (i = 0; i < ARRAY_SIZE(tmp006_freqs); i++) |
| 136 | if ((val == tmp006_freqs[i][0]) && | 139 | if ((val == tmp006_freqs[i][0]) && |
| 137 | (val2 == tmp006_freqs[i][1])) { | 140 | (val2 == tmp006_freqs[i][1])) { |
diff --git a/drivers/infiniband/core/agent.c b/drivers/infiniband/core/agent.c index c7dcfe4ca5f1..0429040304fd 100644 --- a/drivers/infiniband/core/agent.c +++ b/drivers/infiniband/core/agent.c | |||
| @@ -88,7 +88,7 @@ void agent_send_response(const struct ib_mad_hdr *mad_hdr, const struct ib_grh * | |||
| 88 | struct ib_ah *ah; | 88 | struct ib_ah *ah; |
| 89 | struct ib_mad_send_wr_private *mad_send_wr; | 89 | struct ib_mad_send_wr_private *mad_send_wr; |
| 90 | 90 | ||
| 91 | if (device->node_type == RDMA_NODE_IB_SWITCH) | 91 | if (rdma_cap_ib_switch(device)) |
| 92 | port_priv = ib_get_agent_port(device, 0); | 92 | port_priv = ib_get_agent_port(device, 0); |
| 93 | else | 93 | else |
| 94 | port_priv = ib_get_agent_port(device, port_num); | 94 | port_priv = ib_get_agent_port(device, port_num); |
| @@ -122,7 +122,7 @@ void agent_send_response(const struct ib_mad_hdr *mad_hdr, const struct ib_grh * | |||
| 122 | memcpy(send_buf->mad, mad_hdr, resp_mad_len); | 122 | memcpy(send_buf->mad, mad_hdr, resp_mad_len); |
| 123 | send_buf->ah = ah; | 123 | send_buf->ah = ah; |
| 124 | 124 | ||
| 125 | if (device->node_type == RDMA_NODE_IB_SWITCH) { | 125 | if (rdma_cap_ib_switch(device)) { |
| 126 | mad_send_wr = container_of(send_buf, | 126 | mad_send_wr = container_of(send_buf, |
| 127 | struct ib_mad_send_wr_private, | 127 | struct ib_mad_send_wr_private, |
| 128 | send_buf); | 128 | send_buf); |
diff --git a/drivers/infiniband/core/cm.c b/drivers/infiniband/core/cm.c index dbddddd6fb5d..3a972ebf3c0d 100644 --- a/drivers/infiniband/core/cm.c +++ b/drivers/infiniband/core/cm.c | |||
| @@ -169,6 +169,7 @@ struct cm_device { | |||
| 169 | struct ib_device *ib_device; | 169 | struct ib_device *ib_device; |
| 170 | struct device *device; | 170 | struct device *device; |
| 171 | u8 ack_delay; | 171 | u8 ack_delay; |
| 172 | int going_down; | ||
| 172 | struct cm_port *port[0]; | 173 | struct cm_port *port[0]; |
| 173 | }; | 174 | }; |
| 174 | 175 | ||
| @@ -805,6 +806,11 @@ static void cm_enter_timewait(struct cm_id_private *cm_id_priv) | |||
| 805 | { | 806 | { |
| 806 | int wait_time; | 807 | int wait_time; |
| 807 | unsigned long flags; | 808 | unsigned long flags; |
| 809 | struct cm_device *cm_dev; | ||
| 810 | |||
| 811 | cm_dev = ib_get_client_data(cm_id_priv->id.device, &cm_client); | ||
| 812 | if (!cm_dev) | ||
| 813 | return; | ||
| 808 | 814 | ||
| 809 | spin_lock_irqsave(&cm.lock, flags); | 815 | spin_lock_irqsave(&cm.lock, flags); |
| 810 | cm_cleanup_timewait(cm_id_priv->timewait_info); | 816 | cm_cleanup_timewait(cm_id_priv->timewait_info); |
| @@ -818,8 +824,14 @@ static void cm_enter_timewait(struct cm_id_private *cm_id_priv) | |||
| 818 | */ | 824 | */ |
| 819 | cm_id_priv->id.state = IB_CM_TIMEWAIT; | 825 | cm_id_priv->id.state = IB_CM_TIMEWAIT; |
| 820 | wait_time = cm_convert_to_ms(cm_id_priv->av.timeout); | 826 | wait_time = cm_convert_to_ms(cm_id_priv->av.timeout); |
| 821 | queue_delayed_work(cm.wq, &cm_id_priv->timewait_info->work.work, | 827 | |
| 822 | msecs_to_jiffies(wait_time)); | 828 | /* Check if the device started its remove_one */ |
| 829 | spin_lock_irq(&cm.lock); | ||
| 830 | if (!cm_dev->going_down) | ||
| 831 | queue_delayed_work(cm.wq, &cm_id_priv->timewait_info->work.work, | ||
| 832 | msecs_to_jiffies(wait_time)); | ||
| 833 | spin_unlock_irq(&cm.lock); | ||
| 834 | |||
| 823 | cm_id_priv->timewait_info = NULL; | 835 | cm_id_priv->timewait_info = NULL; |
| 824 | } | 836 | } |
| 825 | 837 | ||
| @@ -3305,6 +3317,11 @@ static int cm_establish(struct ib_cm_id *cm_id) | |||
| 3305 | struct cm_work *work; | 3317 | struct cm_work *work; |
| 3306 | unsigned long flags; | 3318 | unsigned long flags; |
| 3307 | int ret = 0; | 3319 | int ret = 0; |
| 3320 | struct cm_device *cm_dev; | ||
| 3321 | |||
| 3322 | cm_dev = ib_get_client_data(cm_id->device, &cm_client); | ||
| 3323 | if (!cm_dev) | ||
| 3324 | return -ENODEV; | ||
| 3308 | 3325 | ||
| 3309 | work = kmalloc(sizeof *work, GFP_ATOMIC); | 3326 | work = kmalloc(sizeof *work, GFP_ATOMIC); |
| 3310 | if (!work) | 3327 | if (!work) |
| @@ -3343,7 +3360,17 @@ static int cm_establish(struct ib_cm_id *cm_id) | |||
| 3343 | work->remote_id = cm_id->remote_id; | 3360 | work->remote_id = cm_id->remote_id; |
| 3344 | work->mad_recv_wc = NULL; | 3361 | work->mad_recv_wc = NULL; |
| 3345 | work->cm_event.event = IB_CM_USER_ESTABLISHED; | 3362 | work->cm_event.event = IB_CM_USER_ESTABLISHED; |
| 3346 | queue_delayed_work(cm.wq, &work->work, 0); | 3363 | |
| 3364 | /* Check if the device started its remove_one */ | ||
| 3365 | spin_lock_irq(&cm.lock); | ||
| 3366 | if (!cm_dev->going_down) { | ||
| 3367 | queue_delayed_work(cm.wq, &work->work, 0); | ||
| 3368 | } else { | ||
| 3369 | kfree(work); | ||
| 3370 | ret = -ENODEV; | ||
| 3371 | } | ||
| 3372 | spin_unlock_irq(&cm.lock); | ||
| 3373 | |||
| 3347 | out: | 3374 | out: |
| 3348 | return ret; | 3375 | return ret; |
| 3349 | } | 3376 | } |
| @@ -3394,6 +3421,7 @@ static void cm_recv_handler(struct ib_mad_agent *mad_agent, | |||
| 3394 | enum ib_cm_event_type event; | 3421 | enum ib_cm_event_type event; |
| 3395 | u16 attr_id; | 3422 | u16 attr_id; |
| 3396 | int paths = 0; | 3423 | int paths = 0; |
| 3424 | int going_down = 0; | ||
| 3397 | 3425 | ||
| 3398 | switch (mad_recv_wc->recv_buf.mad->mad_hdr.attr_id) { | 3426 | switch (mad_recv_wc->recv_buf.mad->mad_hdr.attr_id) { |
| 3399 | case CM_REQ_ATTR_ID: | 3427 | case CM_REQ_ATTR_ID: |
| @@ -3452,7 +3480,19 @@ static void cm_recv_handler(struct ib_mad_agent *mad_agent, | |||
| 3452 | work->cm_event.event = event; | 3480 | work->cm_event.event = event; |
| 3453 | work->mad_recv_wc = mad_recv_wc; | 3481 | work->mad_recv_wc = mad_recv_wc; |
| 3454 | work->port = port; | 3482 | work->port = port; |
| 3455 | queue_delayed_work(cm.wq, &work->work, 0); | 3483 | |
| 3484 | /* Check if the device started its remove_one */ | ||
| 3485 | spin_lock_irq(&cm.lock); | ||
| 3486 | if (!port->cm_dev->going_down) | ||
| 3487 | queue_delayed_work(cm.wq, &work->work, 0); | ||
| 3488 | else | ||
| 3489 | going_down = 1; | ||
| 3490 | spin_unlock_irq(&cm.lock); | ||
| 3491 | |||
| 3492 | if (going_down) { | ||
| 3493 | kfree(work); | ||
| 3494 | ib_free_recv_mad(mad_recv_wc); | ||
| 3495 | } | ||
| 3456 | } | 3496 | } |
| 3457 | 3497 | ||
| 3458 | static int cm_init_qp_init_attr(struct cm_id_private *cm_id_priv, | 3498 | static int cm_init_qp_init_attr(struct cm_id_private *cm_id_priv, |
| @@ -3771,7 +3811,7 @@ static void cm_add_one(struct ib_device *ib_device) | |||
| 3771 | 3811 | ||
| 3772 | cm_dev->ib_device = ib_device; | 3812 | cm_dev->ib_device = ib_device; |
| 3773 | cm_get_ack_delay(cm_dev); | 3813 | cm_get_ack_delay(cm_dev); |
| 3774 | 3814 | cm_dev->going_down = 0; | |
| 3775 | cm_dev->device = device_create(&cm_class, &ib_device->dev, | 3815 | cm_dev->device = device_create(&cm_class, &ib_device->dev, |
| 3776 | MKDEV(0, 0), NULL, | 3816 | MKDEV(0, 0), NULL, |
| 3777 | "%s", ib_device->name); | 3817 | "%s", ib_device->name); |
| @@ -3864,14 +3904,23 @@ static void cm_remove_one(struct ib_device *ib_device) | |||
| 3864 | list_del(&cm_dev->list); | 3904 | list_del(&cm_dev->list); |
| 3865 | write_unlock_irqrestore(&cm.device_lock, flags); | 3905 | write_unlock_irqrestore(&cm.device_lock, flags); |
| 3866 | 3906 | ||
| 3907 | spin_lock_irq(&cm.lock); | ||
| 3908 | cm_dev->going_down = 1; | ||
| 3909 | spin_unlock_irq(&cm.lock); | ||
| 3910 | |||
| 3867 | for (i = 1; i <= ib_device->phys_port_cnt; i++) { | 3911 | for (i = 1; i <= ib_device->phys_port_cnt; i++) { |
| 3868 | if (!rdma_cap_ib_cm(ib_device, i)) | 3912 | if (!rdma_cap_ib_cm(ib_device, i)) |
| 3869 | continue; | 3913 | continue; |
| 3870 | 3914 | ||
| 3871 | port = cm_dev->port[i-1]; | 3915 | port = cm_dev->port[i-1]; |
| 3872 | ib_modify_port(ib_device, port->port_num, 0, &port_modify); | 3916 | ib_modify_port(ib_device, port->port_num, 0, &port_modify); |
| 3873 | ib_unregister_mad_agent(port->mad_agent); | 3917 | /* |
| 3918 | * We flush the queue here after the going_down set, this | ||
| 3919 | * verify that no new works will be queued in the recv handler, | ||
| 3920 | * after that we can call the unregister_mad_agent | ||
| 3921 | */ | ||
| 3874 | flush_workqueue(cm.wq); | 3922 | flush_workqueue(cm.wq); |
| 3923 | ib_unregister_mad_agent(port->mad_agent); | ||
| 3875 | cm_remove_port_fs(port); | 3924 | cm_remove_port_fs(port); |
| 3876 | } | 3925 | } |
| 3877 | device_unregister(cm_dev->device); | 3926 | device_unregister(cm_dev->device); |
diff --git a/drivers/infiniband/core/iwpm_msg.c b/drivers/infiniband/core/iwpm_msg.c index e6ffa2e66c1a..22a3abee2a54 100644 --- a/drivers/infiniband/core/iwpm_msg.c +++ b/drivers/infiniband/core/iwpm_msg.c | |||
| @@ -67,7 +67,8 @@ int iwpm_register_pid(struct iwpm_dev_data *pm_msg, u8 nl_client) | |||
| 67 | err_str = "Invalid port mapper client"; | 67 | err_str = "Invalid port mapper client"; |
| 68 | goto pid_query_error; | 68 | goto pid_query_error; |
| 69 | } | 69 | } |
| 70 | if (iwpm_registered_client(nl_client)) | 70 | if (iwpm_check_registration(nl_client, IWPM_REG_VALID) || |
| 71 | iwpm_user_pid == IWPM_PID_UNAVAILABLE) | ||
| 71 | return 0; | 72 | return 0; |
| 72 | skb = iwpm_create_nlmsg(RDMA_NL_IWPM_REG_PID, &nlh, nl_client); | 73 | skb = iwpm_create_nlmsg(RDMA_NL_IWPM_REG_PID, &nlh, nl_client); |
| 73 | if (!skb) { | 74 | if (!skb) { |
| @@ -106,7 +107,6 @@ int iwpm_register_pid(struct iwpm_dev_data *pm_msg, u8 nl_client) | |||
| 106 | ret = ibnl_multicast(skb, nlh, RDMA_NL_GROUP_IWPM, GFP_KERNEL); | 107 | ret = ibnl_multicast(skb, nlh, RDMA_NL_GROUP_IWPM, GFP_KERNEL); |
| 107 | if (ret) { | 108 | if (ret) { |
| 108 | skb = NULL; /* skb is freed in the netlink send-op handling */ | 109 | skb = NULL; /* skb is freed in the netlink send-op handling */ |
| 109 | iwpm_set_registered(nl_client, 1); | ||
| 110 | iwpm_user_pid = IWPM_PID_UNAVAILABLE; | 110 | iwpm_user_pid = IWPM_PID_UNAVAILABLE; |
| 111 | err_str = "Unable to send a nlmsg"; | 111 | err_str = "Unable to send a nlmsg"; |
| 112 | goto pid_query_error; | 112 | goto pid_query_error; |
| @@ -144,12 +144,12 @@ int iwpm_add_mapping(struct iwpm_sa_data *pm_msg, u8 nl_client) | |||
| 144 | err_str = "Invalid port mapper client"; | 144 | err_str = "Invalid port mapper client"; |
| 145 | goto add_mapping_error; | 145 | goto add_mapping_error; |
| 146 | } | 146 | } |
| 147 | if (!iwpm_registered_client(nl_client)) { | 147 | if (!iwpm_valid_pid()) |
| 148 | return 0; | ||
| 149 | if (!iwpm_check_registration(nl_client, IWPM_REG_VALID)) { | ||
| 148 | err_str = "Unregistered port mapper client"; | 150 | err_str = "Unregistered port mapper client"; |
| 149 | goto add_mapping_error; | 151 | goto add_mapping_error; |
| 150 | } | 152 | } |
| 151 | if (!iwpm_valid_pid()) | ||
| 152 | return 0; | ||
| 153 | skb = iwpm_create_nlmsg(RDMA_NL_IWPM_ADD_MAPPING, &nlh, nl_client); | 153 | skb = iwpm_create_nlmsg(RDMA_NL_IWPM_ADD_MAPPING, &nlh, nl_client); |
| 154 | if (!skb) { | 154 | if (!skb) { |
| 155 | err_str = "Unable to create a nlmsg"; | 155 | err_str = "Unable to create a nlmsg"; |
| @@ -214,12 +214,12 @@ int iwpm_add_and_query_mapping(struct iwpm_sa_data *pm_msg, u8 nl_client) | |||
| 214 | err_str = "Invalid port mapper client"; | 214 | err_str = "Invalid port mapper client"; |
| 215 | goto query_mapping_error; | 215 | goto query_mapping_error; |
| 216 | } | 216 | } |
| 217 | if (!iwpm_registered_client(nl_client)) { | 217 | if (!iwpm_valid_pid()) |
| 218 | return 0; | ||
| 219 | if (!iwpm_check_registration(nl_client, IWPM_REG_VALID)) { | ||
| 218 | err_str = "Unregistered port mapper client"; | 220 | err_str = "Unregistered port mapper client"; |
| 219 | goto query_mapping_error; | 221 | goto query_mapping_error; |
| 220 | } | 222 | } |
| 221 | if (!iwpm_valid_pid()) | ||
| 222 | return 0; | ||
| 223 | ret = -ENOMEM; | 223 | ret = -ENOMEM; |
| 224 | skb = iwpm_create_nlmsg(RDMA_NL_IWPM_QUERY_MAPPING, &nlh, nl_client); | 224 | skb = iwpm_create_nlmsg(RDMA_NL_IWPM_QUERY_MAPPING, &nlh, nl_client); |
| 225 | if (!skb) { | 225 | if (!skb) { |
| @@ -288,12 +288,12 @@ int iwpm_remove_mapping(struct sockaddr_storage *local_addr, u8 nl_client) | |||
| 288 | err_str = "Invalid port mapper client"; | 288 | err_str = "Invalid port mapper client"; |
| 289 | goto remove_mapping_error; | 289 | goto remove_mapping_error; |
| 290 | } | 290 | } |
| 291 | if (!iwpm_registered_client(nl_client)) { | 291 | if (!iwpm_valid_pid()) |
| 292 | return 0; | ||
| 293 | if (iwpm_check_registration(nl_client, IWPM_REG_UNDEF)) { | ||
| 292 | err_str = "Unregistered port mapper client"; | 294 | err_str = "Unregistered port mapper client"; |
| 293 | goto remove_mapping_error; | 295 | goto remove_mapping_error; |
| 294 | } | 296 | } |
| 295 | if (!iwpm_valid_pid()) | ||
| 296 | return 0; | ||
| 297 | skb = iwpm_create_nlmsg(RDMA_NL_IWPM_REMOVE_MAPPING, &nlh, nl_client); | 297 | skb = iwpm_create_nlmsg(RDMA_NL_IWPM_REMOVE_MAPPING, &nlh, nl_client); |
| 298 | if (!skb) { | 298 | if (!skb) { |
| 299 | ret = -ENOMEM; | 299 | ret = -ENOMEM; |
| @@ -388,7 +388,7 @@ int iwpm_register_pid_cb(struct sk_buff *skb, struct netlink_callback *cb) | |||
| 388 | pr_debug("%s: iWarp Port Mapper (pid = %d) is available!\n", | 388 | pr_debug("%s: iWarp Port Mapper (pid = %d) is available!\n", |
| 389 | __func__, iwpm_user_pid); | 389 | __func__, iwpm_user_pid); |
| 390 | if (iwpm_valid_client(nl_client)) | 390 | if (iwpm_valid_client(nl_client)) |
| 391 | iwpm_set_registered(nl_client, 1); | 391 | iwpm_set_registration(nl_client, IWPM_REG_VALID); |
| 392 | register_pid_response_exit: | 392 | register_pid_response_exit: |
| 393 | nlmsg_request->request_done = 1; | 393 | nlmsg_request->request_done = 1; |
| 394 | /* always for found nlmsg_request */ | 394 | /* always for found nlmsg_request */ |
| @@ -644,7 +644,6 @@ int iwpm_mapping_info_cb(struct sk_buff *skb, struct netlink_callback *cb) | |||
| 644 | { | 644 | { |
| 645 | struct nlattr *nltb[IWPM_NLA_MAPINFO_REQ_MAX]; | 645 | struct nlattr *nltb[IWPM_NLA_MAPINFO_REQ_MAX]; |
| 646 | const char *msg_type = "Mapping Info response"; | 646 | const char *msg_type = "Mapping Info response"; |
| 647 | int iwpm_pid; | ||
| 648 | u8 nl_client; | 647 | u8 nl_client; |
| 649 | char *iwpm_name; | 648 | char *iwpm_name; |
| 650 | u16 iwpm_version; | 649 | u16 iwpm_version; |
| @@ -669,14 +668,14 @@ int iwpm_mapping_info_cb(struct sk_buff *skb, struct netlink_callback *cb) | |||
| 669 | __func__, nl_client); | 668 | __func__, nl_client); |
| 670 | return ret; | 669 | return ret; |
| 671 | } | 670 | } |
| 672 | iwpm_set_registered(nl_client, 0); | 671 | iwpm_set_registration(nl_client, IWPM_REG_INCOMPL); |
| 673 | atomic_set(&echo_nlmsg_seq, cb->nlh->nlmsg_seq); | 672 | atomic_set(&echo_nlmsg_seq, cb->nlh->nlmsg_seq); |
| 673 | iwpm_user_pid = cb->nlh->nlmsg_pid; | ||
| 674 | if (!iwpm_mapinfo_available()) | 674 | if (!iwpm_mapinfo_available()) |
| 675 | return 0; | 675 | return 0; |
| 676 | iwpm_pid = cb->nlh->nlmsg_pid; | ||
| 677 | pr_debug("%s: iWarp Port Mapper (pid = %d) is available!\n", | 676 | pr_debug("%s: iWarp Port Mapper (pid = %d) is available!\n", |
| 678 | __func__, iwpm_pid); | 677 | __func__, iwpm_user_pid); |
| 679 | ret = iwpm_send_mapinfo(nl_client, iwpm_pid); | 678 | ret = iwpm_send_mapinfo(nl_client, iwpm_user_pid); |
| 680 | return ret; | 679 | return ret; |
| 681 | } | 680 | } |
| 682 | EXPORT_SYMBOL(iwpm_mapping_info_cb); | 681 | EXPORT_SYMBOL(iwpm_mapping_info_cb); |
diff --git a/drivers/infiniband/core/iwpm_util.c b/drivers/infiniband/core/iwpm_util.c index a626795bf9c7..5fb089e91353 100644 --- a/drivers/infiniband/core/iwpm_util.c +++ b/drivers/infiniband/core/iwpm_util.c | |||
| @@ -78,6 +78,7 @@ init_exit: | |||
| 78 | mutex_unlock(&iwpm_admin_lock); | 78 | mutex_unlock(&iwpm_admin_lock); |
| 79 | if (!ret) { | 79 | if (!ret) { |
| 80 | iwpm_set_valid(nl_client, 1); | 80 | iwpm_set_valid(nl_client, 1); |
| 81 | iwpm_set_registration(nl_client, IWPM_REG_UNDEF); | ||
| 81 | pr_debug("%s: Mapinfo and reminfo tables are created\n", | 82 | pr_debug("%s: Mapinfo and reminfo tables are created\n", |
| 82 | __func__); | 83 | __func__); |
| 83 | } | 84 | } |
| @@ -106,6 +107,7 @@ int iwpm_exit(u8 nl_client) | |||
| 106 | } | 107 | } |
| 107 | mutex_unlock(&iwpm_admin_lock); | 108 | mutex_unlock(&iwpm_admin_lock); |
| 108 | iwpm_set_valid(nl_client, 0); | 109 | iwpm_set_valid(nl_client, 0); |
| 110 | iwpm_set_registration(nl_client, IWPM_REG_UNDEF); | ||
| 109 | return 0; | 111 | return 0; |
| 110 | } | 112 | } |
| 111 | EXPORT_SYMBOL(iwpm_exit); | 113 | EXPORT_SYMBOL(iwpm_exit); |
| @@ -397,17 +399,23 @@ void iwpm_set_valid(u8 nl_client, int valid) | |||
| 397 | } | 399 | } |
| 398 | 400 | ||
| 399 | /* valid client */ | 401 | /* valid client */ |
| 400 | int iwpm_registered_client(u8 nl_client) | 402 | u32 iwpm_get_registration(u8 nl_client) |
| 401 | { | 403 | { |
| 402 | return iwpm_admin.reg_list[nl_client]; | 404 | return iwpm_admin.reg_list[nl_client]; |
| 403 | } | 405 | } |
| 404 | 406 | ||
| 405 | /* valid client */ | 407 | /* valid client */ |
| 406 | void iwpm_set_registered(u8 nl_client, int reg) | 408 | void iwpm_set_registration(u8 nl_client, u32 reg) |
| 407 | { | 409 | { |
| 408 | iwpm_admin.reg_list[nl_client] = reg; | 410 | iwpm_admin.reg_list[nl_client] = reg; |
| 409 | } | 411 | } |
| 410 | 412 | ||
| 413 | /* valid client */ | ||
| 414 | u32 iwpm_check_registration(u8 nl_client, u32 reg) | ||
| 415 | { | ||
| 416 | return (iwpm_get_registration(nl_client) & reg); | ||
| 417 | } | ||
| 418 | |||
| 411 | int iwpm_compare_sockaddr(struct sockaddr_storage *a_sockaddr, | 419 | int iwpm_compare_sockaddr(struct sockaddr_storage *a_sockaddr, |
| 412 | struct sockaddr_storage *b_sockaddr) | 420 | struct sockaddr_storage *b_sockaddr) |
| 413 | { | 421 | { |
diff --git a/drivers/infiniband/core/iwpm_util.h b/drivers/infiniband/core/iwpm_util.h index ee2d9ff095be..b7b9e194ce81 100644 --- a/drivers/infiniband/core/iwpm_util.h +++ b/drivers/infiniband/core/iwpm_util.h | |||
| @@ -58,6 +58,10 @@ | |||
| 58 | #define IWPM_PID_UNDEFINED -1 | 58 | #define IWPM_PID_UNDEFINED -1 |
| 59 | #define IWPM_PID_UNAVAILABLE -2 | 59 | #define IWPM_PID_UNAVAILABLE -2 |
| 60 | 60 | ||
| 61 | #define IWPM_REG_UNDEF 0x01 | ||
| 62 | #define IWPM_REG_VALID 0x02 | ||
| 63 | #define IWPM_REG_INCOMPL 0x04 | ||
| 64 | |||
| 61 | struct iwpm_nlmsg_request { | 65 | struct iwpm_nlmsg_request { |
| 62 | struct list_head inprocess_list; | 66 | struct list_head inprocess_list; |
| 63 | __u32 nlmsg_seq; | 67 | __u32 nlmsg_seq; |
| @@ -88,7 +92,7 @@ struct iwpm_admin_data { | |||
| 88 | atomic_t refcount; | 92 | atomic_t refcount; |
| 89 | atomic_t nlmsg_seq; | 93 | atomic_t nlmsg_seq; |
| 90 | int client_list[RDMA_NL_NUM_CLIENTS]; | 94 | int client_list[RDMA_NL_NUM_CLIENTS]; |
| 91 | int reg_list[RDMA_NL_NUM_CLIENTS]; | 95 | u32 reg_list[RDMA_NL_NUM_CLIENTS]; |
| 92 | }; | 96 | }; |
| 93 | 97 | ||
| 94 | /** | 98 | /** |
| @@ -159,19 +163,31 @@ int iwpm_valid_client(u8 nl_client); | |||
| 159 | void iwpm_set_valid(u8 nl_client, int valid); | 163 | void iwpm_set_valid(u8 nl_client, int valid); |
| 160 | 164 | ||
| 161 | /** | 165 | /** |
| 162 | * iwpm_registered_client - Check if the port mapper client is registered | 166 | * iwpm_check_registration - Check if the client registration |
| 167 | * matches the given one | ||
| 163 | * @nl_client: The index of the netlink client | 168 | * @nl_client: The index of the netlink client |
| 169 | * @reg: The given registration type to compare with | ||
| 164 | * | 170 | * |
| 165 | * Call iwpm_register_pid() to register a client | 171 | * Call iwpm_register_pid() to register a client |
| 172 | * Returns true if the client registration matches reg, | ||
| 173 | * otherwise returns false | ||
| 174 | */ | ||
| 175 | u32 iwpm_check_registration(u8 nl_client, u32 reg); | ||
| 176 | |||
| 177 | /** | ||
| 178 | * iwpm_set_registration - Set the client registration | ||
| 179 | * @nl_client: The index of the netlink client | ||
| 180 | * @reg: Registration type to set | ||
| 166 | */ | 181 | */ |
| 167 | int iwpm_registered_client(u8 nl_client); | 182 | void iwpm_set_registration(u8 nl_client, u32 reg); |
| 168 | 183 | ||
| 169 | /** | 184 | /** |
| 170 | * iwpm_set_registered - Set the port mapper client to registered or not | 185 | * iwpm_get_registration |
| 171 | * @nl_client: The index of the netlink client | 186 | * @nl_client: The index of the netlink client |
| 172 | * @reg: 1 if registered or 0 if not | 187 | * |
| 188 | * Returns the client registration type | ||
| 173 | */ | 189 | */ |
| 174 | void iwpm_set_registered(u8 nl_client, int reg); | 190 | u32 iwpm_get_registration(u8 nl_client); |
| 175 | 191 | ||
| 176 | /** | 192 | /** |
| 177 | * iwpm_send_mapinfo - Send local and mapped IPv4/IPv6 address info of | 193 | * iwpm_send_mapinfo - Send local and mapped IPv4/IPv6 address info of |
diff --git a/drivers/infiniband/core/mad.c b/drivers/infiniband/core/mad.c index a4b1466c1bf6..786fc51bf04b 100644 --- a/drivers/infiniband/core/mad.c +++ b/drivers/infiniband/core/mad.c | |||
| @@ -769,7 +769,7 @@ static int handle_outgoing_dr_smp(struct ib_mad_agent_private *mad_agent_priv, | |||
| 769 | bool opa = rdma_cap_opa_mad(mad_agent_priv->qp_info->port_priv->device, | 769 | bool opa = rdma_cap_opa_mad(mad_agent_priv->qp_info->port_priv->device, |
| 770 | mad_agent_priv->qp_info->port_priv->port_num); | 770 | mad_agent_priv->qp_info->port_priv->port_num); |
| 771 | 771 | ||
| 772 | if (device->node_type == RDMA_NODE_IB_SWITCH && | 772 | if (rdma_cap_ib_switch(device) && |
| 773 | smp->mgmt_class == IB_MGMT_CLASS_SUBN_DIRECTED_ROUTE) | 773 | smp->mgmt_class == IB_MGMT_CLASS_SUBN_DIRECTED_ROUTE) |
| 774 | port_num = send_wr->wr.ud.port_num; | 774 | port_num = send_wr->wr.ud.port_num; |
| 775 | else | 775 | else |
| @@ -787,14 +787,15 @@ static int handle_outgoing_dr_smp(struct ib_mad_agent_private *mad_agent_priv, | |||
| 787 | if ((opa_get_smp_direction(opa_smp) | 787 | if ((opa_get_smp_direction(opa_smp) |
| 788 | ? opa_smp->route.dr.dr_dlid : opa_smp->route.dr.dr_slid) == | 788 | ? opa_smp->route.dr.dr_dlid : opa_smp->route.dr.dr_slid) == |
| 789 | OPA_LID_PERMISSIVE && | 789 | OPA_LID_PERMISSIVE && |
| 790 | opa_smi_handle_dr_smp_send(opa_smp, device->node_type, | 790 | opa_smi_handle_dr_smp_send(opa_smp, |
| 791 | rdma_cap_ib_switch(device), | ||
| 791 | port_num) == IB_SMI_DISCARD) { | 792 | port_num) == IB_SMI_DISCARD) { |
| 792 | ret = -EINVAL; | 793 | ret = -EINVAL; |
| 793 | dev_err(&device->dev, "OPA Invalid directed route\n"); | 794 | dev_err(&device->dev, "OPA Invalid directed route\n"); |
| 794 | goto out; | 795 | goto out; |
| 795 | } | 796 | } |
| 796 | opa_drslid = be32_to_cpu(opa_smp->route.dr.dr_slid); | 797 | opa_drslid = be32_to_cpu(opa_smp->route.dr.dr_slid); |
| 797 | if (opa_drslid != OPA_LID_PERMISSIVE && | 798 | if (opa_drslid != be32_to_cpu(OPA_LID_PERMISSIVE) && |
| 798 | opa_drslid & 0xffff0000) { | 799 | opa_drslid & 0xffff0000) { |
| 799 | ret = -EINVAL; | 800 | ret = -EINVAL; |
| 800 | dev_err(&device->dev, "OPA Invalid dr_slid 0x%x\n", | 801 | dev_err(&device->dev, "OPA Invalid dr_slid 0x%x\n", |
| @@ -810,7 +811,7 @@ static int handle_outgoing_dr_smp(struct ib_mad_agent_private *mad_agent_priv, | |||
| 810 | } else { | 811 | } else { |
| 811 | if ((ib_get_smp_direction(smp) ? smp->dr_dlid : smp->dr_slid) == | 812 | if ((ib_get_smp_direction(smp) ? smp->dr_dlid : smp->dr_slid) == |
| 812 | IB_LID_PERMISSIVE && | 813 | IB_LID_PERMISSIVE && |
| 813 | smi_handle_dr_smp_send(smp, device->node_type, port_num) == | 814 | smi_handle_dr_smp_send(smp, rdma_cap_ib_switch(device), port_num) == |
| 814 | IB_SMI_DISCARD) { | 815 | IB_SMI_DISCARD) { |
| 815 | ret = -EINVAL; | 816 | ret = -EINVAL; |
| 816 | dev_err(&device->dev, "Invalid directed route\n"); | 817 | dev_err(&device->dev, "Invalid directed route\n"); |
| @@ -2030,7 +2031,7 @@ static enum smi_action handle_ib_smi(const struct ib_mad_port_private *port_priv | |||
| 2030 | struct ib_smp *smp = (struct ib_smp *)recv->mad; | 2031 | struct ib_smp *smp = (struct ib_smp *)recv->mad; |
| 2031 | 2032 | ||
| 2032 | if (smi_handle_dr_smp_recv(smp, | 2033 | if (smi_handle_dr_smp_recv(smp, |
| 2033 | port_priv->device->node_type, | 2034 | rdma_cap_ib_switch(port_priv->device), |
| 2034 | port_num, | 2035 | port_num, |
| 2035 | port_priv->device->phys_port_cnt) == | 2036 | port_priv->device->phys_port_cnt) == |
| 2036 | IB_SMI_DISCARD) | 2037 | IB_SMI_DISCARD) |
| @@ -2042,13 +2043,13 @@ static enum smi_action handle_ib_smi(const struct ib_mad_port_private *port_priv | |||
| 2042 | 2043 | ||
| 2043 | if (retsmi == IB_SMI_SEND) { /* don't forward */ | 2044 | if (retsmi == IB_SMI_SEND) { /* don't forward */ |
| 2044 | if (smi_handle_dr_smp_send(smp, | 2045 | if (smi_handle_dr_smp_send(smp, |
| 2045 | port_priv->device->node_type, | 2046 | rdma_cap_ib_switch(port_priv->device), |
| 2046 | port_num) == IB_SMI_DISCARD) | 2047 | port_num) == IB_SMI_DISCARD) |
| 2047 | return IB_SMI_DISCARD; | 2048 | return IB_SMI_DISCARD; |
| 2048 | 2049 | ||
| 2049 | if (smi_check_local_smp(smp, port_priv->device) == IB_SMI_DISCARD) | 2050 | if (smi_check_local_smp(smp, port_priv->device) == IB_SMI_DISCARD) |
| 2050 | return IB_SMI_DISCARD; | 2051 | return IB_SMI_DISCARD; |
| 2051 | } else if (port_priv->device->node_type == RDMA_NODE_IB_SWITCH) { | 2052 | } else if (rdma_cap_ib_switch(port_priv->device)) { |
| 2052 | /* forward case for switches */ | 2053 | /* forward case for switches */ |
| 2053 | memcpy(response, recv, mad_priv_size(response)); | 2054 | memcpy(response, recv, mad_priv_size(response)); |
| 2054 | response->header.recv_wc.wc = &response->header.wc; | 2055 | response->header.recv_wc.wc = &response->header.wc; |
| @@ -2115,7 +2116,7 @@ handle_opa_smi(struct ib_mad_port_private *port_priv, | |||
| 2115 | struct opa_smp *smp = (struct opa_smp *)recv->mad; | 2116 | struct opa_smp *smp = (struct opa_smp *)recv->mad; |
| 2116 | 2117 | ||
| 2117 | if (opa_smi_handle_dr_smp_recv(smp, | 2118 | if (opa_smi_handle_dr_smp_recv(smp, |
| 2118 | port_priv->device->node_type, | 2119 | rdma_cap_ib_switch(port_priv->device), |
| 2119 | port_num, | 2120 | port_num, |
| 2120 | port_priv->device->phys_port_cnt) == | 2121 | port_priv->device->phys_port_cnt) == |
| 2121 | IB_SMI_DISCARD) | 2122 | IB_SMI_DISCARD) |
| @@ -2127,7 +2128,7 @@ handle_opa_smi(struct ib_mad_port_private *port_priv, | |||
| 2127 | 2128 | ||
| 2128 | if (retsmi == IB_SMI_SEND) { /* don't forward */ | 2129 | if (retsmi == IB_SMI_SEND) { /* don't forward */ |
| 2129 | if (opa_smi_handle_dr_smp_send(smp, | 2130 | if (opa_smi_handle_dr_smp_send(smp, |
| 2130 | port_priv->device->node_type, | 2131 | rdma_cap_ib_switch(port_priv->device), |
| 2131 | port_num) == IB_SMI_DISCARD) | 2132 | port_num) == IB_SMI_DISCARD) |
| 2132 | return IB_SMI_DISCARD; | 2133 | return IB_SMI_DISCARD; |
| 2133 | 2134 | ||
| @@ -2135,7 +2136,7 @@ handle_opa_smi(struct ib_mad_port_private *port_priv, | |||
| 2135 | IB_SMI_DISCARD) | 2136 | IB_SMI_DISCARD) |
| 2136 | return IB_SMI_DISCARD; | 2137 | return IB_SMI_DISCARD; |
| 2137 | 2138 | ||
| 2138 | } else if (port_priv->device->node_type == RDMA_NODE_IB_SWITCH) { | 2139 | } else if (rdma_cap_ib_switch(port_priv->device)) { |
| 2139 | /* forward case for switches */ | 2140 | /* forward case for switches */ |
| 2140 | memcpy(response, recv, mad_priv_size(response)); | 2141 | memcpy(response, recv, mad_priv_size(response)); |
| 2141 | response->header.recv_wc.wc = &response->header.wc; | 2142 | response->header.recv_wc.wc = &response->header.wc; |
| @@ -2235,7 +2236,7 @@ static void ib_mad_recv_done_handler(struct ib_mad_port_private *port_priv, | |||
| 2235 | goto out; | 2236 | goto out; |
| 2236 | } | 2237 | } |
| 2237 | 2238 | ||
| 2238 | if (port_priv->device->node_type == RDMA_NODE_IB_SWITCH) | 2239 | if (rdma_cap_ib_switch(port_priv->device)) |
| 2239 | port_num = wc->port_num; | 2240 | port_num = wc->port_num; |
| 2240 | else | 2241 | else |
| 2241 | port_num = port_priv->port_num; | 2242 | port_num = port_priv->port_num; |
| @@ -3297,17 +3298,11 @@ static int ib_mad_port_close(struct ib_device *device, int port_num) | |||
| 3297 | 3298 | ||
| 3298 | static void ib_mad_init_device(struct ib_device *device) | 3299 | static void ib_mad_init_device(struct ib_device *device) |
| 3299 | { | 3300 | { |
| 3300 | int start, end, i; | 3301 | int start, i; |
| 3301 | 3302 | ||
| 3302 | if (device->node_type == RDMA_NODE_IB_SWITCH) { | 3303 | start = rdma_start_port(device); |
| 3303 | start = 0; | ||
| 3304 | end = 0; | ||
| 3305 | } else { | ||
| 3306 | start = 1; | ||
| 3307 | end = device->phys_port_cnt; | ||
| 3308 | } | ||
| 3309 | 3304 | ||
| 3310 | for (i = start; i <= end; i++) { | 3305 | for (i = start; i <= rdma_end_port(device); i++) { |
| 3311 | if (!rdma_cap_ib_mad(device, i)) | 3306 | if (!rdma_cap_ib_mad(device, i)) |
| 3312 | continue; | 3307 | continue; |
| 3313 | 3308 | ||
| @@ -3342,17 +3337,9 @@ error: | |||
| 3342 | 3337 | ||
| 3343 | static void ib_mad_remove_device(struct ib_device *device) | 3338 | static void ib_mad_remove_device(struct ib_device *device) |
| 3344 | { | 3339 | { |
| 3345 | int start, end, i; | 3340 | int i; |
| 3346 | |||
| 3347 | if (device->node_type == RDMA_NODE_IB_SWITCH) { | ||
| 3348 | start = 0; | ||
| 3349 | end = 0; | ||
| 3350 | } else { | ||
| 3351 | start = 1; | ||
| 3352 | end = device->phys_port_cnt; | ||
| 3353 | } | ||
| 3354 | 3341 | ||
| 3355 | for (i = start; i <= end; i++) { | 3342 | for (i = rdma_start_port(device); i <= rdma_end_port(device); i++) { |
| 3356 | if (!rdma_cap_ib_mad(device, i)) | 3343 | if (!rdma_cap_ib_mad(device, i)) |
| 3357 | continue; | 3344 | continue; |
| 3358 | 3345 | ||
diff --git a/drivers/infiniband/core/multicast.c b/drivers/infiniband/core/multicast.c index 1244f02a5c6d..2cb865c7ce7a 100644 --- a/drivers/infiniband/core/multicast.c +++ b/drivers/infiniband/core/multicast.c | |||
| @@ -812,12 +812,8 @@ static void mcast_add_one(struct ib_device *device) | |||
| 812 | if (!dev) | 812 | if (!dev) |
| 813 | return; | 813 | return; |
| 814 | 814 | ||
| 815 | if (device->node_type == RDMA_NODE_IB_SWITCH) | 815 | dev->start_port = rdma_start_port(device); |
| 816 | dev->start_port = dev->end_port = 0; | 816 | dev->end_port = rdma_end_port(device); |
| 817 | else { | ||
| 818 | dev->start_port = 1; | ||
| 819 | dev->end_port = device->phys_port_cnt; | ||
| 820 | } | ||
| 821 | 817 | ||
| 822 | for (i = 0; i <= dev->end_port - dev->start_port; i++) { | 818 | for (i = 0; i <= dev->end_port - dev->start_port; i++) { |
| 823 | if (!rdma_cap_ib_mcast(device, dev->start_port + i)) | 819 | if (!rdma_cap_ib_mcast(device, dev->start_port + i)) |
diff --git a/drivers/infiniband/core/opa_smi.h b/drivers/infiniband/core/opa_smi.h index 62d91bfa4cb7..3bfab3505a29 100644 --- a/drivers/infiniband/core/opa_smi.h +++ b/drivers/infiniband/core/opa_smi.h | |||
| @@ -39,12 +39,12 @@ | |||
| 39 | 39 | ||
| 40 | #include "smi.h" | 40 | #include "smi.h" |
| 41 | 41 | ||
| 42 | enum smi_action opa_smi_handle_dr_smp_recv(struct opa_smp *smp, u8 node_type, | 42 | enum smi_action opa_smi_handle_dr_smp_recv(struct opa_smp *smp, bool is_switch, |
| 43 | int port_num, int phys_port_cnt); | 43 | int port_num, int phys_port_cnt); |
| 44 | int opa_smi_get_fwd_port(struct opa_smp *smp); | 44 | int opa_smi_get_fwd_port(struct opa_smp *smp); |
| 45 | extern enum smi_forward_action opa_smi_check_forward_dr_smp(struct opa_smp *smp); | 45 | extern enum smi_forward_action opa_smi_check_forward_dr_smp(struct opa_smp *smp); |
| 46 | extern enum smi_action opa_smi_handle_dr_smp_send(struct opa_smp *smp, | 46 | extern enum smi_action opa_smi_handle_dr_smp_send(struct opa_smp *smp, |
| 47 | u8 node_type, int port_num); | 47 | bool is_switch, int port_num); |
| 48 | 48 | ||
| 49 | /* | 49 | /* |
| 50 | * Return IB_SMI_HANDLE if the SMP should be handled by the local SMA/SM | 50 | * Return IB_SMI_HANDLE if the SMP should be handled by the local SMA/SM |
diff --git a/drivers/infiniband/core/sa_query.c b/drivers/infiniband/core/sa_query.c index 0fae85062a65..ca919f429666 100644 --- a/drivers/infiniband/core/sa_query.c +++ b/drivers/infiniband/core/sa_query.c | |||
| @@ -1156,12 +1156,8 @@ static void ib_sa_add_one(struct ib_device *device) | |||
| 1156 | int s, e, i; | 1156 | int s, e, i; |
| 1157 | int count = 0; | 1157 | int count = 0; |
| 1158 | 1158 | ||
| 1159 | if (device->node_type == RDMA_NODE_IB_SWITCH) | 1159 | s = rdma_start_port(device); |
| 1160 | s = e = 0; | 1160 | e = rdma_end_port(device); |
| 1161 | else { | ||
| 1162 | s = 1; | ||
| 1163 | e = device->phys_port_cnt; | ||
| 1164 | } | ||
| 1165 | 1161 | ||
| 1166 | sa_dev = kzalloc(sizeof *sa_dev + | 1162 | sa_dev = kzalloc(sizeof *sa_dev + |
| 1167 | (e - s + 1) * sizeof (struct ib_sa_port), | 1163 | (e - s + 1) * sizeof (struct ib_sa_port), |
diff --git a/drivers/infiniband/core/smi.c b/drivers/infiniband/core/smi.c index 368a561d1a5d..f19b23817c2b 100644 --- a/drivers/infiniband/core/smi.c +++ b/drivers/infiniband/core/smi.c | |||
| @@ -41,7 +41,7 @@ | |||
| 41 | #include "smi.h" | 41 | #include "smi.h" |
| 42 | #include "opa_smi.h" | 42 | #include "opa_smi.h" |
| 43 | 43 | ||
| 44 | static enum smi_action __smi_handle_dr_smp_send(u8 node_type, int port_num, | 44 | static enum smi_action __smi_handle_dr_smp_send(bool is_switch, int port_num, |
| 45 | u8 *hop_ptr, u8 hop_cnt, | 45 | u8 *hop_ptr, u8 hop_cnt, |
| 46 | const u8 *initial_path, | 46 | const u8 *initial_path, |
| 47 | const u8 *return_path, | 47 | const u8 *return_path, |
| @@ -64,7 +64,7 @@ static enum smi_action __smi_handle_dr_smp_send(u8 node_type, int port_num, | |||
| 64 | 64 | ||
| 65 | /* C14-9:2 */ | 65 | /* C14-9:2 */ |
| 66 | if (*hop_ptr && *hop_ptr < hop_cnt) { | 66 | if (*hop_ptr && *hop_ptr < hop_cnt) { |
| 67 | if (node_type != RDMA_NODE_IB_SWITCH) | 67 | if (!is_switch) |
| 68 | return IB_SMI_DISCARD; | 68 | return IB_SMI_DISCARD; |
| 69 | 69 | ||
| 70 | /* return_path set when received */ | 70 | /* return_path set when received */ |
| @@ -77,7 +77,7 @@ static enum smi_action __smi_handle_dr_smp_send(u8 node_type, int port_num, | |||
| 77 | if (*hop_ptr == hop_cnt) { | 77 | if (*hop_ptr == hop_cnt) { |
| 78 | /* return_path set when received */ | 78 | /* return_path set when received */ |
| 79 | (*hop_ptr)++; | 79 | (*hop_ptr)++; |
| 80 | return (node_type == RDMA_NODE_IB_SWITCH || | 80 | return (is_switch || |
| 81 | dr_dlid_is_permissive ? | 81 | dr_dlid_is_permissive ? |
| 82 | IB_SMI_HANDLE : IB_SMI_DISCARD); | 82 | IB_SMI_HANDLE : IB_SMI_DISCARD); |
| 83 | } | 83 | } |
| @@ -96,7 +96,7 @@ static enum smi_action __smi_handle_dr_smp_send(u8 node_type, int port_num, | |||
| 96 | 96 | ||
| 97 | /* C14-13:2 */ | 97 | /* C14-13:2 */ |
| 98 | if (2 <= *hop_ptr && *hop_ptr <= hop_cnt) { | 98 | if (2 <= *hop_ptr && *hop_ptr <= hop_cnt) { |
| 99 | if (node_type != RDMA_NODE_IB_SWITCH) | 99 | if (!is_switch) |
| 100 | return IB_SMI_DISCARD; | 100 | return IB_SMI_DISCARD; |
| 101 | 101 | ||
| 102 | (*hop_ptr)--; | 102 | (*hop_ptr)--; |
| @@ -108,7 +108,7 @@ static enum smi_action __smi_handle_dr_smp_send(u8 node_type, int port_num, | |||
| 108 | if (*hop_ptr == 1) { | 108 | if (*hop_ptr == 1) { |
| 109 | (*hop_ptr)--; | 109 | (*hop_ptr)--; |
| 110 | /* C14-13:3 -- SMPs destined for SM shouldn't be here */ | 110 | /* C14-13:3 -- SMPs destined for SM shouldn't be here */ |
| 111 | return (node_type == RDMA_NODE_IB_SWITCH || | 111 | return (is_switch || |
| 112 | dr_slid_is_permissive ? | 112 | dr_slid_is_permissive ? |
| 113 | IB_SMI_HANDLE : IB_SMI_DISCARD); | 113 | IB_SMI_HANDLE : IB_SMI_DISCARD); |
| 114 | } | 114 | } |
| @@ -127,9 +127,9 @@ static enum smi_action __smi_handle_dr_smp_send(u8 node_type, int port_num, | |||
| 127 | * Return IB_SMI_DISCARD if the SMP should be discarded | 127 | * Return IB_SMI_DISCARD if the SMP should be discarded |
| 128 | */ | 128 | */ |
| 129 | enum smi_action smi_handle_dr_smp_send(struct ib_smp *smp, | 129 | enum smi_action smi_handle_dr_smp_send(struct ib_smp *smp, |
| 130 | u8 node_type, int port_num) | 130 | bool is_switch, int port_num) |
| 131 | { | 131 | { |
| 132 | return __smi_handle_dr_smp_send(node_type, port_num, | 132 | return __smi_handle_dr_smp_send(is_switch, port_num, |
| 133 | &smp->hop_ptr, smp->hop_cnt, | 133 | &smp->hop_ptr, smp->hop_cnt, |
| 134 | smp->initial_path, | 134 | smp->initial_path, |
| 135 | smp->return_path, | 135 | smp->return_path, |
| @@ -139,9 +139,9 @@ enum smi_action smi_handle_dr_smp_send(struct ib_smp *smp, | |||
| 139 | } | 139 | } |
| 140 | 140 | ||
| 141 | enum smi_action opa_smi_handle_dr_smp_send(struct opa_smp *smp, | 141 | enum smi_action opa_smi_handle_dr_smp_send(struct opa_smp *smp, |
| 142 | u8 node_type, int port_num) | 142 | bool is_switch, int port_num) |
| 143 | { | 143 | { |
| 144 | return __smi_handle_dr_smp_send(node_type, port_num, | 144 | return __smi_handle_dr_smp_send(is_switch, port_num, |
| 145 | &smp->hop_ptr, smp->hop_cnt, | 145 | &smp->hop_ptr, smp->hop_cnt, |
| 146 | smp->route.dr.initial_path, | 146 | smp->route.dr.initial_path, |
| 147 | smp->route.dr.return_path, | 147 | smp->route.dr.return_path, |
| @@ -152,7 +152,7 @@ enum smi_action opa_smi_handle_dr_smp_send(struct opa_smp *smp, | |||
| 152 | OPA_LID_PERMISSIVE); | 152 | OPA_LID_PERMISSIVE); |
| 153 | } | 153 | } |
| 154 | 154 | ||
| 155 | static enum smi_action __smi_handle_dr_smp_recv(u8 node_type, int port_num, | 155 | static enum smi_action __smi_handle_dr_smp_recv(bool is_switch, int port_num, |
| 156 | int phys_port_cnt, | 156 | int phys_port_cnt, |
| 157 | u8 *hop_ptr, u8 hop_cnt, | 157 | u8 *hop_ptr, u8 hop_cnt, |
| 158 | const u8 *initial_path, | 158 | const u8 *initial_path, |
| @@ -173,7 +173,7 @@ static enum smi_action __smi_handle_dr_smp_recv(u8 node_type, int port_num, | |||
| 173 | 173 | ||
| 174 | /* C14-9:2 -- intermediate hop */ | 174 | /* C14-9:2 -- intermediate hop */ |
| 175 | if (*hop_ptr && *hop_ptr < hop_cnt) { | 175 | if (*hop_ptr && *hop_ptr < hop_cnt) { |
| 176 | if (node_type != RDMA_NODE_IB_SWITCH) | 176 | if (!is_switch) |
| 177 | return IB_SMI_DISCARD; | 177 | return IB_SMI_DISCARD; |
| 178 | 178 | ||
| 179 | return_path[*hop_ptr] = port_num; | 179 | return_path[*hop_ptr] = port_num; |
| @@ -188,7 +188,7 @@ static enum smi_action __smi_handle_dr_smp_recv(u8 node_type, int port_num, | |||
| 188 | return_path[*hop_ptr] = port_num; | 188 | return_path[*hop_ptr] = port_num; |
| 189 | /* hop_ptr updated when sending */ | 189 | /* hop_ptr updated when sending */ |
| 190 | 190 | ||
| 191 | return (node_type == RDMA_NODE_IB_SWITCH || | 191 | return (is_switch || |
| 192 | dr_dlid_is_permissive ? | 192 | dr_dlid_is_permissive ? |
| 193 | IB_SMI_HANDLE : IB_SMI_DISCARD); | 193 | IB_SMI_HANDLE : IB_SMI_DISCARD); |
| 194 | } | 194 | } |
| @@ -208,7 +208,7 @@ static enum smi_action __smi_handle_dr_smp_recv(u8 node_type, int port_num, | |||
| 208 | 208 | ||
| 209 | /* C14-13:2 */ | 209 | /* C14-13:2 */ |
| 210 | if (2 <= *hop_ptr && *hop_ptr <= hop_cnt) { | 210 | if (2 <= *hop_ptr && *hop_ptr <= hop_cnt) { |
| 211 | if (node_type != RDMA_NODE_IB_SWITCH) | 211 | if (!is_switch) |
| 212 | return IB_SMI_DISCARD; | 212 | return IB_SMI_DISCARD; |
| 213 | 213 | ||
| 214 | /* hop_ptr updated when sending */ | 214 | /* hop_ptr updated when sending */ |
| @@ -224,8 +224,7 @@ static enum smi_action __smi_handle_dr_smp_recv(u8 node_type, int port_num, | |||
| 224 | return IB_SMI_HANDLE; | 224 | return IB_SMI_HANDLE; |
| 225 | } | 225 | } |
| 226 | /* hop_ptr updated when sending */ | 226 | /* hop_ptr updated when sending */ |
| 227 | return (node_type == RDMA_NODE_IB_SWITCH ? | 227 | return (is_switch ? IB_SMI_HANDLE : IB_SMI_DISCARD); |
| 228 | IB_SMI_HANDLE : IB_SMI_DISCARD); | ||
| 229 | } | 228 | } |
| 230 | 229 | ||
| 231 | /* C14-13:4 -- hop_ptr = 0 -> give to SM */ | 230 | /* C14-13:4 -- hop_ptr = 0 -> give to SM */ |
| @@ -238,10 +237,10 @@ static enum smi_action __smi_handle_dr_smp_recv(u8 node_type, int port_num, | |||
| 238 | * Adjust information for a received SMP | 237 | * Adjust information for a received SMP |
| 239 | * Return IB_SMI_DISCARD if the SMP should be dropped | 238 | * Return IB_SMI_DISCARD if the SMP should be dropped |
| 240 | */ | 239 | */ |
| 241 | enum smi_action smi_handle_dr_smp_recv(struct ib_smp *smp, u8 node_type, | 240 | enum smi_action smi_handle_dr_smp_recv(struct ib_smp *smp, bool is_switch, |
| 242 | int port_num, int phys_port_cnt) | 241 | int port_num, int phys_port_cnt) |
| 243 | { | 242 | { |
| 244 | return __smi_handle_dr_smp_recv(node_type, port_num, phys_port_cnt, | 243 | return __smi_handle_dr_smp_recv(is_switch, port_num, phys_port_cnt, |
| 245 | &smp->hop_ptr, smp->hop_cnt, | 244 | &smp->hop_ptr, smp->hop_cnt, |
| 246 | smp->initial_path, | 245 | smp->initial_path, |
| 247 | smp->return_path, | 246 | smp->return_path, |
| @@ -254,10 +253,10 @@ enum smi_action smi_handle_dr_smp_recv(struct ib_smp *smp, u8 node_type, | |||
| 254 | * Adjust information for a received SMP | 253 | * Adjust information for a received SMP |
| 255 | * Return IB_SMI_DISCARD if the SMP should be dropped | 254 | * Return IB_SMI_DISCARD if the SMP should be dropped |
| 256 | */ | 255 | */ |
| 257 | enum smi_action opa_smi_handle_dr_smp_recv(struct opa_smp *smp, u8 node_type, | 256 | enum smi_action opa_smi_handle_dr_smp_recv(struct opa_smp *smp, bool is_switch, |
| 258 | int port_num, int phys_port_cnt) | 257 | int port_num, int phys_port_cnt) |
| 259 | { | 258 | { |
| 260 | return __smi_handle_dr_smp_recv(node_type, port_num, phys_port_cnt, | 259 | return __smi_handle_dr_smp_recv(is_switch, port_num, phys_port_cnt, |
| 261 | &smp->hop_ptr, smp->hop_cnt, | 260 | &smp->hop_ptr, smp->hop_cnt, |
| 262 | smp->route.dr.initial_path, | 261 | smp->route.dr.initial_path, |
| 263 | smp->route.dr.return_path, | 262 | smp->route.dr.return_path, |
diff --git a/drivers/infiniband/core/smi.h b/drivers/infiniband/core/smi.h index aff96bac49b4..33c91c8a16e9 100644 --- a/drivers/infiniband/core/smi.h +++ b/drivers/infiniband/core/smi.h | |||
| @@ -51,12 +51,12 @@ enum smi_forward_action { | |||
| 51 | IB_SMI_FORWARD /* SMP should be forwarded (for switches only) */ | 51 | IB_SMI_FORWARD /* SMP should be forwarded (for switches only) */ |
| 52 | }; | 52 | }; |
| 53 | 53 | ||
| 54 | enum smi_action smi_handle_dr_smp_recv(struct ib_smp *smp, u8 node_type, | 54 | enum smi_action smi_handle_dr_smp_recv(struct ib_smp *smp, bool is_switch, |
| 55 | int port_num, int phys_port_cnt); | 55 | int port_num, int phys_port_cnt); |
| 56 | int smi_get_fwd_port(struct ib_smp *smp); | 56 | int smi_get_fwd_port(struct ib_smp *smp); |
| 57 | extern enum smi_forward_action smi_check_forward_dr_smp(struct ib_smp *smp); | 57 | extern enum smi_forward_action smi_check_forward_dr_smp(struct ib_smp *smp); |
| 58 | extern enum smi_action smi_handle_dr_smp_send(struct ib_smp *smp, | 58 | extern enum smi_action smi_handle_dr_smp_send(struct ib_smp *smp, |
| 59 | u8 node_type, int port_num); | 59 | bool is_switch, int port_num); |
| 60 | 60 | ||
| 61 | /* | 61 | /* |
| 62 | * Return IB_SMI_HANDLE if the SMP should be handled by the local SMA/SM | 62 | * Return IB_SMI_HANDLE if the SMP should be handled by the local SMA/SM |
diff --git a/drivers/infiniband/core/sysfs.c b/drivers/infiniband/core/sysfs.c index ed6b6c85c334..0b84a9cdfe5b 100644 --- a/drivers/infiniband/core/sysfs.c +++ b/drivers/infiniband/core/sysfs.c | |||
| @@ -870,7 +870,7 @@ int ib_device_register_sysfs(struct ib_device *device, | |||
| 870 | goto err_put; | 870 | goto err_put; |
| 871 | } | 871 | } |
| 872 | 872 | ||
| 873 | if (device->node_type == RDMA_NODE_IB_SWITCH) { | 873 | if (rdma_cap_ib_switch(device)) { |
| 874 | ret = add_port(device, 0, port_callback); | 874 | ret = add_port(device, 0, port_callback); |
| 875 | if (ret) | 875 | if (ret) |
| 876 | goto err_put; | 876 | goto err_put; |
diff --git a/drivers/infiniband/core/ucm.c b/drivers/infiniband/core/ucm.c index 62c24b1452b8..009481073644 100644 --- a/drivers/infiniband/core/ucm.c +++ b/drivers/infiniband/core/ucm.c | |||
| @@ -1193,6 +1193,7 @@ static int ib_ucm_close(struct inode *inode, struct file *filp) | |||
| 1193 | return 0; | 1193 | return 0; |
| 1194 | } | 1194 | } |
| 1195 | 1195 | ||
| 1196 | static DECLARE_BITMAP(overflow_map, IB_UCM_MAX_DEVICES); | ||
| 1196 | static void ib_ucm_release_dev(struct device *dev) | 1197 | static void ib_ucm_release_dev(struct device *dev) |
| 1197 | { | 1198 | { |
| 1198 | struct ib_ucm_device *ucm_dev; | 1199 | struct ib_ucm_device *ucm_dev; |
| @@ -1202,7 +1203,7 @@ static void ib_ucm_release_dev(struct device *dev) | |||
| 1202 | if (ucm_dev->devnum < IB_UCM_MAX_DEVICES) | 1203 | if (ucm_dev->devnum < IB_UCM_MAX_DEVICES) |
| 1203 | clear_bit(ucm_dev->devnum, dev_map); | 1204 | clear_bit(ucm_dev->devnum, dev_map); |
| 1204 | else | 1205 | else |
| 1205 | clear_bit(ucm_dev->devnum - IB_UCM_MAX_DEVICES, dev_map); | 1206 | clear_bit(ucm_dev->devnum - IB_UCM_MAX_DEVICES, overflow_map); |
| 1206 | kfree(ucm_dev); | 1207 | kfree(ucm_dev); |
| 1207 | } | 1208 | } |
| 1208 | 1209 | ||
| @@ -1226,7 +1227,6 @@ static ssize_t show_ibdev(struct device *dev, struct device_attribute *attr, | |||
| 1226 | static DEVICE_ATTR(ibdev, S_IRUGO, show_ibdev, NULL); | 1227 | static DEVICE_ATTR(ibdev, S_IRUGO, show_ibdev, NULL); |
| 1227 | 1228 | ||
| 1228 | static dev_t overflow_maj; | 1229 | static dev_t overflow_maj; |
| 1229 | static DECLARE_BITMAP(overflow_map, IB_UCM_MAX_DEVICES); | ||
| 1230 | static int find_overflow_devnum(void) | 1230 | static int find_overflow_devnum(void) |
| 1231 | { | 1231 | { |
| 1232 | int ret; | 1232 | int ret; |
diff --git a/drivers/infiniband/core/ucma.c b/drivers/infiniband/core/ucma.c index ad45469f7582..29b21213ea75 100644 --- a/drivers/infiniband/core/ucma.c +++ b/drivers/infiniband/core/ucma.c | |||
| @@ -1354,10 +1354,10 @@ static void ucma_lock_files(struct ucma_file *file1, struct ucma_file *file2) | |||
| 1354 | /* Acquire mutex's based on pointer comparison to prevent deadlock. */ | 1354 | /* Acquire mutex's based on pointer comparison to prevent deadlock. */ |
| 1355 | if (file1 < file2) { | 1355 | if (file1 < file2) { |
| 1356 | mutex_lock(&file1->mut); | 1356 | mutex_lock(&file1->mut); |
| 1357 | mutex_lock(&file2->mut); | 1357 | mutex_lock_nested(&file2->mut, SINGLE_DEPTH_NESTING); |
| 1358 | } else { | 1358 | } else { |
| 1359 | mutex_lock(&file2->mut); | 1359 | mutex_lock(&file2->mut); |
| 1360 | mutex_lock(&file1->mut); | 1360 | mutex_lock_nested(&file1->mut, SINGLE_DEPTH_NESTING); |
| 1361 | } | 1361 | } |
| 1362 | } | 1362 | } |
| 1363 | 1363 | ||
| @@ -1616,6 +1616,7 @@ static void __exit ucma_cleanup(void) | |||
| 1616 | device_remove_file(ucma_misc.this_device, &dev_attr_abi_version); | 1616 | device_remove_file(ucma_misc.this_device, &dev_attr_abi_version); |
| 1617 | misc_deregister(&ucma_misc); | 1617 | misc_deregister(&ucma_misc); |
| 1618 | idr_destroy(&ctx_idr); | 1618 | idr_destroy(&ctx_idr); |
| 1619 | idr_destroy(&multicast_idr); | ||
| 1619 | } | 1620 | } |
| 1620 | 1621 | ||
| 1621 | module_init(ucma_init); | 1622 | module_init(ucma_init); |
diff --git a/drivers/infiniband/hw/ehca/ehca_sqp.c b/drivers/infiniband/hw/ehca/ehca_sqp.c index 12b5bc23832b..376b031c2c7f 100644 --- a/drivers/infiniband/hw/ehca/ehca_sqp.c +++ b/drivers/infiniband/hw/ehca/ehca_sqp.c | |||
| @@ -226,8 +226,9 @@ int ehca_process_mad(struct ib_device *ibdev, int mad_flags, u8 port_num, | |||
| 226 | const struct ib_mad *in_mad = (const struct ib_mad *)in; | 226 | const struct ib_mad *in_mad = (const struct ib_mad *)in; |
| 227 | struct ib_mad *out_mad = (struct ib_mad *)out; | 227 | struct ib_mad *out_mad = (struct ib_mad *)out; |
| 228 | 228 | ||
| 229 | BUG_ON(in_mad_size != sizeof(*in_mad) || | 229 | if (WARN_ON_ONCE(in_mad_size != sizeof(*in_mad) || |
| 230 | *out_mad_size != sizeof(*out_mad)); | 230 | *out_mad_size != sizeof(*out_mad))) |
| 231 | return IB_MAD_RESULT_FAILURE; | ||
| 231 | 232 | ||
| 232 | if (!port_num || port_num > ibdev->phys_port_cnt || !in_wc) | 233 | if (!port_num || port_num > ibdev->phys_port_cnt || !in_wc) |
| 233 | return IB_MAD_RESULT_FAILURE; | 234 | return IB_MAD_RESULT_FAILURE; |
diff --git a/drivers/infiniband/hw/ipath/ipath_mad.c b/drivers/infiniband/hw/ipath/ipath_mad.c index 948188e37f95..ad3a926ab3c5 100644 --- a/drivers/infiniband/hw/ipath/ipath_mad.c +++ b/drivers/infiniband/hw/ipath/ipath_mad.c | |||
| @@ -1499,8 +1499,9 @@ int ipath_process_mad(struct ib_device *ibdev, int mad_flags, u8 port_num, | |||
| 1499 | const struct ib_mad *in_mad = (const struct ib_mad *)in; | 1499 | const struct ib_mad *in_mad = (const struct ib_mad *)in; |
| 1500 | struct ib_mad *out_mad = (struct ib_mad *)out; | 1500 | struct ib_mad *out_mad = (struct ib_mad *)out; |
| 1501 | 1501 | ||
| 1502 | BUG_ON(in_mad_size != sizeof(*in_mad) || | 1502 | if (WARN_ON_ONCE(in_mad_size != sizeof(*in_mad) || |
| 1503 | *out_mad_size != sizeof(*out_mad)); | 1503 | *out_mad_size != sizeof(*out_mad))) |
| 1504 | return IB_MAD_RESULT_FAILURE; | ||
| 1504 | 1505 | ||
| 1505 | switch (in_mad->mad_hdr.mgmt_class) { | 1506 | switch (in_mad->mad_hdr.mgmt_class) { |
| 1506 | case IB_MGMT_CLASS_SUBN_DIRECTED_ROUTE: | 1507 | case IB_MGMT_CLASS_SUBN_DIRECTED_ROUTE: |
diff --git a/drivers/infiniband/hw/ipath/ipath_verbs.c b/drivers/infiniband/hw/ipath/ipath_verbs.c index 48253b839a6f..30ba49c4a98c 100644 --- a/drivers/infiniband/hw/ipath/ipath_verbs.c +++ b/drivers/infiniband/hw/ipath/ipath_verbs.c | |||
| @@ -2044,9 +2044,9 @@ int ipath_register_ib_device(struct ipath_devdata *dd) | |||
| 2044 | 2044 | ||
| 2045 | spin_lock_init(&idev->qp_table.lock); | 2045 | spin_lock_init(&idev->qp_table.lock); |
| 2046 | spin_lock_init(&idev->lk_table.lock); | 2046 | spin_lock_init(&idev->lk_table.lock); |
| 2047 | idev->sm_lid = __constant_be16_to_cpu(IB_LID_PERMISSIVE); | 2047 | idev->sm_lid = be16_to_cpu(IB_LID_PERMISSIVE); |
| 2048 | /* Set the prefix to the default value (see ch. 4.1.1) */ | 2048 | /* Set the prefix to the default value (see ch. 4.1.1) */ |
| 2049 | idev->gid_prefix = __constant_cpu_to_be64(0xfe80000000000000ULL); | 2049 | idev->gid_prefix = cpu_to_be64(0xfe80000000000000ULL); |
| 2050 | 2050 | ||
| 2051 | ret = ipath_init_qp_table(idev, ib_ipath_qp_table_size); | 2051 | ret = ipath_init_qp_table(idev, ib_ipath_qp_table_size); |
| 2052 | if (ret) | 2052 | if (ret) |
diff --git a/drivers/infiniband/hw/mlx4/mad.c b/drivers/infiniband/hw/mlx4/mad.c index 85a50df2f203..68b3dfa922bf 100644 --- a/drivers/infiniband/hw/mlx4/mad.c +++ b/drivers/infiniband/hw/mlx4/mad.c | |||
| @@ -860,21 +860,31 @@ int mlx4_ib_process_mad(struct ib_device *ibdev, int mad_flags, u8 port_num, | |||
| 860 | struct mlx4_ib_dev *dev = to_mdev(ibdev); | 860 | struct mlx4_ib_dev *dev = to_mdev(ibdev); |
| 861 | const struct ib_mad *in_mad = (const struct ib_mad *)in; | 861 | const struct ib_mad *in_mad = (const struct ib_mad *)in; |
| 862 | struct ib_mad *out_mad = (struct ib_mad *)out; | 862 | struct ib_mad *out_mad = (struct ib_mad *)out; |
| 863 | enum rdma_link_layer link = rdma_port_get_link_layer(ibdev, port_num); | ||
| 863 | 864 | ||
| 864 | BUG_ON(in_mad_size != sizeof(*in_mad) || | 865 | if (WARN_ON_ONCE(in_mad_size != sizeof(*in_mad) || |
| 865 | *out_mad_size != sizeof(*out_mad)); | 866 | *out_mad_size != sizeof(*out_mad))) |
| 867 | return IB_MAD_RESULT_FAILURE; | ||
| 866 | 868 | ||
| 867 | switch (rdma_port_get_link_layer(ibdev, port_num)) { | 869 | /* iboe_process_mad() which uses the HCA flow-counters to implement IB PMA |
| 868 | case IB_LINK_LAYER_INFINIBAND: | 870 | * queries, should be called only by VFs and for that specific purpose |
| 869 | if (!mlx4_is_slave(dev->dev)) | 871 | */ |
| 870 | return ib_process_mad(ibdev, mad_flags, port_num, in_wc, | 872 | if (link == IB_LINK_LAYER_INFINIBAND) { |
| 871 | in_grh, in_mad, out_mad); | 873 | if (mlx4_is_slave(dev->dev) && |
| 872 | case IB_LINK_LAYER_ETHERNET: | 874 | in_mad->mad_hdr.mgmt_class == IB_MGMT_CLASS_PERF_MGMT && |
| 873 | return iboe_process_mad(ibdev, mad_flags, port_num, in_wc, | 875 | in_mad->mad_hdr.attr_id == IB_PMA_PORT_COUNTERS) |
| 874 | in_grh, in_mad, out_mad); | 876 | return iboe_process_mad(ibdev, mad_flags, port_num, in_wc, |
| 875 | default: | 877 | in_grh, in_mad, out_mad); |
| 876 | return -EINVAL; | 878 | |
| 879 | return ib_process_mad(ibdev, mad_flags, port_num, in_wc, | ||
| 880 | in_grh, in_mad, out_mad); | ||
| 877 | } | 881 | } |
| 882 | |||
| 883 | if (link == IB_LINK_LAYER_ETHERNET) | ||
| 884 | return iboe_process_mad(ibdev, mad_flags, port_num, in_wc, | ||
| 885 | in_grh, in_mad, out_mad); | ||
| 886 | |||
| 887 | return -EINVAL; | ||
| 878 | } | 888 | } |
| 879 | 889 | ||
| 880 | static void send_handler(struct ib_mad_agent *agent, | 890 | static void send_handler(struct ib_mad_agent *agent, |
diff --git a/drivers/infiniband/hw/mlx4/main.c b/drivers/infiniband/hw/mlx4/main.c index 067a691ecbed..8be6db816460 100644 --- a/drivers/infiniband/hw/mlx4/main.c +++ b/drivers/infiniband/hw/mlx4/main.c | |||
| @@ -253,14 +253,15 @@ static int mlx4_ib_query_device(struct ib_device *ibdev, | |||
| 253 | props->hca_core_clock = dev->dev->caps.hca_core_clock * 1000UL; | 253 | props->hca_core_clock = dev->dev->caps.hca_core_clock * 1000UL; |
| 254 | props->timestamp_mask = 0xFFFFFFFFFFFFULL; | 254 | props->timestamp_mask = 0xFFFFFFFFFFFFULL; |
| 255 | 255 | ||
| 256 | err = mlx4_get_internal_clock_params(dev->dev, &clock_params); | 256 | if (!mlx4_is_slave(dev->dev)) |
| 257 | if (err) | 257 | err = mlx4_get_internal_clock_params(dev->dev, &clock_params); |
| 258 | goto out; | ||
| 259 | 258 | ||
| 260 | if (uhw->outlen >= resp.response_length + sizeof(resp.hca_core_clock_offset)) { | 259 | if (uhw->outlen >= resp.response_length + sizeof(resp.hca_core_clock_offset)) { |
| 261 | resp.hca_core_clock_offset = clock_params.offset % PAGE_SIZE; | ||
| 262 | resp.response_length += sizeof(resp.hca_core_clock_offset); | 260 | resp.response_length += sizeof(resp.hca_core_clock_offset); |
| 263 | resp.comp_mask |= QUERY_DEVICE_RESP_MASK_TIMESTAMP; | 261 | if (!err && !mlx4_is_slave(dev->dev)) { |
| 262 | resp.comp_mask |= QUERY_DEVICE_RESP_MASK_TIMESTAMP; | ||
| 263 | resp.hca_core_clock_offset = clock_params.offset % PAGE_SIZE; | ||
| 264 | } | ||
| 264 | } | 265 | } |
| 265 | 266 | ||
| 266 | if (uhw->outlen) { | 267 | if (uhw->outlen) { |
| @@ -2669,31 +2670,33 @@ static void do_slave_init(struct mlx4_ib_dev *ibdev, int slave, int do_init) | |||
| 2669 | dm = kcalloc(ports, sizeof(*dm), GFP_ATOMIC); | 2670 | dm = kcalloc(ports, sizeof(*dm), GFP_ATOMIC); |
| 2670 | if (!dm) { | 2671 | if (!dm) { |
| 2671 | pr_err("failed to allocate memory for tunneling qp update\n"); | 2672 | pr_err("failed to allocate memory for tunneling qp update\n"); |
| 2672 | goto out; | 2673 | return; |
| 2673 | } | 2674 | } |
| 2674 | 2675 | ||
| 2675 | for (i = 0; i < ports; i++) { | 2676 | for (i = 0; i < ports; i++) { |
| 2676 | dm[i] = kmalloc(sizeof (struct mlx4_ib_demux_work), GFP_ATOMIC); | 2677 | dm[i] = kmalloc(sizeof (struct mlx4_ib_demux_work), GFP_ATOMIC); |
| 2677 | if (!dm[i]) { | 2678 | if (!dm[i]) { |
| 2678 | pr_err("failed to allocate memory for tunneling qp update work struct\n"); | 2679 | pr_err("failed to allocate memory for tunneling qp update work struct\n"); |
| 2679 | for (i = 0; i < dev->caps.num_ports; i++) { | 2680 | while (--i >= 0) |
| 2680 | if (dm[i]) | 2681 | kfree(dm[i]); |
| 2681 | kfree(dm[i]); | ||
| 2682 | } | ||
| 2683 | goto out; | 2682 | goto out; |
| 2684 | } | 2683 | } |
| 2685 | } | ||
| 2686 | /* initialize or tear down tunnel QPs for the slave */ | ||
| 2687 | for (i = 0; i < ports; i++) { | ||
| 2688 | INIT_WORK(&dm[i]->work, mlx4_ib_tunnels_update_work); | 2684 | INIT_WORK(&dm[i]->work, mlx4_ib_tunnels_update_work); |
| 2689 | dm[i]->port = first_port + i + 1; | 2685 | dm[i]->port = first_port + i + 1; |
| 2690 | dm[i]->slave = slave; | 2686 | dm[i]->slave = slave; |
| 2691 | dm[i]->do_init = do_init; | 2687 | dm[i]->do_init = do_init; |
| 2692 | dm[i]->dev = ibdev; | 2688 | dm[i]->dev = ibdev; |
| 2693 | spin_lock_irqsave(&ibdev->sriov.going_down_lock, flags); | 2689 | } |
| 2694 | if (!ibdev->sriov.is_going_down) | 2690 | /* initialize or tear down tunnel QPs for the slave */ |
| 2691 | spin_lock_irqsave(&ibdev->sriov.going_down_lock, flags); | ||
| 2692 | if (!ibdev->sriov.is_going_down) { | ||
| 2693 | for (i = 0; i < ports; i++) | ||
| 2695 | queue_work(ibdev->sriov.demux[i].ud_wq, &dm[i]->work); | 2694 | queue_work(ibdev->sriov.demux[i].ud_wq, &dm[i]->work); |
| 2696 | spin_unlock_irqrestore(&ibdev->sriov.going_down_lock, flags); | 2695 | spin_unlock_irqrestore(&ibdev->sriov.going_down_lock, flags); |
| 2696 | } else { | ||
| 2697 | spin_unlock_irqrestore(&ibdev->sriov.going_down_lock, flags); | ||
| 2698 | for (i = 0; i < ports; i++) | ||
| 2699 | kfree(dm[i]); | ||
| 2697 | } | 2700 | } |
| 2698 | out: | 2701 | out: |
| 2699 | kfree(dm); | 2702 | kfree(dm); |
diff --git a/drivers/infiniband/hw/mlx5/mad.c b/drivers/infiniband/hw/mlx5/mad.c index 01fc97db45d6..b84d13a487cc 100644 --- a/drivers/infiniband/hw/mlx5/mad.c +++ b/drivers/infiniband/hw/mlx5/mad.c | |||
| @@ -68,8 +68,9 @@ int mlx5_ib_process_mad(struct ib_device *ibdev, int mad_flags, u8 port_num, | |||
| 68 | const struct ib_mad *in_mad = (const struct ib_mad *)in; | 68 | const struct ib_mad *in_mad = (const struct ib_mad *)in; |
| 69 | struct ib_mad *out_mad = (struct ib_mad *)out; | 69 | struct ib_mad *out_mad = (struct ib_mad *)out; |
| 70 | 70 | ||
| 71 | BUG_ON(in_mad_size != sizeof(*in_mad) || | 71 | if (WARN_ON_ONCE(in_mad_size != sizeof(*in_mad) || |
| 72 | *out_mad_size != sizeof(*out_mad)); | 72 | *out_mad_size != sizeof(*out_mad))) |
| 73 | return IB_MAD_RESULT_FAILURE; | ||
| 73 | 74 | ||
| 74 | slid = in_wc ? in_wc->slid : be16_to_cpu(IB_LID_PERMISSIVE); | 75 | slid = in_wc ? in_wc->slid : be16_to_cpu(IB_LID_PERMISSIVE); |
| 75 | 76 | ||
diff --git a/drivers/infiniband/hw/mthca/mthca_mad.c b/drivers/infiniband/hw/mthca/mthca_mad.c index 6b2418b74c99..7c3f2fb44ba5 100644 --- a/drivers/infiniband/hw/mthca/mthca_mad.c +++ b/drivers/infiniband/hw/mthca/mthca_mad.c | |||
| @@ -209,8 +209,9 @@ int mthca_process_mad(struct ib_device *ibdev, | |||
| 209 | const struct ib_mad *in_mad = (const struct ib_mad *)in; | 209 | const struct ib_mad *in_mad = (const struct ib_mad *)in; |
| 210 | struct ib_mad *out_mad = (struct ib_mad *)out; | 210 | struct ib_mad *out_mad = (struct ib_mad *)out; |
| 211 | 211 | ||
| 212 | BUG_ON(in_mad_size != sizeof(*in_mad) || | 212 | if (WARN_ON_ONCE(in_mad_size != sizeof(*in_mad) || |
| 213 | *out_mad_size != sizeof(*out_mad)); | 213 | *out_mad_size != sizeof(*out_mad))) |
| 214 | return IB_MAD_RESULT_FAILURE; | ||
| 214 | 215 | ||
| 215 | /* Forward locally generated traps to the SM */ | 216 | /* Forward locally generated traps to the SM */ |
| 216 | if (in_mad->mad_hdr.method == IB_MGMT_METHOD_TRAP && | 217 | if (in_mad->mad_hdr.method == IB_MGMT_METHOD_TRAP && |
diff --git a/drivers/infiniband/hw/nes/nes_cm.c b/drivers/infiniband/hw/nes/nes_cm.c index 9047af429906..8a3ad170d790 100644 --- a/drivers/infiniband/hw/nes/nes_cm.c +++ b/drivers/infiniband/hw/nes/nes_cm.c | |||
| @@ -1520,8 +1520,9 @@ static int nes_addr_resolve_neigh(struct nes_vnic *nesvnic, u32 dst_ip, int arpi | |||
| 1520 | int rc = arpindex; | 1520 | int rc = arpindex; |
| 1521 | struct net_device *netdev; | 1521 | struct net_device *netdev; |
| 1522 | struct nes_adapter *nesadapter = nesvnic->nesdev->nesadapter; | 1522 | struct nes_adapter *nesadapter = nesvnic->nesdev->nesadapter; |
| 1523 | __be32 dst_ipaddr = htonl(dst_ip); | ||
| 1523 | 1524 | ||
| 1524 | rt = ip_route_output(&init_net, htonl(dst_ip), 0, 0, 0); | 1525 | rt = ip_route_output(&init_net, dst_ipaddr, nesvnic->local_ipaddr, 0, 0); |
| 1525 | if (IS_ERR(rt)) { | 1526 | if (IS_ERR(rt)) { |
| 1526 | printk(KERN_ERR "%s: ip_route_output_key failed for 0x%08X\n", | 1527 | printk(KERN_ERR "%s: ip_route_output_key failed for 0x%08X\n", |
| 1527 | __func__, dst_ip); | 1528 | __func__, dst_ip); |
| @@ -1533,7 +1534,7 @@ static int nes_addr_resolve_neigh(struct nes_vnic *nesvnic, u32 dst_ip, int arpi | |||
| 1533 | else | 1534 | else |
| 1534 | netdev = nesvnic->netdev; | 1535 | netdev = nesvnic->netdev; |
| 1535 | 1536 | ||
| 1536 | neigh = neigh_lookup(&arp_tbl, &rt->rt_gateway, netdev); | 1537 | neigh = dst_neigh_lookup(&rt->dst, &dst_ipaddr); |
| 1537 | 1538 | ||
| 1538 | rcu_read_lock(); | 1539 | rcu_read_lock(); |
| 1539 | if (neigh) { | 1540 | if (neigh) { |
diff --git a/drivers/infiniband/hw/nes/nes_hw.c b/drivers/infiniband/hw/nes/nes_hw.c index 02120d340d50..4713dd7ed764 100644 --- a/drivers/infiniband/hw/nes/nes_hw.c +++ b/drivers/infiniband/hw/nes/nes_hw.c | |||
| @@ -3861,7 +3861,7 @@ void nes_manage_arp_cache(struct net_device *netdev, unsigned char *mac_addr, | |||
| 3861 | (((u32)mac_addr[2]) << 24) | (((u32)mac_addr[3]) << 16) | | 3861 | (((u32)mac_addr[2]) << 24) | (((u32)mac_addr[3]) << 16) | |
| 3862 | (((u32)mac_addr[4]) << 8) | (u32)mac_addr[5]); | 3862 | (((u32)mac_addr[4]) << 8) | (u32)mac_addr[5]); |
| 3863 | cqp_wqe->wqe_words[NES_CQP_ARP_WQE_MAC_HIGH_IDX] = cpu_to_le32( | 3863 | cqp_wqe->wqe_words[NES_CQP_ARP_WQE_MAC_HIGH_IDX] = cpu_to_le32( |
| 3864 | (((u32)mac_addr[0]) << 16) | (u32)mac_addr[1]); | 3864 | (((u32)mac_addr[0]) << 8) | (u32)mac_addr[1]); |
| 3865 | } else { | 3865 | } else { |
| 3866 | cqp_wqe->wqe_words[NES_CQP_ARP_WQE_MAC_ADDR_LOW_IDX] = 0; | 3866 | cqp_wqe->wqe_words[NES_CQP_ARP_WQE_MAC_ADDR_LOW_IDX] = 0; |
| 3867 | cqp_wqe->wqe_words[NES_CQP_ARP_WQE_MAC_HIGH_IDX] = 0; | 3867 | cqp_wqe->wqe_words[NES_CQP_ARP_WQE_MAC_HIGH_IDX] = 0; |
diff --git a/drivers/infiniband/hw/ocrdma/ocrdma_ah.c b/drivers/infiniband/hw/ocrdma/ocrdma_ah.c index 4bafa15708d0..29b27675dd70 100644 --- a/drivers/infiniband/hw/ocrdma/ocrdma_ah.c +++ b/drivers/infiniband/hw/ocrdma/ocrdma_ah.c | |||
| @@ -215,8 +215,9 @@ int ocrdma_process_mad(struct ib_device *ibdev, | |||
| 215 | const struct ib_mad *in_mad = (const struct ib_mad *)in; | 215 | const struct ib_mad *in_mad = (const struct ib_mad *)in; |
| 216 | struct ib_mad *out_mad = (struct ib_mad *)out; | 216 | struct ib_mad *out_mad = (struct ib_mad *)out; |
| 217 | 217 | ||
| 218 | BUG_ON(in_mad_size != sizeof(*in_mad) || | 218 | if (WARN_ON_ONCE(in_mad_size != sizeof(*in_mad) || |
| 219 | *out_mad_size != sizeof(*out_mad)); | 219 | *out_mad_size != sizeof(*out_mad))) |
| 220 | return IB_MAD_RESULT_FAILURE; | ||
| 220 | 221 | ||
| 221 | switch (in_mad->mad_hdr.mgmt_class) { | 222 | switch (in_mad->mad_hdr.mgmt_class) { |
| 222 | case IB_MGMT_CLASS_PERF_MGMT: | 223 | case IB_MGMT_CLASS_PERF_MGMT: |
diff --git a/drivers/infiniband/hw/ocrdma/ocrdma_main.c b/drivers/infiniband/hw/ocrdma/ocrdma_main.c index 8a1398b253a2..d98a707a5eb9 100644 --- a/drivers/infiniband/hw/ocrdma/ocrdma_main.c +++ b/drivers/infiniband/hw/ocrdma/ocrdma_main.c | |||
| @@ -696,6 +696,7 @@ static void __exit ocrdma_exit_module(void) | |||
| 696 | ocrdma_unregister_inet6addr_notifier(); | 696 | ocrdma_unregister_inet6addr_notifier(); |
| 697 | ocrdma_unregister_inetaddr_notifier(); | 697 | ocrdma_unregister_inetaddr_notifier(); |
| 698 | ocrdma_rem_debugfs(); | 698 | ocrdma_rem_debugfs(); |
| 699 | idr_destroy(&ocrdma_dev_id); | ||
| 699 | } | 700 | } |
| 700 | 701 | ||
| 701 | module_init(ocrdma_init_module); | 702 | module_init(ocrdma_init_module); |
diff --git a/drivers/infiniband/hw/qib/qib_mad.c b/drivers/infiniband/hw/qib/qib_mad.c index 05e3242d8442..9625e7c438e5 100644 --- a/drivers/infiniband/hw/qib/qib_mad.c +++ b/drivers/infiniband/hw/qib/qib_mad.c | |||
| @@ -2412,8 +2412,9 @@ int qib_process_mad(struct ib_device *ibdev, int mad_flags, u8 port, | |||
| 2412 | const struct ib_mad *in_mad = (const struct ib_mad *)in; | 2412 | const struct ib_mad *in_mad = (const struct ib_mad *)in; |
| 2413 | struct ib_mad *out_mad = (struct ib_mad *)out; | 2413 | struct ib_mad *out_mad = (struct ib_mad *)out; |
| 2414 | 2414 | ||
| 2415 | BUG_ON(in_mad_size != sizeof(*in_mad) || | 2415 | if (WARN_ON_ONCE(in_mad_size != sizeof(*in_mad) || |
| 2416 | *out_mad_size != sizeof(*out_mad)); | 2416 | *out_mad_size != sizeof(*out_mad))) |
| 2417 | return IB_MAD_RESULT_FAILURE; | ||
| 2417 | 2418 | ||
| 2418 | switch (in_mad->mad_hdr.mgmt_class) { | 2419 | switch (in_mad->mad_hdr.mgmt_class) { |
| 2419 | case IB_MGMT_CLASS_SUBN_DIRECTED_ROUTE: | 2420 | case IB_MGMT_CLASS_SUBN_DIRECTED_ROUTE: |
diff --git a/drivers/infiniband/ulp/ipoib/ipoib.h b/drivers/infiniband/ulp/ipoib/ipoib.h index bd94b0a6e9e5..79859c4d43c9 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib.h +++ b/drivers/infiniband/ulp/ipoib/ipoib.h | |||
| @@ -239,7 +239,7 @@ struct ipoib_cm_tx { | |||
| 239 | struct net_device *dev; | 239 | struct net_device *dev; |
| 240 | struct ipoib_neigh *neigh; | 240 | struct ipoib_neigh *neigh; |
| 241 | struct ipoib_path *path; | 241 | struct ipoib_path *path; |
| 242 | struct ipoib_cm_tx_buf *tx_ring; | 242 | struct ipoib_tx_buf *tx_ring; |
| 243 | unsigned tx_head; | 243 | unsigned tx_head; |
| 244 | unsigned tx_tail; | 244 | unsigned tx_tail; |
| 245 | unsigned long flags; | 245 | unsigned long flags; |
| @@ -504,6 +504,33 @@ int ipoib_mcast_stop_thread(struct net_device *dev); | |||
| 504 | void ipoib_mcast_dev_down(struct net_device *dev); | 504 | void ipoib_mcast_dev_down(struct net_device *dev); |
| 505 | void ipoib_mcast_dev_flush(struct net_device *dev); | 505 | void ipoib_mcast_dev_flush(struct net_device *dev); |
| 506 | 506 | ||
| 507 | int ipoib_dma_map_tx(struct ib_device *ca, struct ipoib_tx_buf *tx_req); | ||
| 508 | void ipoib_dma_unmap_tx(struct ipoib_dev_priv *priv, | ||
| 509 | struct ipoib_tx_buf *tx_req); | ||
| 510 | |||
| 511 | static inline void ipoib_build_sge(struct ipoib_dev_priv *priv, | ||
| 512 | struct ipoib_tx_buf *tx_req) | ||
| 513 | { | ||
| 514 | int i, off; | ||
| 515 | struct sk_buff *skb = tx_req->skb; | ||
| 516 | skb_frag_t *frags = skb_shinfo(skb)->frags; | ||
| 517 | int nr_frags = skb_shinfo(skb)->nr_frags; | ||
| 518 | u64 *mapping = tx_req->mapping; | ||
| 519 | |||
| 520 | if (skb_headlen(skb)) { | ||
| 521 | priv->tx_sge[0].addr = mapping[0]; | ||
| 522 | priv->tx_sge[0].length = skb_headlen(skb); | ||
| 523 | off = 1; | ||
| 524 | } else | ||
| 525 | off = 0; | ||
| 526 | |||
| 527 | for (i = 0; i < nr_frags; ++i) { | ||
| 528 | priv->tx_sge[i + off].addr = mapping[i + off]; | ||
| 529 | priv->tx_sge[i + off].length = skb_frag_size(&frags[i]); | ||
| 530 | } | ||
| 531 | priv->tx_wr.num_sge = nr_frags + off; | ||
| 532 | } | ||
| 533 | |||
| 507 | #ifdef CONFIG_INFINIBAND_IPOIB_DEBUG | 534 | #ifdef CONFIG_INFINIBAND_IPOIB_DEBUG |
| 508 | struct ipoib_mcast_iter *ipoib_mcast_iter_init(struct net_device *dev); | 535 | struct ipoib_mcast_iter *ipoib_mcast_iter_init(struct net_device *dev); |
| 509 | int ipoib_mcast_iter_next(struct ipoib_mcast_iter *iter); | 536 | int ipoib_mcast_iter_next(struct ipoib_mcast_iter *iter); |
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_cm.c b/drivers/infiniband/ulp/ipoib/ipoib_cm.c index cf32a778e7d0..ee39be6ccfb0 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_cm.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_cm.c | |||
| @@ -694,14 +694,12 @@ repost: | |||
| 694 | static inline int post_send(struct ipoib_dev_priv *priv, | 694 | static inline int post_send(struct ipoib_dev_priv *priv, |
| 695 | struct ipoib_cm_tx *tx, | 695 | struct ipoib_cm_tx *tx, |
| 696 | unsigned int wr_id, | 696 | unsigned int wr_id, |
| 697 | u64 addr, int len) | 697 | struct ipoib_tx_buf *tx_req) |
| 698 | { | 698 | { |
| 699 | struct ib_send_wr *bad_wr; | 699 | struct ib_send_wr *bad_wr; |
| 700 | 700 | ||
| 701 | priv->tx_sge[0].addr = addr; | 701 | ipoib_build_sge(priv, tx_req); |
| 702 | priv->tx_sge[0].length = len; | ||
| 703 | 702 | ||
| 704 | priv->tx_wr.num_sge = 1; | ||
| 705 | priv->tx_wr.wr_id = wr_id | IPOIB_OP_CM; | 703 | priv->tx_wr.wr_id = wr_id | IPOIB_OP_CM; |
| 706 | 704 | ||
| 707 | return ib_post_send(tx->qp, &priv->tx_wr, &bad_wr); | 705 | return ib_post_send(tx->qp, &priv->tx_wr, &bad_wr); |
| @@ -710,8 +708,7 @@ static inline int post_send(struct ipoib_dev_priv *priv, | |||
| 710 | void ipoib_cm_send(struct net_device *dev, struct sk_buff *skb, struct ipoib_cm_tx *tx) | 708 | void ipoib_cm_send(struct net_device *dev, struct sk_buff *skb, struct ipoib_cm_tx *tx) |
| 711 | { | 709 | { |
| 712 | struct ipoib_dev_priv *priv = netdev_priv(dev); | 710 | struct ipoib_dev_priv *priv = netdev_priv(dev); |
| 713 | struct ipoib_cm_tx_buf *tx_req; | 711 | struct ipoib_tx_buf *tx_req; |
| 714 | u64 addr; | ||
| 715 | int rc; | 712 | int rc; |
| 716 | 713 | ||
| 717 | if (unlikely(skb->len > tx->mtu)) { | 714 | if (unlikely(skb->len > tx->mtu)) { |
| @@ -735,24 +732,21 @@ void ipoib_cm_send(struct net_device *dev, struct sk_buff *skb, struct ipoib_cm_ | |||
| 735 | */ | 732 | */ |
| 736 | tx_req = &tx->tx_ring[tx->tx_head & (ipoib_sendq_size - 1)]; | 733 | tx_req = &tx->tx_ring[tx->tx_head & (ipoib_sendq_size - 1)]; |
| 737 | tx_req->skb = skb; | 734 | tx_req->skb = skb; |
| 738 | addr = ib_dma_map_single(priv->ca, skb->data, skb->len, DMA_TO_DEVICE); | 735 | |
| 739 | if (unlikely(ib_dma_mapping_error(priv->ca, addr))) { | 736 | if (unlikely(ipoib_dma_map_tx(priv->ca, tx_req))) { |
| 740 | ++dev->stats.tx_errors; | 737 | ++dev->stats.tx_errors; |
| 741 | dev_kfree_skb_any(skb); | 738 | dev_kfree_skb_any(skb); |
| 742 | return; | 739 | return; |
| 743 | } | 740 | } |
| 744 | 741 | ||
| 745 | tx_req->mapping = addr; | ||
| 746 | |||
| 747 | skb_orphan(skb); | 742 | skb_orphan(skb); |
| 748 | skb_dst_drop(skb); | 743 | skb_dst_drop(skb); |
| 749 | 744 | ||
| 750 | rc = post_send(priv, tx, tx->tx_head & (ipoib_sendq_size - 1), | 745 | rc = post_send(priv, tx, tx->tx_head & (ipoib_sendq_size - 1), tx_req); |
| 751 | addr, skb->len); | ||
| 752 | if (unlikely(rc)) { | 746 | if (unlikely(rc)) { |
| 753 | ipoib_warn(priv, "post_send failed, error %d\n", rc); | 747 | ipoib_warn(priv, "post_send failed, error %d\n", rc); |
| 754 | ++dev->stats.tx_errors; | 748 | ++dev->stats.tx_errors; |
| 755 | ib_dma_unmap_single(priv->ca, addr, skb->len, DMA_TO_DEVICE); | 749 | ipoib_dma_unmap_tx(priv, tx_req); |
| 756 | dev_kfree_skb_any(skb); | 750 | dev_kfree_skb_any(skb); |
| 757 | } else { | 751 | } else { |
| 758 | dev->trans_start = jiffies; | 752 | dev->trans_start = jiffies; |
| @@ -777,7 +771,7 @@ void ipoib_cm_handle_tx_wc(struct net_device *dev, struct ib_wc *wc) | |||
| 777 | struct ipoib_dev_priv *priv = netdev_priv(dev); | 771 | struct ipoib_dev_priv *priv = netdev_priv(dev); |
| 778 | struct ipoib_cm_tx *tx = wc->qp->qp_context; | 772 | struct ipoib_cm_tx *tx = wc->qp->qp_context; |
| 779 | unsigned int wr_id = wc->wr_id & ~IPOIB_OP_CM; | 773 | unsigned int wr_id = wc->wr_id & ~IPOIB_OP_CM; |
| 780 | struct ipoib_cm_tx_buf *tx_req; | 774 | struct ipoib_tx_buf *tx_req; |
| 781 | unsigned long flags; | 775 | unsigned long flags; |
| 782 | 776 | ||
| 783 | ipoib_dbg_data(priv, "cm send completion: id %d, status: %d\n", | 777 | ipoib_dbg_data(priv, "cm send completion: id %d, status: %d\n", |
| @@ -791,7 +785,7 @@ void ipoib_cm_handle_tx_wc(struct net_device *dev, struct ib_wc *wc) | |||
| 791 | 785 | ||
| 792 | tx_req = &tx->tx_ring[wr_id]; | 786 | tx_req = &tx->tx_ring[wr_id]; |
| 793 | 787 | ||
| 794 | ib_dma_unmap_single(priv->ca, tx_req->mapping, tx_req->skb->len, DMA_TO_DEVICE); | 788 | ipoib_dma_unmap_tx(priv, tx_req); |
| 795 | 789 | ||
| 796 | /* FIXME: is this right? Shouldn't we only increment on success? */ | 790 | /* FIXME: is this right? Shouldn't we only increment on success? */ |
| 797 | ++dev->stats.tx_packets; | 791 | ++dev->stats.tx_packets; |
| @@ -1036,6 +1030,9 @@ static struct ib_qp *ipoib_cm_create_tx_qp(struct net_device *dev, struct ipoib_ | |||
| 1036 | 1030 | ||
| 1037 | struct ib_qp *tx_qp; | 1031 | struct ib_qp *tx_qp; |
| 1038 | 1032 | ||
| 1033 | if (dev->features & NETIF_F_SG) | ||
| 1034 | attr.cap.max_send_sge = MAX_SKB_FRAGS + 1; | ||
| 1035 | |||
| 1039 | tx_qp = ib_create_qp(priv->pd, &attr); | 1036 | tx_qp = ib_create_qp(priv->pd, &attr); |
| 1040 | if (PTR_ERR(tx_qp) == -EINVAL) { | 1037 | if (PTR_ERR(tx_qp) == -EINVAL) { |
| 1041 | ipoib_warn(priv, "can't use GFP_NOIO for QPs on device %s, using GFP_KERNEL\n", | 1038 | ipoib_warn(priv, "can't use GFP_NOIO for QPs on device %s, using GFP_KERNEL\n", |
| @@ -1170,7 +1167,7 @@ err_tx: | |||
| 1170 | static void ipoib_cm_tx_destroy(struct ipoib_cm_tx *p) | 1167 | static void ipoib_cm_tx_destroy(struct ipoib_cm_tx *p) |
| 1171 | { | 1168 | { |
| 1172 | struct ipoib_dev_priv *priv = netdev_priv(p->dev); | 1169 | struct ipoib_dev_priv *priv = netdev_priv(p->dev); |
| 1173 | struct ipoib_cm_tx_buf *tx_req; | 1170 | struct ipoib_tx_buf *tx_req; |
| 1174 | unsigned long begin; | 1171 | unsigned long begin; |
| 1175 | 1172 | ||
| 1176 | ipoib_dbg(priv, "Destroy active connection 0x%x head 0x%x tail 0x%x\n", | 1173 | ipoib_dbg(priv, "Destroy active connection 0x%x head 0x%x tail 0x%x\n", |
| @@ -1197,8 +1194,7 @@ timeout: | |||
| 1197 | 1194 | ||
| 1198 | while ((int) p->tx_tail - (int) p->tx_head < 0) { | 1195 | while ((int) p->tx_tail - (int) p->tx_head < 0) { |
| 1199 | tx_req = &p->tx_ring[p->tx_tail & (ipoib_sendq_size - 1)]; | 1196 | tx_req = &p->tx_ring[p->tx_tail & (ipoib_sendq_size - 1)]; |
| 1200 | ib_dma_unmap_single(priv->ca, tx_req->mapping, tx_req->skb->len, | 1197 | ipoib_dma_unmap_tx(priv, tx_req); |
| 1201 | DMA_TO_DEVICE); | ||
| 1202 | dev_kfree_skb_any(tx_req->skb); | 1198 | dev_kfree_skb_any(tx_req->skb); |
| 1203 | ++p->tx_tail; | 1199 | ++p->tx_tail; |
| 1204 | netif_tx_lock_bh(p->dev); | 1200 | netif_tx_lock_bh(p->dev); |
| @@ -1455,7 +1451,6 @@ static void ipoib_cm_stale_task(struct work_struct *work) | |||
| 1455 | spin_unlock_irq(&priv->lock); | 1451 | spin_unlock_irq(&priv->lock); |
| 1456 | } | 1452 | } |
| 1457 | 1453 | ||
| 1458 | |||
| 1459 | static ssize_t show_mode(struct device *d, struct device_attribute *attr, | 1454 | static ssize_t show_mode(struct device *d, struct device_attribute *attr, |
| 1460 | char *buf) | 1455 | char *buf) |
| 1461 | { | 1456 | { |
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_ib.c b/drivers/infiniband/ulp/ipoib/ipoib_ib.c index 63b92cbb29ad..d266667ca9b8 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_ib.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_ib.c | |||
| @@ -263,8 +263,7 @@ repost: | |||
| 263 | "for buf %d\n", wr_id); | 263 | "for buf %d\n", wr_id); |
| 264 | } | 264 | } |
| 265 | 265 | ||
| 266 | static int ipoib_dma_map_tx(struct ib_device *ca, | 266 | int ipoib_dma_map_tx(struct ib_device *ca, struct ipoib_tx_buf *tx_req) |
| 267 | struct ipoib_tx_buf *tx_req) | ||
| 268 | { | 267 | { |
| 269 | struct sk_buff *skb = tx_req->skb; | 268 | struct sk_buff *skb = tx_req->skb; |
| 270 | u64 *mapping = tx_req->mapping; | 269 | u64 *mapping = tx_req->mapping; |
| @@ -305,8 +304,8 @@ partial_error: | |||
| 305 | return -EIO; | 304 | return -EIO; |
| 306 | } | 305 | } |
| 307 | 306 | ||
| 308 | static void ipoib_dma_unmap_tx(struct ib_device *ca, | 307 | void ipoib_dma_unmap_tx(struct ipoib_dev_priv *priv, |
| 309 | struct ipoib_tx_buf *tx_req) | 308 | struct ipoib_tx_buf *tx_req) |
| 310 | { | 309 | { |
| 311 | struct sk_buff *skb = tx_req->skb; | 310 | struct sk_buff *skb = tx_req->skb; |
| 312 | u64 *mapping = tx_req->mapping; | 311 | u64 *mapping = tx_req->mapping; |
| @@ -314,7 +313,8 @@ static void ipoib_dma_unmap_tx(struct ib_device *ca, | |||
| 314 | int off; | 313 | int off; |
| 315 | 314 | ||
| 316 | if (skb_headlen(skb)) { | 315 | if (skb_headlen(skb)) { |
| 317 | ib_dma_unmap_single(ca, mapping[0], skb_headlen(skb), DMA_TO_DEVICE); | 316 | ib_dma_unmap_single(priv->ca, mapping[0], skb_headlen(skb), |
| 317 | DMA_TO_DEVICE); | ||
| 318 | off = 1; | 318 | off = 1; |
| 319 | } else | 319 | } else |
| 320 | off = 0; | 320 | off = 0; |
| @@ -322,8 +322,8 @@ static void ipoib_dma_unmap_tx(struct ib_device *ca, | |||
| 322 | for (i = 0; i < skb_shinfo(skb)->nr_frags; ++i) { | 322 | for (i = 0; i < skb_shinfo(skb)->nr_frags; ++i) { |
| 323 | const skb_frag_t *frag = &skb_shinfo(skb)->frags[i]; | 323 | const skb_frag_t *frag = &skb_shinfo(skb)->frags[i]; |
| 324 | 324 | ||
| 325 | ib_dma_unmap_page(ca, mapping[i + off], skb_frag_size(frag), | 325 | ib_dma_unmap_page(priv->ca, mapping[i + off], |
| 326 | DMA_TO_DEVICE); | 326 | skb_frag_size(frag), DMA_TO_DEVICE); |
| 327 | } | 327 | } |
| 328 | } | 328 | } |
| 329 | 329 | ||
| @@ -389,7 +389,7 @@ static void ipoib_ib_handle_tx_wc(struct net_device *dev, struct ib_wc *wc) | |||
| 389 | 389 | ||
| 390 | tx_req = &priv->tx_ring[wr_id]; | 390 | tx_req = &priv->tx_ring[wr_id]; |
| 391 | 391 | ||
| 392 | ipoib_dma_unmap_tx(priv->ca, tx_req); | 392 | ipoib_dma_unmap_tx(priv, tx_req); |
| 393 | 393 | ||
| 394 | ++dev->stats.tx_packets; | 394 | ++dev->stats.tx_packets; |
| 395 | dev->stats.tx_bytes += tx_req->skb->len; | 395 | dev->stats.tx_bytes += tx_req->skb->len; |
| @@ -514,24 +514,10 @@ static inline int post_send(struct ipoib_dev_priv *priv, | |||
| 514 | void *head, int hlen) | 514 | void *head, int hlen) |
| 515 | { | 515 | { |
| 516 | struct ib_send_wr *bad_wr; | 516 | struct ib_send_wr *bad_wr; |
| 517 | int i, off; | ||
| 518 | struct sk_buff *skb = tx_req->skb; | 517 | struct sk_buff *skb = tx_req->skb; |
| 519 | skb_frag_t *frags = skb_shinfo(skb)->frags; | ||
| 520 | int nr_frags = skb_shinfo(skb)->nr_frags; | ||
| 521 | u64 *mapping = tx_req->mapping; | ||
| 522 | 518 | ||
| 523 | if (skb_headlen(skb)) { | 519 | ipoib_build_sge(priv, tx_req); |
| 524 | priv->tx_sge[0].addr = mapping[0]; | ||
| 525 | priv->tx_sge[0].length = skb_headlen(skb); | ||
| 526 | off = 1; | ||
| 527 | } else | ||
| 528 | off = 0; | ||
| 529 | 520 | ||
| 530 | for (i = 0; i < nr_frags; ++i) { | ||
| 531 | priv->tx_sge[i + off].addr = mapping[i + off]; | ||
| 532 | priv->tx_sge[i + off].length = skb_frag_size(&frags[i]); | ||
| 533 | } | ||
| 534 | priv->tx_wr.num_sge = nr_frags + off; | ||
| 535 | priv->tx_wr.wr_id = wr_id; | 521 | priv->tx_wr.wr_id = wr_id; |
| 536 | priv->tx_wr.wr.ud.remote_qpn = qpn; | 522 | priv->tx_wr.wr.ud.remote_qpn = qpn; |
| 537 | priv->tx_wr.wr.ud.ah = address; | 523 | priv->tx_wr.wr.ud.ah = address; |
| @@ -617,7 +603,7 @@ void ipoib_send(struct net_device *dev, struct sk_buff *skb, | |||
| 617 | ipoib_warn(priv, "post_send failed, error %d\n", rc); | 603 | ipoib_warn(priv, "post_send failed, error %d\n", rc); |
| 618 | ++dev->stats.tx_errors; | 604 | ++dev->stats.tx_errors; |
| 619 | --priv->tx_outstanding; | 605 | --priv->tx_outstanding; |
| 620 | ipoib_dma_unmap_tx(priv->ca, tx_req); | 606 | ipoib_dma_unmap_tx(priv, tx_req); |
| 621 | dev_kfree_skb_any(skb); | 607 | dev_kfree_skb_any(skb); |
| 622 | if (netif_queue_stopped(dev)) | 608 | if (netif_queue_stopped(dev)) |
| 623 | netif_wake_queue(dev); | 609 | netif_wake_queue(dev); |
| @@ -868,7 +854,7 @@ int ipoib_ib_dev_stop(struct net_device *dev) | |||
| 868 | while ((int) priv->tx_tail - (int) priv->tx_head < 0) { | 854 | while ((int) priv->tx_tail - (int) priv->tx_head < 0) { |
| 869 | tx_req = &priv->tx_ring[priv->tx_tail & | 855 | tx_req = &priv->tx_ring[priv->tx_tail & |
| 870 | (ipoib_sendq_size - 1)]; | 856 | (ipoib_sendq_size - 1)]; |
| 871 | ipoib_dma_unmap_tx(priv->ca, tx_req); | 857 | ipoib_dma_unmap_tx(priv, tx_req); |
| 872 | dev_kfree_skb_any(tx_req->skb); | 858 | dev_kfree_skb_any(tx_req->skb); |
| 873 | ++priv->tx_tail; | 859 | ++priv->tx_tail; |
| 874 | --priv->tx_outstanding; | 860 | --priv->tx_outstanding; |
| @@ -985,20 +971,21 @@ static inline int update_child_pkey(struct ipoib_dev_priv *priv) | |||
| 985 | } | 971 | } |
| 986 | 972 | ||
| 987 | static void __ipoib_ib_dev_flush(struct ipoib_dev_priv *priv, | 973 | static void __ipoib_ib_dev_flush(struct ipoib_dev_priv *priv, |
| 988 | enum ipoib_flush_level level) | 974 | enum ipoib_flush_level level, |
| 975 | int nesting) | ||
| 989 | { | 976 | { |
| 990 | struct ipoib_dev_priv *cpriv; | 977 | struct ipoib_dev_priv *cpriv; |
| 991 | struct net_device *dev = priv->dev; | 978 | struct net_device *dev = priv->dev; |
| 992 | int result; | 979 | int result; |
| 993 | 980 | ||
| 994 | down_read(&priv->vlan_rwsem); | 981 | down_read_nested(&priv->vlan_rwsem, nesting); |
| 995 | 982 | ||
| 996 | /* | 983 | /* |
| 997 | * Flush any child interfaces too -- they might be up even if | 984 | * Flush any child interfaces too -- they might be up even if |
| 998 | * the parent is down. | 985 | * the parent is down. |
| 999 | */ | 986 | */ |
| 1000 | list_for_each_entry(cpriv, &priv->child_intfs, list) | 987 | list_for_each_entry(cpriv, &priv->child_intfs, list) |
| 1001 | __ipoib_ib_dev_flush(cpriv, level); | 988 | __ipoib_ib_dev_flush(cpriv, level, nesting + 1); |
| 1002 | 989 | ||
| 1003 | up_read(&priv->vlan_rwsem); | 990 | up_read(&priv->vlan_rwsem); |
| 1004 | 991 | ||
| @@ -1076,7 +1063,7 @@ void ipoib_ib_dev_flush_light(struct work_struct *work) | |||
| 1076 | struct ipoib_dev_priv *priv = | 1063 | struct ipoib_dev_priv *priv = |
| 1077 | container_of(work, struct ipoib_dev_priv, flush_light); | 1064 | container_of(work, struct ipoib_dev_priv, flush_light); |
| 1078 | 1065 | ||
| 1079 | __ipoib_ib_dev_flush(priv, IPOIB_FLUSH_LIGHT); | 1066 | __ipoib_ib_dev_flush(priv, IPOIB_FLUSH_LIGHT, 0); |
| 1080 | } | 1067 | } |
| 1081 | 1068 | ||
| 1082 | void ipoib_ib_dev_flush_normal(struct work_struct *work) | 1069 | void ipoib_ib_dev_flush_normal(struct work_struct *work) |
| @@ -1084,7 +1071,7 @@ void ipoib_ib_dev_flush_normal(struct work_struct *work) | |||
| 1084 | struct ipoib_dev_priv *priv = | 1071 | struct ipoib_dev_priv *priv = |
| 1085 | container_of(work, struct ipoib_dev_priv, flush_normal); | 1072 | container_of(work, struct ipoib_dev_priv, flush_normal); |
| 1086 | 1073 | ||
| 1087 | __ipoib_ib_dev_flush(priv, IPOIB_FLUSH_NORMAL); | 1074 | __ipoib_ib_dev_flush(priv, IPOIB_FLUSH_NORMAL, 0); |
| 1088 | } | 1075 | } |
| 1089 | 1076 | ||
| 1090 | void ipoib_ib_dev_flush_heavy(struct work_struct *work) | 1077 | void ipoib_ib_dev_flush_heavy(struct work_struct *work) |
| @@ -1092,7 +1079,7 @@ void ipoib_ib_dev_flush_heavy(struct work_struct *work) | |||
| 1092 | struct ipoib_dev_priv *priv = | 1079 | struct ipoib_dev_priv *priv = |
| 1093 | container_of(work, struct ipoib_dev_priv, flush_heavy); | 1080 | container_of(work, struct ipoib_dev_priv, flush_heavy); |
| 1094 | 1081 | ||
| 1095 | __ipoib_ib_dev_flush(priv, IPOIB_FLUSH_HEAVY); | 1082 | __ipoib_ib_dev_flush(priv, IPOIB_FLUSH_HEAVY, 0); |
| 1096 | } | 1083 | } |
| 1097 | 1084 | ||
| 1098 | void ipoib_ib_dev_cleanup(struct net_device *dev) | 1085 | void ipoib_ib_dev_cleanup(struct net_device *dev) |
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_main.c b/drivers/infiniband/ulp/ipoib/ipoib_main.c index da149c278cb8..b2943c84a5dd 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_main.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_main.c | |||
| @@ -190,7 +190,7 @@ static netdev_features_t ipoib_fix_features(struct net_device *dev, netdev_featu | |||
| 190 | struct ipoib_dev_priv *priv = netdev_priv(dev); | 190 | struct ipoib_dev_priv *priv = netdev_priv(dev); |
| 191 | 191 | ||
| 192 | if (test_bit(IPOIB_FLAG_ADMIN_CM, &priv->flags)) | 192 | if (test_bit(IPOIB_FLAG_ADMIN_CM, &priv->flags)) |
| 193 | features &= ~(NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_TSO); | 193 | features &= ~(NETIF_F_IP_CSUM | NETIF_F_TSO); |
| 194 | 194 | ||
| 195 | return features; | 195 | return features; |
| 196 | } | 196 | } |
| @@ -232,6 +232,7 @@ int ipoib_set_mode(struct net_device *dev, const char *buf) | |||
| 232 | ipoib_warn(priv, "enabling connected mode " | 232 | ipoib_warn(priv, "enabling connected mode " |
| 233 | "will cause multicast packet drops\n"); | 233 | "will cause multicast packet drops\n"); |
| 234 | netdev_update_features(dev); | 234 | netdev_update_features(dev); |
| 235 | dev_set_mtu(dev, ipoib_cm_max_mtu(dev)); | ||
| 235 | rtnl_unlock(); | 236 | rtnl_unlock(); |
| 236 | priv->tx_wr.send_flags &= ~IB_SEND_IP_CSUM; | 237 | priv->tx_wr.send_flags &= ~IB_SEND_IP_CSUM; |
| 237 | 238 | ||
| @@ -1577,7 +1578,8 @@ static struct net_device *ipoib_add_port(const char *format, | |||
| 1577 | SET_NETDEV_DEV(priv->dev, hca->dma_device); | 1578 | SET_NETDEV_DEV(priv->dev, hca->dma_device); |
| 1578 | priv->dev->dev_id = port - 1; | 1579 | priv->dev->dev_id = port - 1; |
| 1579 | 1580 | ||
| 1580 | if (!ib_query_port(hca, port, &attr)) | 1581 | result = ib_query_port(hca, port, &attr); |
| 1582 | if (!result) | ||
| 1581 | priv->max_ib_mtu = ib_mtu_enum_to_int(attr.max_mtu); | 1583 | priv->max_ib_mtu = ib_mtu_enum_to_int(attr.max_mtu); |
| 1582 | else { | 1584 | else { |
| 1583 | printk(KERN_WARNING "%s: ib_query_port %d failed\n", | 1585 | printk(KERN_WARNING "%s: ib_query_port %d failed\n", |
| @@ -1598,7 +1600,8 @@ static struct net_device *ipoib_add_port(const char *format, | |||
| 1598 | goto device_init_failed; | 1600 | goto device_init_failed; |
| 1599 | } | 1601 | } |
| 1600 | 1602 | ||
| 1601 | if (ipoib_set_dev_features(priv, hca)) | 1603 | result = ipoib_set_dev_features(priv, hca); |
| 1604 | if (result) | ||
| 1602 | goto device_init_failed; | 1605 | goto device_init_failed; |
| 1603 | 1606 | ||
| 1604 | /* | 1607 | /* |
| @@ -1684,7 +1687,7 @@ static void ipoib_add_one(struct ib_device *device) | |||
| 1684 | struct list_head *dev_list; | 1687 | struct list_head *dev_list; |
| 1685 | struct net_device *dev; | 1688 | struct net_device *dev; |
| 1686 | struct ipoib_dev_priv *priv; | 1689 | struct ipoib_dev_priv *priv; |
| 1687 | int s, e, p; | 1690 | int p; |
| 1688 | int count = 0; | 1691 | int count = 0; |
| 1689 | 1692 | ||
| 1690 | dev_list = kmalloc(sizeof *dev_list, GFP_KERNEL); | 1693 | dev_list = kmalloc(sizeof *dev_list, GFP_KERNEL); |
| @@ -1693,15 +1696,7 @@ static void ipoib_add_one(struct ib_device *device) | |||
| 1693 | 1696 | ||
| 1694 | INIT_LIST_HEAD(dev_list); | 1697 | INIT_LIST_HEAD(dev_list); |
| 1695 | 1698 | ||
| 1696 | if (device->node_type == RDMA_NODE_IB_SWITCH) { | 1699 | for (p = rdma_start_port(device); p <= rdma_end_port(device); ++p) { |
| 1697 | s = 0; | ||
| 1698 | e = 0; | ||
| 1699 | } else { | ||
| 1700 | s = 1; | ||
| 1701 | e = device->phys_port_cnt; | ||
| 1702 | } | ||
| 1703 | |||
| 1704 | for (p = s; p <= e; ++p) { | ||
| 1705 | if (!rdma_protocol_ib(device, p)) | 1700 | if (!rdma_protocol_ib(device, p)) |
| 1706 | continue; | 1701 | continue; |
| 1707 | dev = ipoib_add_port("ib%d", device, p); | 1702 | dev = ipoib_add_port("ib%d", device, p); |
diff --git a/drivers/infiniband/ulp/srp/ib_srp.c b/drivers/infiniband/ulp/srp/ib_srp.c index 267dc4f75502..31a20b462266 100644 --- a/drivers/infiniband/ulp/srp/ib_srp.c +++ b/drivers/infiniband/ulp/srp/ib_srp.c | |||
| @@ -161,13 +161,10 @@ static int srp_tmo_set(const char *val, const struct kernel_param *kp) | |||
| 161 | { | 161 | { |
| 162 | int tmo, res; | 162 | int tmo, res; |
| 163 | 163 | ||
| 164 | if (strncmp(val, "off", 3) != 0) { | 164 | res = srp_parse_tmo(&tmo, val); |
| 165 | res = kstrtoint(val, 0, &tmo); | 165 | if (res) |
| 166 | if (res) | 166 | goto out; |
| 167 | goto out; | 167 | |
| 168 | } else { | ||
| 169 | tmo = -1; | ||
| 170 | } | ||
| 171 | if (kp->arg == &srp_reconnect_delay) | 168 | if (kp->arg == &srp_reconnect_delay) |
| 172 | res = srp_tmo_valid(tmo, srp_fast_io_fail_tmo, | 169 | res = srp_tmo_valid(tmo, srp_fast_io_fail_tmo, |
| 173 | srp_dev_loss_tmo); | 170 | srp_dev_loss_tmo); |
| @@ -3379,7 +3376,7 @@ static void srp_add_one(struct ib_device *device) | |||
| 3379 | struct srp_device *srp_dev; | 3376 | struct srp_device *srp_dev; |
| 3380 | struct ib_device_attr *dev_attr; | 3377 | struct ib_device_attr *dev_attr; |
| 3381 | struct srp_host *host; | 3378 | struct srp_host *host; |
| 3382 | int mr_page_shift, s, e, p; | 3379 | int mr_page_shift, p; |
| 3383 | u64 max_pages_per_mr; | 3380 | u64 max_pages_per_mr; |
| 3384 | 3381 | ||
| 3385 | dev_attr = kmalloc(sizeof *dev_attr, GFP_KERNEL); | 3382 | dev_attr = kmalloc(sizeof *dev_attr, GFP_KERNEL); |
| @@ -3443,15 +3440,7 @@ static void srp_add_one(struct ib_device *device) | |||
| 3443 | if (IS_ERR(srp_dev->mr)) | 3440 | if (IS_ERR(srp_dev->mr)) |
| 3444 | goto err_pd; | 3441 | goto err_pd; |
| 3445 | 3442 | ||
| 3446 | if (device->node_type == RDMA_NODE_IB_SWITCH) { | 3443 | for (p = rdma_start_port(device); p <= rdma_end_port(device); ++p) { |
| 3447 | s = 0; | ||
| 3448 | e = 0; | ||
| 3449 | } else { | ||
| 3450 | s = 1; | ||
| 3451 | e = device->phys_port_cnt; | ||
| 3452 | } | ||
| 3453 | |||
| 3454 | for (p = s; p <= e; ++p) { | ||
| 3455 | host = srp_add_port(srp_dev, p); | 3444 | host = srp_add_port(srp_dev, p); |
| 3456 | if (host) | 3445 | if (host) |
| 3457 | list_add_tail(&host->list, &srp_dev->dev_list); | 3446 | list_add_tail(&host->list, &srp_dev->dev_list); |
diff --git a/drivers/infiniband/ulp/srpt/ib_srpt.c b/drivers/infiniband/ulp/srpt/ib_srpt.c index 82897ca17f32..60ff0a2390e5 100644 --- a/drivers/infiniband/ulp/srpt/ib_srpt.c +++ b/drivers/infiniband/ulp/srpt/ib_srpt.c | |||
| @@ -302,7 +302,7 @@ static void srpt_get_iou(struct ib_dm_mad *mad) | |||
| 302 | int i; | 302 | int i; |
| 303 | 303 | ||
| 304 | ioui = (struct ib_dm_iou_info *)mad->data; | 304 | ioui = (struct ib_dm_iou_info *)mad->data; |
| 305 | ioui->change_id = __constant_cpu_to_be16(1); | 305 | ioui->change_id = cpu_to_be16(1); |
| 306 | ioui->max_controllers = 16; | 306 | ioui->max_controllers = 16; |
| 307 | 307 | ||
| 308 | /* set present for slot 1 and empty for the rest */ | 308 | /* set present for slot 1 and empty for the rest */ |
| @@ -330,13 +330,13 @@ static void srpt_get_ioc(struct srpt_port *sport, u32 slot, | |||
| 330 | 330 | ||
| 331 | if (!slot || slot > 16) { | 331 | if (!slot || slot > 16) { |
| 332 | mad->mad_hdr.status | 332 | mad->mad_hdr.status |
| 333 | = __constant_cpu_to_be16(DM_MAD_STATUS_INVALID_FIELD); | 333 | = cpu_to_be16(DM_MAD_STATUS_INVALID_FIELD); |
| 334 | return; | 334 | return; |
| 335 | } | 335 | } |
| 336 | 336 | ||
| 337 | if (slot > 2) { | 337 | if (slot > 2) { |
| 338 | mad->mad_hdr.status | 338 | mad->mad_hdr.status |
| 339 | = __constant_cpu_to_be16(DM_MAD_STATUS_NO_IOC); | 339 | = cpu_to_be16(DM_MAD_STATUS_NO_IOC); |
| 340 | return; | 340 | return; |
| 341 | } | 341 | } |
| 342 | 342 | ||
| @@ -348,10 +348,10 @@ static void srpt_get_ioc(struct srpt_port *sport, u32 slot, | |||
| 348 | iocp->device_version = cpu_to_be16(sdev->dev_attr.hw_ver); | 348 | iocp->device_version = cpu_to_be16(sdev->dev_attr.hw_ver); |
| 349 | iocp->subsys_vendor_id = cpu_to_be32(sdev->dev_attr.vendor_id); | 349 | iocp->subsys_vendor_id = cpu_to_be32(sdev->dev_attr.vendor_id); |
| 350 | iocp->subsys_device_id = 0x0; | 350 | iocp->subsys_device_id = 0x0; |
| 351 | iocp->io_class = __constant_cpu_to_be16(SRP_REV16A_IB_IO_CLASS); | 351 | iocp->io_class = cpu_to_be16(SRP_REV16A_IB_IO_CLASS); |
| 352 | iocp->io_subclass = __constant_cpu_to_be16(SRP_IO_SUBCLASS); | 352 | iocp->io_subclass = cpu_to_be16(SRP_IO_SUBCLASS); |
| 353 | iocp->protocol = __constant_cpu_to_be16(SRP_PROTOCOL); | 353 | iocp->protocol = cpu_to_be16(SRP_PROTOCOL); |
| 354 | iocp->protocol_version = __constant_cpu_to_be16(SRP_PROTOCOL_VERSION); | 354 | iocp->protocol_version = cpu_to_be16(SRP_PROTOCOL_VERSION); |
| 355 | iocp->send_queue_depth = cpu_to_be16(sdev->srq_size); | 355 | iocp->send_queue_depth = cpu_to_be16(sdev->srq_size); |
| 356 | iocp->rdma_read_depth = 4; | 356 | iocp->rdma_read_depth = 4; |
| 357 | iocp->send_size = cpu_to_be32(srp_max_req_size); | 357 | iocp->send_size = cpu_to_be32(srp_max_req_size); |
| @@ -379,13 +379,13 @@ static void srpt_get_svc_entries(u64 ioc_guid, | |||
| 379 | 379 | ||
| 380 | if (!slot || slot > 16) { | 380 | if (!slot || slot > 16) { |
| 381 | mad->mad_hdr.status | 381 | mad->mad_hdr.status |
| 382 | = __constant_cpu_to_be16(DM_MAD_STATUS_INVALID_FIELD); | 382 | = cpu_to_be16(DM_MAD_STATUS_INVALID_FIELD); |
| 383 | return; | 383 | return; |
| 384 | } | 384 | } |
| 385 | 385 | ||
| 386 | if (slot > 2 || lo > hi || hi > 1) { | 386 | if (slot > 2 || lo > hi || hi > 1) { |
| 387 | mad->mad_hdr.status | 387 | mad->mad_hdr.status |
| 388 | = __constant_cpu_to_be16(DM_MAD_STATUS_NO_IOC); | 388 | = cpu_to_be16(DM_MAD_STATUS_NO_IOC); |
| 389 | return; | 389 | return; |
| 390 | } | 390 | } |
| 391 | 391 | ||
| @@ -436,7 +436,7 @@ static void srpt_mgmt_method_get(struct srpt_port *sp, struct ib_mad *rq_mad, | |||
| 436 | break; | 436 | break; |
| 437 | default: | 437 | default: |
| 438 | rsp_mad->mad_hdr.status = | 438 | rsp_mad->mad_hdr.status = |
| 439 | __constant_cpu_to_be16(DM_MAD_STATUS_UNSUP_METHOD_ATTR); | 439 | cpu_to_be16(DM_MAD_STATUS_UNSUP_METHOD_ATTR); |
| 440 | break; | 440 | break; |
| 441 | } | 441 | } |
| 442 | } | 442 | } |
| @@ -493,11 +493,11 @@ static void srpt_mad_recv_handler(struct ib_mad_agent *mad_agent, | |||
| 493 | break; | 493 | break; |
| 494 | case IB_MGMT_METHOD_SET: | 494 | case IB_MGMT_METHOD_SET: |
| 495 | dm_mad->mad_hdr.status = | 495 | dm_mad->mad_hdr.status = |
| 496 | __constant_cpu_to_be16(DM_MAD_STATUS_UNSUP_METHOD_ATTR); | 496 | cpu_to_be16(DM_MAD_STATUS_UNSUP_METHOD_ATTR); |
| 497 | break; | 497 | break; |
| 498 | default: | 498 | default: |
| 499 | dm_mad->mad_hdr.status = | 499 | dm_mad->mad_hdr.status = |
| 500 | __constant_cpu_to_be16(DM_MAD_STATUS_UNSUP_METHOD); | 500 | cpu_to_be16(DM_MAD_STATUS_UNSUP_METHOD); |
| 501 | break; | 501 | break; |
| 502 | } | 502 | } |
| 503 | 503 | ||
| @@ -1535,7 +1535,7 @@ static int srpt_build_cmd_rsp(struct srpt_rdma_ch *ch, | |||
| 1535 | memset(srp_rsp, 0, sizeof *srp_rsp); | 1535 | memset(srp_rsp, 0, sizeof *srp_rsp); |
| 1536 | srp_rsp->opcode = SRP_RSP; | 1536 | srp_rsp->opcode = SRP_RSP; |
| 1537 | srp_rsp->req_lim_delta = | 1537 | srp_rsp->req_lim_delta = |
| 1538 | __constant_cpu_to_be32(1 + atomic_xchg(&ch->req_lim_delta, 0)); | 1538 | cpu_to_be32(1 + atomic_xchg(&ch->req_lim_delta, 0)); |
| 1539 | srp_rsp->tag = tag; | 1539 | srp_rsp->tag = tag; |
| 1540 | srp_rsp->status = status; | 1540 | srp_rsp->status = status; |
| 1541 | 1541 | ||
| @@ -1585,8 +1585,8 @@ static int srpt_build_tskmgmt_rsp(struct srpt_rdma_ch *ch, | |||
| 1585 | memset(srp_rsp, 0, sizeof *srp_rsp); | 1585 | memset(srp_rsp, 0, sizeof *srp_rsp); |
| 1586 | 1586 | ||
| 1587 | srp_rsp->opcode = SRP_RSP; | 1587 | srp_rsp->opcode = SRP_RSP; |
| 1588 | srp_rsp->req_lim_delta = __constant_cpu_to_be32(1 | 1588 | srp_rsp->req_lim_delta = |
| 1589 | + atomic_xchg(&ch->req_lim_delta, 0)); | 1589 | cpu_to_be32(1 + atomic_xchg(&ch->req_lim_delta, 0)); |
| 1590 | srp_rsp->tag = tag; | 1590 | srp_rsp->tag = tag; |
| 1591 | 1591 | ||
| 1592 | srp_rsp->flags |= SRP_RSP_FLAG_RSPVALID; | 1592 | srp_rsp->flags |= SRP_RSP_FLAG_RSPVALID; |
| @@ -1630,7 +1630,7 @@ static uint64_t srpt_unpack_lun(const uint8_t *lun, int len) | |||
| 1630 | switch (len) { | 1630 | switch (len) { |
| 1631 | case 8: | 1631 | case 8: |
| 1632 | if ((*((__be64 *)lun) & | 1632 | if ((*((__be64 *)lun) & |
| 1633 | __constant_cpu_to_be64(0x0000FFFFFFFFFFFFLL)) != 0) | 1633 | cpu_to_be64(0x0000FFFFFFFFFFFFLL)) != 0) |
| 1634 | goto out_err; | 1634 | goto out_err; |
| 1635 | break; | 1635 | break; |
| 1636 | case 4: | 1636 | case 4: |
| @@ -2449,8 +2449,8 @@ static int srpt_cm_req_recv(struct ib_cm_id *cm_id, | |||
| 2449 | } | 2449 | } |
| 2450 | 2450 | ||
| 2451 | if (it_iu_len > srp_max_req_size || it_iu_len < 64) { | 2451 | if (it_iu_len > srp_max_req_size || it_iu_len < 64) { |
| 2452 | rej->reason = __constant_cpu_to_be32( | 2452 | rej->reason = cpu_to_be32( |
| 2453 | SRP_LOGIN_REJ_REQ_IT_IU_LENGTH_TOO_LARGE); | 2453 | SRP_LOGIN_REJ_REQ_IT_IU_LENGTH_TOO_LARGE); |
| 2454 | ret = -EINVAL; | 2454 | ret = -EINVAL; |
| 2455 | pr_err("rejected SRP_LOGIN_REQ because its" | 2455 | pr_err("rejected SRP_LOGIN_REQ because its" |
| 2456 | " length (%d bytes) is out of range (%d .. %d)\n", | 2456 | " length (%d bytes) is out of range (%d .. %d)\n", |
| @@ -2459,8 +2459,8 @@ static int srpt_cm_req_recv(struct ib_cm_id *cm_id, | |||
| 2459 | } | 2459 | } |
| 2460 | 2460 | ||
| 2461 | if (!sport->enabled) { | 2461 | if (!sport->enabled) { |
| 2462 | rej->reason = __constant_cpu_to_be32( | 2462 | rej->reason = cpu_to_be32( |
| 2463 | SRP_LOGIN_REJ_INSUFFICIENT_RESOURCES); | 2463 | SRP_LOGIN_REJ_INSUFFICIENT_RESOURCES); |
| 2464 | ret = -EINVAL; | 2464 | ret = -EINVAL; |
| 2465 | pr_err("rejected SRP_LOGIN_REQ because the target port" | 2465 | pr_err("rejected SRP_LOGIN_REQ because the target port" |
| 2466 | " has not yet been enabled\n"); | 2466 | " has not yet been enabled\n"); |
| @@ -2505,8 +2505,8 @@ static int srpt_cm_req_recv(struct ib_cm_id *cm_id, | |||
| 2505 | if (*(__be64 *)req->target_port_id != cpu_to_be64(srpt_service_guid) | 2505 | if (*(__be64 *)req->target_port_id != cpu_to_be64(srpt_service_guid) |
| 2506 | || *(__be64 *)(req->target_port_id + 8) != | 2506 | || *(__be64 *)(req->target_port_id + 8) != |
| 2507 | cpu_to_be64(srpt_service_guid)) { | 2507 | cpu_to_be64(srpt_service_guid)) { |
| 2508 | rej->reason = __constant_cpu_to_be32( | 2508 | rej->reason = cpu_to_be32( |
| 2509 | SRP_LOGIN_REJ_UNABLE_ASSOCIATE_CHANNEL); | 2509 | SRP_LOGIN_REJ_UNABLE_ASSOCIATE_CHANNEL); |
| 2510 | ret = -ENOMEM; | 2510 | ret = -ENOMEM; |
| 2511 | pr_err("rejected SRP_LOGIN_REQ because it" | 2511 | pr_err("rejected SRP_LOGIN_REQ because it" |
| 2512 | " has an invalid target port identifier.\n"); | 2512 | " has an invalid target port identifier.\n"); |
| @@ -2515,8 +2515,8 @@ static int srpt_cm_req_recv(struct ib_cm_id *cm_id, | |||
| 2515 | 2515 | ||
| 2516 | ch = kzalloc(sizeof *ch, GFP_KERNEL); | 2516 | ch = kzalloc(sizeof *ch, GFP_KERNEL); |
| 2517 | if (!ch) { | 2517 | if (!ch) { |
| 2518 | rej->reason = __constant_cpu_to_be32( | 2518 | rej->reason = cpu_to_be32( |
| 2519 | SRP_LOGIN_REJ_INSUFFICIENT_RESOURCES); | 2519 | SRP_LOGIN_REJ_INSUFFICIENT_RESOURCES); |
| 2520 | pr_err("rejected SRP_LOGIN_REQ because no memory.\n"); | 2520 | pr_err("rejected SRP_LOGIN_REQ because no memory.\n"); |
| 2521 | ret = -ENOMEM; | 2521 | ret = -ENOMEM; |
| 2522 | goto reject; | 2522 | goto reject; |
| @@ -2552,8 +2552,8 @@ static int srpt_cm_req_recv(struct ib_cm_id *cm_id, | |||
| 2552 | 2552 | ||
| 2553 | ret = srpt_create_ch_ib(ch); | 2553 | ret = srpt_create_ch_ib(ch); |
| 2554 | if (ret) { | 2554 | if (ret) { |
| 2555 | rej->reason = __constant_cpu_to_be32( | 2555 | rej->reason = cpu_to_be32( |
| 2556 | SRP_LOGIN_REJ_INSUFFICIENT_RESOURCES); | 2556 | SRP_LOGIN_REJ_INSUFFICIENT_RESOURCES); |
| 2557 | pr_err("rejected SRP_LOGIN_REQ because creating" | 2557 | pr_err("rejected SRP_LOGIN_REQ because creating" |
| 2558 | " a new RDMA channel failed.\n"); | 2558 | " a new RDMA channel failed.\n"); |
| 2559 | goto free_ring; | 2559 | goto free_ring; |
| @@ -2561,8 +2561,7 @@ static int srpt_cm_req_recv(struct ib_cm_id *cm_id, | |||
| 2561 | 2561 | ||
| 2562 | ret = srpt_ch_qp_rtr(ch, ch->qp); | 2562 | ret = srpt_ch_qp_rtr(ch, ch->qp); |
| 2563 | if (ret) { | 2563 | if (ret) { |
| 2564 | rej->reason = __constant_cpu_to_be32( | 2564 | rej->reason = cpu_to_be32(SRP_LOGIN_REJ_INSUFFICIENT_RESOURCES); |
| 2565 | SRP_LOGIN_REJ_INSUFFICIENT_RESOURCES); | ||
| 2566 | pr_err("rejected SRP_LOGIN_REQ because enabling" | 2565 | pr_err("rejected SRP_LOGIN_REQ because enabling" |
| 2567 | " RTR failed (error code = %d)\n", ret); | 2566 | " RTR failed (error code = %d)\n", ret); |
| 2568 | goto destroy_ib; | 2567 | goto destroy_ib; |
| @@ -2580,15 +2579,15 @@ static int srpt_cm_req_recv(struct ib_cm_id *cm_id, | |||
| 2580 | if (!nacl) { | 2579 | if (!nacl) { |
| 2581 | pr_info("Rejected login because no ACL has been" | 2580 | pr_info("Rejected login because no ACL has been" |
| 2582 | " configured yet for initiator %s.\n", ch->sess_name); | 2581 | " configured yet for initiator %s.\n", ch->sess_name); |
| 2583 | rej->reason = __constant_cpu_to_be32( | 2582 | rej->reason = cpu_to_be32( |
| 2584 | SRP_LOGIN_REJ_CHANNEL_LIMIT_REACHED); | 2583 | SRP_LOGIN_REJ_CHANNEL_LIMIT_REACHED); |
| 2585 | goto destroy_ib; | 2584 | goto destroy_ib; |
| 2586 | } | 2585 | } |
| 2587 | 2586 | ||
| 2588 | ch->sess = transport_init_session(TARGET_PROT_NORMAL); | 2587 | ch->sess = transport_init_session(TARGET_PROT_NORMAL); |
| 2589 | if (IS_ERR(ch->sess)) { | 2588 | if (IS_ERR(ch->sess)) { |
| 2590 | rej->reason = __constant_cpu_to_be32( | 2589 | rej->reason = cpu_to_be32( |
| 2591 | SRP_LOGIN_REJ_INSUFFICIENT_RESOURCES); | 2590 | SRP_LOGIN_REJ_INSUFFICIENT_RESOURCES); |
| 2592 | pr_debug("Failed to create session\n"); | 2591 | pr_debug("Failed to create session\n"); |
| 2593 | goto deregister_session; | 2592 | goto deregister_session; |
| 2594 | } | 2593 | } |
| @@ -2604,8 +2603,8 @@ static int srpt_cm_req_recv(struct ib_cm_id *cm_id, | |||
| 2604 | rsp->max_it_iu_len = req->req_it_iu_len; | 2603 | rsp->max_it_iu_len = req->req_it_iu_len; |
| 2605 | rsp->max_ti_iu_len = req->req_it_iu_len; | 2604 | rsp->max_ti_iu_len = req->req_it_iu_len; |
| 2606 | ch->max_ti_iu_len = it_iu_len; | 2605 | ch->max_ti_iu_len = it_iu_len; |
| 2607 | rsp->buf_fmt = __constant_cpu_to_be16(SRP_BUF_FORMAT_DIRECT | 2606 | rsp->buf_fmt = cpu_to_be16(SRP_BUF_FORMAT_DIRECT |
| 2608 | | SRP_BUF_FORMAT_INDIRECT); | 2607 | | SRP_BUF_FORMAT_INDIRECT); |
| 2609 | rsp->req_lim_delta = cpu_to_be32(ch->rq_size); | 2608 | rsp->req_lim_delta = cpu_to_be32(ch->rq_size); |
| 2610 | atomic_set(&ch->req_lim, ch->rq_size); | 2609 | atomic_set(&ch->req_lim, ch->rq_size); |
| 2611 | atomic_set(&ch->req_lim_delta, 0); | 2610 | atomic_set(&ch->req_lim_delta, 0); |
| @@ -2655,8 +2654,8 @@ free_ch: | |||
| 2655 | reject: | 2654 | reject: |
| 2656 | rej->opcode = SRP_LOGIN_REJ; | 2655 | rej->opcode = SRP_LOGIN_REJ; |
| 2657 | rej->tag = req->tag; | 2656 | rej->tag = req->tag; |
| 2658 | rej->buf_fmt = __constant_cpu_to_be16(SRP_BUF_FORMAT_DIRECT | 2657 | rej->buf_fmt = cpu_to_be16(SRP_BUF_FORMAT_DIRECT |
| 2659 | | SRP_BUF_FORMAT_INDIRECT); | 2658 | | SRP_BUF_FORMAT_INDIRECT); |
| 2660 | 2659 | ||
| 2661 | ib_send_cm_rej(cm_id, IB_CM_REJ_CONSUMER_DEFINED, NULL, 0, | 2660 | ib_send_cm_rej(cm_id, IB_CM_REJ_CONSUMER_DEFINED, NULL, 0, |
| 2662 | (void *)rej, sizeof *rej); | 2661 | (void *)rej, sizeof *rej); |
diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c index 1b7e155869f6..c00e2db351ba 100644 --- a/drivers/irqchip/irq-gic-v3-its.c +++ b/drivers/irqchip/irq-gic-v3-its.c | |||
| @@ -75,6 +75,13 @@ struct its_node { | |||
| 75 | 75 | ||
| 76 | #define ITS_ITT_ALIGN SZ_256 | 76 | #define ITS_ITT_ALIGN SZ_256 |
| 77 | 77 | ||
| 78 | struct event_lpi_map { | ||
| 79 | unsigned long *lpi_map; | ||
| 80 | u16 *col_map; | ||
| 81 | irq_hw_number_t lpi_base; | ||
| 82 | int nr_lpis; | ||
| 83 | }; | ||
| 84 | |||
| 78 | /* | 85 | /* |
| 79 | * The ITS view of a device - belongs to an ITS, a collection, owns an | 86 | * The ITS view of a device - belongs to an ITS, a collection, owns an |
| 80 | * interrupt translation table, and a list of interrupts. | 87 | * interrupt translation table, and a list of interrupts. |
| @@ -82,11 +89,8 @@ struct its_node { | |||
| 82 | struct its_device { | 89 | struct its_device { |
| 83 | struct list_head entry; | 90 | struct list_head entry; |
| 84 | struct its_node *its; | 91 | struct its_node *its; |
| 85 | struct its_collection *collection; | 92 | struct event_lpi_map event_map; |
| 86 | void *itt; | 93 | void *itt; |
| 87 | unsigned long *lpi_map; | ||
| 88 | irq_hw_number_t lpi_base; | ||
| 89 | int nr_lpis; | ||
| 90 | u32 nr_ites; | 94 | u32 nr_ites; |
| 91 | u32 device_id; | 95 | u32 device_id; |
| 92 | }; | 96 | }; |
| @@ -99,6 +103,14 @@ static struct rdists *gic_rdists; | |||
| 99 | #define gic_data_rdist() (raw_cpu_ptr(gic_rdists->rdist)) | 103 | #define gic_data_rdist() (raw_cpu_ptr(gic_rdists->rdist)) |
| 100 | #define gic_data_rdist_rd_base() (gic_data_rdist()->rd_base) | 104 | #define gic_data_rdist_rd_base() (gic_data_rdist()->rd_base) |
| 101 | 105 | ||
| 106 | static struct its_collection *dev_event_to_col(struct its_device *its_dev, | ||
| 107 | u32 event) | ||
| 108 | { | ||
| 109 | struct its_node *its = its_dev->its; | ||
| 110 | |||
| 111 | return its->collections + its_dev->event_map.col_map[event]; | ||
| 112 | } | ||
| 113 | |||
| 102 | /* | 114 | /* |
| 103 | * ITS command descriptors - parameters to be encoded in a command | 115 | * ITS command descriptors - parameters to be encoded in a command |
| 104 | * block. | 116 | * block. |
| @@ -134,7 +146,7 @@ struct its_cmd_desc { | |||
| 134 | struct { | 146 | struct { |
| 135 | struct its_device *dev; | 147 | struct its_device *dev; |
| 136 | struct its_collection *col; | 148 | struct its_collection *col; |
| 137 | u32 id; | 149 | u32 event_id; |
| 138 | } its_movi_cmd; | 150 | } its_movi_cmd; |
| 139 | 151 | ||
| 140 | struct { | 152 | struct { |
| @@ -241,7 +253,7 @@ static struct its_collection *its_build_mapd_cmd(struct its_cmd_block *cmd, | |||
| 241 | 253 | ||
| 242 | its_fixup_cmd(cmd); | 254 | its_fixup_cmd(cmd); |
| 243 | 255 | ||
| 244 | return desc->its_mapd_cmd.dev->collection; | 256 | return NULL; |
| 245 | } | 257 | } |
| 246 | 258 | ||
| 247 | static struct its_collection *its_build_mapc_cmd(struct its_cmd_block *cmd, | 259 | static struct its_collection *its_build_mapc_cmd(struct its_cmd_block *cmd, |
| @@ -260,52 +272,72 @@ static struct its_collection *its_build_mapc_cmd(struct its_cmd_block *cmd, | |||
| 260 | static struct its_collection *its_build_mapvi_cmd(struct its_cmd_block *cmd, | 272 | static struct its_collection *its_build_mapvi_cmd(struct its_cmd_block *cmd, |
| 261 | struct its_cmd_desc *desc) | 273 | struct its_cmd_desc *desc) |
| 262 | { | 274 | { |
| 275 | struct its_collection *col; | ||
| 276 | |||
| 277 | col = dev_event_to_col(desc->its_mapvi_cmd.dev, | ||
| 278 | desc->its_mapvi_cmd.event_id); | ||
| 279 | |||
| 263 | its_encode_cmd(cmd, GITS_CMD_MAPVI); | 280 | its_encode_cmd(cmd, GITS_CMD_MAPVI); |
| 264 | its_encode_devid(cmd, desc->its_mapvi_cmd.dev->device_id); | 281 | its_encode_devid(cmd, desc->its_mapvi_cmd.dev->device_id); |
| 265 | its_encode_event_id(cmd, desc->its_mapvi_cmd.event_id); | 282 | its_encode_event_id(cmd, desc->its_mapvi_cmd.event_id); |
| 266 | its_encode_phys_id(cmd, desc->its_mapvi_cmd.phys_id); | 283 | its_encode_phys_id(cmd, desc->its_mapvi_cmd.phys_id); |
| 267 | its_encode_collection(cmd, desc->its_mapvi_cmd.dev->collection->col_id); | 284 | its_encode_collection(cmd, col->col_id); |
| 268 | 285 | ||
| 269 | its_fixup_cmd(cmd); | 286 | its_fixup_cmd(cmd); |
| 270 | 287 | ||
| 271 | return desc->its_mapvi_cmd.dev->collection; | 288 | return col; |
| 272 | } | 289 | } |
| 273 | 290 | ||
| 274 | static struct its_collection *its_build_movi_cmd(struct its_cmd_block *cmd, | 291 | static struct its_collection *its_build_movi_cmd(struct its_cmd_block *cmd, |
| 275 | struct its_cmd_desc *desc) | 292 | struct its_cmd_desc *desc) |
| 276 | { | 293 | { |
| 294 | struct its_collection *col; | ||
| 295 | |||
| 296 | col = dev_event_to_col(desc->its_movi_cmd.dev, | ||
| 297 | desc->its_movi_cmd.event_id); | ||
| 298 | |||
| 277 | its_encode_cmd(cmd, GITS_CMD_MOVI); | 299 | its_encode_cmd(cmd, GITS_CMD_MOVI); |
| 278 | its_encode_devid(cmd, desc->its_movi_cmd.dev->device_id); | 300 | its_encode_devid(cmd, desc->its_movi_cmd.dev->device_id); |
| 279 | its_encode_event_id(cmd, desc->its_movi_cmd.id); | 301 | its_encode_event_id(cmd, desc->its_movi_cmd.event_id); |
| 280 | its_encode_collection(cmd, desc->its_movi_cmd.col->col_id); | 302 | its_encode_collection(cmd, desc->its_movi_cmd.col->col_id); |
| 281 | 303 | ||
| 282 | its_fixup_cmd(cmd); | 304 | its_fixup_cmd(cmd); |
| 283 | 305 | ||
| 284 | return desc->its_movi_cmd.dev->collection; | 306 | return col; |
| 285 | } | 307 | } |
| 286 | 308 | ||
| 287 | static struct its_collection *its_build_discard_cmd(struct its_cmd_block *cmd, | 309 | static struct its_collection *its_build_discard_cmd(struct its_cmd_block *cmd, |
| 288 | struct its_cmd_desc *desc) | 310 | struct its_cmd_desc *desc) |
| 289 | { | 311 | { |
| 312 | struct its_collection *col; | ||
| 313 | |||
| 314 | col = dev_event_to_col(desc->its_discard_cmd.dev, | ||
| 315 | desc->its_discard_cmd.event_id); | ||
| 316 | |||
| 290 | its_encode_cmd(cmd, GITS_CMD_DISCARD); | 317 | its_encode_cmd(cmd, GITS_CMD_DISCARD); |
| 291 | its_encode_devid(cmd, desc->its_discard_cmd.dev->device_id); | 318 | its_encode_devid(cmd, desc->its_discard_cmd.dev->device_id); |
| 292 | its_encode_event_id(cmd, desc->its_discard_cmd.event_id); | 319 | its_encode_event_id(cmd, desc->its_discard_cmd.event_id); |
| 293 | 320 | ||
| 294 | its_fixup_cmd(cmd); | 321 | its_fixup_cmd(cmd); |
| 295 | 322 | ||
| 296 | return desc->its_discard_cmd.dev->collection; | 323 | return col; |
| 297 | } | 324 | } |
| 298 | 325 | ||
| 299 | static struct its_collection *its_build_inv_cmd(struct its_cmd_block *cmd, | 326 | static struct its_collection *its_build_inv_cmd(struct its_cmd_block *cmd, |
| 300 | struct its_cmd_desc *desc) | 327 | struct its_cmd_desc *desc) |
| 301 | { | 328 | { |
| 329 | struct its_collection *col; | ||
| 330 | |||
| 331 | col = dev_event_to_col(desc->its_inv_cmd.dev, | ||
| 332 | desc->its_inv_cmd.event_id); | ||
| 333 | |||
| 302 | its_encode_cmd(cmd, GITS_CMD_INV); | 334 | its_encode_cmd(cmd, GITS_CMD_INV); |
| 303 | its_encode_devid(cmd, desc->its_inv_cmd.dev->device_id); | 335 | its_encode_devid(cmd, desc->its_inv_cmd.dev->device_id); |
| 304 | its_encode_event_id(cmd, desc->its_inv_cmd.event_id); | 336 | its_encode_event_id(cmd, desc->its_inv_cmd.event_id); |
| 305 | 337 | ||
| 306 | its_fixup_cmd(cmd); | 338 | its_fixup_cmd(cmd); |
| 307 | 339 | ||
| 308 | return desc->its_inv_cmd.dev->collection; | 340 | return col; |
| 309 | } | 341 | } |
| 310 | 342 | ||
| 311 | static struct its_collection *its_build_invall_cmd(struct its_cmd_block *cmd, | 343 | static struct its_collection *its_build_invall_cmd(struct its_cmd_block *cmd, |
| @@ -497,7 +529,7 @@ static void its_send_movi(struct its_device *dev, | |||
| 497 | 529 | ||
| 498 | desc.its_movi_cmd.dev = dev; | 530 | desc.its_movi_cmd.dev = dev; |
| 499 | desc.its_movi_cmd.col = col; | 531 | desc.its_movi_cmd.col = col; |
| 500 | desc.its_movi_cmd.id = id; | 532 | desc.its_movi_cmd.event_id = id; |
| 501 | 533 | ||
| 502 | its_send_single_command(dev->its, its_build_movi_cmd, &desc); | 534 | its_send_single_command(dev->its, its_build_movi_cmd, &desc); |
| 503 | } | 535 | } |
| @@ -528,7 +560,7 @@ static void its_send_invall(struct its_node *its, struct its_collection *col) | |||
| 528 | static inline u32 its_get_event_id(struct irq_data *d) | 560 | static inline u32 its_get_event_id(struct irq_data *d) |
| 529 | { | 561 | { |
| 530 | struct its_device *its_dev = irq_data_get_irq_chip_data(d); | 562 | struct its_device *its_dev = irq_data_get_irq_chip_data(d); |
| 531 | return d->hwirq - its_dev->lpi_base; | 563 | return d->hwirq - its_dev->event_map.lpi_base; |
| 532 | } | 564 | } |
| 533 | 565 | ||
| 534 | static void lpi_set_config(struct irq_data *d, bool enable) | 566 | static void lpi_set_config(struct irq_data *d, bool enable) |
| @@ -583,7 +615,7 @@ static int its_set_affinity(struct irq_data *d, const struct cpumask *mask_val, | |||
| 583 | 615 | ||
| 584 | target_col = &its_dev->its->collections[cpu]; | 616 | target_col = &its_dev->its->collections[cpu]; |
| 585 | its_send_movi(its_dev, target_col, id); | 617 | its_send_movi(its_dev, target_col, id); |
| 586 | its_dev->collection = target_col; | 618 | its_dev->event_map.col_map[id] = cpu; |
| 587 | 619 | ||
| 588 | return IRQ_SET_MASK_OK_DONE; | 620 | return IRQ_SET_MASK_OK_DONE; |
| 589 | } | 621 | } |
| @@ -713,8 +745,10 @@ out: | |||
| 713 | return bitmap; | 745 | return bitmap; |
| 714 | } | 746 | } |
| 715 | 747 | ||
| 716 | static void its_lpi_free(unsigned long *bitmap, int base, int nr_ids) | 748 | static void its_lpi_free(struct event_lpi_map *map) |
| 717 | { | 749 | { |
| 750 | int base = map->lpi_base; | ||
| 751 | int nr_ids = map->nr_lpis; | ||
| 718 | int lpi; | 752 | int lpi; |
| 719 | 753 | ||
| 720 | spin_lock(&lpi_lock); | 754 | spin_lock(&lpi_lock); |
| @@ -731,7 +765,8 @@ static void its_lpi_free(unsigned long *bitmap, int base, int nr_ids) | |||
| 731 | 765 | ||
| 732 | spin_unlock(&lpi_lock); | 766 | spin_unlock(&lpi_lock); |
| 733 | 767 | ||
| 734 | kfree(bitmap); | 768 | kfree(map->lpi_map); |
| 769 | kfree(map->col_map); | ||
| 735 | } | 770 | } |
| 736 | 771 | ||
| 737 | /* | 772 | /* |
| @@ -1099,11 +1134,11 @@ static struct its_device *its_create_device(struct its_node *its, u32 dev_id, | |||
| 1099 | struct its_device *dev; | 1134 | struct its_device *dev; |
| 1100 | unsigned long *lpi_map; | 1135 | unsigned long *lpi_map; |
| 1101 | unsigned long flags; | 1136 | unsigned long flags; |
| 1137 | u16 *col_map = NULL; | ||
| 1102 | void *itt; | 1138 | void *itt; |
| 1103 | int lpi_base; | 1139 | int lpi_base; |
| 1104 | int nr_lpis; | 1140 | int nr_lpis; |
| 1105 | int nr_ites; | 1141 | int nr_ites; |
| 1106 | int cpu; | ||
| 1107 | int sz; | 1142 | int sz; |
| 1108 | 1143 | ||
| 1109 | dev = kzalloc(sizeof(*dev), GFP_KERNEL); | 1144 | dev = kzalloc(sizeof(*dev), GFP_KERNEL); |
| @@ -1117,20 +1152,24 @@ static struct its_device *its_create_device(struct its_node *its, u32 dev_id, | |||
| 1117 | sz = max(sz, ITS_ITT_ALIGN) + ITS_ITT_ALIGN - 1; | 1152 | sz = max(sz, ITS_ITT_ALIGN) + ITS_ITT_ALIGN - 1; |
| 1118 | itt = kzalloc(sz, GFP_KERNEL); | 1153 | itt = kzalloc(sz, GFP_KERNEL); |
| 1119 | lpi_map = its_lpi_alloc_chunks(nvecs, &lpi_base, &nr_lpis); | 1154 | lpi_map = its_lpi_alloc_chunks(nvecs, &lpi_base, &nr_lpis); |
| 1155 | if (lpi_map) | ||
| 1156 | col_map = kzalloc(sizeof(*col_map) * nr_lpis, GFP_KERNEL); | ||
| 1120 | 1157 | ||
| 1121 | if (!dev || !itt || !lpi_map) { | 1158 | if (!dev || !itt || !lpi_map || !col_map) { |
| 1122 | kfree(dev); | 1159 | kfree(dev); |
| 1123 | kfree(itt); | 1160 | kfree(itt); |
| 1124 | kfree(lpi_map); | 1161 | kfree(lpi_map); |
| 1162 | kfree(col_map); | ||
| 1125 | return NULL; | 1163 | return NULL; |
| 1126 | } | 1164 | } |
| 1127 | 1165 | ||
| 1128 | dev->its = its; | 1166 | dev->its = its; |
| 1129 | dev->itt = itt; | 1167 | dev->itt = itt; |
| 1130 | dev->nr_ites = nr_ites; | 1168 | dev->nr_ites = nr_ites; |
| 1131 | dev->lpi_map = lpi_map; | 1169 | dev->event_map.lpi_map = lpi_map; |
| 1132 | dev->lpi_base = lpi_base; | 1170 | dev->event_map.col_map = col_map; |
| 1133 | dev->nr_lpis = nr_lpis; | 1171 | dev->event_map.lpi_base = lpi_base; |
| 1172 | dev->event_map.nr_lpis = nr_lpis; | ||
| 1134 | dev->device_id = dev_id; | 1173 | dev->device_id = dev_id; |
| 1135 | INIT_LIST_HEAD(&dev->entry); | 1174 | INIT_LIST_HEAD(&dev->entry); |
| 1136 | 1175 | ||
| @@ -1138,10 +1177,6 @@ static struct its_device *its_create_device(struct its_node *its, u32 dev_id, | |||
| 1138 | list_add(&dev->entry, &its->its_device_list); | 1177 | list_add(&dev->entry, &its->its_device_list); |
| 1139 | raw_spin_unlock_irqrestore(&its->lock, flags); | 1178 | raw_spin_unlock_irqrestore(&its->lock, flags); |
| 1140 | 1179 | ||
| 1141 | /* Bind the device to the first possible CPU */ | ||
| 1142 | cpu = cpumask_first(cpu_online_mask); | ||
| 1143 | dev->collection = &its->collections[cpu]; | ||
| 1144 | |||
| 1145 | /* Map device to its ITT */ | 1180 | /* Map device to its ITT */ |
| 1146 | its_send_mapd(dev, 1); | 1181 | its_send_mapd(dev, 1); |
| 1147 | 1182 | ||
| @@ -1163,12 +1198,13 @@ static int its_alloc_device_irq(struct its_device *dev, irq_hw_number_t *hwirq) | |||
| 1163 | { | 1198 | { |
| 1164 | int idx; | 1199 | int idx; |
| 1165 | 1200 | ||
| 1166 | idx = find_first_zero_bit(dev->lpi_map, dev->nr_lpis); | 1201 | idx = find_first_zero_bit(dev->event_map.lpi_map, |
| 1167 | if (idx == dev->nr_lpis) | 1202 | dev->event_map.nr_lpis); |
| 1203 | if (idx == dev->event_map.nr_lpis) | ||
| 1168 | return -ENOSPC; | 1204 | return -ENOSPC; |
| 1169 | 1205 | ||
| 1170 | *hwirq = dev->lpi_base + idx; | 1206 | *hwirq = dev->event_map.lpi_base + idx; |
| 1171 | set_bit(idx, dev->lpi_map); | 1207 | set_bit(idx, dev->event_map.lpi_map); |
| 1172 | 1208 | ||
| 1173 | return 0; | 1209 | return 0; |
| 1174 | } | 1210 | } |
| @@ -1288,7 +1324,8 @@ static int its_irq_domain_alloc(struct irq_domain *domain, unsigned int virq, | |||
| 1288 | irq_domain_set_hwirq_and_chip(domain, virq + i, | 1324 | irq_domain_set_hwirq_and_chip(domain, virq + i, |
| 1289 | hwirq, &its_irq_chip, its_dev); | 1325 | hwirq, &its_irq_chip, its_dev); |
| 1290 | dev_dbg(info->scratchpad[1].ptr, "ID:%d pID:%d vID:%d\n", | 1326 | dev_dbg(info->scratchpad[1].ptr, "ID:%d pID:%d vID:%d\n", |
| 1291 | (int)(hwirq - its_dev->lpi_base), (int)hwirq, virq + i); | 1327 | (int)(hwirq - its_dev->event_map.lpi_base), |
| 1328 | (int)hwirq, virq + i); | ||
| 1292 | } | 1329 | } |
| 1293 | 1330 | ||
| 1294 | return 0; | 1331 | return 0; |
| @@ -1300,6 +1337,9 @@ static void its_irq_domain_activate(struct irq_domain *domain, | |||
| 1300 | struct its_device *its_dev = irq_data_get_irq_chip_data(d); | 1337 | struct its_device *its_dev = irq_data_get_irq_chip_data(d); |
| 1301 | u32 event = its_get_event_id(d); | 1338 | u32 event = its_get_event_id(d); |
| 1302 | 1339 | ||
| 1340 | /* Bind the LPI to the first possible CPU */ | ||
| 1341 | its_dev->event_map.col_map[event] = cpumask_first(cpu_online_mask); | ||
| 1342 | |||
| 1303 | /* Map the GIC IRQ and event to the device */ | 1343 | /* Map the GIC IRQ and event to the device */ |
| 1304 | its_send_mapvi(its_dev, d->hwirq, event); | 1344 | its_send_mapvi(its_dev, d->hwirq, event); |
| 1305 | } | 1345 | } |
| @@ -1327,17 +1367,16 @@ static void its_irq_domain_free(struct irq_domain *domain, unsigned int virq, | |||
| 1327 | u32 event = its_get_event_id(data); | 1367 | u32 event = its_get_event_id(data); |
| 1328 | 1368 | ||
| 1329 | /* Mark interrupt index as unused */ | 1369 | /* Mark interrupt index as unused */ |
| 1330 | clear_bit(event, its_dev->lpi_map); | 1370 | clear_bit(event, its_dev->event_map.lpi_map); |
| 1331 | 1371 | ||
| 1332 | /* Nuke the entry in the domain */ | 1372 | /* Nuke the entry in the domain */ |
| 1333 | irq_domain_reset_irq_data(data); | 1373 | irq_domain_reset_irq_data(data); |
| 1334 | } | 1374 | } |
| 1335 | 1375 | ||
| 1336 | /* If all interrupts have been freed, start mopping the floor */ | 1376 | /* If all interrupts have been freed, start mopping the floor */ |
| 1337 | if (bitmap_empty(its_dev->lpi_map, its_dev->nr_lpis)) { | 1377 | if (bitmap_empty(its_dev->event_map.lpi_map, |
| 1338 | its_lpi_free(its_dev->lpi_map, | 1378 | its_dev->event_map.nr_lpis)) { |
| 1339 | its_dev->lpi_base, | 1379 | its_lpi_free(&its_dev->event_map); |
| 1340 | its_dev->nr_lpis); | ||
| 1341 | 1380 | ||
| 1342 | /* Unmap device/itt */ | 1381 | /* Unmap device/itt */ |
| 1343 | its_send_mapd(its_dev, 0); | 1382 | its_send_mapd(its_dev, 0); |
diff --git a/drivers/irqchip/spear-shirq.c b/drivers/irqchip/spear-shirq.c index a45121546caf..acb721b31bcf 100644 --- a/drivers/irqchip/spear-shirq.c +++ b/drivers/irqchip/spear-shirq.c | |||
| @@ -2,7 +2,7 @@ | |||
| 2 | * SPEAr platform shared irq layer source file | 2 | * SPEAr platform shared irq layer source file |
| 3 | * | 3 | * |
| 4 | * Copyright (C) 2009-2012 ST Microelectronics | 4 | * Copyright (C) 2009-2012 ST Microelectronics |
| 5 | * Viresh Kumar <viresh.linux@gmail.com> | 5 | * Viresh Kumar <vireshk@kernel.org> |
| 6 | * | 6 | * |
| 7 | * Copyright (C) 2012 ST Microelectronics | 7 | * Copyright (C) 2012 ST Microelectronics |
| 8 | * Shiraz Hashim <shiraz.linux.kernel@gmail.com> | 8 | * Shiraz Hashim <shiraz.linux.kernel@gmail.com> |
diff --git a/drivers/isdn/gigaset/ser-gigaset.c b/drivers/isdn/gigaset/ser-gigaset.c index 8c91fd5eb6fd..375be509e95f 100644 --- a/drivers/isdn/gigaset/ser-gigaset.c +++ b/drivers/isdn/gigaset/ser-gigaset.c | |||
| @@ -524,9 +524,18 @@ gigaset_tty_open(struct tty_struct *tty) | |||
| 524 | cs->hw.ser->tty = tty; | 524 | cs->hw.ser->tty = tty; |
| 525 | atomic_set(&cs->hw.ser->refcnt, 1); | 525 | atomic_set(&cs->hw.ser->refcnt, 1); |
| 526 | init_completion(&cs->hw.ser->dead_cmp); | 526 | init_completion(&cs->hw.ser->dead_cmp); |
| 527 | |||
| 528 | tty->disc_data = cs; | 527 | tty->disc_data = cs; |
| 529 | 528 | ||
| 529 | /* Set the amount of data we're willing to receive per call | ||
| 530 | * from the hardware driver to half of the input buffer size | ||
| 531 | * to leave some reserve. | ||
| 532 | * Note: We don't do flow control towards the hardware driver. | ||
| 533 | * If more data is received than will fit into the input buffer, | ||
| 534 | * it will be dropped and an error will be logged. This should | ||
| 535 | * never happen as the device is slow and the buffer size ample. | ||
| 536 | */ | ||
| 537 | tty->receive_room = RBUFSIZE/2; | ||
| 538 | |||
| 530 | /* OK.. Initialization of the datastructures and the HW is done.. Now | 539 | /* OK.. Initialization of the datastructures and the HW is done.. Now |
| 531 | * startup system and notify the LL that we are ready to run | 540 | * startup system and notify the LL that we are ready to run |
| 532 | */ | 541 | */ |
| @@ -598,28 +607,6 @@ static int gigaset_tty_hangup(struct tty_struct *tty) | |||
| 598 | } | 607 | } |
| 599 | 608 | ||
| 600 | /* | 609 | /* |
| 601 | * Read on the tty. | ||
| 602 | * Unused, received data goes only to the Gigaset driver. | ||
| 603 | */ | ||
| 604 | static ssize_t | ||
| 605 | gigaset_tty_read(struct tty_struct *tty, struct file *file, | ||
| 606 | unsigned char __user *buf, size_t count) | ||
| 607 | { | ||
| 608 | return -EAGAIN; | ||
| 609 | } | ||
| 610 | |||
| 611 | /* | ||
| 612 | * Write on the tty. | ||
| 613 | * Unused, transmit data comes only from the Gigaset driver. | ||
| 614 | */ | ||
| 615 | static ssize_t | ||
| 616 | gigaset_tty_write(struct tty_struct *tty, struct file *file, | ||
| 617 | const unsigned char *buf, size_t count) | ||
| 618 | { | ||
| 619 | return -EAGAIN; | ||
| 620 | } | ||
| 621 | |||
| 622 | /* | ||
| 623 | * Ioctl on the tty. | 610 | * Ioctl on the tty. |
| 624 | * Called in process context only. | 611 | * Called in process context only. |
| 625 | * May be re-entered by multiple ioctl calling threads. | 612 | * May be re-entered by multiple ioctl calling threads. |
| @@ -752,8 +739,6 @@ static struct tty_ldisc_ops gigaset_ldisc = { | |||
| 752 | .open = gigaset_tty_open, | 739 | .open = gigaset_tty_open, |
| 753 | .close = gigaset_tty_close, | 740 | .close = gigaset_tty_close, |
| 754 | .hangup = gigaset_tty_hangup, | 741 | .hangup = gigaset_tty_hangup, |
| 755 | .read = gigaset_tty_read, | ||
| 756 | .write = gigaset_tty_write, | ||
| 757 | .ioctl = gigaset_tty_ioctl, | 742 | .ioctl = gigaset_tty_ioctl, |
| 758 | .receive_buf = gigaset_tty_receive, | 743 | .receive_buf = gigaset_tty_receive, |
| 759 | .write_wakeup = gigaset_tty_wakeup, | 744 | .write_wakeup = gigaset_tty_wakeup, |
diff --git a/drivers/md/bcache/closure.h b/drivers/md/bcache/closure.h index a08e3eeac3c5..79a6d63e8ed3 100644 --- a/drivers/md/bcache/closure.h +++ b/drivers/md/bcache/closure.h | |||
| @@ -320,7 +320,6 @@ static inline void closure_wake_up(struct closure_waitlist *list) | |||
| 320 | do { \ | 320 | do { \ |
| 321 | set_closure_fn(_cl, _fn, _wq); \ | 321 | set_closure_fn(_cl, _fn, _wq); \ |
| 322 | closure_sub(_cl, CLOSURE_RUNNING + 1); \ | 322 | closure_sub(_cl, CLOSURE_RUNNING + 1); \ |
| 323 | return; \ | ||
| 324 | } while (0) | 323 | } while (0) |
| 325 | 324 | ||
| 326 | /** | 325 | /** |
| @@ -349,7 +348,6 @@ do { \ | |||
| 349 | do { \ | 348 | do { \ |
| 350 | set_closure_fn(_cl, _fn, _wq); \ | 349 | set_closure_fn(_cl, _fn, _wq); \ |
| 351 | closure_queue(_cl); \ | 350 | closure_queue(_cl); \ |
| 352 | return; \ | ||
| 353 | } while (0) | 351 | } while (0) |
| 354 | 352 | ||
| 355 | /** | 353 | /** |
| @@ -365,7 +363,6 @@ do { \ | |||
| 365 | do { \ | 363 | do { \ |
| 366 | set_closure_fn(_cl, _destructor, NULL); \ | 364 | set_closure_fn(_cl, _destructor, NULL); \ |
| 367 | closure_sub(_cl, CLOSURE_RUNNING - CLOSURE_DESTRUCTOR + 1); \ | 365 | closure_sub(_cl, CLOSURE_RUNNING - CLOSURE_DESTRUCTOR + 1); \ |
| 368 | return; \ | ||
| 369 | } while (0) | 366 | } while (0) |
| 370 | 367 | ||
| 371 | /** | 368 | /** |
diff --git a/drivers/md/bcache/io.c b/drivers/md/bcache/io.c index cb64e64a4789..bf6a9ca18403 100644 --- a/drivers/md/bcache/io.c +++ b/drivers/md/bcache/io.c | |||
| @@ -105,6 +105,7 @@ void bch_generic_make_request(struct bio *bio, struct bio_split_pool *p) | |||
| 105 | } while (n != bio); | 105 | } while (n != bio); |
| 106 | 106 | ||
| 107 | continue_at(&s->cl, bch_bio_submit_split_done, NULL); | 107 | continue_at(&s->cl, bch_bio_submit_split_done, NULL); |
| 108 | return; | ||
| 108 | submit: | 109 | submit: |
| 109 | generic_make_request(bio); | 110 | generic_make_request(bio); |
| 110 | } | 111 | } |
diff --git a/drivers/md/bcache/journal.c b/drivers/md/bcache/journal.c index ce64fc851251..418607a6ba33 100644 --- a/drivers/md/bcache/journal.c +++ b/drivers/md/bcache/journal.c | |||
| @@ -592,12 +592,14 @@ static void journal_write_unlocked(struct closure *cl) | |||
| 592 | 592 | ||
| 593 | if (!w->need_write) { | 593 | if (!w->need_write) { |
| 594 | closure_return_with_destructor(cl, journal_write_unlock); | 594 | closure_return_with_destructor(cl, journal_write_unlock); |
| 595 | return; | ||
| 595 | } else if (journal_full(&c->journal)) { | 596 | } else if (journal_full(&c->journal)) { |
| 596 | journal_reclaim(c); | 597 | journal_reclaim(c); |
| 597 | spin_unlock(&c->journal.lock); | 598 | spin_unlock(&c->journal.lock); |
| 598 | 599 | ||
| 599 | btree_flush_write(c); | 600 | btree_flush_write(c); |
| 600 | continue_at(cl, journal_write, system_wq); | 601 | continue_at(cl, journal_write, system_wq); |
| 602 | return; | ||
| 601 | } | 603 | } |
| 602 | 604 | ||
| 603 | c->journal.blocks_free -= set_blocks(w->data, block_bytes(c)); | 605 | c->journal.blocks_free -= set_blocks(w->data, block_bytes(c)); |
diff --git a/drivers/md/bcache/request.c b/drivers/md/bcache/request.c index 4afb2d26b148..f292790997d7 100644 --- a/drivers/md/bcache/request.c +++ b/drivers/md/bcache/request.c | |||
| @@ -88,8 +88,10 @@ static void bch_data_insert_keys(struct closure *cl) | |||
| 88 | if (journal_ref) | 88 | if (journal_ref) |
| 89 | atomic_dec_bug(journal_ref); | 89 | atomic_dec_bug(journal_ref); |
| 90 | 90 | ||
| 91 | if (!op->insert_data_done) | 91 | if (!op->insert_data_done) { |
| 92 | continue_at(cl, bch_data_insert_start, op->wq); | 92 | continue_at(cl, bch_data_insert_start, op->wq); |
| 93 | return; | ||
| 94 | } | ||
| 93 | 95 | ||
| 94 | bch_keylist_free(&op->insert_keys); | 96 | bch_keylist_free(&op->insert_keys); |
| 95 | closure_return(cl); | 97 | closure_return(cl); |
| @@ -216,8 +218,10 @@ static void bch_data_insert_start(struct closure *cl) | |||
| 216 | /* 1 for the device pointer and 1 for the chksum */ | 218 | /* 1 for the device pointer and 1 for the chksum */ |
| 217 | if (bch_keylist_realloc(&op->insert_keys, | 219 | if (bch_keylist_realloc(&op->insert_keys, |
| 218 | 3 + (op->csum ? 1 : 0), | 220 | 3 + (op->csum ? 1 : 0), |
| 219 | op->c)) | 221 | op->c)) { |
| 220 | continue_at(cl, bch_data_insert_keys, op->wq); | 222 | continue_at(cl, bch_data_insert_keys, op->wq); |
| 223 | return; | ||
| 224 | } | ||
| 221 | 225 | ||
| 222 | k = op->insert_keys.top; | 226 | k = op->insert_keys.top; |
| 223 | bkey_init(k); | 227 | bkey_init(k); |
| @@ -255,6 +259,7 @@ static void bch_data_insert_start(struct closure *cl) | |||
| 255 | 259 | ||
| 256 | op->insert_data_done = true; | 260 | op->insert_data_done = true; |
| 257 | continue_at(cl, bch_data_insert_keys, op->wq); | 261 | continue_at(cl, bch_data_insert_keys, op->wq); |
| 262 | return; | ||
| 258 | err: | 263 | err: |
| 259 | /* bch_alloc_sectors() blocks if s->writeback = true */ | 264 | /* bch_alloc_sectors() blocks if s->writeback = true */ |
| 260 | BUG_ON(op->writeback); | 265 | BUG_ON(op->writeback); |
| @@ -576,8 +581,10 @@ static void cache_lookup(struct closure *cl) | |||
| 576 | ret = bch_btree_map_keys(&s->op, s->iop.c, | 581 | ret = bch_btree_map_keys(&s->op, s->iop.c, |
| 577 | &KEY(s->iop.inode, bio->bi_iter.bi_sector, 0), | 582 | &KEY(s->iop.inode, bio->bi_iter.bi_sector, 0), |
| 578 | cache_lookup_fn, MAP_END_KEY); | 583 | cache_lookup_fn, MAP_END_KEY); |
| 579 | if (ret == -EAGAIN) | 584 | if (ret == -EAGAIN) { |
| 580 | continue_at(cl, cache_lookup, bcache_wq); | 585 | continue_at(cl, cache_lookup, bcache_wq); |
| 586 | return; | ||
| 587 | } | ||
| 581 | 588 | ||
| 582 | closure_return(cl); | 589 | closure_return(cl); |
| 583 | } | 590 | } |
| @@ -1085,6 +1092,7 @@ static void flash_dev_make_request(struct request_queue *q, struct bio *bio) | |||
| 1085 | continue_at_nobarrier(&s->cl, | 1092 | continue_at_nobarrier(&s->cl, |
| 1086 | flash_dev_nodata, | 1093 | flash_dev_nodata, |
| 1087 | bcache_wq); | 1094 | bcache_wq); |
| 1095 | return; | ||
| 1088 | } else if (rw) { | 1096 | } else if (rw) { |
| 1089 | bch_keybuf_check_overlapping(&s->iop.c->moving_gc_keys, | 1097 | bch_keybuf_check_overlapping(&s->iop.c->moving_gc_keys, |
| 1090 | &KEY(d->id, bio->bi_iter.bi_sector, 0), | 1098 | &KEY(d->id, bio->bi_iter.bi_sector, 0), |
diff --git a/drivers/md/dm-cache-target.c b/drivers/md/dm-cache-target.c index 1b4e1756b169..b680da5d7b93 100644 --- a/drivers/md/dm-cache-target.c +++ b/drivers/md/dm-cache-target.c | |||
| @@ -424,7 +424,6 @@ static void free_migration(struct dm_cache_migration *mg) | |||
| 424 | wake_up(&cache->migration_wait); | 424 | wake_up(&cache->migration_wait); |
| 425 | 425 | ||
| 426 | mempool_free(mg, cache->migration_pool); | 426 | mempool_free(mg, cache->migration_pool); |
| 427 | wake_worker(cache); | ||
| 428 | } | 427 | } |
| 429 | 428 | ||
| 430 | static int prealloc_data_structs(struct cache *cache, struct prealloc *p) | 429 | static int prealloc_data_structs(struct cache *cache, struct prealloc *p) |
| @@ -1947,6 +1946,7 @@ static int commit_if_needed(struct cache *cache) | |||
| 1947 | 1946 | ||
| 1948 | static void process_deferred_bios(struct cache *cache) | 1947 | static void process_deferred_bios(struct cache *cache) |
| 1949 | { | 1948 | { |
| 1949 | bool prealloc_used = false; | ||
| 1950 | unsigned long flags; | 1950 | unsigned long flags; |
| 1951 | struct bio_list bios; | 1951 | struct bio_list bios; |
| 1952 | struct bio *bio; | 1952 | struct bio *bio; |
| @@ -1981,13 +1981,16 @@ static void process_deferred_bios(struct cache *cache) | |||
| 1981 | process_discard_bio(cache, &structs, bio); | 1981 | process_discard_bio(cache, &structs, bio); |
| 1982 | else | 1982 | else |
| 1983 | process_bio(cache, &structs, bio); | 1983 | process_bio(cache, &structs, bio); |
| 1984 | prealloc_used = true; | ||
| 1984 | } | 1985 | } |
| 1985 | 1986 | ||
| 1986 | prealloc_free_structs(cache, &structs); | 1987 | if (prealloc_used) |
| 1988 | prealloc_free_structs(cache, &structs); | ||
| 1987 | } | 1989 | } |
| 1988 | 1990 | ||
| 1989 | static void process_deferred_cells(struct cache *cache) | 1991 | static void process_deferred_cells(struct cache *cache) |
| 1990 | { | 1992 | { |
| 1993 | bool prealloc_used = false; | ||
| 1991 | unsigned long flags; | 1994 | unsigned long flags; |
| 1992 | struct dm_bio_prison_cell *cell, *tmp; | 1995 | struct dm_bio_prison_cell *cell, *tmp; |
| 1993 | struct list_head cells; | 1996 | struct list_head cells; |
| @@ -2015,9 +2018,11 @@ static void process_deferred_cells(struct cache *cache) | |||
| 2015 | } | 2018 | } |
| 2016 | 2019 | ||
| 2017 | process_cell(cache, &structs, cell); | 2020 | process_cell(cache, &structs, cell); |
| 2021 | prealloc_used = true; | ||
| 2018 | } | 2022 | } |
| 2019 | 2023 | ||
| 2020 | prealloc_free_structs(cache, &structs); | 2024 | if (prealloc_used) |
| 2025 | prealloc_free_structs(cache, &structs); | ||
| 2021 | } | 2026 | } |
| 2022 | 2027 | ||
| 2023 | static void process_deferred_flush_bios(struct cache *cache, bool submit_bios) | 2028 | static void process_deferred_flush_bios(struct cache *cache, bool submit_bios) |
| @@ -2062,7 +2067,7 @@ static void process_deferred_writethrough_bios(struct cache *cache) | |||
| 2062 | 2067 | ||
| 2063 | static void writeback_some_dirty_blocks(struct cache *cache) | 2068 | static void writeback_some_dirty_blocks(struct cache *cache) |
| 2064 | { | 2069 | { |
| 2065 | int r = 0; | 2070 | bool prealloc_used = false; |
| 2066 | dm_oblock_t oblock; | 2071 | dm_oblock_t oblock; |
| 2067 | dm_cblock_t cblock; | 2072 | dm_cblock_t cblock; |
| 2068 | struct prealloc structs; | 2073 | struct prealloc structs; |
| @@ -2072,23 +2077,21 @@ static void writeback_some_dirty_blocks(struct cache *cache) | |||
| 2072 | memset(&structs, 0, sizeof(structs)); | 2077 | memset(&structs, 0, sizeof(structs)); |
| 2073 | 2078 | ||
| 2074 | while (spare_migration_bandwidth(cache)) { | 2079 | while (spare_migration_bandwidth(cache)) { |
| 2075 | if (prealloc_data_structs(cache, &structs)) | 2080 | if (policy_writeback_work(cache->policy, &oblock, &cblock, busy)) |
| 2076 | break; | 2081 | break; /* no work to do */ |
| 2077 | 2082 | ||
| 2078 | r = policy_writeback_work(cache->policy, &oblock, &cblock, busy); | 2083 | if (prealloc_data_structs(cache, &structs) || |
| 2079 | if (r) | 2084 | get_cell(cache, oblock, &structs, &old_ocell)) { |
| 2080 | break; | ||
| 2081 | |||
| 2082 | r = get_cell(cache, oblock, &structs, &old_ocell); | ||
| 2083 | if (r) { | ||
| 2084 | policy_set_dirty(cache->policy, oblock); | 2085 | policy_set_dirty(cache->policy, oblock); |
| 2085 | break; | 2086 | break; |
| 2086 | } | 2087 | } |
| 2087 | 2088 | ||
| 2088 | writeback(cache, &structs, oblock, cblock, old_ocell); | 2089 | writeback(cache, &structs, oblock, cblock, old_ocell); |
| 2090 | prealloc_used = true; | ||
| 2089 | } | 2091 | } |
| 2090 | 2092 | ||
| 2091 | prealloc_free_structs(cache, &structs); | 2093 | if (prealloc_used) |
| 2094 | prealloc_free_structs(cache, &structs); | ||
| 2092 | } | 2095 | } |
| 2093 | 2096 | ||
| 2094 | /*---------------------------------------------------------------- | 2097 | /*---------------------------------------------------------------- |
| @@ -3496,7 +3499,7 @@ static void cache_resume(struct dm_target *ti) | |||
| 3496 | * <#demotions> <#promotions> <#dirty> | 3499 | * <#demotions> <#promotions> <#dirty> |
| 3497 | * <#features> <features>* | 3500 | * <#features> <features>* |
| 3498 | * <#core args> <core args> | 3501 | * <#core args> <core args> |
| 3499 | * <policy name> <#policy args> <policy args>* <cache metadata mode> | 3502 | * <policy name> <#policy args> <policy args>* <cache metadata mode> <needs_check> |
| 3500 | */ | 3503 | */ |
| 3501 | static void cache_status(struct dm_target *ti, status_type_t type, | 3504 | static void cache_status(struct dm_target *ti, status_type_t type, |
| 3502 | unsigned status_flags, char *result, unsigned maxlen) | 3505 | unsigned status_flags, char *result, unsigned maxlen) |
| @@ -3582,6 +3585,11 @@ static void cache_status(struct dm_target *ti, status_type_t type, | |||
| 3582 | else | 3585 | else |
| 3583 | DMEMIT("rw "); | 3586 | DMEMIT("rw "); |
| 3584 | 3587 | ||
| 3588 | if (dm_cache_metadata_needs_check(cache->cmd)) | ||
| 3589 | DMEMIT("needs_check "); | ||
| 3590 | else | ||
| 3591 | DMEMIT("- "); | ||
| 3592 | |||
| 3585 | break; | 3593 | break; |
| 3586 | 3594 | ||
| 3587 | case STATUSTYPE_TABLE: | 3595 | case STATUSTYPE_TABLE: |
| @@ -3820,7 +3828,7 @@ static void cache_io_hints(struct dm_target *ti, struct queue_limits *limits) | |||
| 3820 | 3828 | ||
| 3821 | static struct target_type cache_target = { | 3829 | static struct target_type cache_target = { |
| 3822 | .name = "cache", | 3830 | .name = "cache", |
| 3823 | .version = {1, 7, 0}, | 3831 | .version = {1, 8, 0}, |
| 3824 | .module = THIS_MODULE, | 3832 | .module = THIS_MODULE, |
| 3825 | .ctr = cache_ctr, | 3833 | .ctr = cache_ctr, |
| 3826 | .dtr = cache_dtr, | 3834 | .dtr = cache_dtr, |
diff --git a/drivers/md/dm-thin.c b/drivers/md/dm-thin.c index c33f61a4cc28..1c50c580215c 100644 --- a/drivers/md/dm-thin.c +++ b/drivers/md/dm-thin.c | |||
| @@ -18,6 +18,7 @@ | |||
| 18 | #include <linux/init.h> | 18 | #include <linux/init.h> |
| 19 | #include <linux/module.h> | 19 | #include <linux/module.h> |
| 20 | #include <linux/slab.h> | 20 | #include <linux/slab.h> |
| 21 | #include <linux/vmalloc.h> | ||
| 21 | #include <linux/sort.h> | 22 | #include <linux/sort.h> |
| 22 | #include <linux/rbtree.h> | 23 | #include <linux/rbtree.h> |
| 23 | 24 | ||
| @@ -268,7 +269,7 @@ struct pool { | |||
| 268 | process_mapping_fn process_prepared_mapping; | 269 | process_mapping_fn process_prepared_mapping; |
| 269 | process_mapping_fn process_prepared_discard; | 270 | process_mapping_fn process_prepared_discard; |
| 270 | 271 | ||
| 271 | struct dm_bio_prison_cell *cell_sort_array[CELL_SORT_ARRAY_SIZE]; | 272 | struct dm_bio_prison_cell **cell_sort_array; |
| 272 | }; | 273 | }; |
| 273 | 274 | ||
| 274 | static enum pool_mode get_pool_mode(struct pool *pool); | 275 | static enum pool_mode get_pool_mode(struct pool *pool); |
| @@ -2281,18 +2282,23 @@ static void do_waker(struct work_struct *ws) | |||
| 2281 | queue_delayed_work(pool->wq, &pool->waker, COMMIT_PERIOD); | 2282 | queue_delayed_work(pool->wq, &pool->waker, COMMIT_PERIOD); |
| 2282 | } | 2283 | } |
| 2283 | 2284 | ||
| 2285 | static void notify_of_pool_mode_change_to_oods(struct pool *pool); | ||
| 2286 | |||
| 2284 | /* | 2287 | /* |
| 2285 | * We're holding onto IO to allow userland time to react. After the | 2288 | * We're holding onto IO to allow userland time to react. After the |
| 2286 | * timeout either the pool will have been resized (and thus back in | 2289 | * timeout either the pool will have been resized (and thus back in |
| 2287 | * PM_WRITE mode), or we degrade to PM_READ_ONLY and start erroring IO. | 2290 | * PM_WRITE mode), or we degrade to PM_OUT_OF_DATA_SPACE w/ error_if_no_space. |
| 2288 | */ | 2291 | */ |
| 2289 | static void do_no_space_timeout(struct work_struct *ws) | 2292 | static void do_no_space_timeout(struct work_struct *ws) |
| 2290 | { | 2293 | { |
| 2291 | struct pool *pool = container_of(to_delayed_work(ws), struct pool, | 2294 | struct pool *pool = container_of(to_delayed_work(ws), struct pool, |
| 2292 | no_space_timeout); | 2295 | no_space_timeout); |
| 2293 | 2296 | ||
| 2294 | if (get_pool_mode(pool) == PM_OUT_OF_DATA_SPACE && !pool->pf.error_if_no_space) | 2297 | if (get_pool_mode(pool) == PM_OUT_OF_DATA_SPACE && !pool->pf.error_if_no_space) { |
| 2295 | set_pool_mode(pool, PM_READ_ONLY); | 2298 | pool->pf.error_if_no_space = true; |
| 2299 | notify_of_pool_mode_change_to_oods(pool); | ||
| 2300 | error_retry_list(pool); | ||
| 2301 | } | ||
| 2296 | } | 2302 | } |
| 2297 | 2303 | ||
| 2298 | /*----------------------------------------------------------------*/ | 2304 | /*----------------------------------------------------------------*/ |
| @@ -2370,6 +2376,14 @@ static void notify_of_pool_mode_change(struct pool *pool, const char *new_mode) | |||
| 2370 | dm_device_name(pool->pool_md), new_mode); | 2376 | dm_device_name(pool->pool_md), new_mode); |
| 2371 | } | 2377 | } |
| 2372 | 2378 | ||
| 2379 | static void notify_of_pool_mode_change_to_oods(struct pool *pool) | ||
| 2380 | { | ||
| 2381 | if (!pool->pf.error_if_no_space) | ||
| 2382 | notify_of_pool_mode_change(pool, "out-of-data-space (queue IO)"); | ||
| 2383 | else | ||
| 2384 | notify_of_pool_mode_change(pool, "out-of-data-space (error IO)"); | ||
| 2385 | } | ||
| 2386 | |||
| 2373 | static bool passdown_enabled(struct pool_c *pt) | 2387 | static bool passdown_enabled(struct pool_c *pt) |
| 2374 | { | 2388 | { |
| 2375 | return pt->adjusted_pf.discard_passdown; | 2389 | return pt->adjusted_pf.discard_passdown; |
| @@ -2454,7 +2468,7 @@ static void set_pool_mode(struct pool *pool, enum pool_mode new_mode) | |||
| 2454 | * frequently seeing this mode. | 2468 | * frequently seeing this mode. |
| 2455 | */ | 2469 | */ |
| 2456 | if (old_mode != new_mode) | 2470 | if (old_mode != new_mode) |
| 2457 | notify_of_pool_mode_change(pool, "out-of-data-space"); | 2471 | notify_of_pool_mode_change_to_oods(pool); |
| 2458 | pool->process_bio = process_bio_read_only; | 2472 | pool->process_bio = process_bio_read_only; |
| 2459 | pool->process_discard = process_discard_bio; | 2473 | pool->process_discard = process_discard_bio; |
| 2460 | pool->process_cell = process_cell_read_only; | 2474 | pool->process_cell = process_cell_read_only; |
| @@ -2777,6 +2791,7 @@ static void __pool_destroy(struct pool *pool) | |||
| 2777 | { | 2791 | { |
| 2778 | __pool_table_remove(pool); | 2792 | __pool_table_remove(pool); |
| 2779 | 2793 | ||
| 2794 | vfree(pool->cell_sort_array); | ||
| 2780 | if (dm_pool_metadata_close(pool->pmd) < 0) | 2795 | if (dm_pool_metadata_close(pool->pmd) < 0) |
| 2781 | DMWARN("%s: dm_pool_metadata_close() failed.", __func__); | 2796 | DMWARN("%s: dm_pool_metadata_close() failed.", __func__); |
| 2782 | 2797 | ||
| @@ -2889,6 +2904,13 @@ static struct pool *pool_create(struct mapped_device *pool_md, | |||
| 2889 | goto bad_mapping_pool; | 2904 | goto bad_mapping_pool; |
| 2890 | } | 2905 | } |
| 2891 | 2906 | ||
| 2907 | pool->cell_sort_array = vmalloc(sizeof(*pool->cell_sort_array) * CELL_SORT_ARRAY_SIZE); | ||
| 2908 | if (!pool->cell_sort_array) { | ||
| 2909 | *error = "Error allocating cell sort array"; | ||
| 2910 | err_p = ERR_PTR(-ENOMEM); | ||
| 2911 | goto bad_sort_array; | ||
| 2912 | } | ||
| 2913 | |||
| 2892 | pool->ref_count = 1; | 2914 | pool->ref_count = 1; |
| 2893 | pool->last_commit_jiffies = jiffies; | 2915 | pool->last_commit_jiffies = jiffies; |
| 2894 | pool->pool_md = pool_md; | 2916 | pool->pool_md = pool_md; |
| @@ -2897,6 +2919,8 @@ static struct pool *pool_create(struct mapped_device *pool_md, | |||
| 2897 | 2919 | ||
| 2898 | return pool; | 2920 | return pool; |
| 2899 | 2921 | ||
| 2922 | bad_sort_array: | ||
| 2923 | mempool_destroy(pool->mapping_pool); | ||
| 2900 | bad_mapping_pool: | 2924 | bad_mapping_pool: |
| 2901 | dm_deferred_set_destroy(pool->all_io_ds); | 2925 | dm_deferred_set_destroy(pool->all_io_ds); |
| 2902 | bad_all_io_ds: | 2926 | bad_all_io_ds: |
| @@ -3714,6 +3738,7 @@ static void emit_flags(struct pool_features *pf, char *result, | |||
| 3714 | * Status line is: | 3738 | * Status line is: |
| 3715 | * <transaction id> <used metadata sectors>/<total metadata sectors> | 3739 | * <transaction id> <used metadata sectors>/<total metadata sectors> |
| 3716 | * <used data sectors>/<total data sectors> <held metadata root> | 3740 | * <used data sectors>/<total data sectors> <held metadata root> |
| 3741 | * <pool mode> <discard config> <no space config> <needs_check> | ||
| 3717 | */ | 3742 | */ |
| 3718 | static void pool_status(struct dm_target *ti, status_type_t type, | 3743 | static void pool_status(struct dm_target *ti, status_type_t type, |
| 3719 | unsigned status_flags, char *result, unsigned maxlen) | 3744 | unsigned status_flags, char *result, unsigned maxlen) |
| @@ -3815,6 +3840,11 @@ static void pool_status(struct dm_target *ti, status_type_t type, | |||
| 3815 | else | 3840 | else |
| 3816 | DMEMIT("queue_if_no_space "); | 3841 | DMEMIT("queue_if_no_space "); |
| 3817 | 3842 | ||
| 3843 | if (dm_pool_metadata_needs_check(pool->pmd)) | ||
| 3844 | DMEMIT("needs_check "); | ||
| 3845 | else | ||
| 3846 | DMEMIT("- "); | ||
| 3847 | |||
| 3818 | break; | 3848 | break; |
| 3819 | 3849 | ||
| 3820 | case STATUSTYPE_TABLE: | 3850 | case STATUSTYPE_TABLE: |
| @@ -3918,7 +3948,7 @@ static struct target_type pool_target = { | |||
| 3918 | .name = "thin-pool", | 3948 | .name = "thin-pool", |
| 3919 | .features = DM_TARGET_SINGLETON | DM_TARGET_ALWAYS_WRITEABLE | | 3949 | .features = DM_TARGET_SINGLETON | DM_TARGET_ALWAYS_WRITEABLE | |
| 3920 | DM_TARGET_IMMUTABLE, | 3950 | DM_TARGET_IMMUTABLE, |
| 3921 | .version = {1, 15, 0}, | 3951 | .version = {1, 16, 0}, |
| 3922 | .module = THIS_MODULE, | 3952 | .module = THIS_MODULE, |
| 3923 | .ctr = pool_ctr, | 3953 | .ctr = pool_ctr, |
| 3924 | .dtr = pool_dtr, | 3954 | .dtr = pool_dtr, |
| @@ -4305,7 +4335,7 @@ static void thin_io_hints(struct dm_target *ti, struct queue_limits *limits) | |||
| 4305 | 4335 | ||
| 4306 | static struct target_type thin_target = { | 4336 | static struct target_type thin_target = { |
| 4307 | .name = "thin", | 4337 | .name = "thin", |
| 4308 | .version = {1, 15, 0}, | 4338 | .version = {1, 16, 0}, |
| 4309 | .module = THIS_MODULE, | 4339 | .module = THIS_MODULE, |
| 4310 | .ctr = thin_ctr, | 4340 | .ctr = thin_ctr, |
| 4311 | .dtr = thin_dtr, | 4341 | .dtr = thin_dtr, |
diff --git a/drivers/md/dm.c b/drivers/md/dm.c index f331d888e7f5..ab37ae114e94 100644 --- a/drivers/md/dm.c +++ b/drivers/md/dm.c | |||
| @@ -1067,13 +1067,10 @@ static void rq_end_stats(struct mapped_device *md, struct request *orig) | |||
| 1067 | */ | 1067 | */ |
| 1068 | static void rq_completed(struct mapped_device *md, int rw, bool run_queue) | 1068 | static void rq_completed(struct mapped_device *md, int rw, bool run_queue) |
| 1069 | { | 1069 | { |
| 1070 | int nr_requests_pending; | ||
| 1071 | |||
| 1072 | atomic_dec(&md->pending[rw]); | 1070 | atomic_dec(&md->pending[rw]); |
| 1073 | 1071 | ||
| 1074 | /* nudge anyone waiting on suspend queue */ | 1072 | /* nudge anyone waiting on suspend queue */ |
| 1075 | nr_requests_pending = md_in_flight(md); | 1073 | if (!md_in_flight(md)) |
| 1076 | if (!nr_requests_pending) | ||
| 1077 | wake_up(&md->wait); | 1074 | wake_up(&md->wait); |
| 1078 | 1075 | ||
| 1079 | /* | 1076 | /* |
| @@ -1085,8 +1082,7 @@ static void rq_completed(struct mapped_device *md, int rw, bool run_queue) | |||
| 1085 | if (run_queue) { | 1082 | if (run_queue) { |
| 1086 | if (md->queue->mq_ops) | 1083 | if (md->queue->mq_ops) |
| 1087 | blk_mq_run_hw_queues(md->queue, true); | 1084 | blk_mq_run_hw_queues(md->queue, true); |
| 1088 | else if (!nr_requests_pending || | 1085 | else |
| 1089 | (nr_requests_pending >= md->queue->nr_congestion_on)) | ||
| 1090 | blk_run_queue_async(md->queue); | 1086 | blk_run_queue_async(md->queue); |
| 1091 | } | 1087 | } |
| 1092 | 1088 | ||
| @@ -2281,8 +2277,6 @@ static void dm_init_old_md_queue(struct mapped_device *md) | |||
| 2281 | 2277 | ||
| 2282 | static void cleanup_mapped_device(struct mapped_device *md) | 2278 | static void cleanup_mapped_device(struct mapped_device *md) |
| 2283 | { | 2279 | { |
| 2284 | cleanup_srcu_struct(&md->io_barrier); | ||
| 2285 | |||
| 2286 | if (md->wq) | 2280 | if (md->wq) |
| 2287 | destroy_workqueue(md->wq); | 2281 | destroy_workqueue(md->wq); |
| 2288 | if (md->kworker_task) | 2282 | if (md->kworker_task) |
| @@ -2294,6 +2288,8 @@ static void cleanup_mapped_device(struct mapped_device *md) | |||
| 2294 | if (md->bs) | 2288 | if (md->bs) |
| 2295 | bioset_free(md->bs); | 2289 | bioset_free(md->bs); |
| 2296 | 2290 | ||
| 2291 | cleanup_srcu_struct(&md->io_barrier); | ||
| 2292 | |||
| 2297 | if (md->disk) { | 2293 | if (md->disk) { |
| 2298 | spin_lock(&_minor_lock); | 2294 | spin_lock(&_minor_lock); |
| 2299 | md->disk->private_data = NULL; | 2295 | md->disk->private_data = NULL; |
diff --git a/drivers/md/persistent-data/dm-btree-remove.c b/drivers/md/persistent-data/dm-btree-remove.c index e04cfd2d60ef..9836c0ae897c 100644 --- a/drivers/md/persistent-data/dm-btree-remove.c +++ b/drivers/md/persistent-data/dm-btree-remove.c | |||
| @@ -309,8 +309,8 @@ static void redistribute3(struct dm_btree_info *info, struct btree_node *parent, | |||
| 309 | 309 | ||
| 310 | if (s < 0 && nr_center < -s) { | 310 | if (s < 0 && nr_center < -s) { |
| 311 | /* not enough in central node */ | 311 | /* not enough in central node */ |
| 312 | shift(left, center, nr_center); | 312 | shift(left, center, -nr_center); |
| 313 | s = nr_center - target; | 313 | s += nr_center; |
| 314 | shift(left, right, s); | 314 | shift(left, right, s); |
| 315 | nr_right += s; | 315 | nr_right += s; |
| 316 | } else | 316 | } else |
| @@ -323,7 +323,7 @@ static void redistribute3(struct dm_btree_info *info, struct btree_node *parent, | |||
| 323 | if (s > 0 && nr_center < s) { | 323 | if (s > 0 && nr_center < s) { |
| 324 | /* not enough in central node */ | 324 | /* not enough in central node */ |
| 325 | shift(center, right, nr_center); | 325 | shift(center, right, nr_center); |
| 326 | s = target - nr_center; | 326 | s -= nr_center; |
| 327 | shift(left, right, s); | 327 | shift(left, right, s); |
| 328 | nr_left -= s; | 328 | nr_left -= s; |
| 329 | } else | 329 | } else |
diff --git a/drivers/md/persistent-data/dm-btree.c b/drivers/md/persistent-data/dm-btree.c index 200ac12a1d40..fdd3793e22f9 100644 --- a/drivers/md/persistent-data/dm-btree.c +++ b/drivers/md/persistent-data/dm-btree.c | |||
| @@ -255,7 +255,7 @@ int dm_btree_del(struct dm_btree_info *info, dm_block_t root) | |||
| 255 | int r; | 255 | int r; |
| 256 | struct del_stack *s; | 256 | struct del_stack *s; |
| 257 | 257 | ||
| 258 | s = kmalloc(sizeof(*s), GFP_KERNEL); | 258 | s = kmalloc(sizeof(*s), GFP_NOIO); |
| 259 | if (!s) | 259 | if (!s) |
| 260 | return -ENOMEM; | 260 | return -ENOMEM; |
| 261 | s->info = info; | 261 | s->info = info; |
diff --git a/drivers/mfd/stmpe-i2c.c b/drivers/mfd/stmpe-i2c.c index 5c054031c3f8..e14c8c9d189b 100644 --- a/drivers/mfd/stmpe-i2c.c +++ b/drivers/mfd/stmpe-i2c.c | |||
| @@ -6,7 +6,7 @@ | |||
| 6 | * | 6 | * |
| 7 | * License Terms: GNU General Public License, version 2 | 7 | * License Terms: GNU General Public License, version 2 |
| 8 | * Author: Rabin Vincent <rabin.vincent@stericsson.com> for ST-Ericsson | 8 | * Author: Rabin Vincent <rabin.vincent@stericsson.com> for ST-Ericsson |
| 9 | * Author: Viresh Kumar <viresh.linux@gmail.com> for ST Microelectronics | 9 | * Author: Viresh Kumar <vireshk@kernel.org> for ST Microelectronics |
| 10 | */ | 10 | */ |
| 11 | 11 | ||
| 12 | #include <linux/i2c.h> | 12 | #include <linux/i2c.h> |
diff --git a/drivers/mfd/stmpe-spi.c b/drivers/mfd/stmpe-spi.c index a81badbaa917..6fdb30e84a2b 100644 --- a/drivers/mfd/stmpe-spi.c +++ b/drivers/mfd/stmpe-spi.c | |||
| @@ -4,7 +4,7 @@ | |||
| 4 | * Copyright (C) ST Microelectronics SA 2011 | 4 | * Copyright (C) ST Microelectronics SA 2011 |
| 5 | * | 5 | * |
| 6 | * License Terms: GNU General Public License, version 2 | 6 | * License Terms: GNU General Public License, version 2 |
| 7 | * Author: Viresh Kumar <viresh.linux@gmail.com> for ST Microelectronics | 7 | * Author: Viresh Kumar <vireshk@kernel.org> for ST Microelectronics |
| 8 | */ | 8 | */ |
| 9 | 9 | ||
| 10 | #include <linux/spi/spi.h> | 10 | #include <linux/spi/spi.h> |
| @@ -146,4 +146,4 @@ module_exit(stmpe_exit); | |||
| 146 | 146 | ||
| 147 | MODULE_LICENSE("GPL v2"); | 147 | MODULE_LICENSE("GPL v2"); |
| 148 | MODULE_DESCRIPTION("STMPE MFD SPI Interface Driver"); | 148 | MODULE_DESCRIPTION("STMPE MFD SPI Interface Driver"); |
| 149 | MODULE_AUTHOR("Viresh Kumar <viresh.linux@gmail.com>"); | 149 | MODULE_AUTHOR("Viresh Kumar <vireshk@kernel.org>"); |
diff --git a/drivers/mmc/host/sdhci-spear.c b/drivers/mmc/host/sdhci-spear.c index df088343d60f..255a896769b8 100644 --- a/drivers/mmc/host/sdhci-spear.c +++ b/drivers/mmc/host/sdhci-spear.c | |||
| @@ -4,7 +4,7 @@ | |||
| 4 | * Support of SDHCI platform devices for spear soc family | 4 | * Support of SDHCI platform devices for spear soc family |
| 5 | * | 5 | * |
| 6 | * Copyright (C) 2010 ST Microelectronics | 6 | * Copyright (C) 2010 ST Microelectronics |
| 7 | * Viresh Kumar <viresh.linux@gmail.com> | 7 | * Viresh Kumar <vireshk@kernel.org> |
| 8 | * | 8 | * |
| 9 | * Inspired by sdhci-pltfm.c | 9 | * Inspired by sdhci-pltfm.c |
| 10 | * | 10 | * |
| @@ -211,5 +211,5 @@ static struct platform_driver sdhci_driver = { | |||
| 211 | module_platform_driver(sdhci_driver); | 211 | module_platform_driver(sdhci_driver); |
| 212 | 212 | ||
| 213 | MODULE_DESCRIPTION("SPEAr Secure Digital Host Controller Interface driver"); | 213 | MODULE_DESCRIPTION("SPEAr Secure Digital Host Controller Interface driver"); |
| 214 | MODULE_AUTHOR("Viresh Kumar <viresh.linux@gmail.com>"); | 214 | MODULE_AUTHOR("Viresh Kumar <vireshk@kernel.org>"); |
| 215 | MODULE_LICENSE("GPL v2"); | 215 | MODULE_LICENSE("GPL v2"); |
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index 1c6a773c87ea..0c627b4733ca 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c | |||
| @@ -625,6 +625,23 @@ static void bond_set_dev_addr(struct net_device *bond_dev, | |||
| 625 | call_netdevice_notifiers(NETDEV_CHANGEADDR, bond_dev); | 625 | call_netdevice_notifiers(NETDEV_CHANGEADDR, bond_dev); |
| 626 | } | 626 | } |
| 627 | 627 | ||
| 628 | static struct slave *bond_get_old_active(struct bonding *bond, | ||
| 629 | struct slave *new_active) | ||
| 630 | { | ||
| 631 | struct slave *slave; | ||
| 632 | struct list_head *iter; | ||
| 633 | |||
| 634 | bond_for_each_slave(bond, slave, iter) { | ||
| 635 | if (slave == new_active) | ||
| 636 | continue; | ||
| 637 | |||
| 638 | if (ether_addr_equal(bond->dev->dev_addr, slave->dev->dev_addr)) | ||
| 639 | return slave; | ||
| 640 | } | ||
| 641 | |||
| 642 | return NULL; | ||
| 643 | } | ||
| 644 | |||
| 628 | /* bond_do_fail_over_mac | 645 | /* bond_do_fail_over_mac |
| 629 | * | 646 | * |
| 630 | * Perform special MAC address swapping for fail_over_mac settings | 647 | * Perform special MAC address swapping for fail_over_mac settings |
| @@ -652,6 +669,9 @@ static void bond_do_fail_over_mac(struct bonding *bond, | |||
| 652 | if (!new_active) | 669 | if (!new_active) |
| 653 | return; | 670 | return; |
| 654 | 671 | ||
| 672 | if (!old_active) | ||
| 673 | old_active = bond_get_old_active(bond, new_active); | ||
| 674 | |||
| 655 | if (old_active) { | 675 | if (old_active) { |
| 656 | ether_addr_copy(tmp_mac, new_active->dev->dev_addr); | 676 | ether_addr_copy(tmp_mac, new_active->dev->dev_addr); |
| 657 | ether_addr_copy(saddr.sa_data, | 677 | ether_addr_copy(saddr.sa_data, |
| @@ -1725,9 +1745,16 @@ err_free: | |||
| 1725 | 1745 | ||
| 1726 | err_undo_flags: | 1746 | err_undo_flags: |
| 1727 | /* Enslave of first slave has failed and we need to fix master's mac */ | 1747 | /* Enslave of first slave has failed and we need to fix master's mac */ |
| 1728 | if (!bond_has_slaves(bond) && | 1748 | if (!bond_has_slaves(bond)) { |
| 1729 | ether_addr_equal_64bits(bond_dev->dev_addr, slave_dev->dev_addr)) | 1749 | if (ether_addr_equal_64bits(bond_dev->dev_addr, |
| 1730 | eth_hw_addr_random(bond_dev); | 1750 | slave_dev->dev_addr)) |
| 1751 | eth_hw_addr_random(bond_dev); | ||
| 1752 | if (bond_dev->type != ARPHRD_ETHER) { | ||
| 1753 | ether_setup(bond_dev); | ||
| 1754 | bond_dev->flags |= IFF_MASTER; | ||
| 1755 | bond_dev->priv_flags &= ~IFF_TX_SKB_SHARING; | ||
| 1756 | } | ||
| 1757 | } | ||
| 1731 | 1758 | ||
| 1732 | return res; | 1759 | return res; |
| 1733 | } | 1760 | } |
| @@ -1916,6 +1943,7 @@ static int bond_release_and_destroy(struct net_device *bond_dev, | |||
| 1916 | bond_dev->priv_flags |= IFF_DISABLE_NETPOLL; | 1943 | bond_dev->priv_flags |= IFF_DISABLE_NETPOLL; |
| 1917 | netdev_info(bond_dev, "Destroying bond %s\n", | 1944 | netdev_info(bond_dev, "Destroying bond %s\n", |
| 1918 | bond_dev->name); | 1945 | bond_dev->name); |
| 1946 | bond_remove_proc_entry(bond); | ||
| 1919 | unregister_netdevice(bond_dev); | 1947 | unregister_netdevice(bond_dev); |
| 1920 | } | 1948 | } |
| 1921 | return ret; | 1949 | return ret; |
diff --git a/drivers/net/can/at91_can.c b/drivers/net/can/at91_can.c index f4e40aa4d2a2..945c0955a967 100644 --- a/drivers/net/can/at91_can.c +++ b/drivers/net/can/at91_can.c | |||
| @@ -577,10 +577,10 @@ static void at91_rx_overflow_err(struct net_device *dev) | |||
| 577 | 577 | ||
| 578 | cf->can_id |= CAN_ERR_CRTL; | 578 | cf->can_id |= CAN_ERR_CRTL; |
| 579 | cf->data[1] = CAN_ERR_CRTL_RX_OVERFLOW; | 579 | cf->data[1] = CAN_ERR_CRTL_RX_OVERFLOW; |
| 580 | netif_receive_skb(skb); | ||
| 581 | 580 | ||
| 582 | stats->rx_packets++; | 581 | stats->rx_packets++; |
| 583 | stats->rx_bytes += cf->can_dlc; | 582 | stats->rx_bytes += cf->can_dlc; |
| 583 | netif_receive_skb(skb); | ||
| 584 | } | 584 | } |
| 585 | 585 | ||
| 586 | /** | 586 | /** |
| @@ -642,10 +642,10 @@ static void at91_read_msg(struct net_device *dev, unsigned int mb) | |||
| 642 | } | 642 | } |
| 643 | 643 | ||
| 644 | at91_read_mb(dev, mb, cf); | 644 | at91_read_mb(dev, mb, cf); |
| 645 | netif_receive_skb(skb); | ||
| 646 | 645 | ||
| 647 | stats->rx_packets++; | 646 | stats->rx_packets++; |
| 648 | stats->rx_bytes += cf->can_dlc; | 647 | stats->rx_bytes += cf->can_dlc; |
| 648 | netif_receive_skb(skb); | ||
| 649 | 649 | ||
| 650 | can_led_event(dev, CAN_LED_EVENT_RX); | 650 | can_led_event(dev, CAN_LED_EVENT_RX); |
| 651 | } | 651 | } |
| @@ -802,10 +802,10 @@ static int at91_poll_err(struct net_device *dev, int quota, u32 reg_sr) | |||
| 802 | return 0; | 802 | return 0; |
| 803 | 803 | ||
| 804 | at91_poll_err_frame(dev, cf, reg_sr); | 804 | at91_poll_err_frame(dev, cf, reg_sr); |
| 805 | netif_receive_skb(skb); | ||
| 806 | 805 | ||
| 807 | dev->stats.rx_packets++; | 806 | dev->stats.rx_packets++; |
| 808 | dev->stats.rx_bytes += cf->can_dlc; | 807 | dev->stats.rx_bytes += cf->can_dlc; |
| 808 | netif_receive_skb(skb); | ||
| 809 | 809 | ||
| 810 | return 1; | 810 | return 1; |
| 811 | } | 811 | } |
| @@ -1067,10 +1067,10 @@ static void at91_irq_err(struct net_device *dev) | |||
| 1067 | return; | 1067 | return; |
| 1068 | 1068 | ||
| 1069 | at91_irq_err_state(dev, cf, new_state); | 1069 | at91_irq_err_state(dev, cf, new_state); |
| 1070 | netif_rx(skb); | ||
| 1071 | 1070 | ||
| 1072 | dev->stats.rx_packets++; | 1071 | dev->stats.rx_packets++; |
| 1073 | dev->stats.rx_bytes += cf->can_dlc; | 1072 | dev->stats.rx_bytes += cf->can_dlc; |
| 1073 | netif_rx(skb); | ||
| 1074 | 1074 | ||
| 1075 | priv->can.state = new_state; | 1075 | priv->can.state = new_state; |
| 1076 | } | 1076 | } |
diff --git a/drivers/net/can/bfin_can.c b/drivers/net/can/bfin_can.c index 27ad312e7abf..57dadd52b428 100644 --- a/drivers/net/can/bfin_can.c +++ b/drivers/net/can/bfin_can.c | |||
| @@ -424,10 +424,9 @@ static void bfin_can_rx(struct net_device *dev, u16 isrc) | |||
| 424 | cf->data[6 - i] = (6 - i) < cf->can_dlc ? (val >> 8) : 0; | 424 | cf->data[6 - i] = (6 - i) < cf->can_dlc ? (val >> 8) : 0; |
| 425 | } | 425 | } |
| 426 | 426 | ||
| 427 | netif_rx(skb); | ||
| 428 | |||
| 429 | stats->rx_packets++; | 427 | stats->rx_packets++; |
| 430 | stats->rx_bytes += cf->can_dlc; | 428 | stats->rx_bytes += cf->can_dlc; |
| 429 | netif_rx(skb); | ||
| 431 | } | 430 | } |
| 432 | 431 | ||
| 433 | static int bfin_can_err(struct net_device *dev, u16 isrc, u16 status) | 432 | static int bfin_can_err(struct net_device *dev, u16 isrc, u16 status) |
| @@ -508,10 +507,9 @@ static int bfin_can_err(struct net_device *dev, u16 isrc, u16 status) | |||
| 508 | 507 | ||
| 509 | priv->can.state = state; | 508 | priv->can.state = state; |
| 510 | 509 | ||
| 511 | netif_rx(skb); | ||
| 512 | |||
| 513 | stats->rx_packets++; | 510 | stats->rx_packets++; |
| 514 | stats->rx_bytes += cf->can_dlc; | 511 | stats->rx_bytes += cf->can_dlc; |
| 512 | netif_rx(skb); | ||
| 515 | 513 | ||
| 516 | return 0; | 514 | return 0; |
| 517 | } | 515 | } |
diff --git a/drivers/net/can/cc770/cc770.c b/drivers/net/can/cc770/cc770.c index c11d44984036..70a8cbb29e75 100644 --- a/drivers/net/can/cc770/cc770.c +++ b/drivers/net/can/cc770/cc770.c | |||
| @@ -504,10 +504,10 @@ static void cc770_rx(struct net_device *dev, unsigned int mo, u8 ctrl1) | |||
| 504 | for (i = 0; i < cf->can_dlc; i++) | 504 | for (i = 0; i < cf->can_dlc; i++) |
| 505 | cf->data[i] = cc770_read_reg(priv, msgobj[mo].data[i]); | 505 | cf->data[i] = cc770_read_reg(priv, msgobj[mo].data[i]); |
| 506 | } | 506 | } |
| 507 | netif_rx(skb); | ||
| 508 | 507 | ||
| 509 | stats->rx_packets++; | 508 | stats->rx_packets++; |
| 510 | stats->rx_bytes += cf->can_dlc; | 509 | stats->rx_bytes += cf->can_dlc; |
| 510 | netif_rx(skb); | ||
| 511 | } | 511 | } |
| 512 | 512 | ||
| 513 | static int cc770_err(struct net_device *dev, u8 status) | 513 | static int cc770_err(struct net_device *dev, u8 status) |
| @@ -584,10 +584,10 @@ static int cc770_err(struct net_device *dev, u8 status) | |||
| 584 | } | 584 | } |
| 585 | } | 585 | } |
| 586 | 586 | ||
| 587 | netif_rx(skb); | ||
| 588 | 587 | ||
| 589 | stats->rx_packets++; | 588 | stats->rx_packets++; |
| 590 | stats->rx_bytes += cf->can_dlc; | 589 | stats->rx_bytes += cf->can_dlc; |
| 590 | netif_rx(skb); | ||
| 591 | 591 | ||
| 592 | return 0; | 592 | return 0; |
| 593 | } | 593 | } |
diff --git a/drivers/net/can/flexcan.c b/drivers/net/can/flexcan.c index 6201c5a1a884..b1e8d729851c 100644 --- a/drivers/net/can/flexcan.c +++ b/drivers/net/can/flexcan.c | |||
| @@ -577,10 +577,10 @@ static int flexcan_poll_bus_err(struct net_device *dev, u32 reg_esr) | |||
| 577 | return 0; | 577 | return 0; |
| 578 | 578 | ||
| 579 | do_bus_err(dev, cf, reg_esr); | 579 | do_bus_err(dev, cf, reg_esr); |
| 580 | netif_receive_skb(skb); | ||
| 581 | 580 | ||
| 582 | dev->stats.rx_packets++; | 581 | dev->stats.rx_packets++; |
| 583 | dev->stats.rx_bytes += cf->can_dlc; | 582 | dev->stats.rx_bytes += cf->can_dlc; |
| 583 | netif_receive_skb(skb); | ||
| 584 | 584 | ||
| 585 | return 1; | 585 | return 1; |
| 586 | } | 586 | } |
| @@ -622,10 +622,9 @@ static int flexcan_poll_state(struct net_device *dev, u32 reg_esr) | |||
| 622 | if (unlikely(new_state == CAN_STATE_BUS_OFF)) | 622 | if (unlikely(new_state == CAN_STATE_BUS_OFF)) |
| 623 | can_bus_off(dev); | 623 | can_bus_off(dev); |
| 624 | 624 | ||
| 625 | netif_receive_skb(skb); | ||
| 626 | |||
| 627 | dev->stats.rx_packets++; | 625 | dev->stats.rx_packets++; |
| 628 | dev->stats.rx_bytes += cf->can_dlc; | 626 | dev->stats.rx_bytes += cf->can_dlc; |
| 627 | netif_receive_skb(skb); | ||
| 629 | 628 | ||
| 630 | return 1; | 629 | return 1; |
| 631 | } | 630 | } |
| @@ -670,10 +669,10 @@ static int flexcan_read_frame(struct net_device *dev) | |||
| 670 | } | 669 | } |
| 671 | 670 | ||
| 672 | flexcan_read_fifo(dev, cf); | 671 | flexcan_read_fifo(dev, cf); |
| 673 | netif_receive_skb(skb); | ||
| 674 | 672 | ||
| 675 | stats->rx_packets++; | 673 | stats->rx_packets++; |
| 676 | stats->rx_bytes += cf->can_dlc; | 674 | stats->rx_bytes += cf->can_dlc; |
| 675 | netif_receive_skb(skb); | ||
| 677 | 676 | ||
| 678 | can_led_event(dev, CAN_LED_EVENT_RX); | 677 | can_led_event(dev, CAN_LED_EVENT_RX); |
| 679 | 678 | ||
diff --git a/drivers/net/can/grcan.c b/drivers/net/can/grcan.c index e3d7e22a4fa0..db9538d4b358 100644 --- a/drivers/net/can/grcan.c +++ b/drivers/net/can/grcan.c | |||
| @@ -1216,11 +1216,12 @@ static int grcan_receive(struct net_device *dev, int budget) | |||
| 1216 | cf->data[i] = (u8)(slot[j] >> shift); | 1216 | cf->data[i] = (u8)(slot[j] >> shift); |
| 1217 | } | 1217 | } |
| 1218 | } | 1218 | } |
| 1219 | netif_receive_skb(skb); | ||
| 1220 | 1219 | ||
| 1221 | /* Update statistics and read pointer */ | 1220 | /* Update statistics and read pointer */ |
| 1222 | stats->rx_packets++; | 1221 | stats->rx_packets++; |
| 1223 | stats->rx_bytes += cf->can_dlc; | 1222 | stats->rx_bytes += cf->can_dlc; |
| 1223 | netif_receive_skb(skb); | ||
| 1224 | |||
| 1224 | rd = grcan_ring_add(rd, GRCAN_MSG_SIZE, dma->rx.size); | 1225 | rd = grcan_ring_add(rd, GRCAN_MSG_SIZE, dma->rx.size); |
| 1225 | } | 1226 | } |
| 1226 | 1227 | ||
diff --git a/drivers/net/can/sja1000/sja1000.c b/drivers/net/can/sja1000/sja1000.c index 32bd7f451aa4..7b92e911a616 100644 --- a/drivers/net/can/sja1000/sja1000.c +++ b/drivers/net/can/sja1000/sja1000.c | |||
| @@ -377,10 +377,9 @@ static void sja1000_rx(struct net_device *dev) | |||
| 377 | /* release receive buffer */ | 377 | /* release receive buffer */ |
| 378 | sja1000_write_cmdreg(priv, CMD_RRB); | 378 | sja1000_write_cmdreg(priv, CMD_RRB); |
| 379 | 379 | ||
| 380 | netif_rx(skb); | ||
| 381 | |||
| 382 | stats->rx_packets++; | 380 | stats->rx_packets++; |
| 383 | stats->rx_bytes += cf->can_dlc; | 381 | stats->rx_bytes += cf->can_dlc; |
| 382 | netif_rx(skb); | ||
| 384 | 383 | ||
| 385 | can_led_event(dev, CAN_LED_EVENT_RX); | 384 | can_led_event(dev, CAN_LED_EVENT_RX); |
| 386 | } | 385 | } |
| @@ -484,10 +483,9 @@ static int sja1000_err(struct net_device *dev, uint8_t isrc, uint8_t status) | |||
| 484 | can_bus_off(dev); | 483 | can_bus_off(dev); |
| 485 | } | 484 | } |
| 486 | 485 | ||
| 487 | netif_rx(skb); | ||
| 488 | |||
| 489 | stats->rx_packets++; | 486 | stats->rx_packets++; |
| 490 | stats->rx_bytes += cf->can_dlc; | 487 | stats->rx_bytes += cf->can_dlc; |
| 488 | netif_rx(skb); | ||
| 491 | 489 | ||
| 492 | return 0; | 490 | return 0; |
| 493 | } | 491 | } |
diff --git a/drivers/net/can/slcan.c b/drivers/net/can/slcan.c index a23a7af8eb9a..9a3f15cb7ef4 100644 --- a/drivers/net/can/slcan.c +++ b/drivers/net/can/slcan.c | |||
| @@ -218,10 +218,10 @@ static void slc_bump(struct slcan *sl) | |||
| 218 | 218 | ||
| 219 | memcpy(skb_put(skb, sizeof(struct can_frame)), | 219 | memcpy(skb_put(skb, sizeof(struct can_frame)), |
| 220 | &cf, sizeof(struct can_frame)); | 220 | &cf, sizeof(struct can_frame)); |
| 221 | netif_rx_ni(skb); | ||
| 222 | 221 | ||
| 223 | sl->dev->stats.rx_packets++; | 222 | sl->dev->stats.rx_packets++; |
| 224 | sl->dev->stats.rx_bytes += cf.can_dlc; | 223 | sl->dev->stats.rx_bytes += cf.can_dlc; |
| 224 | netif_rx_ni(skb); | ||
| 225 | } | 225 | } |
| 226 | 226 | ||
| 227 | /* parse tty input stream */ | 227 | /* parse tty input stream */ |
diff --git a/drivers/net/can/spi/mcp251x.c b/drivers/net/can/spi/mcp251x.c index c1a95a34d62e..b7e83c212023 100644 --- a/drivers/net/can/spi/mcp251x.c +++ b/drivers/net/can/spi/mcp251x.c | |||
| @@ -1086,8 +1086,8 @@ static int mcp251x_can_probe(struct spi_device *spi) | |||
| 1086 | if (ret) | 1086 | if (ret) |
| 1087 | goto out_clk; | 1087 | goto out_clk; |
| 1088 | 1088 | ||
| 1089 | priv->power = devm_regulator_get(&spi->dev, "vdd"); | 1089 | priv->power = devm_regulator_get_optional(&spi->dev, "vdd"); |
| 1090 | priv->transceiver = devm_regulator_get(&spi->dev, "xceiver"); | 1090 | priv->transceiver = devm_regulator_get_optional(&spi->dev, "xceiver"); |
| 1091 | if ((PTR_ERR(priv->power) == -EPROBE_DEFER) || | 1091 | if ((PTR_ERR(priv->power) == -EPROBE_DEFER) || |
| 1092 | (PTR_ERR(priv->transceiver) == -EPROBE_DEFER)) { | 1092 | (PTR_ERR(priv->transceiver) == -EPROBE_DEFER)) { |
| 1093 | ret = -EPROBE_DEFER; | 1093 | ret = -EPROBE_DEFER; |
| @@ -1222,17 +1222,16 @@ static int __maybe_unused mcp251x_can_resume(struct device *dev) | |||
| 1222 | struct spi_device *spi = to_spi_device(dev); | 1222 | struct spi_device *spi = to_spi_device(dev); |
| 1223 | struct mcp251x_priv *priv = spi_get_drvdata(spi); | 1223 | struct mcp251x_priv *priv = spi_get_drvdata(spi); |
| 1224 | 1224 | ||
| 1225 | if (priv->after_suspend & AFTER_SUSPEND_POWER) { | 1225 | if (priv->after_suspend & AFTER_SUSPEND_POWER) |
| 1226 | mcp251x_power_enable(priv->power, 1); | 1226 | mcp251x_power_enable(priv->power, 1); |
| 1227 | |||
| 1228 | if (priv->after_suspend & AFTER_SUSPEND_UP) { | ||
| 1229 | mcp251x_power_enable(priv->transceiver, 1); | ||
| 1227 | queue_work(priv->wq, &priv->restart_work); | 1230 | queue_work(priv->wq, &priv->restart_work); |
| 1228 | } else { | 1231 | } else { |
| 1229 | if (priv->after_suspend & AFTER_SUSPEND_UP) { | 1232 | priv->after_suspend = 0; |
| 1230 | mcp251x_power_enable(priv->transceiver, 1); | ||
| 1231 | queue_work(priv->wq, &priv->restart_work); | ||
| 1232 | } else { | ||
| 1233 | priv->after_suspend = 0; | ||
| 1234 | } | ||
| 1235 | } | 1233 | } |
| 1234 | |||
| 1236 | priv->force_quit = 0; | 1235 | priv->force_quit = 0; |
| 1237 | enable_irq(spi->irq); | 1236 | enable_irq(spi->irq); |
| 1238 | return 0; | 1237 | return 0; |
diff --git a/drivers/net/can/ti_hecc.c b/drivers/net/can/ti_hecc.c index e95a9e1a889f..cf345cbfe819 100644 --- a/drivers/net/can/ti_hecc.c +++ b/drivers/net/can/ti_hecc.c | |||
| @@ -747,9 +747,9 @@ static int ti_hecc_error(struct net_device *ndev, int int_status, | |||
| 747 | } | 747 | } |
| 748 | } | 748 | } |
| 749 | 749 | ||
| 750 | netif_rx(skb); | ||
| 751 | stats->rx_packets++; | 750 | stats->rx_packets++; |
| 752 | stats->rx_bytes += cf->can_dlc; | 751 | stats->rx_bytes += cf->can_dlc; |
| 752 | netif_rx(skb); | ||
| 753 | 753 | ||
| 754 | return 0; | 754 | return 0; |
| 755 | } | 755 | } |
diff --git a/drivers/net/can/usb/ems_usb.c b/drivers/net/can/usb/ems_usb.c index 866bac0ae7e9..2d390384ef3b 100644 --- a/drivers/net/can/usb/ems_usb.c +++ b/drivers/net/can/usb/ems_usb.c | |||
| @@ -324,10 +324,9 @@ static void ems_usb_rx_can_msg(struct ems_usb *dev, struct ems_cpc_msg *msg) | |||
| 324 | cf->data[i] = msg->msg.can_msg.msg[i]; | 324 | cf->data[i] = msg->msg.can_msg.msg[i]; |
| 325 | } | 325 | } |
| 326 | 326 | ||
| 327 | netif_rx(skb); | ||
| 328 | |||
| 329 | stats->rx_packets++; | 327 | stats->rx_packets++; |
| 330 | stats->rx_bytes += cf->can_dlc; | 328 | stats->rx_bytes += cf->can_dlc; |
| 329 | netif_rx(skb); | ||
| 331 | } | 330 | } |
| 332 | 331 | ||
| 333 | static void ems_usb_rx_err(struct ems_usb *dev, struct ems_cpc_msg *msg) | 332 | static void ems_usb_rx_err(struct ems_usb *dev, struct ems_cpc_msg *msg) |
| @@ -400,10 +399,9 @@ static void ems_usb_rx_err(struct ems_usb *dev, struct ems_cpc_msg *msg) | |||
| 400 | stats->rx_errors++; | 399 | stats->rx_errors++; |
| 401 | } | 400 | } |
| 402 | 401 | ||
| 403 | netif_rx(skb); | ||
| 404 | |||
| 405 | stats->rx_packets++; | 402 | stats->rx_packets++; |
| 406 | stats->rx_bytes += cf->can_dlc; | 403 | stats->rx_bytes += cf->can_dlc; |
| 404 | netif_rx(skb); | ||
| 407 | } | 405 | } |
| 408 | 406 | ||
| 409 | /* | 407 | /* |
diff --git a/drivers/net/can/usb/esd_usb2.c b/drivers/net/can/usb/esd_usb2.c index 411c1af92c62..0e5a4493ba4f 100644 --- a/drivers/net/can/usb/esd_usb2.c +++ b/drivers/net/can/usb/esd_usb2.c | |||
| @@ -301,13 +301,12 @@ static void esd_usb2_rx_event(struct esd_usb2_net_priv *priv, | |||
| 301 | cf->data[7] = rxerr; | 301 | cf->data[7] = rxerr; |
| 302 | } | 302 | } |
| 303 | 303 | ||
| 304 | netif_rx(skb); | ||
| 305 | |||
| 306 | priv->bec.txerr = txerr; | 304 | priv->bec.txerr = txerr; |
| 307 | priv->bec.rxerr = rxerr; | 305 | priv->bec.rxerr = rxerr; |
| 308 | 306 | ||
| 309 | stats->rx_packets++; | 307 | stats->rx_packets++; |
| 310 | stats->rx_bytes += cf->can_dlc; | 308 | stats->rx_bytes += cf->can_dlc; |
| 309 | netif_rx(skb); | ||
| 311 | } | 310 | } |
| 312 | } | 311 | } |
| 313 | 312 | ||
| @@ -347,10 +346,9 @@ static void esd_usb2_rx_can_msg(struct esd_usb2_net_priv *priv, | |||
| 347 | cf->data[i] = msg->msg.rx.data[i]; | 346 | cf->data[i] = msg->msg.rx.data[i]; |
| 348 | } | 347 | } |
| 349 | 348 | ||
| 350 | netif_rx(skb); | ||
| 351 | |||
| 352 | stats->rx_packets++; | 349 | stats->rx_packets++; |
| 353 | stats->rx_bytes += cf->can_dlc; | 350 | stats->rx_bytes += cf->can_dlc; |
| 351 | netif_rx(skb); | ||
| 354 | } | 352 | } |
| 355 | 353 | ||
| 356 | return; | 354 | return; |
diff --git a/drivers/net/can/usb/peak_usb/pcan_usb.c b/drivers/net/can/usb/peak_usb/pcan_usb.c index 72427f21edff..6b94007ae052 100644 --- a/drivers/net/can/usb/peak_usb/pcan_usb.c +++ b/drivers/net/can/usb/peak_usb/pcan_usb.c | |||
| @@ -526,9 +526,9 @@ static int pcan_usb_decode_error(struct pcan_usb_msg_context *mc, u8 n, | |||
| 526 | hwts->hwtstamp = timeval_to_ktime(tv); | 526 | hwts->hwtstamp = timeval_to_ktime(tv); |
| 527 | } | 527 | } |
| 528 | 528 | ||
| 529 | netif_rx(skb); | ||
| 530 | mc->netdev->stats.rx_packets++; | 529 | mc->netdev->stats.rx_packets++; |
| 531 | mc->netdev->stats.rx_bytes += cf->can_dlc; | 530 | mc->netdev->stats.rx_bytes += cf->can_dlc; |
| 531 | netif_rx(skb); | ||
| 532 | 532 | ||
| 533 | return 0; | 533 | return 0; |
| 534 | } | 534 | } |
| @@ -659,12 +659,11 @@ static int pcan_usb_decode_data(struct pcan_usb_msg_context *mc, u8 status_len) | |||
| 659 | hwts = skb_hwtstamps(skb); | 659 | hwts = skb_hwtstamps(skb); |
| 660 | hwts->hwtstamp = timeval_to_ktime(tv); | 660 | hwts->hwtstamp = timeval_to_ktime(tv); |
| 661 | 661 | ||
| 662 | /* push the skb */ | ||
| 663 | netif_rx(skb); | ||
| 664 | |||
| 665 | /* update statistics */ | 662 | /* update statistics */ |
| 666 | mc->netdev->stats.rx_packets++; | 663 | mc->netdev->stats.rx_packets++; |
| 667 | mc->netdev->stats.rx_bytes += cf->can_dlc; | 664 | mc->netdev->stats.rx_bytes += cf->can_dlc; |
| 665 | /* push the skb */ | ||
| 666 | netif_rx(skb); | ||
| 668 | 667 | ||
| 669 | return 0; | 668 | return 0; |
| 670 | 669 | ||
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 dec51717635e..7d61b3279798 100644 --- a/drivers/net/can/usb/peak_usb/pcan_usb_pro.c +++ b/drivers/net/can/usb/peak_usb/pcan_usb_pro.c | |||
| @@ -553,9 +553,9 @@ static int pcan_usb_pro_handle_canmsg(struct pcan_usb_pro_interface *usb_if, | |||
| 553 | hwts = skb_hwtstamps(skb); | 553 | hwts = skb_hwtstamps(skb); |
| 554 | hwts->hwtstamp = timeval_to_ktime(tv); | 554 | hwts->hwtstamp = timeval_to_ktime(tv); |
| 555 | 555 | ||
| 556 | netif_rx(skb); | ||
| 557 | netdev->stats.rx_packets++; | 556 | netdev->stats.rx_packets++; |
| 558 | netdev->stats.rx_bytes += can_frame->can_dlc; | 557 | netdev->stats.rx_bytes += can_frame->can_dlc; |
| 558 | netif_rx(skb); | ||
| 559 | 559 | ||
| 560 | return 0; | 560 | return 0; |
| 561 | } | 561 | } |
| @@ -670,9 +670,9 @@ static int pcan_usb_pro_handle_error(struct pcan_usb_pro_interface *usb_if, | |||
| 670 | peak_usb_get_ts_tv(&usb_if->time_ref, le32_to_cpu(er->ts32), &tv); | 670 | peak_usb_get_ts_tv(&usb_if->time_ref, le32_to_cpu(er->ts32), &tv); |
| 671 | hwts = skb_hwtstamps(skb); | 671 | hwts = skb_hwtstamps(skb); |
| 672 | hwts->hwtstamp = timeval_to_ktime(tv); | 672 | hwts->hwtstamp = timeval_to_ktime(tv); |
| 673 | netif_rx(skb); | ||
| 674 | netdev->stats.rx_packets++; | 673 | netdev->stats.rx_packets++; |
| 675 | netdev->stats.rx_bytes += can_frame->can_dlc; | 674 | netdev->stats.rx_bytes += can_frame->can_dlc; |
| 675 | netif_rx(skb); | ||
| 676 | 676 | ||
| 677 | return 0; | 677 | return 0; |
| 678 | } | 678 | } |
diff --git a/drivers/net/can/usb/usb_8dev.c b/drivers/net/can/usb/usb_8dev.c index dd52c7a4c80d..de95b1ccba3e 100644 --- a/drivers/net/can/usb/usb_8dev.c +++ b/drivers/net/can/usb/usb_8dev.c | |||
| @@ -461,10 +461,9 @@ static void usb_8dev_rx_err_msg(struct usb_8dev_priv *priv, | |||
| 461 | priv->bec.txerr = txerr; | 461 | priv->bec.txerr = txerr; |
| 462 | priv->bec.rxerr = rxerr; | 462 | priv->bec.rxerr = rxerr; |
| 463 | 463 | ||
| 464 | netif_rx(skb); | ||
| 465 | |||
| 466 | stats->rx_packets++; | 464 | stats->rx_packets++; |
| 467 | stats->rx_bytes += cf->can_dlc; | 465 | stats->rx_bytes += cf->can_dlc; |
| 466 | netif_rx(skb); | ||
| 468 | } | 467 | } |
| 469 | 468 | ||
| 470 | /* Read data and status frames */ | 469 | /* Read data and status frames */ |
| @@ -494,10 +493,9 @@ static void usb_8dev_rx_can_msg(struct usb_8dev_priv *priv, | |||
| 494 | else | 493 | else |
| 495 | memcpy(cf->data, msg->data, cf->can_dlc); | 494 | memcpy(cf->data, msg->data, cf->can_dlc); |
| 496 | 495 | ||
| 497 | netif_rx(skb); | ||
| 498 | |||
| 499 | stats->rx_packets++; | 496 | stats->rx_packets++; |
| 500 | stats->rx_bytes += cf->can_dlc; | 497 | stats->rx_bytes += cf->can_dlc; |
| 498 | netif_rx(skb); | ||
| 501 | 499 | ||
| 502 | can_led_event(priv->netdev, CAN_LED_EVENT_RX); | 500 | can_led_event(priv->netdev, CAN_LED_EVENT_RX); |
| 503 | } else { | 501 | } else { |
diff --git a/drivers/net/dsa/bcm_sf2.c b/drivers/net/dsa/bcm_sf2.c index 3297604f8216..289e20443d83 100644 --- a/drivers/net/dsa/bcm_sf2.c +++ b/drivers/net/dsa/bcm_sf2.c | |||
| @@ -696,9 +696,20 @@ static int bcm_sf2_sw_setup(struct dsa_switch *ds) | |||
| 696 | } | 696 | } |
| 697 | 697 | ||
| 698 | /* Include the pseudo-PHY address and the broadcast PHY address to | 698 | /* Include the pseudo-PHY address and the broadcast PHY address to |
| 699 | * divert reads towards our workaround | 699 | * divert reads towards our workaround. This is only required for |
| 700 | * 7445D0, since 7445E0 disconnects the internal switch pseudo-PHY such | ||
| 701 | * that we can use the regular SWITCH_MDIO master controller instead. | ||
| 702 | * | ||
| 703 | * By default, DSA initializes ds->phys_mii_mask to ds->phys_port_mask | ||
| 704 | * to have a 1:1 mapping between Port address and PHY address in order | ||
| 705 | * to utilize the slave_mii_bus instance to read from Port PHYs. This is | ||
| 706 | * not what we want here, so we initialize phys_mii_mask 0 to always | ||
| 707 | * utilize the "master" MDIO bus backed by the "mdio-unimac" driver. | ||
| 700 | */ | 708 | */ |
| 701 | ds->phys_mii_mask |= ((1 << BRCM_PSEUDO_PHY_ADDR) | (1 << 0)); | 709 | if (of_machine_is_compatible("brcm,bcm7445d0")) |
| 710 | ds->phys_mii_mask |= ((1 << BRCM_PSEUDO_PHY_ADDR) | (1 << 0)); | ||
| 711 | else | ||
| 712 | ds->phys_mii_mask = 0; | ||
| 702 | 713 | ||
| 703 | rev = reg_readl(priv, REG_SWITCH_REVISION); | 714 | rev = reg_readl(priv, REG_SWITCH_REVISION); |
| 704 | priv->hw_params.top_rev = (rev >> SWITCH_TOP_REV_SHIFT) & | 715 | priv->hw_params.top_rev = (rev >> SWITCH_TOP_REV_SHIFT) & |
diff --git a/drivers/net/dsa/mv88e6xxx.c b/drivers/net/dsa/mv88e6xxx.c index f394e4d4d9e0..5158375b7abd 100644 --- a/drivers/net/dsa/mv88e6xxx.c +++ b/drivers/net/dsa/mv88e6xxx.c | |||
| @@ -1175,7 +1175,7 @@ int mv88e6xxx_leave_bridge(struct dsa_switch *ds, int port, u32 br_port_mask) | |||
| 1175 | 1175 | ||
| 1176 | newfid = __ffs(ps->fid_mask); | 1176 | newfid = __ffs(ps->fid_mask); |
| 1177 | ps->fid[port] = newfid; | 1177 | ps->fid[port] = newfid; |
| 1178 | ps->fid_mask &= (1 << newfid); | 1178 | ps->fid_mask &= ~(1 << newfid); |
| 1179 | ps->bridge_mask[fid] &= ~(1 << port); | 1179 | ps->bridge_mask[fid] &= ~(1 << port); |
| 1180 | ps->bridge_mask[newfid] = 1 << port; | 1180 | ps->bridge_mask[newfid] = 1 << port; |
| 1181 | 1181 | ||
diff --git a/drivers/net/ethernet/broadcom/sb1250-mac.c b/drivers/net/ethernet/broadcom/sb1250-mac.c index ac27e24264a5..f557a2aaec23 100644 --- a/drivers/net/ethernet/broadcom/sb1250-mac.c +++ b/drivers/net/ethernet/broadcom/sb1250-mac.c | |||
| @@ -1508,16 +1508,7 @@ static void sbmac_channel_start(struct sbmac_softc *s) | |||
| 1508 | __raw_writeq(reg, port); | 1508 | __raw_writeq(reg, port); |
| 1509 | port = s->sbm_base + R_MAC_ETHERNET_ADDR; | 1509 | port = s->sbm_base + R_MAC_ETHERNET_ADDR; |
| 1510 | 1510 | ||
| 1511 | #ifdef CONFIG_SB1_PASS_1_WORKAROUNDS | ||
| 1512 | /* | ||
| 1513 | * Pass1 SOCs do not receive packets addressed to the | ||
| 1514 | * destination address in the R_MAC_ETHERNET_ADDR register. | ||
| 1515 | * Set the value to zero. | ||
| 1516 | */ | ||
| 1517 | __raw_writeq(0, port); | ||
| 1518 | #else | ||
| 1519 | __raw_writeq(reg, port); | 1511 | __raw_writeq(reg, port); |
| 1520 | #endif | ||
| 1521 | 1512 | ||
| 1522 | /* | 1513 | /* |
| 1523 | * Set the receive filter for no packets, and write values | 1514 | * Set the receive filter for no packets, and write values |
diff --git a/drivers/net/ethernet/freescale/fec_main.c b/drivers/net/ethernet/freescale/fec_main.c index 42e20e5385ac..1f89c59b4353 100644 --- a/drivers/net/ethernet/freescale/fec_main.c +++ b/drivers/net/ethernet/freescale/fec_main.c | |||
| @@ -24,7 +24,6 @@ | |||
| 24 | #include <linux/module.h> | 24 | #include <linux/module.h> |
| 25 | #include <linux/kernel.h> | 25 | #include <linux/kernel.h> |
| 26 | #include <linux/string.h> | 26 | #include <linux/string.h> |
| 27 | #include <linux/pm_runtime.h> | ||
| 28 | #include <linux/ptrace.h> | 27 | #include <linux/ptrace.h> |
| 29 | #include <linux/errno.h> | 28 | #include <linux/errno.h> |
| 30 | #include <linux/ioport.h> | 29 | #include <linux/ioport.h> |
| @@ -78,7 +77,6 @@ static void fec_enet_itr_coal_init(struct net_device *ndev); | |||
| 78 | #define FEC_ENET_RAEM_V 0x8 | 77 | #define FEC_ENET_RAEM_V 0x8 |
| 79 | #define FEC_ENET_RAFL_V 0x8 | 78 | #define FEC_ENET_RAFL_V 0x8 |
| 80 | #define FEC_ENET_OPD_V 0xFFF0 | 79 | #define FEC_ENET_OPD_V 0xFFF0 |
| 81 | #define FEC_MDIO_PM_TIMEOUT 100 /* ms */ | ||
| 82 | 80 | ||
| 83 | static struct platform_device_id fec_devtype[] = { | 81 | static struct platform_device_id fec_devtype[] = { |
| 84 | { | 82 | { |
| @@ -1769,13 +1767,7 @@ static void fec_enet_adjust_link(struct net_device *ndev) | |||
| 1769 | static int fec_enet_mdio_read(struct mii_bus *bus, int mii_id, int regnum) | 1767 | static int fec_enet_mdio_read(struct mii_bus *bus, int mii_id, int regnum) |
| 1770 | { | 1768 | { |
| 1771 | struct fec_enet_private *fep = bus->priv; | 1769 | struct fec_enet_private *fep = bus->priv; |
| 1772 | struct device *dev = &fep->pdev->dev; | ||
| 1773 | unsigned long time_left; | 1770 | unsigned long time_left; |
| 1774 | int ret = 0; | ||
| 1775 | |||
| 1776 | ret = pm_runtime_get_sync(dev); | ||
| 1777 | if (IS_ERR_VALUE(ret)) | ||
| 1778 | return ret; | ||
| 1779 | 1771 | ||
| 1780 | fep->mii_timeout = 0; | 1772 | fep->mii_timeout = 0; |
| 1781 | init_completion(&fep->mdio_done); | 1773 | init_completion(&fep->mdio_done); |
| @@ -1791,30 +1783,18 @@ static int fec_enet_mdio_read(struct mii_bus *bus, int mii_id, int regnum) | |||
| 1791 | if (time_left == 0) { | 1783 | if (time_left == 0) { |
| 1792 | fep->mii_timeout = 1; | 1784 | fep->mii_timeout = 1; |
| 1793 | netdev_err(fep->netdev, "MDIO read timeout\n"); | 1785 | netdev_err(fep->netdev, "MDIO read timeout\n"); |
| 1794 | ret = -ETIMEDOUT; | 1786 | return -ETIMEDOUT; |
| 1795 | goto out; | ||
| 1796 | } | 1787 | } |
| 1797 | 1788 | ||
| 1798 | ret = FEC_MMFR_DATA(readl(fep->hwp + FEC_MII_DATA)); | 1789 | /* return value */ |
| 1799 | 1790 | return FEC_MMFR_DATA(readl(fep->hwp + FEC_MII_DATA)); | |
| 1800 | out: | ||
| 1801 | pm_runtime_mark_last_busy(dev); | ||
| 1802 | pm_runtime_put_autosuspend(dev); | ||
| 1803 | |||
| 1804 | return ret; | ||
| 1805 | } | 1791 | } |
| 1806 | 1792 | ||
| 1807 | static int fec_enet_mdio_write(struct mii_bus *bus, int mii_id, int regnum, | 1793 | static int fec_enet_mdio_write(struct mii_bus *bus, int mii_id, int regnum, |
| 1808 | u16 value) | 1794 | u16 value) |
| 1809 | { | 1795 | { |
| 1810 | struct fec_enet_private *fep = bus->priv; | 1796 | struct fec_enet_private *fep = bus->priv; |
| 1811 | struct device *dev = &fep->pdev->dev; | ||
| 1812 | unsigned long time_left; | 1797 | unsigned long time_left; |
| 1813 | int ret = 0; | ||
| 1814 | |||
| 1815 | ret = pm_runtime_get_sync(dev); | ||
| 1816 | if (IS_ERR_VALUE(ret)) | ||
| 1817 | return ret; | ||
| 1818 | 1798 | ||
| 1819 | fep->mii_timeout = 0; | 1799 | fep->mii_timeout = 0; |
| 1820 | init_completion(&fep->mdio_done); | 1800 | init_completion(&fep->mdio_done); |
| @@ -1831,13 +1811,10 @@ static int fec_enet_mdio_write(struct mii_bus *bus, int mii_id, int regnum, | |||
| 1831 | if (time_left == 0) { | 1811 | if (time_left == 0) { |
| 1832 | fep->mii_timeout = 1; | 1812 | fep->mii_timeout = 1; |
| 1833 | netdev_err(fep->netdev, "MDIO write timeout\n"); | 1813 | netdev_err(fep->netdev, "MDIO write timeout\n"); |
| 1834 | ret = -ETIMEDOUT; | 1814 | return -ETIMEDOUT; |
| 1835 | } | 1815 | } |
| 1836 | 1816 | ||
| 1837 | pm_runtime_mark_last_busy(dev); | 1817 | return 0; |
| 1838 | pm_runtime_put_autosuspend(dev); | ||
| 1839 | |||
| 1840 | return ret; | ||
| 1841 | } | 1818 | } |
| 1842 | 1819 | ||
| 1843 | static int fec_enet_clk_enable(struct net_device *ndev, bool enable) | 1820 | static int fec_enet_clk_enable(struct net_device *ndev, bool enable) |
| @@ -1849,6 +1826,9 @@ static int fec_enet_clk_enable(struct net_device *ndev, bool enable) | |||
| 1849 | ret = clk_prepare_enable(fep->clk_ahb); | 1826 | ret = clk_prepare_enable(fep->clk_ahb); |
| 1850 | if (ret) | 1827 | if (ret) |
| 1851 | return ret; | 1828 | return ret; |
| 1829 | ret = clk_prepare_enable(fep->clk_ipg); | ||
| 1830 | if (ret) | ||
| 1831 | goto failed_clk_ipg; | ||
| 1852 | if (fep->clk_enet_out) { | 1832 | if (fep->clk_enet_out) { |
| 1853 | ret = clk_prepare_enable(fep->clk_enet_out); | 1833 | ret = clk_prepare_enable(fep->clk_enet_out); |
| 1854 | if (ret) | 1834 | if (ret) |
| @@ -1872,6 +1852,7 @@ static int fec_enet_clk_enable(struct net_device *ndev, bool enable) | |||
| 1872 | } | 1852 | } |
| 1873 | } else { | 1853 | } else { |
| 1874 | clk_disable_unprepare(fep->clk_ahb); | 1854 | clk_disable_unprepare(fep->clk_ahb); |
| 1855 | clk_disable_unprepare(fep->clk_ipg); | ||
| 1875 | if (fep->clk_enet_out) | 1856 | if (fep->clk_enet_out) |
| 1876 | clk_disable_unprepare(fep->clk_enet_out); | 1857 | clk_disable_unprepare(fep->clk_enet_out); |
| 1877 | if (fep->clk_ptp) { | 1858 | if (fep->clk_ptp) { |
| @@ -1893,6 +1874,8 @@ failed_clk_ptp: | |||
| 1893 | if (fep->clk_enet_out) | 1874 | if (fep->clk_enet_out) |
| 1894 | clk_disable_unprepare(fep->clk_enet_out); | 1875 | clk_disable_unprepare(fep->clk_enet_out); |
| 1895 | failed_clk_enet_out: | 1876 | failed_clk_enet_out: |
| 1877 | clk_disable_unprepare(fep->clk_ipg); | ||
| 1878 | failed_clk_ipg: | ||
| 1896 | clk_disable_unprepare(fep->clk_ahb); | 1879 | clk_disable_unprepare(fep->clk_ahb); |
| 1897 | 1880 | ||
| 1898 | return ret; | 1881 | return ret; |
| @@ -2864,14 +2847,10 @@ fec_enet_open(struct net_device *ndev) | |||
| 2864 | struct fec_enet_private *fep = netdev_priv(ndev); | 2847 | struct fec_enet_private *fep = netdev_priv(ndev); |
| 2865 | int ret; | 2848 | int ret; |
| 2866 | 2849 | ||
| 2867 | ret = pm_runtime_get_sync(&fep->pdev->dev); | ||
| 2868 | if (IS_ERR_VALUE(ret)) | ||
| 2869 | return ret; | ||
| 2870 | |||
| 2871 | pinctrl_pm_select_default_state(&fep->pdev->dev); | 2850 | pinctrl_pm_select_default_state(&fep->pdev->dev); |
| 2872 | ret = fec_enet_clk_enable(ndev, true); | 2851 | ret = fec_enet_clk_enable(ndev, true); |
| 2873 | if (ret) | 2852 | if (ret) |
| 2874 | goto clk_enable; | 2853 | return ret; |
| 2875 | 2854 | ||
| 2876 | /* I should reset the ring buffers here, but I don't yet know | 2855 | /* I should reset the ring buffers here, but I don't yet know |
| 2877 | * a simple way to do that. | 2856 | * a simple way to do that. |
| @@ -2902,9 +2881,6 @@ err_enet_mii_probe: | |||
| 2902 | fec_enet_free_buffers(ndev); | 2881 | fec_enet_free_buffers(ndev); |
| 2903 | err_enet_alloc: | 2882 | err_enet_alloc: |
| 2904 | fec_enet_clk_enable(ndev, false); | 2883 | fec_enet_clk_enable(ndev, false); |
| 2905 | clk_enable: | ||
| 2906 | pm_runtime_mark_last_busy(&fep->pdev->dev); | ||
| 2907 | pm_runtime_put_autosuspend(&fep->pdev->dev); | ||
| 2908 | pinctrl_pm_select_sleep_state(&fep->pdev->dev); | 2884 | pinctrl_pm_select_sleep_state(&fep->pdev->dev); |
| 2909 | return ret; | 2885 | return ret; |
| 2910 | } | 2886 | } |
| @@ -2927,9 +2903,6 @@ fec_enet_close(struct net_device *ndev) | |||
| 2927 | 2903 | ||
| 2928 | fec_enet_clk_enable(ndev, false); | 2904 | fec_enet_clk_enable(ndev, false); |
| 2929 | pinctrl_pm_select_sleep_state(&fep->pdev->dev); | 2905 | pinctrl_pm_select_sleep_state(&fep->pdev->dev); |
| 2930 | pm_runtime_mark_last_busy(&fep->pdev->dev); | ||
| 2931 | pm_runtime_put_autosuspend(&fep->pdev->dev); | ||
| 2932 | |||
| 2933 | fec_enet_free_buffers(ndev); | 2906 | fec_enet_free_buffers(ndev); |
| 2934 | 2907 | ||
| 2935 | return 0; | 2908 | return 0; |
| @@ -3415,10 +3388,6 @@ fec_probe(struct platform_device *pdev) | |||
| 3415 | if (ret) | 3388 | if (ret) |
| 3416 | goto failed_clk; | 3389 | goto failed_clk; |
| 3417 | 3390 | ||
| 3418 | ret = clk_prepare_enable(fep->clk_ipg); | ||
| 3419 | if (ret) | ||
| 3420 | goto failed_clk_ipg; | ||
| 3421 | |||
| 3422 | fep->reg_phy = devm_regulator_get(&pdev->dev, "phy"); | 3391 | fep->reg_phy = devm_regulator_get(&pdev->dev, "phy"); |
| 3423 | if (!IS_ERR(fep->reg_phy)) { | 3392 | if (!IS_ERR(fep->reg_phy)) { |
| 3424 | ret = regulator_enable(fep->reg_phy); | 3393 | ret = regulator_enable(fep->reg_phy); |
| @@ -3465,8 +3434,6 @@ fec_probe(struct platform_device *pdev) | |||
| 3465 | netif_carrier_off(ndev); | 3434 | netif_carrier_off(ndev); |
| 3466 | fec_enet_clk_enable(ndev, false); | 3435 | fec_enet_clk_enable(ndev, false); |
| 3467 | pinctrl_pm_select_sleep_state(&pdev->dev); | 3436 | pinctrl_pm_select_sleep_state(&pdev->dev); |
| 3468 | pm_runtime_set_active(&pdev->dev); | ||
| 3469 | pm_runtime_enable(&pdev->dev); | ||
| 3470 | 3437 | ||
| 3471 | ret = register_netdev(ndev); | 3438 | ret = register_netdev(ndev); |
| 3472 | if (ret) | 3439 | if (ret) |
| @@ -3480,12 +3447,6 @@ fec_probe(struct platform_device *pdev) | |||
| 3480 | 3447 | ||
| 3481 | fep->rx_copybreak = COPYBREAK_DEFAULT; | 3448 | fep->rx_copybreak = COPYBREAK_DEFAULT; |
| 3482 | INIT_WORK(&fep->tx_timeout_work, fec_enet_timeout_work); | 3449 | INIT_WORK(&fep->tx_timeout_work, fec_enet_timeout_work); |
| 3483 | |||
| 3484 | pm_runtime_set_autosuspend_delay(&pdev->dev, FEC_MDIO_PM_TIMEOUT); | ||
| 3485 | pm_runtime_use_autosuspend(&pdev->dev); | ||
| 3486 | pm_runtime_mark_last_busy(&pdev->dev); | ||
| 3487 | pm_runtime_put_autosuspend(&pdev->dev); | ||
| 3488 | |||
| 3489 | return 0; | 3450 | return 0; |
| 3490 | 3451 | ||
| 3491 | failed_register: | 3452 | failed_register: |
| @@ -3496,8 +3457,6 @@ failed_init: | |||
| 3496 | if (fep->reg_phy) | 3457 | if (fep->reg_phy) |
| 3497 | regulator_disable(fep->reg_phy); | 3458 | regulator_disable(fep->reg_phy); |
| 3498 | failed_regulator: | 3459 | failed_regulator: |
| 3499 | clk_disable_unprepare(fep->clk_ipg); | ||
| 3500 | failed_clk_ipg: | ||
| 3501 | fec_enet_clk_enable(ndev, false); | 3460 | fec_enet_clk_enable(ndev, false); |
| 3502 | failed_clk: | 3461 | failed_clk: |
| 3503 | failed_phy: | 3462 | failed_phy: |
| @@ -3609,28 +3568,7 @@ failed_clk: | |||
| 3609 | return ret; | 3568 | return ret; |
| 3610 | } | 3569 | } |
| 3611 | 3570 | ||
| 3612 | static int __maybe_unused fec_runtime_suspend(struct device *dev) | 3571 | static SIMPLE_DEV_PM_OPS(fec_pm_ops, fec_suspend, fec_resume); |
| 3613 | { | ||
| 3614 | struct net_device *ndev = dev_get_drvdata(dev); | ||
| 3615 | struct fec_enet_private *fep = netdev_priv(ndev); | ||
| 3616 | |||
| 3617 | clk_disable_unprepare(fep->clk_ipg); | ||
| 3618 | |||
| 3619 | return 0; | ||
| 3620 | } | ||
| 3621 | |||
| 3622 | static int __maybe_unused fec_runtime_resume(struct device *dev) | ||
| 3623 | { | ||
| 3624 | struct net_device *ndev = dev_get_drvdata(dev); | ||
| 3625 | struct fec_enet_private *fep = netdev_priv(ndev); | ||
| 3626 | |||
| 3627 | return clk_prepare_enable(fep->clk_ipg); | ||
| 3628 | } | ||
| 3629 | |||
| 3630 | static const struct dev_pm_ops fec_pm_ops = { | ||
| 3631 | SET_SYSTEM_SLEEP_PM_OPS(fec_suspend, fec_resume) | ||
| 3632 | SET_RUNTIME_PM_OPS(fec_runtime_suspend, fec_runtime_resume, NULL) | ||
| 3633 | }; | ||
| 3634 | 3572 | ||
| 3635 | static struct platform_driver fec_driver = { | 3573 | static struct platform_driver fec_driver = { |
| 3636 | .driver = { | 3574 | .driver = { |
diff --git a/drivers/net/ethernet/marvell/mvneta.c b/drivers/net/ethernet/marvell/mvneta.c index e4fb172d91a6..fe2299ac4f5c 100644 --- a/drivers/net/ethernet/marvell/mvneta.c +++ b/drivers/net/ethernet/marvell/mvneta.c | |||
| @@ -1462,7 +1462,7 @@ static int mvneta_rx(struct mvneta_port *pp, int rx_todo, | |||
| 1462 | struct mvneta_rx_queue *rxq) | 1462 | struct mvneta_rx_queue *rxq) |
| 1463 | { | 1463 | { |
| 1464 | struct net_device *dev = pp->dev; | 1464 | struct net_device *dev = pp->dev; |
| 1465 | int rx_done, rx_filled; | 1465 | int rx_done; |
| 1466 | u32 rcvd_pkts = 0; | 1466 | u32 rcvd_pkts = 0; |
| 1467 | u32 rcvd_bytes = 0; | 1467 | u32 rcvd_bytes = 0; |
| 1468 | 1468 | ||
| @@ -1473,7 +1473,6 @@ static int mvneta_rx(struct mvneta_port *pp, int rx_todo, | |||
| 1473 | rx_todo = rx_done; | 1473 | rx_todo = rx_done; |
| 1474 | 1474 | ||
| 1475 | rx_done = 0; | 1475 | rx_done = 0; |
| 1476 | rx_filled = 0; | ||
| 1477 | 1476 | ||
| 1478 | /* Fairness NAPI loop */ | 1477 | /* Fairness NAPI loop */ |
| 1479 | while (rx_done < rx_todo) { | 1478 | while (rx_done < rx_todo) { |
| @@ -1484,7 +1483,6 @@ static int mvneta_rx(struct mvneta_port *pp, int rx_todo, | |||
| 1484 | int rx_bytes, err; | 1483 | int rx_bytes, err; |
| 1485 | 1484 | ||
| 1486 | rx_done++; | 1485 | rx_done++; |
| 1487 | rx_filled++; | ||
| 1488 | rx_status = rx_desc->status; | 1486 | rx_status = rx_desc->status; |
| 1489 | rx_bytes = rx_desc->data_size - (ETH_FCS_LEN + MVNETA_MH_SIZE); | 1487 | rx_bytes = rx_desc->data_size - (ETH_FCS_LEN + MVNETA_MH_SIZE); |
| 1490 | data = (unsigned char *)rx_desc->buf_cookie; | 1488 | data = (unsigned char *)rx_desc->buf_cookie; |
| @@ -1524,6 +1522,14 @@ static int mvneta_rx(struct mvneta_port *pp, int rx_todo, | |||
| 1524 | continue; | 1522 | continue; |
| 1525 | } | 1523 | } |
| 1526 | 1524 | ||
| 1525 | /* Refill processing */ | ||
| 1526 | err = mvneta_rx_refill(pp, rx_desc); | ||
| 1527 | if (err) { | ||
| 1528 | netdev_err(dev, "Linux processing - Can't refill\n"); | ||
| 1529 | rxq->missed++; | ||
| 1530 | goto err_drop_frame; | ||
| 1531 | } | ||
| 1532 | |||
| 1527 | skb = build_skb(data, pp->frag_size > PAGE_SIZE ? 0 : pp->frag_size); | 1533 | skb = build_skb(data, pp->frag_size > PAGE_SIZE ? 0 : pp->frag_size); |
| 1528 | if (!skb) | 1534 | if (!skb) |
| 1529 | goto err_drop_frame; | 1535 | goto err_drop_frame; |
| @@ -1543,14 +1549,6 @@ static int mvneta_rx(struct mvneta_port *pp, int rx_todo, | |||
| 1543 | mvneta_rx_csum(pp, rx_status, skb); | 1549 | mvneta_rx_csum(pp, rx_status, skb); |
| 1544 | 1550 | ||
| 1545 | napi_gro_receive(&pp->napi, skb); | 1551 | napi_gro_receive(&pp->napi, skb); |
| 1546 | |||
| 1547 | /* Refill processing */ | ||
| 1548 | err = mvneta_rx_refill(pp, rx_desc); | ||
| 1549 | if (err) { | ||
| 1550 | netdev_err(dev, "Linux processing - Can't refill\n"); | ||
| 1551 | rxq->missed++; | ||
| 1552 | rx_filled--; | ||
| 1553 | } | ||
| 1554 | } | 1552 | } |
| 1555 | 1553 | ||
| 1556 | if (rcvd_pkts) { | 1554 | if (rcvd_pkts) { |
| @@ -1563,7 +1561,7 @@ static int mvneta_rx(struct mvneta_port *pp, int rx_todo, | |||
| 1563 | } | 1561 | } |
| 1564 | 1562 | ||
| 1565 | /* Update rxq management counters */ | 1563 | /* Update rxq management counters */ |
| 1566 | mvneta_rxq_desc_num_update(pp, rxq, rx_done, rx_filled); | 1564 | mvneta_rxq_desc_num_update(pp, rxq, rx_done, rx_done); |
| 1567 | 1565 | ||
| 1568 | return rx_done; | 1566 | return rx_done; |
| 1569 | } | 1567 | } |
diff --git a/drivers/net/ethernet/renesas/ravb_main.c b/drivers/net/ethernet/renesas/ravb_main.c index 47287c1cc7e0..779bb58a068e 100644 --- a/drivers/net/ethernet/renesas/ravb_main.c +++ b/drivers/net/ethernet/renesas/ravb_main.c | |||
| @@ -228,9 +228,7 @@ static void ravb_ring_format(struct net_device *ndev, int q) | |||
| 228 | struct ravb_desc *desc; | 228 | struct ravb_desc *desc; |
| 229 | int rx_ring_size = sizeof(*rx_desc) * priv->num_rx_ring[q]; | 229 | int rx_ring_size = sizeof(*rx_desc) * priv->num_rx_ring[q]; |
| 230 | int tx_ring_size = sizeof(*tx_desc) * priv->num_tx_ring[q]; | 230 | int tx_ring_size = sizeof(*tx_desc) * priv->num_tx_ring[q]; |
| 231 | struct sk_buff *skb; | ||
| 232 | dma_addr_t dma_addr; | 231 | dma_addr_t dma_addr; |
| 233 | void *buffer; | ||
| 234 | int i; | 232 | int i; |
| 235 | 233 | ||
| 236 | priv->cur_rx[q] = 0; | 234 | priv->cur_rx[q] = 0; |
| @@ -241,41 +239,28 @@ static void ravb_ring_format(struct net_device *ndev, int q) | |||
| 241 | memset(priv->rx_ring[q], 0, rx_ring_size); | 239 | memset(priv->rx_ring[q], 0, rx_ring_size); |
| 242 | /* Build RX ring buffer */ | 240 | /* Build RX ring buffer */ |
| 243 | for (i = 0; i < priv->num_rx_ring[q]; i++) { | 241 | for (i = 0; i < priv->num_rx_ring[q]; i++) { |
| 244 | priv->rx_skb[q][i] = NULL; | ||
| 245 | skb = netdev_alloc_skb(ndev, PKT_BUF_SZ + RAVB_ALIGN - 1); | ||
| 246 | if (!skb) | ||
| 247 | break; | ||
| 248 | ravb_set_buffer_align(skb); | ||
| 249 | /* RX descriptor */ | 242 | /* RX descriptor */ |
| 250 | rx_desc = &priv->rx_ring[q][i]; | 243 | rx_desc = &priv->rx_ring[q][i]; |
| 251 | /* The size of the buffer should be on 16-byte boundary. */ | 244 | /* The size of the buffer should be on 16-byte boundary. */ |
| 252 | rx_desc->ds_cc = cpu_to_le16(ALIGN(PKT_BUF_SZ, 16)); | 245 | rx_desc->ds_cc = cpu_to_le16(ALIGN(PKT_BUF_SZ, 16)); |
| 253 | dma_addr = dma_map_single(&ndev->dev, skb->data, | 246 | dma_addr = dma_map_single(&ndev->dev, priv->rx_skb[q][i]->data, |
| 254 | ALIGN(PKT_BUF_SZ, 16), | 247 | ALIGN(PKT_BUF_SZ, 16), |
| 255 | DMA_FROM_DEVICE); | 248 | DMA_FROM_DEVICE); |
| 256 | if (dma_mapping_error(&ndev->dev, dma_addr)) { | 249 | /* We just set the data size to 0 for a failed mapping which |
| 257 | dev_kfree_skb(skb); | 250 | * should prevent DMA from happening... |
| 258 | break; | 251 | */ |
| 259 | } | 252 | if (dma_mapping_error(&ndev->dev, dma_addr)) |
| 260 | priv->rx_skb[q][i] = skb; | 253 | rx_desc->ds_cc = cpu_to_le16(0); |
| 261 | rx_desc->dptr = cpu_to_le32(dma_addr); | 254 | rx_desc->dptr = cpu_to_le32(dma_addr); |
| 262 | rx_desc->die_dt = DT_FEMPTY; | 255 | rx_desc->die_dt = DT_FEMPTY; |
| 263 | } | 256 | } |
| 264 | rx_desc = &priv->rx_ring[q][i]; | 257 | rx_desc = &priv->rx_ring[q][i]; |
| 265 | rx_desc->dptr = cpu_to_le32((u32)priv->rx_desc_dma[q]); | 258 | rx_desc->dptr = cpu_to_le32((u32)priv->rx_desc_dma[q]); |
| 266 | rx_desc->die_dt = DT_LINKFIX; /* type */ | 259 | rx_desc->die_dt = DT_LINKFIX; /* type */ |
| 267 | priv->dirty_rx[q] = (u32)(i - priv->num_rx_ring[q]); | ||
| 268 | 260 | ||
| 269 | memset(priv->tx_ring[q], 0, tx_ring_size); | 261 | memset(priv->tx_ring[q], 0, tx_ring_size); |
| 270 | /* Build TX ring buffer */ | 262 | /* Build TX ring buffer */ |
| 271 | for (i = 0; i < priv->num_tx_ring[q]; i++) { | 263 | for (i = 0; i < priv->num_tx_ring[q]; i++) { |
| 272 | priv->tx_skb[q][i] = NULL; | ||
| 273 | priv->tx_buffers[q][i] = NULL; | ||
| 274 | buffer = kmalloc(PKT_BUF_SZ + RAVB_ALIGN - 1, GFP_KERNEL); | ||
| 275 | if (!buffer) | ||
| 276 | break; | ||
| 277 | /* Aligned TX buffer */ | ||
| 278 | priv->tx_buffers[q][i] = buffer; | ||
| 279 | tx_desc = &priv->tx_ring[q][i]; | 264 | tx_desc = &priv->tx_ring[q][i]; |
| 280 | tx_desc->die_dt = DT_EEMPTY; | 265 | tx_desc->die_dt = DT_EEMPTY; |
| 281 | } | 266 | } |
| @@ -298,7 +283,10 @@ static void ravb_ring_format(struct net_device *ndev, int q) | |||
| 298 | static int ravb_ring_init(struct net_device *ndev, int q) | 283 | static int ravb_ring_init(struct net_device *ndev, int q) |
| 299 | { | 284 | { |
| 300 | struct ravb_private *priv = netdev_priv(ndev); | 285 | struct ravb_private *priv = netdev_priv(ndev); |
| 286 | struct sk_buff *skb; | ||
| 301 | int ring_size; | 287 | int ring_size; |
| 288 | void *buffer; | ||
| 289 | int i; | ||
| 302 | 290 | ||
| 303 | /* Allocate RX and TX skb rings */ | 291 | /* Allocate RX and TX skb rings */ |
| 304 | priv->rx_skb[q] = kcalloc(priv->num_rx_ring[q], | 292 | priv->rx_skb[q] = kcalloc(priv->num_rx_ring[q], |
| @@ -308,12 +296,28 @@ static int ravb_ring_init(struct net_device *ndev, int q) | |||
| 308 | if (!priv->rx_skb[q] || !priv->tx_skb[q]) | 296 | if (!priv->rx_skb[q] || !priv->tx_skb[q]) |
| 309 | goto error; | 297 | goto error; |
| 310 | 298 | ||
| 299 | for (i = 0; i < priv->num_rx_ring[q]; i++) { | ||
| 300 | skb = netdev_alloc_skb(ndev, PKT_BUF_SZ + RAVB_ALIGN - 1); | ||
| 301 | if (!skb) | ||
| 302 | goto error; | ||
| 303 | ravb_set_buffer_align(skb); | ||
| 304 | priv->rx_skb[q][i] = skb; | ||
| 305 | } | ||
| 306 | |||
| 311 | /* Allocate rings for the aligned buffers */ | 307 | /* Allocate rings for the aligned buffers */ |
| 312 | priv->tx_buffers[q] = kcalloc(priv->num_tx_ring[q], | 308 | priv->tx_buffers[q] = kcalloc(priv->num_tx_ring[q], |
| 313 | sizeof(*priv->tx_buffers[q]), GFP_KERNEL); | 309 | sizeof(*priv->tx_buffers[q]), GFP_KERNEL); |
| 314 | if (!priv->tx_buffers[q]) | 310 | if (!priv->tx_buffers[q]) |
| 315 | goto error; | 311 | goto error; |
| 316 | 312 | ||
| 313 | for (i = 0; i < priv->num_tx_ring[q]; i++) { | ||
| 314 | buffer = kmalloc(PKT_BUF_SZ + RAVB_ALIGN - 1, GFP_KERNEL); | ||
| 315 | if (!buffer) | ||
| 316 | goto error; | ||
| 317 | /* Aligned TX buffer */ | ||
| 318 | priv->tx_buffers[q][i] = buffer; | ||
| 319 | } | ||
| 320 | |||
| 317 | /* Allocate all RX descriptors. */ | 321 | /* Allocate all RX descriptors. */ |
| 318 | ring_size = sizeof(struct ravb_ex_rx_desc) * (priv->num_rx_ring[q] + 1); | 322 | ring_size = sizeof(struct ravb_ex_rx_desc) * (priv->num_rx_ring[q] + 1); |
| 319 | priv->rx_ring[q] = dma_alloc_coherent(NULL, ring_size, | 323 | priv->rx_ring[q] = dma_alloc_coherent(NULL, ring_size, |
| @@ -524,6 +528,10 @@ static bool ravb_rx(struct net_device *ndev, int *quota, int q) | |||
| 524 | if (--boguscnt < 0) | 528 | if (--boguscnt < 0) |
| 525 | break; | 529 | break; |
| 526 | 530 | ||
| 531 | /* We use 0-byte descriptors to mark the DMA mapping errors */ | ||
| 532 | if (!pkt_len) | ||
| 533 | continue; | ||
| 534 | |||
| 527 | if (desc_status & MSC_MC) | 535 | if (desc_status & MSC_MC) |
| 528 | stats->multicast++; | 536 | stats->multicast++; |
| 529 | 537 | ||
| @@ -543,10 +551,9 @@ static bool ravb_rx(struct net_device *ndev, int *quota, int q) | |||
| 543 | 551 | ||
| 544 | skb = priv->rx_skb[q][entry]; | 552 | skb = priv->rx_skb[q][entry]; |
| 545 | priv->rx_skb[q][entry] = NULL; | 553 | priv->rx_skb[q][entry] = NULL; |
| 546 | dma_sync_single_for_cpu(&ndev->dev, | 554 | dma_unmap_single(&ndev->dev, le32_to_cpu(desc->dptr), |
| 547 | le32_to_cpu(desc->dptr), | 555 | ALIGN(PKT_BUF_SZ, 16), |
| 548 | ALIGN(PKT_BUF_SZ, 16), | 556 | DMA_FROM_DEVICE); |
| 549 | DMA_FROM_DEVICE); | ||
| 550 | get_ts &= (q == RAVB_NC) ? | 557 | get_ts &= (q == RAVB_NC) ? |
| 551 | RAVB_RXTSTAMP_TYPE_V2_L2_EVENT : | 558 | RAVB_RXTSTAMP_TYPE_V2_L2_EVENT : |
| 552 | ~RAVB_RXTSTAMP_TYPE_V2_L2_EVENT; | 559 | ~RAVB_RXTSTAMP_TYPE_V2_L2_EVENT; |
| @@ -584,17 +591,15 @@ static bool ravb_rx(struct net_device *ndev, int *quota, int q) | |||
| 584 | if (!skb) | 591 | if (!skb) |
| 585 | break; /* Better luck next round. */ | 592 | break; /* Better luck next round. */ |
| 586 | ravb_set_buffer_align(skb); | 593 | ravb_set_buffer_align(skb); |
| 587 | dma_unmap_single(&ndev->dev, le32_to_cpu(desc->dptr), | ||
| 588 | ALIGN(PKT_BUF_SZ, 16), | ||
| 589 | DMA_FROM_DEVICE); | ||
| 590 | dma_addr = dma_map_single(&ndev->dev, skb->data, | 594 | dma_addr = dma_map_single(&ndev->dev, skb->data, |
| 591 | le16_to_cpu(desc->ds_cc), | 595 | le16_to_cpu(desc->ds_cc), |
| 592 | DMA_FROM_DEVICE); | 596 | DMA_FROM_DEVICE); |
| 593 | skb_checksum_none_assert(skb); | 597 | skb_checksum_none_assert(skb); |
| 594 | if (dma_mapping_error(&ndev->dev, dma_addr)) { | 598 | /* We just set the data size to 0 for a failed mapping |
| 595 | dev_kfree_skb_any(skb); | 599 | * which should prevent DMA from happening... |
| 596 | break; | 600 | */ |
| 597 | } | 601 | if (dma_mapping_error(&ndev->dev, dma_addr)) |
| 602 | desc->ds_cc = cpu_to_le16(0); | ||
| 598 | desc->dptr = cpu_to_le32(dma_addr); | 603 | desc->dptr = cpu_to_le32(dma_addr); |
| 599 | priv->rx_skb[q][entry] = skb; | 604 | priv->rx_skb[q][entry] = skb; |
| 600 | } | 605 | } |
| @@ -1279,7 +1284,6 @@ static netdev_tx_t ravb_start_xmit(struct sk_buff *skb, struct net_device *ndev) | |||
| 1279 | u32 dma_addr; | 1284 | u32 dma_addr; |
| 1280 | void *buffer; | 1285 | void *buffer; |
| 1281 | u32 entry; | 1286 | u32 entry; |
| 1282 | u32 tccr; | ||
| 1283 | 1287 | ||
| 1284 | spin_lock_irqsave(&priv->lock, flags); | 1288 | spin_lock_irqsave(&priv->lock, flags); |
| 1285 | if (priv->cur_tx[q] - priv->dirty_tx[q] >= priv->num_tx_ring[q]) { | 1289 | if (priv->cur_tx[q] - priv->dirty_tx[q] >= priv->num_tx_ring[q]) { |
| @@ -1328,9 +1332,7 @@ static netdev_tx_t ravb_start_xmit(struct sk_buff *skb, struct net_device *ndev) | |||
| 1328 | dma_wmb(); | 1332 | dma_wmb(); |
| 1329 | desc->die_dt = DT_FSINGLE; | 1333 | desc->die_dt = DT_FSINGLE; |
| 1330 | 1334 | ||
| 1331 | tccr = ravb_read(ndev, TCCR); | 1335 | ravb_write(ndev, ravb_read(ndev, TCCR) | (TCCR_TSRQ0 << q), TCCR); |
| 1332 | if (!(tccr & (TCCR_TSRQ0 << q))) | ||
| 1333 | ravb_write(ndev, tccr | (TCCR_TSRQ0 << q), TCCR); | ||
| 1334 | 1336 | ||
| 1335 | priv->cur_tx[q]++; | 1337 | priv->cur_tx[q]++; |
| 1336 | if (priv->cur_tx[q] - priv->dirty_tx[q] >= priv->num_tx_ring[q] && | 1338 | if (priv->cur_tx[q] - priv->dirty_tx[q] >= priv->num_tx_ring[q] && |
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c index 50f7a7a26821..864b476f7fd5 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | |||
| @@ -2843,7 +2843,7 @@ int stmmac_dvr_probe(struct device *device, | |||
| 2843 | if (res->mac) | 2843 | if (res->mac) |
| 2844 | memcpy(priv->dev->dev_addr, res->mac, ETH_ALEN); | 2844 | memcpy(priv->dev->dev_addr, res->mac, ETH_ALEN); |
| 2845 | 2845 | ||
| 2846 | dev_set_drvdata(device, priv); | 2846 | dev_set_drvdata(device, priv->dev); |
| 2847 | 2847 | ||
| 2848 | /* Verify driver arguments */ | 2848 | /* Verify driver arguments */ |
| 2849 | stmmac_verify_args(); | 2849 | stmmac_verify_args(); |
diff --git a/drivers/net/ethernet/ti/cpsw.c b/drivers/net/ethernet/ti/cpsw.c index f335bf119ab5..d155bf2573cd 100644 --- a/drivers/net/ethernet/ti/cpsw.c +++ b/drivers/net/ethernet/ti/cpsw.c | |||
| @@ -793,9 +793,7 @@ static irqreturn_t cpsw_rx_interrupt(int irq, void *dev_id) | |||
| 793 | static int cpsw_poll(struct napi_struct *napi, int budget) | 793 | static int cpsw_poll(struct napi_struct *napi, int budget) |
| 794 | { | 794 | { |
| 795 | struct cpsw_priv *priv = napi_to_priv(napi); | 795 | struct cpsw_priv *priv = napi_to_priv(napi); |
| 796 | int num_tx, num_rx; | 796 | int num_rx; |
| 797 | |||
| 798 | num_tx = cpdma_chan_process(priv->txch, 128); | ||
| 799 | 797 | ||
| 800 | num_rx = cpdma_chan_process(priv->rxch, budget); | 798 | num_rx = cpdma_chan_process(priv->rxch, budget); |
| 801 | if (num_rx < budget) { | 799 | if (num_rx < budget) { |
| @@ -810,9 +808,8 @@ static int cpsw_poll(struct napi_struct *napi, int budget) | |||
| 810 | } | 808 | } |
| 811 | } | 809 | } |
| 812 | 810 | ||
| 813 | if (num_rx || num_tx) | 811 | if (num_rx) |
| 814 | cpsw_dbg(priv, intr, "poll %d rx, %d tx pkts\n", | 812 | cpsw_dbg(priv, intr, "poll %d rx pkts\n", num_rx); |
| 815 | num_rx, num_tx); | ||
| 816 | 813 | ||
| 817 | return num_rx; | 814 | return num_rx; |
| 818 | } | 815 | } |
diff --git a/drivers/net/ethernet/ti/netcp_core.c b/drivers/net/ethernet/ti/netcp_core.c index 3e47202b9010..3ca87f26582a 100644 --- a/drivers/net/ethernet/ti/netcp_core.c +++ b/drivers/net/ethernet/ti/netcp_core.c | |||
| @@ -1617,11 +1617,11 @@ static int netcp_ndo_open(struct net_device *ndev) | |||
| 1617 | } | 1617 | } |
| 1618 | mutex_unlock(&netcp_modules_lock); | 1618 | mutex_unlock(&netcp_modules_lock); |
| 1619 | 1619 | ||
| 1620 | netcp_rxpool_refill(netcp); | ||
| 1621 | napi_enable(&netcp->rx_napi); | 1620 | napi_enable(&netcp->rx_napi); |
| 1622 | napi_enable(&netcp->tx_napi); | 1621 | napi_enable(&netcp->tx_napi); |
| 1623 | knav_queue_enable_notify(netcp->tx_compl_q); | 1622 | knav_queue_enable_notify(netcp->tx_compl_q); |
| 1624 | knav_queue_enable_notify(netcp->rx_queue); | 1623 | knav_queue_enable_notify(netcp->rx_queue); |
| 1624 | netcp_rxpool_refill(netcp); | ||
| 1625 | netif_tx_wake_all_queues(ndev); | 1625 | netif_tx_wake_all_queues(ndev); |
| 1626 | dev_dbg(netcp->ndev_dev, "netcp device %s opened\n", ndev->name); | 1626 | dev_dbg(netcp->ndev_dev, "netcp device %s opened\n", ndev->name); |
| 1627 | return 0; | 1627 | return 0; |
diff --git a/drivers/net/ipvlan/ipvlan.h b/drivers/net/ipvlan/ipvlan.h index 953a97492fab..9542b7bac61a 100644 --- a/drivers/net/ipvlan/ipvlan.h +++ b/drivers/net/ipvlan/ipvlan.h | |||
| @@ -67,8 +67,6 @@ struct ipvl_dev { | |||
| 67 | struct ipvl_port *port; | 67 | struct ipvl_port *port; |
| 68 | struct net_device *phy_dev; | 68 | struct net_device *phy_dev; |
| 69 | struct list_head addrs; | 69 | struct list_head addrs; |
| 70 | int ipv4cnt; | ||
| 71 | int ipv6cnt; | ||
| 72 | struct ipvl_pcpu_stats __percpu *pcpu_stats; | 70 | struct ipvl_pcpu_stats __percpu *pcpu_stats; |
| 73 | DECLARE_BITMAP(mac_filters, IPVLAN_MAC_FILTER_SIZE); | 71 | DECLARE_BITMAP(mac_filters, IPVLAN_MAC_FILTER_SIZE); |
| 74 | netdev_features_t sfeatures; | 72 | netdev_features_t sfeatures; |
| @@ -106,6 +104,11 @@ static inline struct ipvl_port *ipvlan_port_get_rcu(const struct net_device *d) | |||
| 106 | return rcu_dereference(d->rx_handler_data); | 104 | return rcu_dereference(d->rx_handler_data); |
| 107 | } | 105 | } |
| 108 | 106 | ||
| 107 | static inline struct ipvl_port *ipvlan_port_get_rcu_bh(const struct net_device *d) | ||
| 108 | { | ||
| 109 | return rcu_dereference_bh(d->rx_handler_data); | ||
| 110 | } | ||
| 111 | |||
| 109 | static inline struct ipvl_port *ipvlan_port_get_rtnl(const struct net_device *d) | 112 | static inline struct ipvl_port *ipvlan_port_get_rtnl(const struct net_device *d) |
| 110 | { | 113 | { |
| 111 | return rtnl_dereference(d->rx_handler_data); | 114 | return rtnl_dereference(d->rx_handler_data); |
| @@ -124,5 +127,5 @@ struct ipvl_addr *ipvlan_find_addr(const struct ipvl_dev *ipvlan, | |||
| 124 | bool ipvlan_addr_busy(struct ipvl_port *port, void *iaddr, bool is_v6); | 127 | bool ipvlan_addr_busy(struct ipvl_port *port, void *iaddr, bool is_v6); |
| 125 | struct ipvl_addr *ipvlan_ht_addr_lookup(const struct ipvl_port *port, | 128 | struct ipvl_addr *ipvlan_ht_addr_lookup(const struct ipvl_port *port, |
| 126 | const void *iaddr, bool is_v6); | 129 | const void *iaddr, bool is_v6); |
| 127 | void ipvlan_ht_addr_del(struct ipvl_addr *addr, bool sync); | 130 | void ipvlan_ht_addr_del(struct ipvl_addr *addr); |
| 128 | #endif /* __IPVLAN_H */ | 131 | #endif /* __IPVLAN_H */ |
diff --git a/drivers/net/ipvlan/ipvlan_core.c b/drivers/net/ipvlan/ipvlan_core.c index 8afbedad620d..207f62e8de9a 100644 --- a/drivers/net/ipvlan/ipvlan_core.c +++ b/drivers/net/ipvlan/ipvlan_core.c | |||
| @@ -85,11 +85,9 @@ void ipvlan_ht_addr_add(struct ipvl_dev *ipvlan, struct ipvl_addr *addr) | |||
| 85 | hlist_add_head_rcu(&addr->hlnode, &port->hlhead[hash]); | 85 | hlist_add_head_rcu(&addr->hlnode, &port->hlhead[hash]); |
| 86 | } | 86 | } |
| 87 | 87 | ||
| 88 | void ipvlan_ht_addr_del(struct ipvl_addr *addr, bool sync) | 88 | void ipvlan_ht_addr_del(struct ipvl_addr *addr) |
| 89 | { | 89 | { |
| 90 | hlist_del_init_rcu(&addr->hlnode); | 90 | hlist_del_init_rcu(&addr->hlnode); |
| 91 | if (sync) | ||
| 92 | synchronize_rcu(); | ||
| 93 | } | 91 | } |
| 94 | 92 | ||
| 95 | struct ipvl_addr *ipvlan_find_addr(const struct ipvl_dev *ipvlan, | 93 | struct ipvl_addr *ipvlan_find_addr(const struct ipvl_dev *ipvlan, |
| @@ -531,7 +529,7 @@ static int ipvlan_xmit_mode_l2(struct sk_buff *skb, struct net_device *dev) | |||
| 531 | int ipvlan_queue_xmit(struct sk_buff *skb, struct net_device *dev) | 529 | int ipvlan_queue_xmit(struct sk_buff *skb, struct net_device *dev) |
| 532 | { | 530 | { |
| 533 | struct ipvl_dev *ipvlan = netdev_priv(dev); | 531 | struct ipvl_dev *ipvlan = netdev_priv(dev); |
| 534 | struct ipvl_port *port = ipvlan_port_get_rcu(ipvlan->phy_dev); | 532 | struct ipvl_port *port = ipvlan_port_get_rcu_bh(ipvlan->phy_dev); |
| 535 | 533 | ||
| 536 | if (!port) | 534 | if (!port) |
| 537 | goto out; | 535 | goto out; |
diff --git a/drivers/net/ipvlan/ipvlan_main.c b/drivers/net/ipvlan/ipvlan_main.c index 1acc283160d9..20b58bdecf75 100644 --- a/drivers/net/ipvlan/ipvlan_main.c +++ b/drivers/net/ipvlan/ipvlan_main.c | |||
| @@ -153,10 +153,9 @@ static int ipvlan_open(struct net_device *dev) | |||
| 153 | else | 153 | else |
| 154 | dev->flags &= ~IFF_NOARP; | 154 | dev->flags &= ~IFF_NOARP; |
| 155 | 155 | ||
| 156 | if (ipvlan->ipv6cnt > 0 || ipvlan->ipv4cnt > 0) { | 156 | list_for_each_entry(addr, &ipvlan->addrs, anode) |
| 157 | list_for_each_entry(addr, &ipvlan->addrs, anode) | 157 | ipvlan_ht_addr_add(ipvlan, addr); |
| 158 | ipvlan_ht_addr_add(ipvlan, addr); | 158 | |
| 159 | } | ||
| 160 | return dev_uc_add(phy_dev, phy_dev->dev_addr); | 159 | return dev_uc_add(phy_dev, phy_dev->dev_addr); |
| 161 | } | 160 | } |
| 162 | 161 | ||
| @@ -171,10 +170,9 @@ static int ipvlan_stop(struct net_device *dev) | |||
| 171 | 170 | ||
| 172 | dev_uc_del(phy_dev, phy_dev->dev_addr); | 171 | dev_uc_del(phy_dev, phy_dev->dev_addr); |
| 173 | 172 | ||
| 174 | if (ipvlan->ipv6cnt > 0 || ipvlan->ipv4cnt > 0) { | 173 | list_for_each_entry(addr, &ipvlan->addrs, anode) |
| 175 | list_for_each_entry(addr, &ipvlan->addrs, anode) | 174 | ipvlan_ht_addr_del(addr); |
| 176 | ipvlan_ht_addr_del(addr, !dev->dismantle); | 175 | |
| 177 | } | ||
| 178 | return 0; | 176 | return 0; |
| 179 | } | 177 | } |
| 180 | 178 | ||
| @@ -471,8 +469,6 @@ static int ipvlan_link_new(struct net *src_net, struct net_device *dev, | |||
| 471 | ipvlan->port = port; | 469 | ipvlan->port = port; |
| 472 | ipvlan->sfeatures = IPVLAN_FEATURES; | 470 | ipvlan->sfeatures = IPVLAN_FEATURES; |
| 473 | INIT_LIST_HEAD(&ipvlan->addrs); | 471 | INIT_LIST_HEAD(&ipvlan->addrs); |
| 474 | ipvlan->ipv4cnt = 0; | ||
| 475 | ipvlan->ipv6cnt = 0; | ||
| 476 | 472 | ||
| 477 | /* TODO Probably put random address here to be presented to the | 473 | /* TODO Probably put random address here to be presented to the |
| 478 | * world but keep using the physical-dev address for the outgoing | 474 | * world but keep using the physical-dev address for the outgoing |
| @@ -508,12 +504,12 @@ static void ipvlan_link_delete(struct net_device *dev, struct list_head *head) | |||
| 508 | struct ipvl_dev *ipvlan = netdev_priv(dev); | 504 | struct ipvl_dev *ipvlan = netdev_priv(dev); |
| 509 | struct ipvl_addr *addr, *next; | 505 | struct ipvl_addr *addr, *next; |
| 510 | 506 | ||
| 511 | if (ipvlan->ipv6cnt > 0 || ipvlan->ipv4cnt > 0) { | 507 | list_for_each_entry_safe(addr, next, &ipvlan->addrs, anode) { |
| 512 | list_for_each_entry_safe(addr, next, &ipvlan->addrs, anode) { | 508 | ipvlan_ht_addr_del(addr); |
| 513 | ipvlan_ht_addr_del(addr, !dev->dismantle); | 509 | list_del(&addr->anode); |
| 514 | list_del(&addr->anode); | 510 | kfree_rcu(addr, rcu); |
| 515 | } | ||
| 516 | } | 511 | } |
| 512 | |||
| 517 | list_del_rcu(&ipvlan->pnode); | 513 | list_del_rcu(&ipvlan->pnode); |
| 518 | unregister_netdevice_queue(dev, head); | 514 | unregister_netdevice_queue(dev, head); |
| 519 | netdev_upper_dev_unlink(ipvlan->phy_dev, dev); | 515 | netdev_upper_dev_unlink(ipvlan->phy_dev, dev); |
| @@ -627,7 +623,7 @@ static int ipvlan_add_addr6(struct ipvl_dev *ipvlan, struct in6_addr *ip6_addr) | |||
| 627 | memcpy(&addr->ip6addr, ip6_addr, sizeof(struct in6_addr)); | 623 | memcpy(&addr->ip6addr, ip6_addr, sizeof(struct in6_addr)); |
| 628 | addr->atype = IPVL_IPV6; | 624 | addr->atype = IPVL_IPV6; |
| 629 | list_add_tail(&addr->anode, &ipvlan->addrs); | 625 | list_add_tail(&addr->anode, &ipvlan->addrs); |
| 630 | ipvlan->ipv6cnt++; | 626 | |
| 631 | /* If the interface is not up, the address will be added to the hash | 627 | /* If the interface is not up, the address will be added to the hash |
| 632 | * list by ipvlan_open. | 628 | * list by ipvlan_open. |
| 633 | */ | 629 | */ |
| @@ -645,10 +641,8 @@ static void ipvlan_del_addr6(struct ipvl_dev *ipvlan, struct in6_addr *ip6_addr) | |||
| 645 | if (!addr) | 641 | if (!addr) |
| 646 | return; | 642 | return; |
| 647 | 643 | ||
| 648 | ipvlan_ht_addr_del(addr, true); | 644 | ipvlan_ht_addr_del(addr); |
| 649 | list_del(&addr->anode); | 645 | list_del(&addr->anode); |
| 650 | ipvlan->ipv6cnt--; | ||
| 651 | WARN_ON(ipvlan->ipv6cnt < 0); | ||
| 652 | kfree_rcu(addr, rcu); | 646 | kfree_rcu(addr, rcu); |
| 653 | 647 | ||
| 654 | return; | 648 | return; |
| @@ -661,6 +655,10 @@ static int ipvlan_addr6_event(struct notifier_block *unused, | |||
| 661 | struct net_device *dev = (struct net_device *)if6->idev->dev; | 655 | struct net_device *dev = (struct net_device *)if6->idev->dev; |
| 662 | struct ipvl_dev *ipvlan = netdev_priv(dev); | 656 | struct ipvl_dev *ipvlan = netdev_priv(dev); |
| 663 | 657 | ||
| 658 | /* FIXME IPv6 autoconf calls us from bh without RTNL */ | ||
| 659 | if (in_softirq()) | ||
| 660 | return NOTIFY_DONE; | ||
| 661 | |||
| 664 | if (!netif_is_ipvlan(dev)) | 662 | if (!netif_is_ipvlan(dev)) |
| 665 | return NOTIFY_DONE; | 663 | return NOTIFY_DONE; |
| 666 | 664 | ||
| @@ -699,7 +697,7 @@ static int ipvlan_add_addr4(struct ipvl_dev *ipvlan, struct in_addr *ip4_addr) | |||
| 699 | memcpy(&addr->ip4addr, ip4_addr, sizeof(struct in_addr)); | 697 | memcpy(&addr->ip4addr, ip4_addr, sizeof(struct in_addr)); |
| 700 | addr->atype = IPVL_IPV4; | 698 | addr->atype = IPVL_IPV4; |
| 701 | list_add_tail(&addr->anode, &ipvlan->addrs); | 699 | list_add_tail(&addr->anode, &ipvlan->addrs); |
| 702 | ipvlan->ipv4cnt++; | 700 | |
| 703 | /* If the interface is not up, the address will be added to the hash | 701 | /* If the interface is not up, the address will be added to the hash |
| 704 | * list by ipvlan_open. | 702 | * list by ipvlan_open. |
| 705 | */ | 703 | */ |
| @@ -717,10 +715,8 @@ static void ipvlan_del_addr4(struct ipvl_dev *ipvlan, struct in_addr *ip4_addr) | |||
| 717 | if (!addr) | 715 | if (!addr) |
| 718 | return; | 716 | return; |
| 719 | 717 | ||
| 720 | ipvlan_ht_addr_del(addr, true); | 718 | ipvlan_ht_addr_del(addr); |
| 721 | list_del(&addr->anode); | 719 | list_del(&addr->anode); |
| 722 | ipvlan->ipv4cnt--; | ||
| 723 | WARN_ON(ipvlan->ipv4cnt < 0); | ||
| 724 | kfree_rcu(addr, rcu); | 720 | kfree_rcu(addr, rcu); |
| 725 | 721 | ||
| 726 | return; | 722 | return; |
diff --git a/drivers/net/phy/dp83867.c b/drivers/net/phy/dp83867.c index c7a12e2e07b7..8a3bf5469892 100644 --- a/drivers/net/phy/dp83867.c +++ b/drivers/net/phy/dp83867.c | |||
| @@ -164,7 +164,7 @@ static int dp83867_config_init(struct phy_device *phydev) | |||
| 164 | return ret; | 164 | return ret; |
| 165 | } | 165 | } |
| 166 | 166 | ||
| 167 | if ((phydev->interface >= PHY_INTERFACE_MODE_RGMII_ID) || | 167 | if ((phydev->interface >= PHY_INTERFACE_MODE_RGMII_ID) && |
| 168 | (phydev->interface <= PHY_INTERFACE_MODE_RGMII_RXID)) { | 168 | (phydev->interface <= PHY_INTERFACE_MODE_RGMII_RXID)) { |
| 169 | val = phy_read_mmd_indirect(phydev, DP83867_RGMIICTL, | 169 | val = phy_read_mmd_indirect(phydev, DP83867_RGMIICTL, |
| 170 | DP83867_DEVADDR, phydev->addr); | 170 | DP83867_DEVADDR, phydev->addr); |
diff --git a/drivers/net/phy/mdio_bus.c b/drivers/net/phy/mdio_bus.c index 095ef3fe369a..46a14cbb0215 100644 --- a/drivers/net/phy/mdio_bus.c +++ b/drivers/net/phy/mdio_bus.c | |||
| @@ -421,6 +421,8 @@ static int mdio_bus_match(struct device *dev, struct device_driver *drv) | |||
| 421 | { | 421 | { |
| 422 | struct phy_device *phydev = to_phy_device(dev); | 422 | struct phy_device *phydev = to_phy_device(dev); |
| 423 | struct phy_driver *phydrv = to_phy_driver(drv); | 423 | struct phy_driver *phydrv = to_phy_driver(drv); |
| 424 | const int num_ids = ARRAY_SIZE(phydev->c45_ids.device_ids); | ||
| 425 | int i; | ||
| 424 | 426 | ||
| 425 | if (of_driver_match_device(dev, drv)) | 427 | if (of_driver_match_device(dev, drv)) |
| 426 | return 1; | 428 | return 1; |
| @@ -428,8 +430,21 @@ static int mdio_bus_match(struct device *dev, struct device_driver *drv) | |||
| 428 | if (phydrv->match_phy_device) | 430 | if (phydrv->match_phy_device) |
| 429 | return phydrv->match_phy_device(phydev); | 431 | return phydrv->match_phy_device(phydev); |
| 430 | 432 | ||
| 431 | return (phydrv->phy_id & phydrv->phy_id_mask) == | 433 | if (phydev->is_c45) { |
| 432 | (phydev->phy_id & phydrv->phy_id_mask); | 434 | for (i = 1; i < num_ids; i++) { |
| 435 | if (!(phydev->c45_ids.devices_in_package & (1 << i))) | ||
| 436 | continue; | ||
| 437 | |||
| 438 | if ((phydrv->phy_id & phydrv->phy_id_mask) == | ||
| 439 | (phydev->c45_ids.device_ids[i] & | ||
| 440 | phydrv->phy_id_mask)) | ||
| 441 | return 1; | ||
| 442 | } | ||
| 443 | return 0; | ||
| 444 | } else { | ||
| 445 | return (phydrv->phy_id & phydrv->phy_id_mask) == | ||
| 446 | (phydev->phy_id & phydrv->phy_id_mask); | ||
| 447 | } | ||
| 433 | } | 448 | } |
| 434 | 449 | ||
| 435 | #ifdef CONFIG_PM | 450 | #ifdef CONFIG_PM |
diff --git a/drivers/net/usb/qmi_wwan.c b/drivers/net/usb/qmi_wwan.c index f06c687c5429..1f7a7cd97e50 100644 --- a/drivers/net/usb/qmi_wwan.c +++ b/drivers/net/usb/qmi_wwan.c | |||
| @@ -757,6 +757,7 @@ static const struct usb_device_id products[] = { | |||
| 757 | {QMI_FIXED_INTF(0x1199, 0x901c, 8)}, /* Sierra Wireless EM7700 */ | 757 | {QMI_FIXED_INTF(0x1199, 0x901c, 8)}, /* Sierra Wireless EM7700 */ |
| 758 | {QMI_FIXED_INTF(0x1199, 0x901f, 8)}, /* Sierra Wireless EM7355 */ | 758 | {QMI_FIXED_INTF(0x1199, 0x901f, 8)}, /* Sierra Wireless EM7355 */ |
| 759 | {QMI_FIXED_INTF(0x1199, 0x9041, 8)}, /* Sierra Wireless MC7305/MC7355 */ | 759 | {QMI_FIXED_INTF(0x1199, 0x9041, 8)}, /* Sierra Wireless MC7305/MC7355 */ |
| 760 | {QMI_FIXED_INTF(0x1199, 0x9041, 10)}, /* Sierra Wireless MC7305/MC7355 */ | ||
| 760 | {QMI_FIXED_INTF(0x1199, 0x9051, 8)}, /* Netgear AirCard 340U */ | 761 | {QMI_FIXED_INTF(0x1199, 0x9051, 8)}, /* Netgear AirCard 340U */ |
| 761 | {QMI_FIXED_INTF(0x1199, 0x9053, 8)}, /* Sierra Wireless Modem */ | 762 | {QMI_FIXED_INTF(0x1199, 0x9053, 8)}, /* Sierra Wireless Modem */ |
| 762 | {QMI_FIXED_INTF(0x1199, 0x9054, 8)}, /* Sierra Wireless Modem */ | 763 | {QMI_FIXED_INTF(0x1199, 0x9054, 8)}, /* Sierra Wireless Modem */ |
diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c index 63c7810e1545..7fbca37a1adf 100644 --- a/drivers/net/virtio_net.c +++ b/drivers/net/virtio_net.c | |||
| @@ -1828,7 +1828,8 @@ static int virtnet_probe(struct virtio_device *vdev) | |||
| 1828 | else | 1828 | else |
| 1829 | vi->hdr_len = sizeof(struct virtio_net_hdr); | 1829 | vi->hdr_len = sizeof(struct virtio_net_hdr); |
| 1830 | 1830 | ||
| 1831 | if (virtio_has_feature(vdev, VIRTIO_F_ANY_LAYOUT)) | 1831 | if (virtio_has_feature(vdev, VIRTIO_F_ANY_LAYOUT) || |
| 1832 | virtio_has_feature(vdev, VIRTIO_F_VERSION_1)) | ||
| 1832 | vi->any_header_sg = true; | 1833 | vi->any_header_sg = true; |
| 1833 | 1834 | ||
| 1834 | if (virtio_has_feature(vdev, VIRTIO_NET_F_CTRL_VQ)) | 1835 | if (virtio_has_feature(vdev, VIRTIO_NET_F_CTRL_VQ)) |
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c index 5e15e8e10ed3..a31a6804dc34 100644 --- a/drivers/net/wireless/ath/ath9k/hw.c +++ b/drivers/net/wireless/ath/ath9k/hw.c | |||
| @@ -279,6 +279,7 @@ static void ath9k_hw_read_revisions(struct ath_hw *ah) | |||
| 279 | return; | 279 | return; |
| 280 | case AR9300_DEVID_QCA956X: | 280 | case AR9300_DEVID_QCA956X: |
| 281 | ah->hw_version.macVersion = AR_SREV_VERSION_9561; | 281 | ah->hw_version.macVersion = AR_SREV_VERSION_9561; |
| 282 | return; | ||
| 282 | } | 283 | } |
| 283 | 284 | ||
| 284 | val = REG_READ(ah, AR_SREV) & AR_SREV_ID; | 285 | val = REG_READ(ah, AR_SREV) & AR_SREV_ID; |
diff --git a/drivers/net/wireless/iwlwifi/iwl-fh.h b/drivers/net/wireless/iwlwifi/iwl-fh.h index d56064861a9c..d45dc021cda2 100644 --- a/drivers/net/wireless/iwlwifi/iwl-fh.h +++ b/drivers/net/wireless/iwlwifi/iwl-fh.h | |||
| @@ -438,6 +438,12 @@ static inline unsigned int FH_MEM_CBBC_QUEUE(unsigned int chnl) | |||
| 438 | #define RX_QUEUE_MASK 255 | 438 | #define RX_QUEUE_MASK 255 |
| 439 | #define RX_QUEUE_SIZE_LOG 8 | 439 | #define RX_QUEUE_SIZE_LOG 8 |
| 440 | 440 | ||
| 441 | /* | ||
| 442 | * RX related structures and functions | ||
| 443 | */ | ||
| 444 | #define RX_FREE_BUFFERS 64 | ||
| 445 | #define RX_LOW_WATERMARK 8 | ||
| 446 | |||
| 441 | /** | 447 | /** |
| 442 | * struct iwl_rb_status - reserve buffer status | 448 | * struct iwl_rb_status - reserve buffer status |
| 443 | * host memory mapped FH registers | 449 | * host memory mapped FH registers |
diff --git a/drivers/net/wireless/iwlwifi/iwl-nvm-parse.c b/drivers/net/wireless/iwlwifi/iwl-nvm-parse.c index 80fefe7d7b8c..3b8e85e51002 100644 --- a/drivers/net/wireless/iwlwifi/iwl-nvm-parse.c +++ b/drivers/net/wireless/iwlwifi/iwl-nvm-parse.c | |||
| @@ -540,13 +540,11 @@ static void iwl_set_hw_address_family_8000(struct device *dev, | |||
| 540 | hw_addr = (const u8 *)(mac_override + | 540 | hw_addr = (const u8 *)(mac_override + |
| 541 | MAC_ADDRESS_OVERRIDE_FAMILY_8000); | 541 | MAC_ADDRESS_OVERRIDE_FAMILY_8000); |
| 542 | 542 | ||
| 543 | /* The byte order is little endian 16 bit, meaning 214365 */ | 543 | /* |
| 544 | data->hw_addr[0] = hw_addr[1]; | 544 | * Store the MAC address from MAO section. |
| 545 | data->hw_addr[1] = hw_addr[0]; | 545 | * No byte swapping is required in MAO section |
| 546 | data->hw_addr[2] = hw_addr[3]; | 546 | */ |
| 547 | data->hw_addr[3] = hw_addr[2]; | 547 | memcpy(data->hw_addr, hw_addr, ETH_ALEN); |
| 548 | data->hw_addr[4] = hw_addr[5]; | ||
| 549 | data->hw_addr[5] = hw_addr[4]; | ||
| 550 | 548 | ||
| 551 | /* | 549 | /* |
| 552 | * Force the use of the OTP MAC address in case of reserved MAC | 550 | * Force the use of the OTP MAC address in case of reserved MAC |
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api-scan.h b/drivers/net/wireless/iwlwifi/mvm/fw-api-scan.h index 5e4cbdb44c60..737774a01c74 100644 --- a/drivers/net/wireless/iwlwifi/mvm/fw-api-scan.h +++ b/drivers/net/wireless/iwlwifi/mvm/fw-api-scan.h | |||
| @@ -660,7 +660,8 @@ struct iwl_scan_config { | |||
| 660 | * iwl_umac_scan_flags | 660 | * iwl_umac_scan_flags |
| 661 | *@IWL_UMAC_SCAN_FLAG_PREEMPTIVE: scan process triggered by this scan request | 661 | *@IWL_UMAC_SCAN_FLAG_PREEMPTIVE: scan process triggered by this scan request |
| 662 | * can be preempted by other scan requests with higher priority. | 662 | * can be preempted by other scan requests with higher priority. |
| 663 | * The low priority scan is aborted. | 663 | * The low priority scan will be resumed when the higher proirity scan is |
| 664 | * completed. | ||
| 664 | *@IWL_UMAC_SCAN_FLAG_START_NOTIF: notification will be sent to the driver | 665 | *@IWL_UMAC_SCAN_FLAG_START_NOTIF: notification will be sent to the driver |
| 665 | * when scan starts. | 666 | * when scan starts. |
| 666 | */ | 667 | */ |
diff --git a/drivers/net/wireless/iwlwifi/mvm/scan.c b/drivers/net/wireless/iwlwifi/mvm/scan.c index 5de144968723..5000bfcded61 100644 --- a/drivers/net/wireless/iwlwifi/mvm/scan.c +++ b/drivers/net/wireless/iwlwifi/mvm/scan.c | |||
| @@ -1109,6 +1109,9 @@ static int iwl_mvm_scan_umac(struct iwl_mvm *mvm, struct ieee80211_vif *vif, | |||
| 1109 | cmd->uid = cpu_to_le32(uid); | 1109 | cmd->uid = cpu_to_le32(uid); |
| 1110 | cmd->general_flags = cpu_to_le32(iwl_mvm_scan_umac_flags(mvm, params)); | 1110 | cmd->general_flags = cpu_to_le32(iwl_mvm_scan_umac_flags(mvm, params)); |
| 1111 | 1111 | ||
| 1112 | if (type == IWL_MVM_SCAN_SCHED) | ||
| 1113 | cmd->flags = cpu_to_le32(IWL_UMAC_SCAN_FLAG_PREEMPTIVE); | ||
| 1114 | |||
| 1112 | if (iwl_mvm_scan_use_ebs(mvm, vif, n_iterations)) | 1115 | if (iwl_mvm_scan_use_ebs(mvm, vif, n_iterations)) |
| 1113 | cmd->channel_flags = IWL_SCAN_CHANNEL_FLAG_EBS | | 1116 | cmd->channel_flags = IWL_SCAN_CHANNEL_FLAG_EBS | |
| 1114 | IWL_SCAN_CHANNEL_FLAG_EBS_ACCURATE | | 1117 | IWL_SCAN_CHANNEL_FLAG_EBS_ACCURATE | |
diff --git a/drivers/net/wireless/iwlwifi/mvm/sta.c b/drivers/net/wireless/iwlwifi/mvm/sta.c index d68dc697a4a0..26f076e82149 100644 --- a/drivers/net/wireless/iwlwifi/mvm/sta.c +++ b/drivers/net/wireless/iwlwifi/mvm/sta.c | |||
| @@ -1401,6 +1401,7 @@ int iwl_mvm_set_sta_key(struct iwl_mvm *mvm, | |||
| 1401 | bool mcast = !(keyconf->flags & IEEE80211_KEY_FLAG_PAIRWISE); | 1401 | bool mcast = !(keyconf->flags & IEEE80211_KEY_FLAG_PAIRWISE); |
| 1402 | u8 sta_id; | 1402 | u8 sta_id; |
| 1403 | int ret; | 1403 | int ret; |
| 1404 | static const u8 __maybe_unused zero_addr[ETH_ALEN] = {0}; | ||
| 1404 | 1405 | ||
| 1405 | lockdep_assert_held(&mvm->mutex); | 1406 | lockdep_assert_held(&mvm->mutex); |
| 1406 | 1407 | ||
| @@ -1467,7 +1468,7 @@ int iwl_mvm_set_sta_key(struct iwl_mvm *mvm, | |||
| 1467 | end: | 1468 | end: |
| 1468 | IWL_DEBUG_WEP(mvm, "key: cipher=%x len=%d idx=%d sta=%pM ret=%d\n", | 1469 | IWL_DEBUG_WEP(mvm, "key: cipher=%x len=%d idx=%d sta=%pM ret=%d\n", |
| 1469 | keyconf->cipher, keyconf->keylen, keyconf->keyidx, | 1470 | keyconf->cipher, keyconf->keylen, keyconf->keyidx, |
| 1470 | sta->addr, ret); | 1471 | sta ? sta->addr : zero_addr, ret); |
| 1471 | return ret; | 1472 | return ret; |
| 1472 | } | 1473 | } |
| 1473 | 1474 | ||
diff --git a/drivers/net/wireless/iwlwifi/mvm/time-event.c b/drivers/net/wireless/iwlwifi/mvm/time-event.c index d24b6a83e68c..e472729e5f14 100644 --- a/drivers/net/wireless/iwlwifi/mvm/time-event.c +++ b/drivers/net/wireless/iwlwifi/mvm/time-event.c | |||
| @@ -86,7 +86,7 @@ void iwl_mvm_te_clear_data(struct iwl_mvm *mvm, | |||
| 86 | { | 86 | { |
| 87 | lockdep_assert_held(&mvm->time_event_lock); | 87 | lockdep_assert_held(&mvm->time_event_lock); |
| 88 | 88 | ||
| 89 | if (te_data->id == TE_MAX) | 89 | if (!te_data->vif) |
| 90 | return; | 90 | return; |
| 91 | 91 | ||
| 92 | list_del(&te_data->list); | 92 | list_del(&te_data->list); |
diff --git a/drivers/net/wireless/iwlwifi/mvm/tx.c b/drivers/net/wireless/iwlwifi/mvm/tx.c index 7ba7a118ff5c..89116864d2a0 100644 --- a/drivers/net/wireless/iwlwifi/mvm/tx.c +++ b/drivers/net/wireless/iwlwifi/mvm/tx.c | |||
| @@ -252,7 +252,7 @@ void iwl_mvm_set_tx_cmd_rate(struct iwl_mvm *mvm, struct iwl_tx_cmd *tx_cmd, | |||
| 252 | 252 | ||
| 253 | if (info->band == IEEE80211_BAND_2GHZ && | 253 | if (info->band == IEEE80211_BAND_2GHZ && |
| 254 | !iwl_mvm_bt_coex_is_shared_ant_avail(mvm)) | 254 | !iwl_mvm_bt_coex_is_shared_ant_avail(mvm)) |
| 255 | rate_flags = BIT(mvm->cfg->non_shared_ant) << RATE_MCS_ANT_POS; | 255 | rate_flags = mvm->cfg->non_shared_ant << RATE_MCS_ANT_POS; |
| 256 | else | 256 | else |
| 257 | rate_flags = | 257 | rate_flags = |
| 258 | BIT(mvm->mgmt_last_antenna_idx) << RATE_MCS_ANT_POS; | 258 | BIT(mvm->mgmt_last_antenna_idx) << RATE_MCS_ANT_POS; |
diff --git a/drivers/net/wireless/iwlwifi/pcie/drv.c b/drivers/net/wireless/iwlwifi/pcie/drv.c index 2ed1e4d2774d..9f65c1cff1b1 100644 --- a/drivers/net/wireless/iwlwifi/pcie/drv.c +++ b/drivers/net/wireless/iwlwifi/pcie/drv.c | |||
| @@ -368,12 +368,14 @@ static const struct pci_device_id iwl_hw_card_ids[] = { | |||
| 368 | /* 3165 Series */ | 368 | /* 3165 Series */ |
| 369 | {IWL_PCI_DEVICE(0x3165, 0x4010, iwl3165_2ac_cfg)}, | 369 | {IWL_PCI_DEVICE(0x3165, 0x4010, iwl3165_2ac_cfg)}, |
| 370 | {IWL_PCI_DEVICE(0x3165, 0x4012, iwl3165_2ac_cfg)}, | 370 | {IWL_PCI_DEVICE(0x3165, 0x4012, iwl3165_2ac_cfg)}, |
| 371 | {IWL_PCI_DEVICE(0x3166, 0x4212, iwl3165_2ac_cfg)}, | ||
| 371 | {IWL_PCI_DEVICE(0x3165, 0x4410, iwl3165_2ac_cfg)}, | 372 | {IWL_PCI_DEVICE(0x3165, 0x4410, iwl3165_2ac_cfg)}, |
| 372 | {IWL_PCI_DEVICE(0x3165, 0x4510, iwl3165_2ac_cfg)}, | 373 | {IWL_PCI_DEVICE(0x3165, 0x4510, iwl3165_2ac_cfg)}, |
| 373 | {IWL_PCI_DEVICE(0x3165, 0x4110, iwl3165_2ac_cfg)}, | 374 | {IWL_PCI_DEVICE(0x3165, 0x4110, iwl3165_2ac_cfg)}, |
| 374 | {IWL_PCI_DEVICE(0x3166, 0x4310, iwl3165_2ac_cfg)}, | 375 | {IWL_PCI_DEVICE(0x3166, 0x4310, iwl3165_2ac_cfg)}, |
| 375 | {IWL_PCI_DEVICE(0x3166, 0x4210, iwl3165_2ac_cfg)}, | 376 | {IWL_PCI_DEVICE(0x3166, 0x4210, iwl3165_2ac_cfg)}, |
| 376 | {IWL_PCI_DEVICE(0x3165, 0x8010, iwl3165_2ac_cfg)}, | 377 | {IWL_PCI_DEVICE(0x3165, 0x8010, iwl3165_2ac_cfg)}, |
| 378 | {IWL_PCI_DEVICE(0x3165, 0x8110, iwl3165_2ac_cfg)}, | ||
| 377 | 379 | ||
| 378 | /* 7265 Series */ | 380 | /* 7265 Series */ |
| 379 | {IWL_PCI_DEVICE(0x095A, 0x5010, iwl7265_2ac_cfg)}, | 381 | {IWL_PCI_DEVICE(0x095A, 0x5010, iwl7265_2ac_cfg)}, |
| @@ -426,9 +428,8 @@ static const struct pci_device_id iwl_hw_card_ids[] = { | |||
| 426 | {IWL_PCI_DEVICE(0x24F4, 0x1130, iwl8260_2ac_cfg)}, | 428 | {IWL_PCI_DEVICE(0x24F4, 0x1130, iwl8260_2ac_cfg)}, |
| 427 | {IWL_PCI_DEVICE(0x24F4, 0x1030, iwl8260_2ac_cfg)}, | 429 | {IWL_PCI_DEVICE(0x24F4, 0x1030, iwl8260_2ac_cfg)}, |
| 428 | {IWL_PCI_DEVICE(0x24F3, 0xC010, iwl8260_2ac_cfg)}, | 430 | {IWL_PCI_DEVICE(0x24F3, 0xC010, iwl8260_2ac_cfg)}, |
| 431 | {IWL_PCI_DEVICE(0x24F3, 0xC110, iwl8260_2ac_cfg)}, | ||
| 429 | {IWL_PCI_DEVICE(0x24F3, 0xD010, iwl8260_2ac_cfg)}, | 432 | {IWL_PCI_DEVICE(0x24F3, 0xD010, iwl8260_2ac_cfg)}, |
| 430 | {IWL_PCI_DEVICE(0x24F4, 0xC030, iwl8260_2ac_cfg)}, | ||
| 431 | {IWL_PCI_DEVICE(0x24F4, 0xD030, iwl8260_2ac_cfg)}, | ||
| 432 | {IWL_PCI_DEVICE(0x24F3, 0xC050, iwl8260_2ac_cfg)}, | 433 | {IWL_PCI_DEVICE(0x24F3, 0xC050, iwl8260_2ac_cfg)}, |
| 433 | {IWL_PCI_DEVICE(0x24F3, 0xD050, iwl8260_2ac_cfg)}, | 434 | {IWL_PCI_DEVICE(0x24F3, 0xD050, iwl8260_2ac_cfg)}, |
| 434 | {IWL_PCI_DEVICE(0x24F3, 0x8010, iwl8260_2ac_cfg)}, | 435 | {IWL_PCI_DEVICE(0x24F3, 0x8010, iwl8260_2ac_cfg)}, |
diff --git a/drivers/net/wireless/iwlwifi/pcie/internal.h b/drivers/net/wireless/iwlwifi/pcie/internal.h index 31f72a61cc3f..376b84e54ad7 100644 --- a/drivers/net/wireless/iwlwifi/pcie/internal.h +++ b/drivers/net/wireless/iwlwifi/pcie/internal.h | |||
| @@ -44,15 +44,6 @@ | |||
| 44 | #include "iwl-io.h" | 44 | #include "iwl-io.h" |
| 45 | #include "iwl-op-mode.h" | 45 | #include "iwl-op-mode.h" |
| 46 | 46 | ||
| 47 | /* | ||
| 48 | * RX related structures and functions | ||
| 49 | */ | ||
| 50 | #define RX_NUM_QUEUES 1 | ||
| 51 | #define RX_POST_REQ_ALLOC 2 | ||
| 52 | #define RX_CLAIM_REQ_ALLOC 8 | ||
| 53 | #define RX_POOL_SIZE ((RX_CLAIM_REQ_ALLOC - RX_POST_REQ_ALLOC) * RX_NUM_QUEUES) | ||
| 54 | #define RX_LOW_WATERMARK 8 | ||
| 55 | |||
| 56 | struct iwl_host_cmd; | 47 | struct iwl_host_cmd; |
| 57 | 48 | ||
| 58 | /*This file includes the declaration that are internal to the | 49 | /*This file includes the declaration that are internal to the |
| @@ -86,29 +77,29 @@ struct isr_statistics { | |||
| 86 | * struct iwl_rxq - Rx queue | 77 | * struct iwl_rxq - Rx queue |
| 87 | * @bd: driver's pointer to buffer of receive buffer descriptors (rbd) | 78 | * @bd: driver's pointer to buffer of receive buffer descriptors (rbd) |
| 88 | * @bd_dma: bus address of buffer of receive buffer descriptors (rbd) | 79 | * @bd_dma: bus address of buffer of receive buffer descriptors (rbd) |
| 80 | * @pool: | ||
| 81 | * @queue: | ||
| 89 | * @read: Shared index to newest available Rx buffer | 82 | * @read: Shared index to newest available Rx buffer |
| 90 | * @write: Shared index to oldest written Rx packet | 83 | * @write: Shared index to oldest written Rx packet |
| 91 | * @free_count: Number of pre-allocated buffers in rx_free | 84 | * @free_count: Number of pre-allocated buffers in rx_free |
| 92 | * @used_count: Number of RBDs handled to allocator to use for allocation | ||
| 93 | * @write_actual: | 85 | * @write_actual: |
| 94 | * @rx_free: list of RBDs with allocated RB ready for use | 86 | * @rx_free: list of free SKBs for use |
| 95 | * @rx_used: list of RBDs with no RB attached | 87 | * @rx_used: List of Rx buffers with no SKB |
| 96 | * @need_update: flag to indicate we need to update read/write index | 88 | * @need_update: flag to indicate we need to update read/write index |
| 97 | * @rb_stts: driver's pointer to receive buffer status | 89 | * @rb_stts: driver's pointer to receive buffer status |
| 98 | * @rb_stts_dma: bus address of receive buffer status | 90 | * @rb_stts_dma: bus address of receive buffer status |
| 99 | * @lock: | 91 | * @lock: |
| 100 | * @pool: initial pool of iwl_rx_mem_buffer for the queue | ||
| 101 | * @queue: actual rx queue | ||
| 102 | * | 92 | * |
| 103 | * NOTE: rx_free and rx_used are used as a FIFO for iwl_rx_mem_buffers | 93 | * NOTE: rx_free and rx_used are used as a FIFO for iwl_rx_mem_buffers |
| 104 | */ | 94 | */ |
| 105 | struct iwl_rxq { | 95 | struct iwl_rxq { |
| 106 | __le32 *bd; | 96 | __le32 *bd; |
| 107 | dma_addr_t bd_dma; | 97 | dma_addr_t bd_dma; |
| 98 | struct iwl_rx_mem_buffer pool[RX_QUEUE_SIZE + RX_FREE_BUFFERS]; | ||
| 99 | struct iwl_rx_mem_buffer *queue[RX_QUEUE_SIZE]; | ||
| 108 | u32 read; | 100 | u32 read; |
| 109 | u32 write; | 101 | u32 write; |
| 110 | u32 free_count; | 102 | u32 free_count; |
| 111 | u32 used_count; | ||
| 112 | u32 write_actual; | 103 | u32 write_actual; |
| 113 | struct list_head rx_free; | 104 | struct list_head rx_free; |
| 114 | struct list_head rx_used; | 105 | struct list_head rx_used; |
| @@ -116,32 +107,6 @@ struct iwl_rxq { | |||
| 116 | struct iwl_rb_status *rb_stts; | 107 | struct iwl_rb_status *rb_stts; |
| 117 | dma_addr_t rb_stts_dma; | 108 | dma_addr_t rb_stts_dma; |
| 118 | spinlock_t lock; | 109 | spinlock_t lock; |
| 119 | struct iwl_rx_mem_buffer pool[RX_QUEUE_SIZE]; | ||
| 120 | struct iwl_rx_mem_buffer *queue[RX_QUEUE_SIZE]; | ||
| 121 | }; | ||
| 122 | |||
| 123 | /** | ||
| 124 | * struct iwl_rb_allocator - Rx allocator | ||
| 125 | * @pool: initial pool of allocator | ||
| 126 | * @req_pending: number of requests the allcator had not processed yet | ||
| 127 | * @req_ready: number of requests honored and ready for claiming | ||
| 128 | * @rbd_allocated: RBDs with pages allocated and ready to be handled to | ||
| 129 | * the queue. This is a list of &struct iwl_rx_mem_buffer | ||
| 130 | * @rbd_empty: RBDs with no page attached for allocator use. This is a list | ||
| 131 | * of &struct iwl_rx_mem_buffer | ||
| 132 | * @lock: protects the rbd_allocated and rbd_empty lists | ||
| 133 | * @alloc_wq: work queue for background calls | ||
| 134 | * @rx_alloc: work struct for background calls | ||
| 135 | */ | ||
| 136 | struct iwl_rb_allocator { | ||
| 137 | struct iwl_rx_mem_buffer pool[RX_POOL_SIZE]; | ||
| 138 | atomic_t req_pending; | ||
| 139 | atomic_t req_ready; | ||
| 140 | struct list_head rbd_allocated; | ||
| 141 | struct list_head rbd_empty; | ||
| 142 | spinlock_t lock; | ||
| 143 | struct workqueue_struct *alloc_wq; | ||
| 144 | struct work_struct rx_alloc; | ||
| 145 | }; | 110 | }; |
| 146 | 111 | ||
| 147 | struct iwl_dma_ptr { | 112 | struct iwl_dma_ptr { |
| @@ -285,7 +250,7 @@ iwl_pcie_get_scratchbuf_dma(struct iwl_txq *txq, int idx) | |||
| 285 | /** | 250 | /** |
| 286 | * struct iwl_trans_pcie - PCIe transport specific data | 251 | * struct iwl_trans_pcie - PCIe transport specific data |
| 287 | * @rxq: all the RX queue data | 252 | * @rxq: all the RX queue data |
| 288 | * @rba: allocator for RX replenishing | 253 | * @rx_replenish: work that will be called when buffers need to be allocated |
| 289 | * @drv - pointer to iwl_drv | 254 | * @drv - pointer to iwl_drv |
| 290 | * @trans: pointer to the generic transport area | 255 | * @trans: pointer to the generic transport area |
| 291 | * @scd_base_addr: scheduler sram base address in SRAM | 256 | * @scd_base_addr: scheduler sram base address in SRAM |
| @@ -308,7 +273,7 @@ iwl_pcie_get_scratchbuf_dma(struct iwl_txq *txq, int idx) | |||
| 308 | */ | 273 | */ |
| 309 | struct iwl_trans_pcie { | 274 | struct iwl_trans_pcie { |
| 310 | struct iwl_rxq rxq; | 275 | struct iwl_rxq rxq; |
| 311 | struct iwl_rb_allocator rba; | 276 | struct work_struct rx_replenish; |
| 312 | struct iwl_trans *trans; | 277 | struct iwl_trans *trans; |
| 313 | struct iwl_drv *drv; | 278 | struct iwl_drv *drv; |
| 314 | 279 | ||
diff --git a/drivers/net/wireless/iwlwifi/pcie/rx.c b/drivers/net/wireless/iwlwifi/pcie/rx.c index a3fbaa0ef5e0..adad8d0fae7f 100644 --- a/drivers/net/wireless/iwlwifi/pcie/rx.c +++ b/drivers/net/wireless/iwlwifi/pcie/rx.c | |||
| @@ -1,7 +1,7 @@ | |||
| 1 | /****************************************************************************** | 1 | /****************************************************************************** |
| 2 | * | 2 | * |
| 3 | * Copyright(c) 2003 - 2014 Intel Corporation. All rights reserved. | 3 | * Copyright(c) 2003 - 2014 Intel Corporation. All rights reserved. |
| 4 | * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH | 4 | * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH |
| 5 | * | 5 | * |
| 6 | * Portions of this file are derived from the ipw3945 project, as well | 6 | * Portions of this file are derived from the ipw3945 project, as well |
| 7 | * as portions of the ieee80211 subsystem header files. | 7 | * as portions of the ieee80211 subsystem header files. |
| @@ -74,29 +74,16 @@ | |||
| 74 | * resets the Rx queue buffers with new memory. | 74 | * resets the Rx queue buffers with new memory. |
| 75 | * | 75 | * |
| 76 | * The management in the driver is as follows: | 76 | * The management in the driver is as follows: |
| 77 | * + A list of pre-allocated RBDs is stored in iwl->rxq->rx_free. | 77 | * + A list of pre-allocated SKBs is stored in iwl->rxq->rx_free. When |
| 78 | * When the interrupt handler is called, the request is processed. | 78 | * iwl->rxq->free_count drops to or below RX_LOW_WATERMARK, work is scheduled |
| 79 | * The page is either stolen - transferred to the upper layer | 79 | * to replenish the iwl->rxq->rx_free. |
| 80 | * or reused - added immediately to the iwl->rxq->rx_free list. | 80 | * + In iwl_pcie_rx_replenish (scheduled) if 'processed' != 'read' then the |
| 81 | * + When the page is stolen - the driver updates the matching queue's used | 81 | * iwl->rxq is replenished and the READ INDEX is updated (updating the |
| 82 | * count, detaches the RBD and transfers it to the queue used list. | 82 | * 'processed' and 'read' driver indexes as well) |
| 83 | * When there are two used RBDs - they are transferred to the allocator empty | ||
| 84 | * list. Work is then scheduled for the allocator to start allocating | ||
| 85 | * eight buffers. | ||
| 86 | * When there are another 6 used RBDs - they are transferred to the allocator | ||
| 87 | * empty list and the driver tries to claim the pre-allocated buffers and | ||
| 88 | * add them to iwl->rxq->rx_free. If it fails - it continues to claim them | ||
| 89 | * until ready. | ||
| 90 | * When there are 8+ buffers in the free list - either from allocation or from | ||
| 91 | * 8 reused unstolen pages - restock is called to update the FW and indexes. | ||
| 92 | * + In order to make sure the allocator always has RBDs to use for allocation | ||
| 93 | * the allocator has initial pool in the size of num_queues*(8-2) - the | ||
| 94 | * maximum missing RBDs per allocation request (request posted with 2 | ||
| 95 | * empty RBDs, there is no guarantee when the other 6 RBDs are supplied). | ||
| 96 | * The queues supplies the recycle of the rest of the RBDs. | ||
| 97 | * + A received packet is processed and handed to the kernel network stack, | 83 | * + A received packet is processed and handed to the kernel network stack, |
| 98 | * detached from the iwl->rxq. The driver 'processed' index is updated. | 84 | * detached from the iwl->rxq. The driver 'processed' index is updated. |
| 99 | * + If there are no allocated buffers in iwl->rxq->rx_free, | 85 | * + The Host/Firmware iwl->rxq is replenished at irq thread time from the |
| 86 | * rx_free list. If there are no allocated buffers in iwl->rxq->rx_free, | ||
| 100 | * the READ INDEX is not incremented and iwl->status(RX_STALLED) is set. | 87 | * the READ INDEX is not incremented and iwl->status(RX_STALLED) is set. |
| 101 | * If there were enough free buffers and RX_STALLED is set it is cleared. | 88 | * If there were enough free buffers and RX_STALLED is set it is cleared. |
| 102 | * | 89 | * |
| @@ -105,32 +92,18 @@ | |||
| 105 | * | 92 | * |
| 106 | * iwl_rxq_alloc() Allocates rx_free | 93 | * iwl_rxq_alloc() Allocates rx_free |
| 107 | * iwl_pcie_rx_replenish() Replenishes rx_free list from rx_used, and calls | 94 | * iwl_pcie_rx_replenish() Replenishes rx_free list from rx_used, and calls |
| 108 | * iwl_pcie_rxq_restock. | 95 | * iwl_pcie_rxq_restock |
| 109 | * Used only during initialization. | ||
| 110 | * iwl_pcie_rxq_restock() Moves available buffers from rx_free into Rx | 96 | * iwl_pcie_rxq_restock() Moves available buffers from rx_free into Rx |
| 111 | * queue, updates firmware pointers, and updates | 97 | * queue, updates firmware pointers, and updates |
| 112 | * the WRITE index. | 98 | * the WRITE index. If insufficient rx_free buffers |
| 113 | * iwl_pcie_rx_allocator() Background work for allocating pages. | 99 | * are available, schedules iwl_pcie_rx_replenish |
| 114 | * | 100 | * |
| 115 | * -- enable interrupts -- | 101 | * -- enable interrupts -- |
| 116 | * ISR - iwl_rx() Detach iwl_rx_mem_buffers from pool up to the | 102 | * ISR - iwl_rx() Detach iwl_rx_mem_buffers from pool up to the |
| 117 | * READ INDEX, detaching the SKB from the pool. | 103 | * READ INDEX, detaching the SKB from the pool. |
| 118 | * Moves the packet buffer from queue to rx_used. | 104 | * Moves the packet buffer from queue to rx_used. |
| 119 | * Posts and claims requests to the allocator. | ||
| 120 | * Calls iwl_pcie_rxq_restock to refill any empty | 105 | * Calls iwl_pcie_rxq_restock to refill any empty |
| 121 | * slots. | 106 | * slots. |
| 122 | * | ||
| 123 | * RBD life-cycle: | ||
| 124 | * | ||
| 125 | * Init: | ||
| 126 | * rxq.pool -> rxq.rx_used -> rxq.rx_free -> rxq.queue | ||
| 127 | * | ||
| 128 | * Regular Receive interrupt: | ||
| 129 | * Page Stolen: | ||
| 130 | * rxq.queue -> rxq.rx_used -> allocator.rbd_empty -> | ||
| 131 | * allocator.rbd_allocated -> rxq.rx_free -> rxq.queue | ||
| 132 | * Page not Stolen: | ||
| 133 | * rxq.queue -> rxq.rx_free -> rxq.queue | ||
| 134 | * ... | 107 | * ... |
| 135 | * | 108 | * |
| 136 | */ | 109 | */ |
| @@ -267,6 +240,10 @@ static void iwl_pcie_rxq_restock(struct iwl_trans *trans) | |||
| 267 | rxq->free_count--; | 240 | rxq->free_count--; |
| 268 | } | 241 | } |
| 269 | spin_unlock(&rxq->lock); | 242 | spin_unlock(&rxq->lock); |
| 243 | /* If the pre-allocated buffer pool is dropping low, schedule to | ||
| 244 | * refill it */ | ||
| 245 | if (rxq->free_count <= RX_LOW_WATERMARK) | ||
| 246 | schedule_work(&trans_pcie->rx_replenish); | ||
| 270 | 247 | ||
| 271 | /* If we've added more space for the firmware to place data, tell it. | 248 | /* If we've added more space for the firmware to place data, tell it. |
| 272 | * Increment device's write pointer in multiples of 8. */ | 249 | * Increment device's write pointer in multiples of 8. */ |
| @@ -278,44 +255,6 @@ static void iwl_pcie_rxq_restock(struct iwl_trans *trans) | |||
| 278 | } | 255 | } |
| 279 | 256 | ||
| 280 | /* | 257 | /* |
| 281 | * iwl_pcie_rx_alloc_page - allocates and returns a page. | ||
| 282 | * | ||
| 283 | */ | ||
| 284 | static struct page *iwl_pcie_rx_alloc_page(struct iwl_trans *trans) | ||
| 285 | { | ||
| 286 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); | ||
| 287 | struct iwl_rxq *rxq = &trans_pcie->rxq; | ||
| 288 | struct page *page; | ||
| 289 | gfp_t gfp_mask = GFP_KERNEL; | ||
| 290 | |||
| 291 | if (rxq->free_count > RX_LOW_WATERMARK) | ||
| 292 | gfp_mask |= __GFP_NOWARN; | ||
| 293 | |||
| 294 | if (trans_pcie->rx_page_order > 0) | ||
| 295 | gfp_mask |= __GFP_COMP; | ||
| 296 | |||
| 297 | /* Alloc a new receive buffer */ | ||
| 298 | page = alloc_pages(gfp_mask, trans_pcie->rx_page_order); | ||
| 299 | if (!page) { | ||
| 300 | if (net_ratelimit()) | ||
| 301 | IWL_DEBUG_INFO(trans, "alloc_pages failed, order: %d\n", | ||
| 302 | trans_pcie->rx_page_order); | ||
| 303 | /* Issue an error if the hardware has consumed more than half | ||
| 304 | * of its free buffer list and we don't have enough | ||
| 305 | * pre-allocated buffers. | ||
| 306 | ` */ | ||
| 307 | if (rxq->free_count <= RX_LOW_WATERMARK && | ||
| 308 | iwl_rxq_space(rxq) > (RX_QUEUE_SIZE / 2) && | ||
| 309 | net_ratelimit()) | ||
| 310 | IWL_CRIT(trans, | ||
| 311 | "Failed to alloc_pages with GFP_KERNEL. Only %u free buffers remaining.\n", | ||
| 312 | rxq->free_count); | ||
| 313 | return NULL; | ||
| 314 | } | ||
| 315 | return page; | ||
| 316 | } | ||
| 317 | |||
| 318 | /* | ||
| 319 | * iwl_pcie_rxq_alloc_rbs - allocate a page for each used RBD | 258 | * iwl_pcie_rxq_alloc_rbs - allocate a page for each used RBD |
| 320 | * | 259 | * |
| 321 | * A used RBD is an Rx buffer that has been given to the stack. To use it again | 260 | * A used RBD is an Rx buffer that has been given to the stack. To use it again |
| @@ -324,12 +263,13 @@ static struct page *iwl_pcie_rx_alloc_page(struct iwl_trans *trans) | |||
| 324 | * iwl_pcie_rxq_restock. The latter function will update the HW to use the newly | 263 | * iwl_pcie_rxq_restock. The latter function will update the HW to use the newly |
| 325 | * allocated buffers. | 264 | * allocated buffers. |
| 326 | */ | 265 | */ |
| 327 | static void iwl_pcie_rxq_alloc_rbs(struct iwl_trans *trans) | 266 | static void iwl_pcie_rxq_alloc_rbs(struct iwl_trans *trans, gfp_t priority) |
| 328 | { | 267 | { |
| 329 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); | 268 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); |
| 330 | struct iwl_rxq *rxq = &trans_pcie->rxq; | 269 | struct iwl_rxq *rxq = &trans_pcie->rxq; |
| 331 | struct iwl_rx_mem_buffer *rxb; | 270 | struct iwl_rx_mem_buffer *rxb; |
| 332 | struct page *page; | 271 | struct page *page; |
| 272 | gfp_t gfp_mask = priority; | ||
| 333 | 273 | ||
| 334 | while (1) { | 274 | while (1) { |
| 335 | spin_lock(&rxq->lock); | 275 | spin_lock(&rxq->lock); |
| @@ -339,10 +279,32 @@ static void iwl_pcie_rxq_alloc_rbs(struct iwl_trans *trans) | |||
| 339 | } | 279 | } |
| 340 | spin_unlock(&rxq->lock); | 280 | spin_unlock(&rxq->lock); |
| 341 | 281 | ||
| 282 | if (rxq->free_count > RX_LOW_WATERMARK) | ||
| 283 | gfp_mask |= __GFP_NOWARN; | ||
| 284 | |||
| 285 | if (trans_pcie->rx_page_order > 0) | ||
| 286 | gfp_mask |= __GFP_COMP; | ||
| 287 | |||
| 342 | /* Alloc a new receive buffer */ | 288 | /* Alloc a new receive buffer */ |
| 343 | page = iwl_pcie_rx_alloc_page(trans); | 289 | page = alloc_pages(gfp_mask, trans_pcie->rx_page_order); |
| 344 | if (!page) | 290 | if (!page) { |
| 291 | if (net_ratelimit()) | ||
| 292 | IWL_DEBUG_INFO(trans, "alloc_pages failed, " | ||
| 293 | "order: %d\n", | ||
| 294 | trans_pcie->rx_page_order); | ||
| 295 | |||
| 296 | if ((rxq->free_count <= RX_LOW_WATERMARK) && | ||
| 297 | net_ratelimit()) | ||
| 298 | IWL_CRIT(trans, "Failed to alloc_pages with %s." | ||
| 299 | "Only %u free buffers remaining.\n", | ||
| 300 | priority == GFP_ATOMIC ? | ||
| 301 | "GFP_ATOMIC" : "GFP_KERNEL", | ||
| 302 | rxq->free_count); | ||
| 303 | /* We don't reschedule replenish work here -- we will | ||
| 304 | * call the restock method and if it still needs | ||
| 305 | * more buffers it will schedule replenish */ | ||
| 345 | return; | 306 | return; |
| 307 | } | ||
| 346 | 308 | ||
| 347 | spin_lock(&rxq->lock); | 309 | spin_lock(&rxq->lock); |
| 348 | 310 | ||
| @@ -393,7 +355,7 @@ static void iwl_pcie_rxq_free_rbs(struct iwl_trans *trans) | |||
| 393 | 355 | ||
| 394 | lockdep_assert_held(&rxq->lock); | 356 | lockdep_assert_held(&rxq->lock); |
| 395 | 357 | ||
| 396 | for (i = 0; i < RX_QUEUE_SIZE; i++) { | 358 | for (i = 0; i < RX_FREE_BUFFERS + RX_QUEUE_SIZE; i++) { |
| 397 | if (!rxq->pool[i].page) | 359 | if (!rxq->pool[i].page) |
| 398 | continue; | 360 | continue; |
| 399 | dma_unmap_page(trans->dev, rxq->pool[i].page_dma, | 361 | dma_unmap_page(trans->dev, rxq->pool[i].page_dma, |
| @@ -410,144 +372,32 @@ static void iwl_pcie_rxq_free_rbs(struct iwl_trans *trans) | |||
| 410 | * When moving to rx_free an page is allocated for the slot. | 372 | * When moving to rx_free an page is allocated for the slot. |
| 411 | * | 373 | * |
| 412 | * Also restock the Rx queue via iwl_pcie_rxq_restock. | 374 | * Also restock the Rx queue via iwl_pcie_rxq_restock. |
| 413 | * This is called only during initialization | 375 | * This is called as a scheduled work item (except for during initialization) |
| 414 | */ | 376 | */ |
| 415 | static void iwl_pcie_rx_replenish(struct iwl_trans *trans) | 377 | static void iwl_pcie_rx_replenish(struct iwl_trans *trans, gfp_t gfp) |
| 416 | { | 378 | { |
| 417 | iwl_pcie_rxq_alloc_rbs(trans); | 379 | iwl_pcie_rxq_alloc_rbs(trans, gfp); |
| 418 | 380 | ||
| 419 | iwl_pcie_rxq_restock(trans); | 381 | iwl_pcie_rxq_restock(trans); |
| 420 | } | 382 | } |
| 421 | 383 | ||
| 422 | /* | 384 | static void iwl_pcie_rx_replenish_work(struct work_struct *data) |
| 423 | * iwl_pcie_rx_allocator - Allocates pages in the background for RX queues | ||
| 424 | * | ||
| 425 | * Allocates for each received request 8 pages | ||
| 426 | * Called as a scheduled work item. | ||
| 427 | */ | ||
| 428 | static void iwl_pcie_rx_allocator(struct iwl_trans *trans) | ||
| 429 | { | ||
| 430 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); | ||
| 431 | struct iwl_rb_allocator *rba = &trans_pcie->rba; | ||
| 432 | |||
| 433 | while (atomic_read(&rba->req_pending)) { | ||
| 434 | int i; | ||
| 435 | struct list_head local_empty; | ||
| 436 | struct list_head local_allocated; | ||
| 437 | |||
| 438 | INIT_LIST_HEAD(&local_allocated); | ||
| 439 | spin_lock(&rba->lock); | ||
| 440 | /* swap out the entire rba->rbd_empty to a local list */ | ||
| 441 | list_replace_init(&rba->rbd_empty, &local_empty); | ||
| 442 | spin_unlock(&rba->lock); | ||
| 443 | |||
| 444 | for (i = 0; i < RX_CLAIM_REQ_ALLOC;) { | ||
| 445 | struct iwl_rx_mem_buffer *rxb; | ||
| 446 | struct page *page; | ||
| 447 | |||
| 448 | /* List should never be empty - each reused RBD is | ||
| 449 | * returned to the list, and initial pool covers any | ||
| 450 | * possible gap between the time the page is allocated | ||
| 451 | * to the time the RBD is added. | ||
| 452 | */ | ||
| 453 | BUG_ON(list_empty(&local_empty)); | ||
| 454 | /* Get the first rxb from the rbd list */ | ||
| 455 | rxb = list_first_entry(&local_empty, | ||
| 456 | struct iwl_rx_mem_buffer, list); | ||
| 457 | BUG_ON(rxb->page); | ||
| 458 | |||
| 459 | /* Alloc a new receive buffer */ | ||
| 460 | page = iwl_pcie_rx_alloc_page(trans); | ||
| 461 | if (!page) | ||
| 462 | continue; | ||
| 463 | rxb->page = page; | ||
| 464 | |||
| 465 | /* Get physical address of the RB */ | ||
| 466 | rxb->page_dma = dma_map_page(trans->dev, page, 0, | ||
| 467 | PAGE_SIZE << trans_pcie->rx_page_order, | ||
| 468 | DMA_FROM_DEVICE); | ||
| 469 | if (dma_mapping_error(trans->dev, rxb->page_dma)) { | ||
| 470 | rxb->page = NULL; | ||
| 471 | __free_pages(page, trans_pcie->rx_page_order); | ||
| 472 | continue; | ||
| 473 | } | ||
| 474 | /* dma address must be no more than 36 bits */ | ||
| 475 | BUG_ON(rxb->page_dma & ~DMA_BIT_MASK(36)); | ||
| 476 | /* and also 256 byte aligned! */ | ||
| 477 | BUG_ON(rxb->page_dma & DMA_BIT_MASK(8)); | ||
| 478 | |||
| 479 | /* move the allocated entry to the out list */ | ||
| 480 | list_move(&rxb->list, &local_allocated); | ||
| 481 | i++; | ||
| 482 | } | ||
| 483 | |||
| 484 | spin_lock(&rba->lock); | ||
| 485 | /* add the allocated rbds to the allocator allocated list */ | ||
| 486 | list_splice_tail(&local_allocated, &rba->rbd_allocated); | ||
| 487 | /* add the unused rbds back to the allocator empty list */ | ||
| 488 | list_splice_tail(&local_empty, &rba->rbd_empty); | ||
| 489 | spin_unlock(&rba->lock); | ||
| 490 | |||
| 491 | atomic_dec(&rba->req_pending); | ||
| 492 | atomic_inc(&rba->req_ready); | ||
| 493 | } | ||
| 494 | } | ||
| 495 | |||
| 496 | /* | ||
| 497 | * iwl_pcie_rx_allocator_get - Returns the pre-allocated pages | ||
| 498 | .* | ||
| 499 | .* Called by queue when the queue posted allocation request and | ||
| 500 | * has freed 8 RBDs in order to restock itself. | ||
| 501 | */ | ||
| 502 | static int iwl_pcie_rx_allocator_get(struct iwl_trans *trans, | ||
| 503 | struct iwl_rx_mem_buffer | ||
| 504 | *out[RX_CLAIM_REQ_ALLOC]) | ||
| 505 | { | ||
| 506 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); | ||
| 507 | struct iwl_rb_allocator *rba = &trans_pcie->rba; | ||
| 508 | int i; | ||
| 509 | |||
| 510 | if (atomic_dec_return(&rba->req_ready) < 0) { | ||
| 511 | atomic_inc(&rba->req_ready); | ||
| 512 | IWL_DEBUG_RX(trans, | ||
| 513 | "Allocation request not ready, pending requests = %d\n", | ||
| 514 | atomic_read(&rba->req_pending)); | ||
| 515 | return -ENOMEM; | ||
| 516 | } | ||
| 517 | |||
| 518 | spin_lock(&rba->lock); | ||
| 519 | for (i = 0; i < RX_CLAIM_REQ_ALLOC; i++) { | ||
| 520 | /* Get next free Rx buffer, remove it from free list */ | ||
| 521 | out[i] = list_first_entry(&rba->rbd_allocated, | ||
| 522 | struct iwl_rx_mem_buffer, list); | ||
| 523 | list_del(&out[i]->list); | ||
| 524 | } | ||
| 525 | spin_unlock(&rba->lock); | ||
| 526 | |||
| 527 | return 0; | ||
| 528 | } | ||
| 529 | |||
| 530 | static void iwl_pcie_rx_allocator_work(struct work_struct *data) | ||
| 531 | { | 385 | { |
| 532 | struct iwl_rb_allocator *rba_p = | ||
| 533 | container_of(data, struct iwl_rb_allocator, rx_alloc); | ||
| 534 | struct iwl_trans_pcie *trans_pcie = | 386 | struct iwl_trans_pcie *trans_pcie = |
| 535 | container_of(rba_p, struct iwl_trans_pcie, rba); | 387 | container_of(data, struct iwl_trans_pcie, rx_replenish); |
| 536 | 388 | ||
| 537 | iwl_pcie_rx_allocator(trans_pcie->trans); | 389 | iwl_pcie_rx_replenish(trans_pcie->trans, GFP_KERNEL); |
| 538 | } | 390 | } |
| 539 | 391 | ||
| 540 | static int iwl_pcie_rx_alloc(struct iwl_trans *trans) | 392 | static int iwl_pcie_rx_alloc(struct iwl_trans *trans) |
| 541 | { | 393 | { |
| 542 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); | 394 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); |
| 543 | struct iwl_rxq *rxq = &trans_pcie->rxq; | 395 | struct iwl_rxq *rxq = &trans_pcie->rxq; |
| 544 | struct iwl_rb_allocator *rba = &trans_pcie->rba; | ||
| 545 | struct device *dev = trans->dev; | 396 | struct device *dev = trans->dev; |
| 546 | 397 | ||
| 547 | memset(&trans_pcie->rxq, 0, sizeof(trans_pcie->rxq)); | 398 | memset(&trans_pcie->rxq, 0, sizeof(trans_pcie->rxq)); |
| 548 | 399 | ||
| 549 | spin_lock_init(&rxq->lock); | 400 | spin_lock_init(&rxq->lock); |
| 550 | spin_lock_init(&rba->lock); | ||
| 551 | 401 | ||
| 552 | if (WARN_ON(rxq->bd || rxq->rb_stts)) | 402 | if (WARN_ON(rxq->bd || rxq->rb_stts)) |
| 553 | return -EINVAL; | 403 | return -EINVAL; |
| @@ -637,49 +487,15 @@ static void iwl_pcie_rx_init_rxb_lists(struct iwl_rxq *rxq) | |||
| 637 | INIT_LIST_HEAD(&rxq->rx_free); | 487 | INIT_LIST_HEAD(&rxq->rx_free); |
| 638 | INIT_LIST_HEAD(&rxq->rx_used); | 488 | INIT_LIST_HEAD(&rxq->rx_used); |
| 639 | rxq->free_count = 0; | 489 | rxq->free_count = 0; |
| 640 | rxq->used_count = 0; | ||
| 641 | 490 | ||
| 642 | for (i = 0; i < RX_QUEUE_SIZE; i++) | 491 | for (i = 0; i < RX_FREE_BUFFERS + RX_QUEUE_SIZE; i++) |
| 643 | list_add(&rxq->pool[i].list, &rxq->rx_used); | 492 | list_add(&rxq->pool[i].list, &rxq->rx_used); |
| 644 | } | 493 | } |
| 645 | 494 | ||
| 646 | static void iwl_pcie_rx_init_rba(struct iwl_rb_allocator *rba) | ||
| 647 | { | ||
| 648 | int i; | ||
| 649 | |||
| 650 | lockdep_assert_held(&rba->lock); | ||
| 651 | |||
| 652 | INIT_LIST_HEAD(&rba->rbd_allocated); | ||
| 653 | INIT_LIST_HEAD(&rba->rbd_empty); | ||
| 654 | |||
| 655 | for (i = 0; i < RX_POOL_SIZE; i++) | ||
| 656 | list_add(&rba->pool[i].list, &rba->rbd_empty); | ||
| 657 | } | ||
| 658 | |||
| 659 | static void iwl_pcie_rx_free_rba(struct iwl_trans *trans) | ||
| 660 | { | ||
| 661 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); | ||
| 662 | struct iwl_rb_allocator *rba = &trans_pcie->rba; | ||
| 663 | int i; | ||
| 664 | |||
| 665 | lockdep_assert_held(&rba->lock); | ||
| 666 | |||
| 667 | for (i = 0; i < RX_POOL_SIZE; i++) { | ||
| 668 | if (!rba->pool[i].page) | ||
| 669 | continue; | ||
| 670 | dma_unmap_page(trans->dev, rba->pool[i].page_dma, | ||
| 671 | PAGE_SIZE << trans_pcie->rx_page_order, | ||
| 672 | DMA_FROM_DEVICE); | ||
| 673 | __free_pages(rba->pool[i].page, trans_pcie->rx_page_order); | ||
| 674 | rba->pool[i].page = NULL; | ||
| 675 | } | ||
| 676 | } | ||
| 677 | |||
| 678 | int iwl_pcie_rx_init(struct iwl_trans *trans) | 495 | int iwl_pcie_rx_init(struct iwl_trans *trans) |
| 679 | { | 496 | { |
| 680 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); | 497 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); |
| 681 | struct iwl_rxq *rxq = &trans_pcie->rxq; | 498 | struct iwl_rxq *rxq = &trans_pcie->rxq; |
| 682 | struct iwl_rb_allocator *rba = &trans_pcie->rba; | ||
| 683 | int i, err; | 499 | int i, err; |
| 684 | 500 | ||
| 685 | if (!rxq->bd) { | 501 | if (!rxq->bd) { |
| @@ -687,21 +503,11 @@ int iwl_pcie_rx_init(struct iwl_trans *trans) | |||
| 687 | if (err) | 503 | if (err) |
| 688 | return err; | 504 | return err; |
| 689 | } | 505 | } |
| 690 | if (!rba->alloc_wq) | ||
| 691 | rba->alloc_wq = alloc_workqueue("rb_allocator", | ||
| 692 | WQ_HIGHPRI | WQ_UNBOUND, 1); | ||
| 693 | INIT_WORK(&rba->rx_alloc, iwl_pcie_rx_allocator_work); | ||
| 694 | |||
| 695 | spin_lock(&rba->lock); | ||
| 696 | atomic_set(&rba->req_pending, 0); | ||
| 697 | atomic_set(&rba->req_ready, 0); | ||
| 698 | /* free all first - we might be reconfigured for a different size */ | ||
| 699 | iwl_pcie_rx_free_rba(trans); | ||
| 700 | iwl_pcie_rx_init_rba(rba); | ||
| 701 | spin_unlock(&rba->lock); | ||
| 702 | 506 | ||
| 703 | spin_lock(&rxq->lock); | 507 | spin_lock(&rxq->lock); |
| 704 | 508 | ||
| 509 | INIT_WORK(&trans_pcie->rx_replenish, iwl_pcie_rx_replenish_work); | ||
| 510 | |||
| 705 | /* free all first - we might be reconfigured for a different size */ | 511 | /* free all first - we might be reconfigured for a different size */ |
| 706 | iwl_pcie_rxq_free_rbs(trans); | 512 | iwl_pcie_rxq_free_rbs(trans); |
| 707 | iwl_pcie_rx_init_rxb_lists(rxq); | 513 | iwl_pcie_rx_init_rxb_lists(rxq); |
| @@ -716,7 +522,7 @@ int iwl_pcie_rx_init(struct iwl_trans *trans) | |||
| 716 | memset(rxq->rb_stts, 0, sizeof(*rxq->rb_stts)); | 522 | memset(rxq->rb_stts, 0, sizeof(*rxq->rb_stts)); |
| 717 | spin_unlock(&rxq->lock); | 523 | spin_unlock(&rxq->lock); |
| 718 | 524 | ||
| 719 | iwl_pcie_rx_replenish(trans); | 525 | iwl_pcie_rx_replenish(trans, GFP_KERNEL); |
| 720 | 526 | ||
| 721 | iwl_pcie_rx_hw_init(trans, rxq); | 527 | iwl_pcie_rx_hw_init(trans, rxq); |
| 722 | 528 | ||
| @@ -731,7 +537,6 @@ void iwl_pcie_rx_free(struct iwl_trans *trans) | |||
| 731 | { | 537 | { |
| 732 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); | 538 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); |
| 733 | struct iwl_rxq *rxq = &trans_pcie->rxq; | 539 | struct iwl_rxq *rxq = &trans_pcie->rxq; |
| 734 | struct iwl_rb_allocator *rba = &trans_pcie->rba; | ||
| 735 | 540 | ||
| 736 | /*if rxq->bd is NULL, it means that nothing has been allocated, | 541 | /*if rxq->bd is NULL, it means that nothing has been allocated, |
| 737 | * exit now */ | 542 | * exit now */ |
| @@ -740,15 +545,7 @@ void iwl_pcie_rx_free(struct iwl_trans *trans) | |||
| 740 | return; | 545 | return; |
| 741 | } | 546 | } |
| 742 | 547 | ||
| 743 | cancel_work_sync(&rba->rx_alloc); | 548 | cancel_work_sync(&trans_pcie->rx_replenish); |
| 744 | if (rba->alloc_wq) { | ||
| 745 | destroy_workqueue(rba->alloc_wq); | ||
| 746 | rba->alloc_wq = NULL; | ||
| 747 | } | ||
| 748 | |||
| 749 | spin_lock(&rba->lock); | ||
| 750 | iwl_pcie_rx_free_rba(trans); | ||
| 751 | spin_unlock(&rba->lock); | ||
| 752 | 549 | ||
| 753 | spin_lock(&rxq->lock); | 550 | spin_lock(&rxq->lock); |
| 754 | iwl_pcie_rxq_free_rbs(trans); | 551 | iwl_pcie_rxq_free_rbs(trans); |
| @@ -769,43 +566,6 @@ void iwl_pcie_rx_free(struct iwl_trans *trans) | |||
| 769 | rxq->rb_stts = NULL; | 566 | rxq->rb_stts = NULL; |
| 770 | } | 567 | } |
| 771 | 568 | ||
| 772 | /* | ||
| 773 | * iwl_pcie_rx_reuse_rbd - Recycle used RBDs | ||
| 774 | * | ||
| 775 | * Called when a RBD can be reused. The RBD is transferred to the allocator. | ||
| 776 | * When there are 2 empty RBDs - a request for allocation is posted | ||
| 777 | */ | ||
| 778 | static void iwl_pcie_rx_reuse_rbd(struct iwl_trans *trans, | ||
| 779 | struct iwl_rx_mem_buffer *rxb, | ||
| 780 | struct iwl_rxq *rxq) | ||
| 781 | { | ||
| 782 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); | ||
| 783 | struct iwl_rb_allocator *rba = &trans_pcie->rba; | ||
| 784 | |||
| 785 | /* Count the used RBDs */ | ||
| 786 | rxq->used_count++; | ||
| 787 | |||
| 788 | /* Move the RBD to the used list, will be moved to allocator in batches | ||
| 789 | * before claiming or posting a request*/ | ||
| 790 | list_add_tail(&rxb->list, &rxq->rx_used); | ||
| 791 | |||
| 792 | /* If we have RX_POST_REQ_ALLOC new released rx buffers - | ||
| 793 | * issue a request for allocator. Modulo RX_CLAIM_REQ_ALLOC is | ||
| 794 | * used for the case we failed to claim RX_CLAIM_REQ_ALLOC, | ||
| 795 | * after but we still need to post another request. | ||
| 796 | */ | ||
| 797 | if ((rxq->used_count % RX_CLAIM_REQ_ALLOC) == RX_POST_REQ_ALLOC) { | ||
| 798 | /* Move the 2 RBDs to the allocator ownership. | ||
| 799 | Allocator has another 6 from pool for the request completion*/ | ||
| 800 | spin_lock(&rba->lock); | ||
| 801 | list_splice_tail_init(&rxq->rx_used, &rba->rbd_empty); | ||
| 802 | spin_unlock(&rba->lock); | ||
| 803 | |||
| 804 | atomic_inc(&rba->req_pending); | ||
| 805 | queue_work(rba->alloc_wq, &rba->rx_alloc); | ||
| 806 | } | ||
| 807 | } | ||
| 808 | |||
| 809 | static void iwl_pcie_rx_handle_rb(struct iwl_trans *trans, | 569 | static void iwl_pcie_rx_handle_rb(struct iwl_trans *trans, |
| 810 | struct iwl_rx_mem_buffer *rxb) | 570 | struct iwl_rx_mem_buffer *rxb) |
| 811 | { | 571 | { |
| @@ -928,13 +688,13 @@ static void iwl_pcie_rx_handle_rb(struct iwl_trans *trans, | |||
| 928 | */ | 688 | */ |
| 929 | __free_pages(rxb->page, trans_pcie->rx_page_order); | 689 | __free_pages(rxb->page, trans_pcie->rx_page_order); |
| 930 | rxb->page = NULL; | 690 | rxb->page = NULL; |
| 931 | iwl_pcie_rx_reuse_rbd(trans, rxb, rxq); | 691 | list_add_tail(&rxb->list, &rxq->rx_used); |
| 932 | } else { | 692 | } else { |
| 933 | list_add_tail(&rxb->list, &rxq->rx_free); | 693 | list_add_tail(&rxb->list, &rxq->rx_free); |
| 934 | rxq->free_count++; | 694 | rxq->free_count++; |
| 935 | } | 695 | } |
| 936 | } else | 696 | } else |
| 937 | iwl_pcie_rx_reuse_rbd(trans, rxb, rxq); | 697 | list_add_tail(&rxb->list, &rxq->rx_used); |
| 938 | } | 698 | } |
| 939 | 699 | ||
| 940 | /* | 700 | /* |
| @@ -944,7 +704,10 @@ static void iwl_pcie_rx_handle(struct iwl_trans *trans) | |||
| 944 | { | 704 | { |
| 945 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); | 705 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); |
| 946 | struct iwl_rxq *rxq = &trans_pcie->rxq; | 706 | struct iwl_rxq *rxq = &trans_pcie->rxq; |
| 947 | u32 r, i, j; | 707 | u32 r, i; |
| 708 | u8 fill_rx = 0; | ||
| 709 | u32 count = 8; | ||
| 710 | int total_empty; | ||
| 948 | 711 | ||
| 949 | restart: | 712 | restart: |
| 950 | spin_lock(&rxq->lock); | 713 | spin_lock(&rxq->lock); |
| @@ -957,6 +720,14 @@ restart: | |||
| 957 | if (i == r) | 720 | if (i == r) |
| 958 | IWL_DEBUG_RX(trans, "HW = SW = %d\n", r); | 721 | IWL_DEBUG_RX(trans, "HW = SW = %d\n", r); |
| 959 | 722 | ||
| 723 | /* calculate total frames need to be restock after handling RX */ | ||
| 724 | total_empty = r - rxq->write_actual; | ||
| 725 | if (total_empty < 0) | ||
| 726 | total_empty += RX_QUEUE_SIZE; | ||
| 727 | |||
| 728 | if (total_empty > (RX_QUEUE_SIZE / 2)) | ||
| 729 | fill_rx = 1; | ||
| 730 | |||
| 960 | while (i != r) { | 731 | while (i != r) { |
| 961 | struct iwl_rx_mem_buffer *rxb; | 732 | struct iwl_rx_mem_buffer *rxb; |
| 962 | 733 | ||
| @@ -968,48 +739,29 @@ restart: | |||
| 968 | iwl_pcie_rx_handle_rb(trans, rxb); | 739 | iwl_pcie_rx_handle_rb(trans, rxb); |
| 969 | 740 | ||
| 970 | i = (i + 1) & RX_QUEUE_MASK; | 741 | i = (i + 1) & RX_QUEUE_MASK; |
| 971 | 742 | /* If there are a lot of unused frames, | |
| 972 | /* If we have RX_CLAIM_REQ_ALLOC released rx buffers - | 743 | * restock the Rx queue so ucode wont assert. */ |
| 973 | * try to claim the pre-allocated buffers from the allocator */ | 744 | if (fill_rx) { |
| 974 | if (rxq->used_count >= RX_CLAIM_REQ_ALLOC) { | 745 | count++; |
| 975 | struct iwl_rb_allocator *rba = &trans_pcie->rba; | 746 | if (count >= 8) { |
| 976 | struct iwl_rx_mem_buffer *out[RX_CLAIM_REQ_ALLOC]; | 747 | rxq->read = i; |
| 977 | 748 | spin_unlock(&rxq->lock); | |
| 978 | /* Add the remaining 6 empty RBDs for allocator use */ | 749 | iwl_pcie_rx_replenish(trans, GFP_ATOMIC); |
| 979 | spin_lock(&rba->lock); | 750 | count = 0; |
| 980 | list_splice_tail_init(&rxq->rx_used, &rba->rbd_empty); | 751 | goto restart; |
| 981 | spin_unlock(&rba->lock); | ||
| 982 | |||
| 983 | /* If not ready - continue, will try to reclaim later. | ||
| 984 | * No need to reschedule work - allocator exits only on | ||
| 985 | * success */ | ||
| 986 | if (!iwl_pcie_rx_allocator_get(trans, out)) { | ||
| 987 | /* If success - then RX_CLAIM_REQ_ALLOC | ||
| 988 | * buffers were retrieved and should be added | ||
| 989 | * to free list */ | ||
| 990 | rxq->used_count -= RX_CLAIM_REQ_ALLOC; | ||
| 991 | for (j = 0; j < RX_CLAIM_REQ_ALLOC; j++) { | ||
| 992 | list_add_tail(&out[j]->list, | ||
| 993 | &rxq->rx_free); | ||
| 994 | rxq->free_count++; | ||
| 995 | } | ||
| 996 | } | 752 | } |
| 997 | } | 753 | } |
| 998 | /* handle restock for two cases: | ||
| 999 | * - we just pulled buffers from the allocator | ||
| 1000 | * - we have 8+ unstolen pages accumulated */ | ||
| 1001 | if (rxq->free_count >= RX_CLAIM_REQ_ALLOC) { | ||
| 1002 | rxq->read = i; | ||
| 1003 | spin_unlock(&rxq->lock); | ||
| 1004 | iwl_pcie_rxq_restock(trans); | ||
| 1005 | goto restart; | ||
| 1006 | } | ||
| 1007 | } | 754 | } |
| 1008 | 755 | ||
| 1009 | /* Backtrack one entry */ | 756 | /* Backtrack one entry */ |
| 1010 | rxq->read = i; | 757 | rxq->read = i; |
| 1011 | spin_unlock(&rxq->lock); | 758 | spin_unlock(&rxq->lock); |
| 1012 | 759 | ||
| 760 | if (fill_rx) | ||
| 761 | iwl_pcie_rx_replenish(trans, GFP_ATOMIC); | ||
| 762 | else | ||
| 763 | iwl_pcie_rxq_restock(trans); | ||
| 764 | |||
| 1013 | if (trans_pcie->napi.poll) | 765 | if (trans_pcie->napi.poll) |
| 1014 | napi_gro_flush(&trans_pcie->napi, false); | 766 | napi_gro_flush(&trans_pcie->napi, false); |
| 1015 | } | 767 | } |
diff --git a/drivers/net/wireless/iwlwifi/pcie/trans.c b/drivers/net/wireless/iwlwifi/pcie/trans.c index 43ae658af6ec..6203c4ad9bba 100644 --- a/drivers/net/wireless/iwlwifi/pcie/trans.c +++ b/drivers/net/wireless/iwlwifi/pcie/trans.c | |||
| @@ -182,7 +182,7 @@ static void iwl_trans_pcie_write_shr(struct iwl_trans *trans, u32 reg, u32 val) | |||
| 182 | 182 | ||
| 183 | static void iwl_pcie_set_pwr(struct iwl_trans *trans, bool vaux) | 183 | static void iwl_pcie_set_pwr(struct iwl_trans *trans, bool vaux) |
| 184 | { | 184 | { |
| 185 | if (!trans->cfg->apmg_not_supported) | 185 | if (trans->cfg->apmg_not_supported) |
| 186 | return; | 186 | return; |
| 187 | 187 | ||
| 188 | if (vaux && pci_pme_capable(to_pci_dev(trans->dev), PCI_D3cold)) | 188 | if (vaux && pci_pme_capable(to_pci_dev(trans->dev), PCI_D3cold)) |
| @@ -2459,7 +2459,7 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct pci_dev *pdev, | |||
| 2459 | struct iwl_trans_pcie *trans_pcie; | 2459 | struct iwl_trans_pcie *trans_pcie; |
| 2460 | struct iwl_trans *trans; | 2460 | struct iwl_trans *trans; |
| 2461 | u16 pci_cmd; | 2461 | u16 pci_cmd; |
| 2462 | int err; | 2462 | int ret; |
| 2463 | 2463 | ||
| 2464 | trans = iwl_trans_alloc(sizeof(struct iwl_trans_pcie), | 2464 | trans = iwl_trans_alloc(sizeof(struct iwl_trans_pcie), |
| 2465 | &pdev->dev, cfg, &trans_ops_pcie, 0); | 2465 | &pdev->dev, cfg, &trans_ops_pcie, 0); |
| @@ -2474,8 +2474,8 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct pci_dev *pdev, | |||
| 2474 | spin_lock_init(&trans_pcie->ref_lock); | 2474 | spin_lock_init(&trans_pcie->ref_lock); |
| 2475 | init_waitqueue_head(&trans_pcie->ucode_write_waitq); | 2475 | init_waitqueue_head(&trans_pcie->ucode_write_waitq); |
| 2476 | 2476 | ||
| 2477 | err = pci_enable_device(pdev); | 2477 | ret = pci_enable_device(pdev); |
| 2478 | if (err) | 2478 | if (ret) |
| 2479 | goto out_no_pci; | 2479 | goto out_no_pci; |
| 2480 | 2480 | ||
| 2481 | if (!cfg->base_params->pcie_l1_allowed) { | 2481 | if (!cfg->base_params->pcie_l1_allowed) { |
| @@ -2491,23 +2491,23 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct pci_dev *pdev, | |||
| 2491 | 2491 | ||
| 2492 | pci_set_master(pdev); | 2492 | pci_set_master(pdev); |
| 2493 | 2493 | ||
| 2494 | err = pci_set_dma_mask(pdev, DMA_BIT_MASK(36)); | 2494 | ret = pci_set_dma_mask(pdev, DMA_BIT_MASK(36)); |
| 2495 | if (!err) | 2495 | if (!ret) |
| 2496 | err = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(36)); | 2496 | ret = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(36)); |
| 2497 | if (err) { | 2497 | if (ret) { |
| 2498 | err = pci_set_dma_mask(pdev, DMA_BIT_MASK(32)); | 2498 | ret = pci_set_dma_mask(pdev, DMA_BIT_MASK(32)); |
| 2499 | if (!err) | 2499 | if (!ret) |
| 2500 | err = pci_set_consistent_dma_mask(pdev, | 2500 | ret = pci_set_consistent_dma_mask(pdev, |
| 2501 | DMA_BIT_MASK(32)); | 2501 | DMA_BIT_MASK(32)); |
| 2502 | /* both attempts failed: */ | 2502 | /* both attempts failed: */ |
| 2503 | if (err) { | 2503 | if (ret) { |
| 2504 | dev_err(&pdev->dev, "No suitable DMA available\n"); | 2504 | dev_err(&pdev->dev, "No suitable DMA available\n"); |
| 2505 | goto out_pci_disable_device; | 2505 | goto out_pci_disable_device; |
| 2506 | } | 2506 | } |
| 2507 | } | 2507 | } |
| 2508 | 2508 | ||
| 2509 | err = pci_request_regions(pdev, DRV_NAME); | 2509 | ret = pci_request_regions(pdev, DRV_NAME); |
| 2510 | if (err) { | 2510 | if (ret) { |
| 2511 | dev_err(&pdev->dev, "pci_request_regions failed\n"); | 2511 | dev_err(&pdev->dev, "pci_request_regions failed\n"); |
| 2512 | goto out_pci_disable_device; | 2512 | goto out_pci_disable_device; |
| 2513 | } | 2513 | } |
| @@ -2515,7 +2515,7 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct pci_dev *pdev, | |||
| 2515 | trans_pcie->hw_base = pci_ioremap_bar(pdev, 0); | 2515 | trans_pcie->hw_base = pci_ioremap_bar(pdev, 0); |
| 2516 | if (!trans_pcie->hw_base) { | 2516 | if (!trans_pcie->hw_base) { |
| 2517 | dev_err(&pdev->dev, "pci_ioremap_bar failed\n"); | 2517 | dev_err(&pdev->dev, "pci_ioremap_bar failed\n"); |
| 2518 | err = -ENODEV; | 2518 | ret = -ENODEV; |
| 2519 | goto out_pci_release_regions; | 2519 | goto out_pci_release_regions; |
| 2520 | } | 2520 | } |
| 2521 | 2521 | ||
| @@ -2527,9 +2527,9 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct pci_dev *pdev, | |||
| 2527 | trans_pcie->pci_dev = pdev; | 2527 | trans_pcie->pci_dev = pdev; |
| 2528 | iwl_disable_interrupts(trans); | 2528 | iwl_disable_interrupts(trans); |
| 2529 | 2529 | ||
| 2530 | err = pci_enable_msi(pdev); | 2530 | ret = pci_enable_msi(pdev); |
| 2531 | if (err) { | 2531 | if (ret) { |
| 2532 | dev_err(&pdev->dev, "pci_enable_msi failed(0X%x)\n", err); | 2532 | dev_err(&pdev->dev, "pci_enable_msi failed(0X%x)\n", ret); |
| 2533 | /* enable rfkill interrupt: hw bug w/a */ | 2533 | /* enable rfkill interrupt: hw bug w/a */ |
| 2534 | pci_read_config_word(pdev, PCI_COMMAND, &pci_cmd); | 2534 | pci_read_config_word(pdev, PCI_COMMAND, &pci_cmd); |
| 2535 | if (pci_cmd & PCI_COMMAND_INTX_DISABLE) { | 2535 | if (pci_cmd & PCI_COMMAND_INTX_DISABLE) { |
| @@ -2547,11 +2547,16 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct pci_dev *pdev, | |||
| 2547 | */ | 2547 | */ |
| 2548 | if (trans->cfg->device_family == IWL_DEVICE_FAMILY_8000) { | 2548 | if (trans->cfg->device_family == IWL_DEVICE_FAMILY_8000) { |
| 2549 | unsigned long flags; | 2549 | unsigned long flags; |
| 2550 | int ret; | ||
| 2551 | 2550 | ||
| 2552 | trans->hw_rev = (trans->hw_rev & 0xfff0) | | 2551 | trans->hw_rev = (trans->hw_rev & 0xfff0) | |
| 2553 | (CSR_HW_REV_STEP(trans->hw_rev << 2) << 2); | 2552 | (CSR_HW_REV_STEP(trans->hw_rev << 2) << 2); |
| 2554 | 2553 | ||
| 2554 | ret = iwl_pcie_prepare_card_hw(trans); | ||
| 2555 | if (ret) { | ||
| 2556 | IWL_WARN(trans, "Exit HW not ready\n"); | ||
| 2557 | goto out_pci_disable_msi; | ||
| 2558 | } | ||
| 2559 | |||
| 2555 | /* | 2560 | /* |
| 2556 | * in-order to recognize C step driver should read chip version | 2561 | * in-order to recognize C step driver should read chip version |
| 2557 | * id located at the AUX bus MISC address space. | 2562 | * id located at the AUX bus MISC address space. |
| @@ -2591,13 +2596,14 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct pci_dev *pdev, | |||
| 2591 | /* Initialize the wait queue for commands */ | 2596 | /* Initialize the wait queue for commands */ |
| 2592 | init_waitqueue_head(&trans_pcie->wait_command_queue); | 2597 | init_waitqueue_head(&trans_pcie->wait_command_queue); |
| 2593 | 2598 | ||
| 2594 | if (iwl_pcie_alloc_ict(trans)) | 2599 | ret = iwl_pcie_alloc_ict(trans); |
| 2600 | if (ret) | ||
| 2595 | goto out_pci_disable_msi; | 2601 | goto out_pci_disable_msi; |
| 2596 | 2602 | ||
| 2597 | err = request_threaded_irq(pdev->irq, iwl_pcie_isr, | 2603 | ret = request_threaded_irq(pdev->irq, iwl_pcie_isr, |
| 2598 | iwl_pcie_irq_handler, | 2604 | iwl_pcie_irq_handler, |
| 2599 | IRQF_SHARED, DRV_NAME, trans); | 2605 | IRQF_SHARED, DRV_NAME, trans); |
| 2600 | if (err) { | 2606 | if (ret) { |
| 2601 | IWL_ERR(trans, "Error allocating IRQ %d\n", pdev->irq); | 2607 | IWL_ERR(trans, "Error allocating IRQ %d\n", pdev->irq); |
| 2602 | goto out_free_ict; | 2608 | goto out_free_ict; |
| 2603 | } | 2609 | } |
| @@ -2617,5 +2623,5 @@ out_pci_disable_device: | |||
| 2617 | pci_disable_device(pdev); | 2623 | pci_disable_device(pdev); |
| 2618 | out_no_pci: | 2624 | out_no_pci: |
| 2619 | iwl_trans_free(trans); | 2625 | iwl_trans_free(trans); |
| 2620 | return ERR_PTR(err); | 2626 | return ERR_PTR(ret); |
| 2621 | } | 2627 | } |
diff --git a/drivers/net/xen-netback/netback.c b/drivers/net/xen-netback/netback.c index 880d0d63e872..7d50711476fe 100644 --- a/drivers/net/xen-netback/netback.c +++ b/drivers/net/xen-netback/netback.c | |||
| @@ -1566,13 +1566,13 @@ static inline void xenvif_tx_dealloc_action(struct xenvif_queue *queue) | |||
| 1566 | smp_rmb(); | 1566 | smp_rmb(); |
| 1567 | 1567 | ||
| 1568 | while (dc != dp) { | 1568 | while (dc != dp) { |
| 1569 | BUG_ON(gop - queue->tx_unmap_ops > MAX_PENDING_REQS); | 1569 | BUG_ON(gop - queue->tx_unmap_ops >= MAX_PENDING_REQS); |
| 1570 | pending_idx = | 1570 | pending_idx = |
| 1571 | queue->dealloc_ring[pending_index(dc++)]; | 1571 | queue->dealloc_ring[pending_index(dc++)]; |
| 1572 | 1572 | ||
| 1573 | pending_idx_release[gop-queue->tx_unmap_ops] = | 1573 | pending_idx_release[gop - queue->tx_unmap_ops] = |
| 1574 | pending_idx; | 1574 | pending_idx; |
| 1575 | queue->pages_to_unmap[gop-queue->tx_unmap_ops] = | 1575 | queue->pages_to_unmap[gop - queue->tx_unmap_ops] = |
| 1576 | queue->mmap_pages[pending_idx]; | 1576 | queue->mmap_pages[pending_idx]; |
| 1577 | gnttab_set_unmap_op(gop, | 1577 | gnttab_set_unmap_op(gop, |
| 1578 | idx_to_kaddr(queue, pending_idx), | 1578 | idx_to_kaddr(queue, pending_idx), |
diff --git a/drivers/pinctrl/bcm/pinctrl-bcm2835.c b/drivers/pinctrl/bcm/pinctrl-bcm2835.c index efcf2a2b3975..6177315ab74e 100644 --- a/drivers/pinctrl/bcm/pinctrl-bcm2835.c +++ b/drivers/pinctrl/bcm/pinctrl-bcm2835.c | |||
| @@ -473,6 +473,8 @@ static void bcm2835_gpio_irq_disable(struct irq_data *data) | |||
| 473 | 473 | ||
| 474 | spin_lock_irqsave(&pc->irq_lock[bank], flags); | 474 | spin_lock_irqsave(&pc->irq_lock[bank], flags); |
| 475 | bcm2835_gpio_irq_config(pc, gpio, false); | 475 | bcm2835_gpio_irq_config(pc, gpio, false); |
| 476 | /* Clear events that were latched prior to clearing event sources */ | ||
| 477 | bcm2835_gpio_set_bit(pc, GPEDS0, gpio); | ||
| 476 | clear_bit(offset, &pc->enabled_irq_map[bank]); | 478 | clear_bit(offset, &pc->enabled_irq_map[bank]); |
| 477 | spin_unlock_irqrestore(&pc->irq_lock[bank], flags); | 479 | spin_unlock_irqrestore(&pc->irq_lock[bank], flags); |
| 478 | } | 480 | } |
diff --git a/drivers/pinctrl/freescale/pinctrl-imx1-core.c b/drivers/pinctrl/freescale/pinctrl-imx1-core.c index 5fd4437cee15..88a7fac11bd4 100644 --- a/drivers/pinctrl/freescale/pinctrl-imx1-core.c +++ b/drivers/pinctrl/freescale/pinctrl-imx1-core.c | |||
| @@ -403,14 +403,13 @@ static int imx1_pinconf_set(struct pinctrl_dev *pctldev, | |||
| 403 | unsigned num_configs) | 403 | unsigned num_configs) |
| 404 | { | 404 | { |
| 405 | struct imx1_pinctrl *ipctl = pinctrl_dev_get_drvdata(pctldev); | 405 | struct imx1_pinctrl *ipctl = pinctrl_dev_get_drvdata(pctldev); |
| 406 | const struct imx1_pinctrl_soc_info *info = ipctl->info; | ||
| 407 | int i; | 406 | int i; |
| 408 | 407 | ||
| 409 | for (i = 0; i != num_configs; ++i) { | 408 | for (i = 0; i != num_configs; ++i) { |
| 410 | imx1_write_bit(ipctl, pin_id, configs[i] & 0x01, MX1_PUEN); | 409 | imx1_write_bit(ipctl, pin_id, configs[i] & 0x01, MX1_PUEN); |
| 411 | 410 | ||
| 412 | dev_dbg(ipctl->dev, "pinconf set pullup pin %s\n", | 411 | dev_dbg(ipctl->dev, "pinconf set pullup pin %s\n", |
| 413 | info->pins[pin_id].name); | 412 | pin_desc_get(pctldev, pin_id)->name); |
| 414 | } | 413 | } |
| 415 | 414 | ||
| 416 | return 0; | 415 | return 0; |
diff --git a/drivers/pinctrl/nomadik/pinctrl-abx500.c b/drivers/pinctrl/nomadik/pinctrl-abx500.c index 557d0f2a3031..97681fac082e 100644 --- a/drivers/pinctrl/nomadik/pinctrl-abx500.c +++ b/drivers/pinctrl/nomadik/pinctrl-abx500.c | |||
| @@ -787,7 +787,6 @@ static const struct pinmux_ops abx500_pinmux_ops = { | |||
| 787 | .set_mux = abx500_pmx_set, | 787 | .set_mux = abx500_pmx_set, |
| 788 | .gpio_request_enable = abx500_gpio_request_enable, | 788 | .gpio_request_enable = abx500_gpio_request_enable, |
| 789 | .gpio_disable_free = abx500_gpio_disable_free, | 789 | .gpio_disable_free = abx500_gpio_disable_free, |
| 790 | .strict = true, | ||
| 791 | }; | 790 | }; |
| 792 | 791 | ||
| 793 | static int abx500_get_groups_cnt(struct pinctrl_dev *pctldev) | 792 | static int abx500_get_groups_cnt(struct pinctrl_dev *pctldev) |
diff --git a/drivers/pinctrl/pinctrl-lpc18xx.c b/drivers/pinctrl/pinctrl-lpc18xx.c index ef0b697639a7..347c763a6a78 100644 --- a/drivers/pinctrl/pinctrl-lpc18xx.c +++ b/drivers/pinctrl/pinctrl-lpc18xx.c | |||
| @@ -823,7 +823,7 @@ static int lpc18xx_pconf_set_i2c0(struct pinctrl_dev *pctldev, | |||
| 823 | break; | 823 | break; |
| 824 | 824 | ||
| 825 | case PIN_CONFIG_INPUT_SCHMITT_ENABLE: | 825 | case PIN_CONFIG_INPUT_SCHMITT_ENABLE: |
| 826 | if (param) | 826 | if (param_val) |
| 827 | *reg &= ~(LPC18XX_SCU_I2C0_ZIF << shift); | 827 | *reg &= ~(LPC18XX_SCU_I2C0_ZIF << shift); |
| 828 | else | 828 | else |
| 829 | *reg |= (LPC18XX_SCU_I2C0_ZIF << shift); | 829 | *reg |= (LPC18XX_SCU_I2C0_ZIF << shift); |
| @@ -876,7 +876,7 @@ static int lpc18xx_pconf_set_pin(struct pinctrl_dev *pctldev, | |||
| 876 | break; | 876 | break; |
| 877 | 877 | ||
| 878 | case PIN_CONFIG_INPUT_SCHMITT_ENABLE: | 878 | case PIN_CONFIG_INPUT_SCHMITT_ENABLE: |
| 879 | if (param) | 879 | if (param_val) |
| 880 | *reg &= ~LPC18XX_SCU_PIN_ZIF; | 880 | *reg &= ~LPC18XX_SCU_PIN_ZIF; |
| 881 | else | 881 | else |
| 882 | *reg |= LPC18XX_SCU_PIN_ZIF; | 882 | *reg |= LPC18XX_SCU_PIN_ZIF; |
diff --git a/drivers/pinctrl/pinctrl-single.c b/drivers/pinctrl/pinctrl-single.c index b2de09d3b1a0..0b8d480171a3 100644 --- a/drivers/pinctrl/pinctrl-single.c +++ b/drivers/pinctrl/pinctrl-single.c | |||
| @@ -1760,7 +1760,8 @@ static int pcs_irq_init_chained_handler(struct pcs_device *pcs, | |||
| 1760 | int res; | 1760 | int res; |
| 1761 | 1761 | ||
| 1762 | res = request_irq(pcs_soc->irq, pcs_irq_handler, | 1762 | res = request_irq(pcs_soc->irq, pcs_irq_handler, |
| 1763 | IRQF_SHARED | IRQF_NO_SUSPEND, | 1763 | IRQF_SHARED | IRQF_NO_SUSPEND | |
| 1764 | IRQF_NO_THREAD, | ||
| 1764 | name, pcs_soc); | 1765 | name, pcs_soc); |
| 1765 | if (res) { | 1766 | if (res) { |
| 1766 | pcs_soc->irq = -1; | 1767 | pcs_soc->irq = -1; |
diff --git a/drivers/pinctrl/samsung/pinctrl-samsung.c b/drivers/pinctrl/samsung/pinctrl-samsung.c index 3dd5a3b2ac62..c760bf43d116 100644 --- a/drivers/pinctrl/samsung/pinctrl-samsung.c +++ b/drivers/pinctrl/samsung/pinctrl-samsung.c | |||
| @@ -33,11 +33,6 @@ | |||
| 33 | #include "../core.h" | 33 | #include "../core.h" |
| 34 | #include "pinctrl-samsung.h" | 34 | #include "pinctrl-samsung.h" |
| 35 | 35 | ||
| 36 | #define GROUP_SUFFIX "-grp" | ||
| 37 | #define GSUFFIX_LEN sizeof(GROUP_SUFFIX) | ||
| 38 | #define FUNCTION_SUFFIX "-mux" | ||
| 39 | #define FSUFFIX_LEN sizeof(FUNCTION_SUFFIX) | ||
| 40 | |||
| 41 | /* list of all possible config options supported */ | 36 | /* list of all possible config options supported */ |
| 42 | static struct pin_config { | 37 | static struct pin_config { |
| 43 | const char *property; | 38 | const char *property; |
diff --git a/drivers/pinctrl/sh-pfc/sh_pfc.h b/drivers/pinctrl/sh-pfc/sh_pfc.h index c7508d5f6886..0874cfee6889 100644 --- a/drivers/pinctrl/sh-pfc/sh_pfc.h +++ b/drivers/pinctrl/sh-pfc/sh_pfc.h | |||
| @@ -224,7 +224,7 @@ struct sh_pfc_soc_info { | |||
| 224 | 224 | ||
| 225 | /* PINMUX_GPIO_GP_ALL - Expand to a list of sh_pfc_pin entries */ | 225 | /* PINMUX_GPIO_GP_ALL - Expand to a list of sh_pfc_pin entries */ |
| 226 | #define _GP_GPIO(bank, _pin, _name, sfx) \ | 226 | #define _GP_GPIO(bank, _pin, _name, sfx) \ |
| 227 | [(bank * 32) + _pin] = { \ | 227 | { \ |
| 228 | .pin = (bank * 32) + _pin, \ | 228 | .pin = (bank * 32) + _pin, \ |
| 229 | .name = __stringify(_name), \ | 229 | .name = __stringify(_name), \ |
| 230 | .enum_id = _name##_DATA, \ | 230 | .enum_id = _name##_DATA, \ |
diff --git a/drivers/pinctrl/spear/pinctrl-spear.c b/drivers/pinctrl/spear/pinctrl-spear.c index f87a5eaf75da..0afaf79a4e51 100644 --- a/drivers/pinctrl/spear/pinctrl-spear.c +++ b/drivers/pinctrl/spear/pinctrl-spear.c | |||
| @@ -2,7 +2,7 @@ | |||
| 2 | * Driver for the ST Microelectronics SPEAr pinmux | 2 | * Driver for the ST Microelectronics SPEAr pinmux |
| 3 | * | 3 | * |
| 4 | * Copyright (C) 2012 ST Microelectronics | 4 | * Copyright (C) 2012 ST Microelectronics |
| 5 | * Viresh Kumar <viresh.linux@gmail.com> | 5 | * Viresh Kumar <vireshk@kernel.org> |
| 6 | * | 6 | * |
| 7 | * Inspired from: | 7 | * Inspired from: |
| 8 | * - U300 Pinctl drivers | 8 | * - U300 Pinctl drivers |
diff --git a/drivers/pinctrl/spear/pinctrl-spear.h b/drivers/pinctrl/spear/pinctrl-spear.h index dc8bf85ecb2a..27c2cc8d83ad 100644 --- a/drivers/pinctrl/spear/pinctrl-spear.h +++ b/drivers/pinctrl/spear/pinctrl-spear.h | |||
| @@ -2,7 +2,7 @@ | |||
| 2 | * Driver header file for the ST Microelectronics SPEAr pinmux | 2 | * Driver header file for the ST Microelectronics SPEAr pinmux |
| 3 | * | 3 | * |
| 4 | * Copyright (C) 2012 ST Microelectronics | 4 | * Copyright (C) 2012 ST Microelectronics |
| 5 | * Viresh Kumar <viresh.linux@gmail.com> | 5 | * Viresh Kumar <vireshk@kernel.org> |
| 6 | * | 6 | * |
| 7 | * This file is licensed under the terms of the GNU General Public | 7 | * This file is licensed under the terms of the GNU General Public |
| 8 | * License version 2. This program is licensed "as is" without any | 8 | * License version 2. This program is licensed "as is" without any |
diff --git a/drivers/pinctrl/spear/pinctrl-spear1310.c b/drivers/pinctrl/spear/pinctrl-spear1310.c index a7bdc537efa7..92611bb757ac 100644 --- a/drivers/pinctrl/spear/pinctrl-spear1310.c +++ b/drivers/pinctrl/spear/pinctrl-spear1310.c | |||
| @@ -2,7 +2,7 @@ | |||
| 2 | * Driver for the ST Microelectronics SPEAr1310 pinmux | 2 | * Driver for the ST Microelectronics SPEAr1310 pinmux |
| 3 | * | 3 | * |
| 4 | * Copyright (C) 2012 ST Microelectronics | 4 | * Copyright (C) 2012 ST Microelectronics |
| 5 | * Viresh Kumar <viresh.linux@gmail.com> | 5 | * Viresh Kumar <vireshk@kernel.org> |
| 6 | * | 6 | * |
| 7 | * This file is licensed under the terms of the GNU General Public | 7 | * This file is licensed under the terms of the GNU General Public |
| 8 | * License version 2. This program is licensed "as is" without any | 8 | * License version 2. This program is licensed "as is" without any |
| @@ -2730,7 +2730,7 @@ static void __exit spear1310_pinctrl_exit(void) | |||
| 2730 | } | 2730 | } |
| 2731 | module_exit(spear1310_pinctrl_exit); | 2731 | module_exit(spear1310_pinctrl_exit); |
| 2732 | 2732 | ||
| 2733 | MODULE_AUTHOR("Viresh Kumar <viresh.linux@gmail.com>"); | 2733 | MODULE_AUTHOR("Viresh Kumar <vireshk@kernel.org>"); |
| 2734 | MODULE_DESCRIPTION("ST Microelectronics SPEAr1310 pinctrl driver"); | 2734 | MODULE_DESCRIPTION("ST Microelectronics SPEAr1310 pinctrl driver"); |
| 2735 | MODULE_LICENSE("GPL v2"); | 2735 | MODULE_LICENSE("GPL v2"); |
| 2736 | MODULE_DEVICE_TABLE(of, spear1310_pinctrl_of_match); | 2736 | MODULE_DEVICE_TABLE(of, spear1310_pinctrl_of_match); |
diff --git a/drivers/pinctrl/spear/pinctrl-spear1340.c b/drivers/pinctrl/spear/pinctrl-spear1340.c index f43ec85a0328..f842e9dc40d0 100644 --- a/drivers/pinctrl/spear/pinctrl-spear1340.c +++ b/drivers/pinctrl/spear/pinctrl-spear1340.c | |||
| @@ -2,7 +2,7 @@ | |||
| 2 | * Driver for the ST Microelectronics SPEAr1340 pinmux | 2 | * Driver for the ST Microelectronics SPEAr1340 pinmux |
| 3 | * | 3 | * |
| 4 | * Copyright (C) 2012 ST Microelectronics | 4 | * Copyright (C) 2012 ST Microelectronics |
| 5 | * Viresh Kumar <viresh.linux@gmail.com> | 5 | * Viresh Kumar <vireshk@kernel.org> |
| 6 | * | 6 | * |
| 7 | * This file is licensed under the terms of the GNU General Public | 7 | * This file is licensed under the terms of the GNU General Public |
| 8 | * License version 2. This program is licensed "as is" without any | 8 | * License version 2. This program is licensed "as is" without any |
| @@ -2046,7 +2046,7 @@ static void __exit spear1340_pinctrl_exit(void) | |||
| 2046 | } | 2046 | } |
| 2047 | module_exit(spear1340_pinctrl_exit); | 2047 | module_exit(spear1340_pinctrl_exit); |
| 2048 | 2048 | ||
| 2049 | MODULE_AUTHOR("Viresh Kumar <viresh.linux@gmail.com>"); | 2049 | MODULE_AUTHOR("Viresh Kumar <vireshk@kernel.org>"); |
| 2050 | MODULE_DESCRIPTION("ST Microelectronics SPEAr1340 pinctrl driver"); | 2050 | MODULE_DESCRIPTION("ST Microelectronics SPEAr1340 pinctrl driver"); |
| 2051 | MODULE_LICENSE("GPL v2"); | 2051 | MODULE_LICENSE("GPL v2"); |
| 2052 | MODULE_DEVICE_TABLE(of, spear1340_pinctrl_of_match); | 2052 | MODULE_DEVICE_TABLE(of, spear1340_pinctrl_of_match); |
diff --git a/drivers/pinctrl/spear/pinctrl-spear300.c b/drivers/pinctrl/spear/pinctrl-spear300.c index da8990a8eeef..d998a2ccff48 100644 --- a/drivers/pinctrl/spear/pinctrl-spear300.c +++ b/drivers/pinctrl/spear/pinctrl-spear300.c | |||
| @@ -2,7 +2,7 @@ | |||
| 2 | * Driver for the ST Microelectronics SPEAr300 pinmux | 2 | * Driver for the ST Microelectronics SPEAr300 pinmux |
| 3 | * | 3 | * |
| 4 | * Copyright (C) 2012 ST Microelectronics | 4 | * Copyright (C) 2012 ST Microelectronics |
| 5 | * Viresh Kumar <viresh.linux@gmail.com> | 5 | * Viresh Kumar <vireshk@kernel.org> |
| 6 | * | 6 | * |
| 7 | * This file is licensed under the terms of the GNU General Public | 7 | * This file is licensed under the terms of the GNU General Public |
| 8 | * License version 2. This program is licensed "as is" without any | 8 | * License version 2. This program is licensed "as is" without any |
| @@ -703,7 +703,7 @@ static void __exit spear300_pinctrl_exit(void) | |||
| 703 | } | 703 | } |
| 704 | module_exit(spear300_pinctrl_exit); | 704 | module_exit(spear300_pinctrl_exit); |
| 705 | 705 | ||
| 706 | MODULE_AUTHOR("Viresh Kumar <viresh.linux@gmail.com>"); | 706 | MODULE_AUTHOR("Viresh Kumar <vireshk@kernel.org>"); |
| 707 | MODULE_DESCRIPTION("ST Microelectronics SPEAr300 pinctrl driver"); | 707 | MODULE_DESCRIPTION("ST Microelectronics SPEAr300 pinctrl driver"); |
| 708 | MODULE_LICENSE("GPL v2"); | 708 | MODULE_LICENSE("GPL v2"); |
| 709 | MODULE_DEVICE_TABLE(of, spear300_pinctrl_of_match); | 709 | MODULE_DEVICE_TABLE(of, spear300_pinctrl_of_match); |
diff --git a/drivers/pinctrl/spear/pinctrl-spear310.c b/drivers/pinctrl/spear/pinctrl-spear310.c index 31ede51e819b..609b18aceb16 100644 --- a/drivers/pinctrl/spear/pinctrl-spear310.c +++ b/drivers/pinctrl/spear/pinctrl-spear310.c | |||
| @@ -2,7 +2,7 @@ | |||
| 2 | * Driver for the ST Microelectronics SPEAr310 pinmux | 2 | * Driver for the ST Microelectronics SPEAr310 pinmux |
| 3 | * | 3 | * |
| 4 | * Copyright (C) 2012 ST Microelectronics | 4 | * Copyright (C) 2012 ST Microelectronics |
| 5 | * Viresh Kumar <viresh.linux@gmail.com> | 5 | * Viresh Kumar <vireshk@kernel.org> |
| 6 | * | 6 | * |
| 7 | * This file is licensed under the terms of the GNU General Public | 7 | * This file is licensed under the terms of the GNU General Public |
| 8 | * License version 2. This program is licensed "as is" without any | 8 | * License version 2. This program is licensed "as is" without any |
| @@ -426,7 +426,7 @@ static void __exit spear310_pinctrl_exit(void) | |||
| 426 | } | 426 | } |
| 427 | module_exit(spear310_pinctrl_exit); | 427 | module_exit(spear310_pinctrl_exit); |
| 428 | 428 | ||
| 429 | MODULE_AUTHOR("Viresh Kumar <viresh.linux@gmail.com>"); | 429 | MODULE_AUTHOR("Viresh Kumar <vireshk@kernel.org>"); |
| 430 | MODULE_DESCRIPTION("ST Microelectronics SPEAr310 pinctrl driver"); | 430 | MODULE_DESCRIPTION("ST Microelectronics SPEAr310 pinctrl driver"); |
| 431 | MODULE_LICENSE("GPL v2"); | 431 | MODULE_LICENSE("GPL v2"); |
| 432 | MODULE_DEVICE_TABLE(of, spear310_pinctrl_of_match); | 432 | MODULE_DEVICE_TABLE(of, spear310_pinctrl_of_match); |
diff --git a/drivers/pinctrl/spear/pinctrl-spear320.c b/drivers/pinctrl/spear/pinctrl-spear320.c index 506e40b641e0..c07114431bd4 100644 --- a/drivers/pinctrl/spear/pinctrl-spear320.c +++ b/drivers/pinctrl/spear/pinctrl-spear320.c | |||
| @@ -2,7 +2,7 @@ | |||
| 2 | * Driver for the ST Microelectronics SPEAr320 pinmux | 2 | * Driver for the ST Microelectronics SPEAr320 pinmux |
| 3 | * | 3 | * |
| 4 | * Copyright (C) 2012 ST Microelectronics | 4 | * Copyright (C) 2012 ST Microelectronics |
| 5 | * Viresh Kumar <viresh.linux@gmail.com> | 5 | * Viresh Kumar <vireshk@kernel.org> |
| 6 | * | 6 | * |
| 7 | * This file is licensed under the terms of the GNU General Public | 7 | * This file is licensed under the terms of the GNU General Public |
| 8 | * License version 2. This program is licensed "as is" without any | 8 | * License version 2. This program is licensed "as is" without any |
| @@ -3467,7 +3467,7 @@ static void __exit spear320_pinctrl_exit(void) | |||
| 3467 | } | 3467 | } |
| 3468 | module_exit(spear320_pinctrl_exit); | 3468 | module_exit(spear320_pinctrl_exit); |
| 3469 | 3469 | ||
| 3470 | MODULE_AUTHOR("Viresh Kumar <viresh.linux@gmail.com>"); | 3470 | MODULE_AUTHOR("Viresh Kumar <vireshk@kernel.org>"); |
| 3471 | MODULE_DESCRIPTION("ST Microelectronics SPEAr320 pinctrl driver"); | 3471 | MODULE_DESCRIPTION("ST Microelectronics SPEAr320 pinctrl driver"); |
| 3472 | MODULE_LICENSE("GPL v2"); | 3472 | MODULE_LICENSE("GPL v2"); |
| 3473 | MODULE_DEVICE_TABLE(of, spear320_pinctrl_of_match); | 3473 | MODULE_DEVICE_TABLE(of, spear320_pinctrl_of_match); |
diff --git a/drivers/pinctrl/spear/pinctrl-spear3xx.c b/drivers/pinctrl/spear/pinctrl-spear3xx.c index 12ee21af766b..d3119aafe709 100644 --- a/drivers/pinctrl/spear/pinctrl-spear3xx.c +++ b/drivers/pinctrl/spear/pinctrl-spear3xx.c | |||
| @@ -2,7 +2,7 @@ | |||
| 2 | * Driver for the ST Microelectronics SPEAr3xx pinmux | 2 | * Driver for the ST Microelectronics SPEAr3xx pinmux |
| 3 | * | 3 | * |
| 4 | * Copyright (C) 2012 ST Microelectronics | 4 | * Copyright (C) 2012 ST Microelectronics |
| 5 | * Viresh Kumar <viresh.linux@gmail.com> | 5 | * Viresh Kumar <vireshk@kernel.org> |
| 6 | * | 6 | * |
| 7 | * This file is licensed under the terms of the GNU General Public | 7 | * This file is licensed under the terms of the GNU General Public |
| 8 | * License version 2. This program is licensed "as is" without any | 8 | * License version 2. This program is licensed "as is" without any |
diff --git a/drivers/pinctrl/spear/pinctrl-spear3xx.h b/drivers/pinctrl/spear/pinctrl-spear3xx.h index 7860b36053c4..ce19dcf8f08b 100644 --- a/drivers/pinctrl/spear/pinctrl-spear3xx.h +++ b/drivers/pinctrl/spear/pinctrl-spear3xx.h | |||
| @@ -2,7 +2,7 @@ | |||
| 2 | * Header file for the ST Microelectronics SPEAr3xx pinmux | 2 | * Header file for the ST Microelectronics SPEAr3xx pinmux |
| 3 | * | 3 | * |
| 4 | * Copyright (C) 2012 ST Microelectronics | 4 | * Copyright (C) 2012 ST Microelectronics |
| 5 | * Viresh Kumar <viresh.linux@gmail.com> | 5 | * Viresh Kumar <vireshk@kernel.org> |
| 6 | * | 6 | * |
| 7 | * This file is licensed under the terms of the GNU General Public | 7 | * This file is licensed under the terms of the GNU General Public |
| 8 | * License version 2. This program is licensed "as is" without any | 8 | * License version 2. This program is licensed "as is" without any |
diff --git a/drivers/platform/x86/dell-laptop.c b/drivers/platform/x86/dell-laptop.c index ed317ccac4a2..aaeeae81e3a9 100644 --- a/drivers/platform/x86/dell-laptop.c +++ b/drivers/platform/x86/dell-laptop.c | |||
| @@ -309,12 +309,15 @@ static const struct dmi_system_id dell_quirks[] __initconst = { | |||
| 309 | static struct calling_interface_buffer *buffer; | 309 | static struct calling_interface_buffer *buffer; |
| 310 | static DEFINE_MUTEX(buffer_mutex); | 310 | static DEFINE_MUTEX(buffer_mutex); |
| 311 | 311 | ||
| 312 | static int hwswitch_state; | 312 | static void clear_buffer(void) |
| 313 | { | ||
| 314 | memset(buffer, 0, sizeof(struct calling_interface_buffer)); | ||
| 315 | } | ||
| 313 | 316 | ||
| 314 | static void get_buffer(void) | 317 | static void get_buffer(void) |
| 315 | { | 318 | { |
| 316 | mutex_lock(&buffer_mutex); | 319 | mutex_lock(&buffer_mutex); |
| 317 | memset(buffer, 0, sizeof(struct calling_interface_buffer)); | 320 | clear_buffer(); |
| 318 | } | 321 | } |
| 319 | 322 | ||
| 320 | static void release_buffer(void) | 323 | static void release_buffer(void) |
| @@ -548,21 +551,41 @@ static int dell_rfkill_set(void *data, bool blocked) | |||
| 548 | int disable = blocked ? 1 : 0; | 551 | int disable = blocked ? 1 : 0; |
| 549 | unsigned long radio = (unsigned long)data; | 552 | unsigned long radio = (unsigned long)data; |
| 550 | int hwswitch_bit = (unsigned long)data - 1; | 553 | int hwswitch_bit = (unsigned long)data - 1; |
| 554 | int hwswitch; | ||
| 555 | int status; | ||
| 556 | int ret; | ||
| 551 | 557 | ||
| 552 | get_buffer(); | 558 | get_buffer(); |
| 559 | |||
| 560 | dell_send_request(buffer, 17, 11); | ||
| 561 | ret = buffer->output[0]; | ||
| 562 | status = buffer->output[1]; | ||
| 563 | |||
| 564 | if (ret != 0) | ||
| 565 | goto out; | ||
| 566 | |||
| 567 | clear_buffer(); | ||
| 568 | |||
| 569 | buffer->input[0] = 0x2; | ||
| 553 | dell_send_request(buffer, 17, 11); | 570 | dell_send_request(buffer, 17, 11); |
| 571 | ret = buffer->output[0]; | ||
| 572 | hwswitch = buffer->output[1]; | ||
| 554 | 573 | ||
| 555 | /* If the hardware switch controls this radio, and the hardware | 574 | /* If the hardware switch controls this radio, and the hardware |
| 556 | switch is disabled, always disable the radio */ | 575 | switch is disabled, always disable the radio */ |
| 557 | if ((hwswitch_state & BIT(hwswitch_bit)) && | 576 | if (ret == 0 && (hwswitch & BIT(hwswitch_bit)) && |
| 558 | !(buffer->output[1] & BIT(16))) | 577 | (status & BIT(0)) && !(status & BIT(16))) |
| 559 | disable = 1; | 578 | disable = 1; |
| 560 | 579 | ||
| 580 | clear_buffer(); | ||
| 581 | |||
| 561 | buffer->input[0] = (1 | (radio<<8) | (disable << 16)); | 582 | buffer->input[0] = (1 | (radio<<8) | (disable << 16)); |
| 562 | dell_send_request(buffer, 17, 11); | 583 | dell_send_request(buffer, 17, 11); |
| 584 | ret = buffer->output[0]; | ||
| 563 | 585 | ||
| 586 | out: | ||
| 564 | release_buffer(); | 587 | release_buffer(); |
| 565 | return 0; | 588 | return dell_smi_error(ret); |
| 566 | } | 589 | } |
| 567 | 590 | ||
| 568 | /* Must be called with the buffer held */ | 591 | /* Must be called with the buffer held */ |
| @@ -572,6 +595,7 @@ static void dell_rfkill_update_sw_state(struct rfkill *rfkill, int radio, | |||
| 572 | if (status & BIT(0)) { | 595 | if (status & BIT(0)) { |
| 573 | /* Has hw-switch, sync sw_state to BIOS */ | 596 | /* Has hw-switch, sync sw_state to BIOS */ |
| 574 | int block = rfkill_blocked(rfkill); | 597 | int block = rfkill_blocked(rfkill); |
| 598 | clear_buffer(); | ||
| 575 | buffer->input[0] = (1 | (radio << 8) | (block << 16)); | 599 | buffer->input[0] = (1 | (radio << 8) | (block << 16)); |
| 576 | dell_send_request(buffer, 17, 11); | 600 | dell_send_request(buffer, 17, 11); |
| 577 | } else { | 601 | } else { |
| @@ -581,23 +605,43 @@ static void dell_rfkill_update_sw_state(struct rfkill *rfkill, int radio, | |||
| 581 | } | 605 | } |
| 582 | 606 | ||
| 583 | static void dell_rfkill_update_hw_state(struct rfkill *rfkill, int radio, | 607 | static void dell_rfkill_update_hw_state(struct rfkill *rfkill, int radio, |
| 584 | int status) | 608 | int status, int hwswitch) |
| 585 | { | 609 | { |
| 586 | if (hwswitch_state & (BIT(radio - 1))) | 610 | if (hwswitch & (BIT(radio - 1))) |
| 587 | rfkill_set_hw_state(rfkill, !(status & BIT(16))); | 611 | rfkill_set_hw_state(rfkill, !(status & BIT(16))); |
| 588 | } | 612 | } |
| 589 | 613 | ||
| 590 | static void dell_rfkill_query(struct rfkill *rfkill, void *data) | 614 | static void dell_rfkill_query(struct rfkill *rfkill, void *data) |
| 591 | { | 615 | { |
| 616 | int radio = ((unsigned long)data & 0xF); | ||
| 617 | int hwswitch; | ||
| 592 | int status; | 618 | int status; |
| 619 | int ret; | ||
| 593 | 620 | ||
| 594 | get_buffer(); | 621 | get_buffer(); |
| 622 | |||
| 595 | dell_send_request(buffer, 17, 11); | 623 | dell_send_request(buffer, 17, 11); |
| 624 | ret = buffer->output[0]; | ||
| 596 | status = buffer->output[1]; | 625 | status = buffer->output[1]; |
| 597 | 626 | ||
| 598 | dell_rfkill_update_hw_state(rfkill, (unsigned long)data, status); | 627 | if (ret != 0 || !(status & BIT(0))) { |
| 628 | release_buffer(); | ||
| 629 | return; | ||
| 630 | } | ||
| 631 | |||
| 632 | clear_buffer(); | ||
| 633 | |||
| 634 | buffer->input[0] = 0x2; | ||
| 635 | dell_send_request(buffer, 17, 11); | ||
| 636 | ret = buffer->output[0]; | ||
| 637 | hwswitch = buffer->output[1]; | ||
| 599 | 638 | ||
| 600 | release_buffer(); | 639 | release_buffer(); |
| 640 | |||
| 641 | if (ret != 0) | ||
| 642 | return; | ||
| 643 | |||
| 644 | dell_rfkill_update_hw_state(rfkill, radio, status, hwswitch); | ||
| 601 | } | 645 | } |
| 602 | 646 | ||
| 603 | static const struct rfkill_ops dell_rfkill_ops = { | 647 | static const struct rfkill_ops dell_rfkill_ops = { |
| @@ -609,13 +653,27 @@ static struct dentry *dell_laptop_dir; | |||
| 609 | 653 | ||
| 610 | static int dell_debugfs_show(struct seq_file *s, void *data) | 654 | static int dell_debugfs_show(struct seq_file *s, void *data) |
| 611 | { | 655 | { |
| 656 | int hwswitch_state; | ||
| 657 | int hwswitch_ret; | ||
| 612 | int status; | 658 | int status; |
| 659 | int ret; | ||
| 613 | 660 | ||
| 614 | get_buffer(); | 661 | get_buffer(); |
| 662 | |||
| 615 | dell_send_request(buffer, 17, 11); | 663 | dell_send_request(buffer, 17, 11); |
| 664 | ret = buffer->output[0]; | ||
| 616 | status = buffer->output[1]; | 665 | status = buffer->output[1]; |
| 666 | |||
| 667 | clear_buffer(); | ||
| 668 | |||
| 669 | buffer->input[0] = 0x2; | ||
| 670 | dell_send_request(buffer, 17, 11); | ||
| 671 | hwswitch_ret = buffer->output[0]; | ||
| 672 | hwswitch_state = buffer->output[1]; | ||
| 673 | |||
| 617 | release_buffer(); | 674 | release_buffer(); |
| 618 | 675 | ||
| 676 | seq_printf(s, "return:\t%d\n", ret); | ||
| 619 | seq_printf(s, "status:\t0x%X\n", status); | 677 | seq_printf(s, "status:\t0x%X\n", status); |
| 620 | seq_printf(s, "Bit 0 : Hardware switch supported: %lu\n", | 678 | seq_printf(s, "Bit 0 : Hardware switch supported: %lu\n", |
| 621 | status & BIT(0)); | 679 | status & BIT(0)); |
| @@ -657,7 +715,8 @@ static int dell_debugfs_show(struct seq_file *s, void *data) | |||
| 657 | seq_printf(s, "Bit 21: WiGig is blocked: %lu\n", | 715 | seq_printf(s, "Bit 21: WiGig is blocked: %lu\n", |
| 658 | (status & BIT(21)) >> 21); | 716 | (status & BIT(21)) >> 21); |
| 659 | 717 | ||
| 660 | seq_printf(s, "\nhwswitch_state:\t0x%X\n", hwswitch_state); | 718 | seq_printf(s, "\nhwswitch_return:\t%d\n", hwswitch_ret); |
| 719 | seq_printf(s, "hwswitch_state:\t0x%X\n", hwswitch_state); | ||
| 661 | seq_printf(s, "Bit 0 : Wifi controlled by switch: %lu\n", | 720 | seq_printf(s, "Bit 0 : Wifi controlled by switch: %lu\n", |
| 662 | hwswitch_state & BIT(0)); | 721 | hwswitch_state & BIT(0)); |
| 663 | seq_printf(s, "Bit 1 : Bluetooth controlled by switch: %lu\n", | 722 | seq_printf(s, "Bit 1 : Bluetooth controlled by switch: %lu\n", |
| @@ -693,25 +752,43 @@ static const struct file_operations dell_debugfs_fops = { | |||
| 693 | 752 | ||
| 694 | static void dell_update_rfkill(struct work_struct *ignored) | 753 | static void dell_update_rfkill(struct work_struct *ignored) |
| 695 | { | 754 | { |
| 755 | int hwswitch = 0; | ||
| 696 | int status; | 756 | int status; |
| 757 | int ret; | ||
| 697 | 758 | ||
| 698 | get_buffer(); | 759 | get_buffer(); |
| 760 | |||
| 699 | dell_send_request(buffer, 17, 11); | 761 | dell_send_request(buffer, 17, 11); |
| 762 | ret = buffer->output[0]; | ||
| 700 | status = buffer->output[1]; | 763 | status = buffer->output[1]; |
| 701 | 764 | ||
| 765 | if (ret != 0) | ||
| 766 | goto out; | ||
| 767 | |||
| 768 | clear_buffer(); | ||
| 769 | |||
| 770 | buffer->input[0] = 0x2; | ||
| 771 | dell_send_request(buffer, 17, 11); | ||
| 772 | ret = buffer->output[0]; | ||
| 773 | |||
| 774 | if (ret == 0 && (status & BIT(0))) | ||
| 775 | hwswitch = buffer->output[1]; | ||
| 776 | |||
| 702 | if (wifi_rfkill) { | 777 | if (wifi_rfkill) { |
| 703 | dell_rfkill_update_hw_state(wifi_rfkill, 1, status); | 778 | dell_rfkill_update_hw_state(wifi_rfkill, 1, status, hwswitch); |
| 704 | dell_rfkill_update_sw_state(wifi_rfkill, 1, status); | 779 | dell_rfkill_update_sw_state(wifi_rfkill, 1, status); |
| 705 | } | 780 | } |
| 706 | if (bluetooth_rfkill) { | 781 | if (bluetooth_rfkill) { |
| 707 | dell_rfkill_update_hw_state(bluetooth_rfkill, 2, status); | 782 | dell_rfkill_update_hw_state(bluetooth_rfkill, 2, status, |
| 783 | hwswitch); | ||
| 708 | dell_rfkill_update_sw_state(bluetooth_rfkill, 2, status); | 784 | dell_rfkill_update_sw_state(bluetooth_rfkill, 2, status); |
| 709 | } | 785 | } |
| 710 | if (wwan_rfkill) { | 786 | if (wwan_rfkill) { |
| 711 | dell_rfkill_update_hw_state(wwan_rfkill, 3, status); | 787 | dell_rfkill_update_hw_state(wwan_rfkill, 3, status, hwswitch); |
| 712 | dell_rfkill_update_sw_state(wwan_rfkill, 3, status); | 788 | dell_rfkill_update_sw_state(wwan_rfkill, 3, status); |
| 713 | } | 789 | } |
| 714 | 790 | ||
| 791 | out: | ||
| 715 | release_buffer(); | 792 | release_buffer(); |
| 716 | } | 793 | } |
| 717 | static DECLARE_DELAYED_WORK(dell_rfkill_work, dell_update_rfkill); | 794 | static DECLARE_DELAYED_WORK(dell_rfkill_work, dell_update_rfkill); |
| @@ -773,21 +850,17 @@ static int __init dell_setup_rfkill(void) | |||
| 773 | 850 | ||
| 774 | get_buffer(); | 851 | get_buffer(); |
| 775 | dell_send_request(buffer, 17, 11); | 852 | dell_send_request(buffer, 17, 11); |
| 853 | ret = buffer->output[0]; | ||
| 776 | status = buffer->output[1]; | 854 | status = buffer->output[1]; |
| 777 | buffer->input[0] = 0x2; | ||
| 778 | dell_send_request(buffer, 17, 11); | ||
| 779 | hwswitch_state = buffer->output[1]; | ||
| 780 | release_buffer(); | 855 | release_buffer(); |
| 781 | 856 | ||
| 782 | if (!(status & BIT(0))) { | 857 | /* dell wireless info smbios call is not supported */ |
| 783 | if (force_rfkill) { | 858 | if (ret != 0) |
| 784 | /* No hwsitch, clear all hw-controlled bits */ | 859 | return 0; |
| 785 | hwswitch_state &= ~7; | 860 | |
| 786 | } else { | 861 | /* rfkill is only tested on laptops with a hwswitch */ |
| 787 | /* rfkill is only tested on laptops with a hwswitch */ | 862 | if (!(status & BIT(0)) && !force_rfkill) |
| 788 | return 0; | 863 | return 0; |
| 789 | } | ||
| 790 | } | ||
| 791 | 864 | ||
| 792 | if ((status & (1<<2|1<<8)) == (1<<2|1<<8)) { | 865 | if ((status & (1<<2|1<<8)) == (1<<2|1<<8)) { |
| 793 | wifi_rfkill = rfkill_alloc("dell-wifi", &platform_device->dev, | 866 | wifi_rfkill = rfkill_alloc("dell-wifi", &platform_device->dev, |
| @@ -932,47 +1005,50 @@ static void dell_cleanup_rfkill(void) | |||
| 932 | 1005 | ||
| 933 | static int dell_send_intensity(struct backlight_device *bd) | 1006 | static int dell_send_intensity(struct backlight_device *bd) |
| 934 | { | 1007 | { |
| 935 | int ret = 0; | 1008 | int token; |
| 1009 | int ret; | ||
| 1010 | |||
| 1011 | token = find_token_location(BRIGHTNESS_TOKEN); | ||
| 1012 | if (token == -1) | ||
| 1013 | return -ENODEV; | ||
| 936 | 1014 | ||
| 937 | get_buffer(); | 1015 | get_buffer(); |
| 938 | buffer->input[0] = find_token_location(BRIGHTNESS_TOKEN); | 1016 | buffer->input[0] = token; |
| 939 | buffer->input[1] = bd->props.brightness; | 1017 | buffer->input[1] = bd->props.brightness; |
| 940 | 1018 | ||
| 941 | if (buffer->input[0] == -1) { | ||
| 942 | ret = -ENODEV; | ||
| 943 | goto out; | ||
| 944 | } | ||
| 945 | |||
| 946 | if (power_supply_is_system_supplied() > 0) | 1019 | if (power_supply_is_system_supplied() > 0) |
| 947 | dell_send_request(buffer, 1, 2); | 1020 | dell_send_request(buffer, 1, 2); |
| 948 | else | 1021 | else |
| 949 | dell_send_request(buffer, 1, 1); | 1022 | dell_send_request(buffer, 1, 1); |
| 950 | 1023 | ||
| 951 | out: | 1024 | ret = dell_smi_error(buffer->output[0]); |
| 1025 | |||
| 952 | release_buffer(); | 1026 | release_buffer(); |
| 953 | return ret; | 1027 | return ret; |
| 954 | } | 1028 | } |
| 955 | 1029 | ||
| 956 | static int dell_get_intensity(struct backlight_device *bd) | 1030 | static int dell_get_intensity(struct backlight_device *bd) |
| 957 | { | 1031 | { |
| 958 | int ret = 0; | 1032 | int token; |
| 1033 | int ret; | ||
| 959 | 1034 | ||
| 960 | get_buffer(); | 1035 | token = find_token_location(BRIGHTNESS_TOKEN); |
| 961 | buffer->input[0] = find_token_location(BRIGHTNESS_TOKEN); | 1036 | if (token == -1) |
| 1037 | return -ENODEV; | ||
| 962 | 1038 | ||
| 963 | if (buffer->input[0] == -1) { | 1039 | get_buffer(); |
| 964 | ret = -ENODEV; | 1040 | buffer->input[0] = token; |
| 965 | goto out; | ||
| 966 | } | ||
| 967 | 1041 | ||
| 968 | if (power_supply_is_system_supplied() > 0) | 1042 | if (power_supply_is_system_supplied() > 0) |
| 969 | dell_send_request(buffer, 0, 2); | 1043 | dell_send_request(buffer, 0, 2); |
| 970 | else | 1044 | else |
| 971 | dell_send_request(buffer, 0, 1); | 1045 | dell_send_request(buffer, 0, 1); |
| 972 | 1046 | ||
| 973 | ret = buffer->output[1]; | 1047 | if (buffer->output[0]) |
| 1048 | ret = dell_smi_error(buffer->output[0]); | ||
| 1049 | else | ||
| 1050 | ret = buffer->output[1]; | ||
| 974 | 1051 | ||
| 975 | out: | ||
| 976 | release_buffer(); | 1052 | release_buffer(); |
| 977 | return ret; | 1053 | return ret; |
| 978 | } | 1054 | } |
| @@ -2036,6 +2112,7 @@ static void kbd_led_exit(void) | |||
| 2036 | static int __init dell_init(void) | 2112 | static int __init dell_init(void) |
| 2037 | { | 2113 | { |
| 2038 | int max_intensity = 0; | 2114 | int max_intensity = 0; |
| 2115 | int token; | ||
| 2039 | int ret; | 2116 | int ret; |
| 2040 | 2117 | ||
| 2041 | if (!dmi_check_system(dell_device_table)) | 2118 | if (!dmi_check_system(dell_device_table)) |
| @@ -2094,13 +2171,15 @@ static int __init dell_init(void) | |||
| 2094 | if (acpi_video_get_backlight_type() != acpi_backlight_vendor) | 2171 | if (acpi_video_get_backlight_type() != acpi_backlight_vendor) |
| 2095 | return 0; | 2172 | return 0; |
| 2096 | 2173 | ||
| 2097 | get_buffer(); | 2174 | token = find_token_location(BRIGHTNESS_TOKEN); |
| 2098 | buffer->input[0] = find_token_location(BRIGHTNESS_TOKEN); | 2175 | if (token != -1) { |
| 2099 | if (buffer->input[0] != -1) { | 2176 | get_buffer(); |
| 2177 | buffer->input[0] = token; | ||
| 2100 | dell_send_request(buffer, 0, 2); | 2178 | dell_send_request(buffer, 0, 2); |
| 2101 | max_intensity = buffer->output[3]; | 2179 | if (buffer->output[0] == 0) |
| 2180 | max_intensity = buffer->output[3]; | ||
| 2181 | release_buffer(); | ||
| 2102 | } | 2182 | } |
| 2103 | release_buffer(); | ||
| 2104 | 2183 | ||
| 2105 | if (max_intensity) { | 2184 | if (max_intensity) { |
| 2106 | struct backlight_properties props; | 2185 | struct backlight_properties props; |
diff --git a/drivers/platform/x86/intel_pmc_ipc.c b/drivers/platform/x86/intel_pmc_ipc.c index d734763dab69..105cfffe82c6 100644 --- a/drivers/platform/x86/intel_pmc_ipc.c +++ b/drivers/platform/x86/intel_pmc_ipc.c | |||
| @@ -96,18 +96,18 @@ static struct intel_pmc_ipc_dev { | |||
| 96 | struct completion cmd_complete; | 96 | struct completion cmd_complete; |
| 97 | 97 | ||
| 98 | /* The following PMC BARs share the same ACPI device with the IPC */ | 98 | /* The following PMC BARs share the same ACPI device with the IPC */ |
| 99 | void *acpi_io_base; | 99 | resource_size_t acpi_io_base; |
| 100 | int acpi_io_size; | 100 | int acpi_io_size; |
| 101 | struct platform_device *tco_dev; | 101 | struct platform_device *tco_dev; |
| 102 | 102 | ||
| 103 | /* gcr */ | 103 | /* gcr */ |
| 104 | void *gcr_base; | 104 | resource_size_t gcr_base; |
| 105 | int gcr_size; | 105 | int gcr_size; |
| 106 | 106 | ||
| 107 | /* punit */ | 107 | /* punit */ |
| 108 | void *punit_base; | 108 | resource_size_t punit_base; |
| 109 | int punit_size; | 109 | int punit_size; |
| 110 | void *punit_base2; | 110 | resource_size_t punit_base2; |
| 111 | int punit_size2; | 111 | int punit_size2; |
| 112 | struct platform_device *punit_dev; | 112 | struct platform_device *punit_dev; |
| 113 | } ipcdev; | 113 | } ipcdev; |
| @@ -210,10 +210,15 @@ static int intel_pmc_ipc_check_status(void) | |||
| 210 | return ret; | 210 | return ret; |
| 211 | } | 211 | } |
| 212 | 212 | ||
| 213 | /* | 213 | /** |
| 214 | * intel_pmc_ipc_simple_command | 214 | * intel_pmc_ipc_simple_command() - Simple IPC command |
| 215 | * @cmd: command | 215 | * @cmd: IPC command code. |
| 216 | * @sub: sub type | 216 | * @sub: IPC command sub type. |
| 217 | * | ||
| 218 | * Send a simple IPC command to PMC when don't need to specify | ||
| 219 | * input/output data and source/dest pointers. | ||
| 220 | * | ||
| 221 | * Return: an IPC error code or 0 on success. | ||
| 217 | */ | 222 | */ |
| 218 | int intel_pmc_ipc_simple_command(int cmd, int sub) | 223 | int intel_pmc_ipc_simple_command(int cmd, int sub) |
| 219 | { | 224 | { |
| @@ -232,16 +237,20 @@ int intel_pmc_ipc_simple_command(int cmd, int sub) | |||
| 232 | } | 237 | } |
| 233 | EXPORT_SYMBOL_GPL(intel_pmc_ipc_simple_command); | 238 | EXPORT_SYMBOL_GPL(intel_pmc_ipc_simple_command); |
| 234 | 239 | ||
| 235 | /* | 240 | /** |
| 236 | * intel_pmc_ipc_raw_cmd | 241 | * intel_pmc_ipc_raw_cmd() - IPC command with data and pointers |
| 237 | * @cmd: command | 242 | * @cmd: IPC command code. |
| 238 | * @sub: sub type | 243 | * @sub: IPC command sub type. |
| 239 | * @in: input data | 244 | * @in: input data of this IPC command. |
| 240 | * @inlen: input length in bytes | 245 | * @inlen: input data length in bytes. |
| 241 | * @out: output data | 246 | * @out: output data of this IPC command. |
| 242 | * @outlen: output length in dwords | 247 | * @outlen: output data length in dwords. |
| 243 | * @sptr: data writing to SPTR register | 248 | * @sptr: data writing to SPTR register. |
| 244 | * @dptr: data writing to DPTR register | 249 | * @dptr: data writing to DPTR register. |
| 250 | * | ||
| 251 | * Send an IPC command to PMC with input/output data and source/dest pointers. | ||
| 252 | * | ||
| 253 | * Return: an IPC error code or 0 on success. | ||
| 245 | */ | 254 | */ |
| 246 | int intel_pmc_ipc_raw_cmd(u32 cmd, u32 sub, u8 *in, u32 inlen, u32 *out, | 255 | int intel_pmc_ipc_raw_cmd(u32 cmd, u32 sub, u8 *in, u32 inlen, u32 *out, |
| 247 | u32 outlen, u32 dptr, u32 sptr) | 256 | u32 outlen, u32 dptr, u32 sptr) |
| @@ -278,14 +287,18 @@ int intel_pmc_ipc_raw_cmd(u32 cmd, u32 sub, u8 *in, u32 inlen, u32 *out, | |||
| 278 | } | 287 | } |
| 279 | EXPORT_SYMBOL_GPL(intel_pmc_ipc_raw_cmd); | 288 | EXPORT_SYMBOL_GPL(intel_pmc_ipc_raw_cmd); |
| 280 | 289 | ||
| 281 | /* | 290 | /** |
| 282 | * intel_pmc_ipc_command | 291 | * intel_pmc_ipc_command() - IPC command with input/output data |
| 283 | * @cmd: command | 292 | * @cmd: IPC command code. |
| 284 | * @sub: sub type | 293 | * @sub: IPC command sub type. |
| 285 | * @in: input data | 294 | * @in: input data of this IPC command. |
| 286 | * @inlen: input length in bytes | 295 | * @inlen: input data length in bytes. |
| 287 | * @out: output data | 296 | * @out: output data of this IPC command. |
| 288 | * @outlen: output length in dwords | 297 | * @outlen: output data length in dwords. |
| 298 | * | ||
| 299 | * Send an IPC command to PMC with input/output data. | ||
| 300 | * | ||
| 301 | * Return: an IPC error code or 0 on success. | ||
| 289 | */ | 302 | */ |
| 290 | int intel_pmc_ipc_command(u32 cmd, u32 sub, u8 *in, u32 inlen, | 303 | int intel_pmc_ipc_command(u32 cmd, u32 sub, u8 *in, u32 inlen, |
| 291 | u32 *out, u32 outlen) | 304 | u32 *out, u32 outlen) |
| @@ -480,11 +493,11 @@ static int ipc_create_punit_device(void) | |||
| 480 | pdev->dev.parent = ipcdev.dev; | 493 | pdev->dev.parent = ipcdev.dev; |
| 481 | 494 | ||
| 482 | res = punit_res; | 495 | res = punit_res; |
| 483 | res->start = (resource_size_t)ipcdev.punit_base; | 496 | res->start = ipcdev.punit_base; |
| 484 | res->end = res->start + ipcdev.punit_size - 1; | 497 | res->end = res->start + ipcdev.punit_size - 1; |
| 485 | 498 | ||
| 486 | res = punit_res + PUNIT_RESOURCE_INTER; | 499 | res = punit_res + PUNIT_RESOURCE_INTER; |
| 487 | res->start = (resource_size_t)ipcdev.punit_base2; | 500 | res->start = ipcdev.punit_base2; |
| 488 | res->end = res->start + ipcdev.punit_size2 - 1; | 501 | res->end = res->start + ipcdev.punit_size2 - 1; |
| 489 | 502 | ||
| 490 | ret = platform_device_add_resources(pdev, punit_res, | 503 | ret = platform_device_add_resources(pdev, punit_res, |
| @@ -522,15 +535,15 @@ static int ipc_create_tco_device(void) | |||
| 522 | pdev->dev.parent = ipcdev.dev; | 535 | pdev->dev.parent = ipcdev.dev; |
| 523 | 536 | ||
| 524 | res = tco_res + TCO_RESOURCE_ACPI_IO; | 537 | res = tco_res + TCO_RESOURCE_ACPI_IO; |
| 525 | res->start = (resource_size_t)ipcdev.acpi_io_base + TCO_BASE_OFFSET; | 538 | res->start = ipcdev.acpi_io_base + TCO_BASE_OFFSET; |
| 526 | res->end = res->start + TCO_REGS_SIZE - 1; | 539 | res->end = res->start + TCO_REGS_SIZE - 1; |
| 527 | 540 | ||
| 528 | res = tco_res + TCO_RESOURCE_SMI_EN_IO; | 541 | res = tco_res + TCO_RESOURCE_SMI_EN_IO; |
| 529 | res->start = (resource_size_t)ipcdev.acpi_io_base + SMI_EN_OFFSET; | 542 | res->start = ipcdev.acpi_io_base + SMI_EN_OFFSET; |
| 530 | res->end = res->start + SMI_EN_SIZE - 1; | 543 | res->end = res->start + SMI_EN_SIZE - 1; |
| 531 | 544 | ||
| 532 | res = tco_res + TCO_RESOURCE_GCR_MEM; | 545 | res = tco_res + TCO_RESOURCE_GCR_MEM; |
| 533 | res->start = (resource_size_t)ipcdev.gcr_base; | 546 | res->start = ipcdev.gcr_base; |
| 534 | res->end = res->start + ipcdev.gcr_size - 1; | 547 | res->end = res->start + ipcdev.gcr_size - 1; |
| 535 | 548 | ||
| 536 | ret = platform_device_add_resources(pdev, tco_res, ARRAY_SIZE(tco_res)); | 549 | ret = platform_device_add_resources(pdev, tco_res, ARRAY_SIZE(tco_res)); |
| @@ -589,7 +602,7 @@ static int ipc_plat_get_res(struct platform_device *pdev) | |||
| 589 | return -ENXIO; | 602 | return -ENXIO; |
| 590 | } | 603 | } |
| 591 | size = resource_size(res); | 604 | size = resource_size(res); |
| 592 | ipcdev.acpi_io_base = (void *)res->start; | 605 | ipcdev.acpi_io_base = res->start; |
| 593 | ipcdev.acpi_io_size = size; | 606 | ipcdev.acpi_io_size = size; |
| 594 | dev_info(&pdev->dev, "io res: %llx %x\n", | 607 | dev_info(&pdev->dev, "io res: %llx %x\n", |
| 595 | (long long)res->start, (int)resource_size(res)); | 608 | (long long)res->start, (int)resource_size(res)); |
| @@ -601,7 +614,7 @@ static int ipc_plat_get_res(struct platform_device *pdev) | |||
| 601 | return -ENXIO; | 614 | return -ENXIO; |
| 602 | } | 615 | } |
| 603 | size = resource_size(res); | 616 | size = resource_size(res); |
| 604 | ipcdev.punit_base = (void *)res->start; | 617 | ipcdev.punit_base = res->start; |
| 605 | ipcdev.punit_size = size; | 618 | ipcdev.punit_size = size; |
| 606 | dev_info(&pdev->dev, "punit data res: %llx %x\n", | 619 | dev_info(&pdev->dev, "punit data res: %llx %x\n", |
| 607 | (long long)res->start, (int)resource_size(res)); | 620 | (long long)res->start, (int)resource_size(res)); |
| @@ -613,7 +626,7 @@ static int ipc_plat_get_res(struct platform_device *pdev) | |||
| 613 | return -ENXIO; | 626 | return -ENXIO; |
| 614 | } | 627 | } |
| 615 | size = resource_size(res); | 628 | size = resource_size(res); |
| 616 | ipcdev.punit_base2 = (void *)res->start; | 629 | ipcdev.punit_base2 = res->start; |
| 617 | ipcdev.punit_size2 = size; | 630 | ipcdev.punit_size2 = size; |
| 618 | dev_info(&pdev->dev, "punit interface res: %llx %x\n", | 631 | dev_info(&pdev->dev, "punit interface res: %llx %x\n", |
| 619 | (long long)res->start, (int)resource_size(res)); | 632 | (long long)res->start, (int)resource_size(res)); |
| @@ -637,7 +650,7 @@ static int ipc_plat_get_res(struct platform_device *pdev) | |||
| 637 | } | 650 | } |
| 638 | ipcdev.ipc_base = addr; | 651 | ipcdev.ipc_base = addr; |
| 639 | 652 | ||
| 640 | ipcdev.gcr_base = (void *)(res->start + size); | 653 | ipcdev.gcr_base = res->start + size; |
| 641 | ipcdev.gcr_size = PLAT_RESOURCE_GCR_SIZE; | 654 | ipcdev.gcr_size = PLAT_RESOURCE_GCR_SIZE; |
| 642 | dev_info(&pdev->dev, "ipc res: %llx %x\n", | 655 | dev_info(&pdev->dev, "ipc res: %llx %x\n", |
| 643 | (long long)res->start, (int)resource_size(res)); | 656 | (long long)res->start, (int)resource_size(res)); |
diff --git a/drivers/platform/x86/intel_scu_ipc.c b/drivers/platform/x86/intel_scu_ipc.c index 001b199a8c33..187d1086d15c 100644 --- a/drivers/platform/x86/intel_scu_ipc.c +++ b/drivers/platform/x86/intel_scu_ipc.c | |||
| @@ -216,13 +216,13 @@ static int pwr_reg_rdwr(u16 *addr, u8 *data, u32 count, u32 op, u32 id) | |||
| 216 | int nc; | 216 | int nc; |
| 217 | u32 offset = 0; | 217 | u32 offset = 0; |
| 218 | int err; | 218 | int err; |
| 219 | u8 cbuf[IPC_WWBUF_SIZE] = { }; | 219 | u8 cbuf[IPC_WWBUF_SIZE]; |
| 220 | u32 *wbuf = (u32 *)&cbuf; | 220 | u32 *wbuf = (u32 *)&cbuf; |
| 221 | 221 | ||
| 222 | mutex_lock(&ipclock); | ||
| 223 | |||
| 224 | memset(cbuf, 0, sizeof(cbuf)); | 222 | memset(cbuf, 0, sizeof(cbuf)); |
| 225 | 223 | ||
| 224 | mutex_lock(&ipclock); | ||
| 225 | |||
| 226 | if (ipcdev.pdev == NULL) { | 226 | if (ipcdev.pdev == NULL) { |
| 227 | mutex_unlock(&ipclock); | 227 | mutex_unlock(&ipclock); |
| 228 | return -ENODEV; | 228 | return -ENODEV; |
diff --git a/drivers/rtc/rtc-armada38x.c b/drivers/rtc/rtc-armada38x.c index 4b62d1a875e4..2b08cac62f07 100644 --- a/drivers/rtc/rtc-armada38x.c +++ b/drivers/rtc/rtc-armada38x.c | |||
| @@ -88,7 +88,7 @@ static int armada38x_rtc_set_time(struct device *dev, struct rtc_time *tm) | |||
| 88 | { | 88 | { |
| 89 | struct armada38x_rtc *rtc = dev_get_drvdata(dev); | 89 | struct armada38x_rtc *rtc = dev_get_drvdata(dev); |
| 90 | int ret = 0; | 90 | int ret = 0; |
| 91 | unsigned long time, flags; | 91 | unsigned long time; |
| 92 | 92 | ||
| 93 | ret = rtc_tm_to_time(tm, &time); | 93 | ret = rtc_tm_to_time(tm, &time); |
| 94 | 94 | ||
diff --git a/drivers/rtc/rtc-mt6397.c b/drivers/rtc/rtc-mt6397.c index c0090b698ff3..eab230be5a54 100644 --- a/drivers/rtc/rtc-mt6397.c +++ b/drivers/rtc/rtc-mt6397.c | |||
| @@ -343,6 +343,8 @@ static int mtk_rtc_probe(struct platform_device *pdev) | |||
| 343 | goto out_dispose_irq; | 343 | goto out_dispose_irq; |
| 344 | } | 344 | } |
| 345 | 345 | ||
| 346 | device_init_wakeup(&pdev->dev, 1); | ||
| 347 | |||
| 346 | rtc->rtc_dev = rtc_device_register("mt6397-rtc", &pdev->dev, | 348 | rtc->rtc_dev = rtc_device_register("mt6397-rtc", &pdev->dev, |
| 347 | &mtk_rtc_ops, THIS_MODULE); | 349 | &mtk_rtc_ops, THIS_MODULE); |
| 348 | if (IS_ERR(rtc->rtc_dev)) { | 350 | if (IS_ERR(rtc->rtc_dev)) { |
| @@ -351,8 +353,6 @@ static int mtk_rtc_probe(struct platform_device *pdev) | |||
| 351 | goto out_free_irq; | 353 | goto out_free_irq; |
| 352 | } | 354 | } |
| 353 | 355 | ||
| 354 | device_init_wakeup(&pdev->dev, 1); | ||
| 355 | |||
| 356 | return 0; | 356 | return 0; |
| 357 | 357 | ||
| 358 | out_free_irq: | 358 | out_free_irq: |
diff --git a/drivers/s390/block/dasd.c b/drivers/s390/block/dasd.c index 1aec8ff0b587..f73d2f579a7e 100644 --- a/drivers/s390/block/dasd.c +++ b/drivers/s390/block/dasd.c | |||
| @@ -1863,6 +1863,33 @@ static void __dasd_device_check_expire(struct dasd_device *device) | |||
| 1863 | } | 1863 | } |
| 1864 | 1864 | ||
| 1865 | /* | 1865 | /* |
| 1866 | * return 1 when device is not eligible for IO | ||
| 1867 | */ | ||
| 1868 | static int __dasd_device_is_unusable(struct dasd_device *device, | ||
| 1869 | struct dasd_ccw_req *cqr) | ||
| 1870 | { | ||
| 1871 | int mask = ~(DASD_STOPPED_DC_WAIT | DASD_UNRESUMED_PM); | ||
| 1872 | |||
| 1873 | if (test_bit(DASD_FLAG_OFFLINE, &device->flags)) { | ||
| 1874 | /* dasd is being set offline. */ | ||
| 1875 | return 1; | ||
| 1876 | } | ||
| 1877 | if (device->stopped) { | ||
| 1878 | if (device->stopped & mask) { | ||
| 1879 | /* stopped and CQR will not change that. */ | ||
| 1880 | return 1; | ||
| 1881 | } | ||
| 1882 | if (!test_bit(DASD_CQR_VERIFY_PATH, &cqr->flags)) { | ||
| 1883 | /* CQR is not able to change device to | ||
| 1884 | * operational. */ | ||
| 1885 | return 1; | ||
| 1886 | } | ||
| 1887 | /* CQR required to get device operational. */ | ||
| 1888 | } | ||
| 1889 | return 0; | ||
| 1890 | } | ||
| 1891 | |||
| 1892 | /* | ||
| 1866 | * Take a look at the first request on the ccw queue and check | 1893 | * Take a look at the first request on the ccw queue and check |
| 1867 | * if it needs to be started. | 1894 | * if it needs to be started. |
| 1868 | */ | 1895 | */ |
| @@ -1876,13 +1903,8 @@ static void __dasd_device_start_head(struct dasd_device *device) | |||
| 1876 | cqr = list_entry(device->ccw_queue.next, struct dasd_ccw_req, devlist); | 1903 | cqr = list_entry(device->ccw_queue.next, struct dasd_ccw_req, devlist); |
| 1877 | if (cqr->status != DASD_CQR_QUEUED) | 1904 | if (cqr->status != DASD_CQR_QUEUED) |
| 1878 | return; | 1905 | return; |
| 1879 | /* when device is stopped, return request to previous layer | 1906 | /* if device is not usable return request to upper layer */ |
| 1880 | * exception: only the disconnect or unresumed bits are set and the | 1907 | if (__dasd_device_is_unusable(device, cqr)) { |
| 1881 | * cqr is a path verification request | ||
| 1882 | */ | ||
| 1883 | if (device->stopped && | ||
| 1884 | !(!(device->stopped & ~(DASD_STOPPED_DC_WAIT | DASD_UNRESUMED_PM)) | ||
| 1885 | && test_bit(DASD_CQR_VERIFY_PATH, &cqr->flags))) { | ||
| 1886 | cqr->intrc = -EAGAIN; | 1908 | cqr->intrc = -EAGAIN; |
| 1887 | cqr->status = DASD_CQR_CLEARED; | 1909 | cqr->status = DASD_CQR_CLEARED; |
| 1888 | dasd_schedule_device_bh(device); | 1910 | dasd_schedule_device_bh(device); |
diff --git a/drivers/s390/block/dasd_alias.c b/drivers/s390/block/dasd_alias.c index a2597e683e79..ee3a6faae22a 100644 --- a/drivers/s390/block/dasd_alias.c +++ b/drivers/s390/block/dasd_alias.c | |||
| @@ -699,7 +699,8 @@ struct dasd_device *dasd_alias_get_start_dev(struct dasd_device *base_device) | |||
| 699 | struct dasd_device, alias_list); | 699 | struct dasd_device, alias_list); |
| 700 | spin_unlock_irqrestore(&lcu->lock, flags); | 700 | spin_unlock_irqrestore(&lcu->lock, flags); |
| 701 | alias_priv = (struct dasd_eckd_private *) alias_device->private; | 701 | alias_priv = (struct dasd_eckd_private *) alias_device->private; |
| 702 | if ((alias_priv->count < private->count) && !alias_device->stopped) | 702 | if ((alias_priv->count < private->count) && !alias_device->stopped && |
| 703 | !test_bit(DASD_FLAG_OFFLINE, &alias_device->flags)) | ||
| 703 | return alias_device; | 704 | return alias_device; |
| 704 | else | 705 | else |
| 705 | return NULL; | 706 | return NULL; |
diff --git a/drivers/s390/char/sclp_early.c b/drivers/s390/char/sclp_early.c index aeed7969fd79..7bc6df3100ef 100644 --- a/drivers/s390/char/sclp_early.c +++ b/drivers/s390/char/sclp_early.c | |||
| @@ -7,6 +7,7 @@ | |||
| 7 | #define KMSG_COMPONENT "sclp_early" | 7 | #define KMSG_COMPONENT "sclp_early" |
| 8 | #define pr_fmt(fmt) KMSG_COMPONENT ": " fmt | 8 | #define pr_fmt(fmt) KMSG_COMPONENT ": " fmt |
| 9 | 9 | ||
| 10 | #include <linux/errno.h> | ||
| 10 | #include <asm/ctl_reg.h> | 11 | #include <asm/ctl_reg.h> |
| 11 | #include <asm/sclp.h> | 12 | #include <asm/sclp.h> |
| 12 | #include <asm/ipl.h> | 13 | #include <asm/ipl.h> |
diff --git a/drivers/s390/crypto/zcrypt_api.c b/drivers/s390/crypto/zcrypt_api.c index 08f1830cbfc4..01bf1f5cf2e9 100644 --- a/drivers/s390/crypto/zcrypt_api.c +++ b/drivers/s390/crypto/zcrypt_api.c | |||
| @@ -54,6 +54,10 @@ MODULE_DESCRIPTION("Cryptographic Coprocessor interface, " \ | |||
| 54 | "Copyright IBM Corp. 2001, 2012"); | 54 | "Copyright IBM Corp. 2001, 2012"); |
| 55 | MODULE_LICENSE("GPL"); | 55 | MODULE_LICENSE("GPL"); |
| 56 | 56 | ||
| 57 | static int zcrypt_hwrng_seed = 1; | ||
| 58 | module_param_named(hwrng_seed, zcrypt_hwrng_seed, int, S_IRUSR|S_IRGRP); | ||
| 59 | MODULE_PARM_DESC(hwrng_seed, "Turn on/off hwrng auto seed, default is 1 (on)."); | ||
| 60 | |||
| 57 | static DEFINE_SPINLOCK(zcrypt_device_lock); | 61 | static DEFINE_SPINLOCK(zcrypt_device_lock); |
| 58 | static LIST_HEAD(zcrypt_device_list); | 62 | static LIST_HEAD(zcrypt_device_list); |
| 59 | static int zcrypt_device_count = 0; | 63 | static int zcrypt_device_count = 0; |
| @@ -1373,6 +1377,7 @@ static int zcrypt_rng_data_read(struct hwrng *rng, u32 *data) | |||
| 1373 | static struct hwrng zcrypt_rng_dev = { | 1377 | static struct hwrng zcrypt_rng_dev = { |
| 1374 | .name = "zcrypt", | 1378 | .name = "zcrypt", |
| 1375 | .data_read = zcrypt_rng_data_read, | 1379 | .data_read = zcrypt_rng_data_read, |
| 1380 | .quality = 990, | ||
| 1376 | }; | 1381 | }; |
| 1377 | 1382 | ||
| 1378 | static int zcrypt_rng_device_add(void) | 1383 | static int zcrypt_rng_device_add(void) |
| @@ -1387,6 +1392,8 @@ static int zcrypt_rng_device_add(void) | |||
| 1387 | goto out; | 1392 | goto out; |
| 1388 | } | 1393 | } |
| 1389 | zcrypt_rng_buffer_index = 0; | 1394 | zcrypt_rng_buffer_index = 0; |
| 1395 | if (!zcrypt_hwrng_seed) | ||
| 1396 | zcrypt_rng_dev.quality = 0; | ||
| 1390 | rc = hwrng_register(&zcrypt_rng_dev); | 1397 | rc = hwrng_register(&zcrypt_rng_dev); |
| 1391 | if (rc) | 1398 | if (rc) |
| 1392 | goto out_free; | 1399 | goto out_free; |
diff --git a/drivers/scsi/scsi_sysfs.c b/drivers/scsi/scsi_sysfs.c index 1ac38e73df7e..9ad41168d26d 100644 --- a/drivers/scsi/scsi_sysfs.c +++ b/drivers/scsi/scsi_sysfs.c | |||
| @@ -859,7 +859,7 @@ sdev_store_queue_depth(struct device *dev, struct device_attribute *attr, | |||
| 859 | 859 | ||
| 860 | depth = simple_strtoul(buf, NULL, 0); | 860 | depth = simple_strtoul(buf, NULL, 0); |
| 861 | 861 | ||
| 862 | if (depth < 1 || depth > sht->can_queue) | 862 | if (depth < 1 || depth > sdev->host->can_queue) |
| 863 | return -EINVAL; | 863 | return -EINVAL; |
| 864 | 864 | ||
| 865 | retval = sht->change_queue_depth(sdev, depth); | 865 | retval = sht->change_queue_depth(sdev, depth); |
diff --git a/drivers/scsi/scsi_transport_srp.c b/drivers/scsi/scsi_transport_srp.c index a85292b1d09d..e3cd3ece4412 100644 --- a/drivers/scsi/scsi_transport_srp.c +++ b/drivers/scsi/scsi_transport_srp.c | |||
| @@ -203,7 +203,7 @@ static ssize_t srp_show_tmo(char *buf, int tmo) | |||
| 203 | return tmo >= 0 ? sprintf(buf, "%d\n", tmo) : sprintf(buf, "off\n"); | 203 | return tmo >= 0 ? sprintf(buf, "%d\n", tmo) : sprintf(buf, "off\n"); |
| 204 | } | 204 | } |
| 205 | 205 | ||
| 206 | static int srp_parse_tmo(int *tmo, const char *buf) | 206 | int srp_parse_tmo(int *tmo, const char *buf) |
| 207 | { | 207 | { |
| 208 | int res = 0; | 208 | int res = 0; |
| 209 | 209 | ||
| @@ -214,6 +214,7 @@ static int srp_parse_tmo(int *tmo, const char *buf) | |||
| 214 | 214 | ||
| 215 | return res; | 215 | return res; |
| 216 | } | 216 | } |
| 217 | EXPORT_SYMBOL(srp_parse_tmo); | ||
| 217 | 218 | ||
| 218 | static ssize_t show_reconnect_delay(struct device *dev, | 219 | static ssize_t show_reconnect_delay(struct device *dev, |
| 219 | struct device_attribute *attr, char *buf) | 220 | struct device_attribute *attr, char *buf) |
diff --git a/drivers/scsi/st.c b/drivers/scsi/st.c index 3f25b8fa921d..871f3553987d 100644 --- a/drivers/scsi/st.c +++ b/drivers/scsi/st.c | |||
| @@ -1329,9 +1329,9 @@ static int st_open(struct inode *inode, struct file *filp) | |||
| 1329 | spin_lock(&st_use_lock); | 1329 | spin_lock(&st_use_lock); |
| 1330 | STp->in_use = 0; | 1330 | STp->in_use = 0; |
| 1331 | spin_unlock(&st_use_lock); | 1331 | spin_unlock(&st_use_lock); |
| 1332 | scsi_tape_put(STp); | ||
| 1333 | if (resumed) | 1332 | if (resumed) |
| 1334 | scsi_autopm_put_device(STp->device); | 1333 | scsi_autopm_put_device(STp->device); |
| 1334 | scsi_tape_put(STp); | ||
| 1335 | return retval; | 1335 | return retval; |
| 1336 | 1336 | ||
| 1337 | } | 1337 | } |
diff --git a/drivers/staging/board/Kconfig b/drivers/staging/board/Kconfig index b8ee81840666..3f287c48e082 100644 --- a/drivers/staging/board/Kconfig +++ b/drivers/staging/board/Kconfig | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | config STAGING_BOARD | 1 | config STAGING_BOARD |
| 2 | bool "Staging Board Support" | 2 | bool "Staging Board Support" |
| 3 | depends on OF_ADDRESS | 3 | depends on OF_ADDRESS && OF_IRQ && CLKDEV_LOOKUP |
| 4 | help | 4 | help |
| 5 | Select to enable per-board staging support code. | 5 | Select to enable per-board staging support code. |
| 6 | 6 | ||
diff --git a/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.h b/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.h index 7125eb955ae5..8a9d4a0de129 100644 --- a/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.h +++ b/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.h | |||
| @@ -31,7 +31,6 @@ | |||
| 31 | #define DEBUG_PORTAL_ALLOC | 31 | #define DEBUG_PORTAL_ALLOC |
| 32 | #define DEBUG_SUBSYSTEM S_LND | 32 | #define DEBUG_SUBSYSTEM S_LND |
| 33 | 33 | ||
| 34 | #include <asm/irq.h> | ||
| 35 | #include <linux/crc32.h> | 34 | #include <linux/crc32.h> |
| 36 | #include <linux/errno.h> | 35 | #include <linux/errno.h> |
| 37 | #include <linux/if.h> | 36 | #include <linux/if.h> |
diff --git a/drivers/staging/vt6655/device_main.c b/drivers/staging/vt6655/device_main.c index ed040fbb7df8..b0c8e235b982 100644 --- a/drivers/staging/vt6655/device_main.c +++ b/drivers/staging/vt6655/device_main.c | |||
| @@ -1418,7 +1418,7 @@ static void vnt_bss_info_changed(struct ieee80211_hw *hw, | |||
| 1418 | 1418 | ||
| 1419 | priv->current_aid = conf->aid; | 1419 | priv->current_aid = conf->aid; |
| 1420 | 1420 | ||
| 1421 | if (changed & BSS_CHANGED_BSSID) { | 1421 | if (changed & BSS_CHANGED_BSSID && conf->bssid) { |
| 1422 | unsigned long flags; | 1422 | unsigned long flags; |
| 1423 | 1423 | ||
| 1424 | spin_lock_irqsave(&priv->lock, flags); | 1424 | spin_lock_irqsave(&priv->lock, flags); |
diff --git a/drivers/staging/vt6656/main_usb.c b/drivers/staging/vt6656/main_usb.c index f97323f19acf..af572d718135 100644 --- a/drivers/staging/vt6656/main_usb.c +++ b/drivers/staging/vt6656/main_usb.c | |||
| @@ -701,7 +701,7 @@ static void vnt_bss_info_changed(struct ieee80211_hw *hw, | |||
| 701 | 701 | ||
| 702 | priv->current_aid = conf->aid; | 702 | priv->current_aid = conf->aid; |
| 703 | 703 | ||
| 704 | if (changed & BSS_CHANGED_BSSID) | 704 | if (changed & BSS_CHANGED_BSSID && conf->bssid) |
| 705 | vnt_mac_set_bssid_addr(priv, (u8 *)conf->bssid); | 705 | vnt_mac_set_bssid_addr(priv, (u8 *)conf->bssid); |
| 706 | 706 | ||
| 707 | 707 | ||
diff --git a/drivers/usb/dwc2/core.c b/drivers/usb/dwc2/core.c index e5b546f1152e..c3cc1a78d1e2 100644 --- a/drivers/usb/dwc2/core.c +++ b/drivers/usb/dwc2/core.c | |||
| @@ -72,17 +72,7 @@ static int dwc2_backup_host_registers(struct dwc2_hsotg *hsotg) | |||
| 72 | dev_dbg(hsotg->dev, "%s\n", __func__); | 72 | dev_dbg(hsotg->dev, "%s\n", __func__); |
| 73 | 73 | ||
| 74 | /* Backup Host regs */ | 74 | /* Backup Host regs */ |
| 75 | hr = hsotg->hr_backup; | 75 | hr = &hsotg->hr_backup; |
| 76 | if (!hr) { | ||
| 77 | hr = devm_kzalloc(hsotg->dev, sizeof(*hr), GFP_KERNEL); | ||
| 78 | if (!hr) { | ||
| 79 | dev_err(hsotg->dev, "%s: can't allocate host regs\n", | ||
| 80 | __func__); | ||
| 81 | return -ENOMEM; | ||
| 82 | } | ||
| 83 | |||
| 84 | hsotg->hr_backup = hr; | ||
| 85 | } | ||
| 86 | hr->hcfg = readl(hsotg->regs + HCFG); | 76 | hr->hcfg = readl(hsotg->regs + HCFG); |
| 87 | hr->haintmsk = readl(hsotg->regs + HAINTMSK); | 77 | hr->haintmsk = readl(hsotg->regs + HAINTMSK); |
| 88 | for (i = 0; i < hsotg->core_params->host_channels; ++i) | 78 | for (i = 0; i < hsotg->core_params->host_channels; ++i) |
| @@ -90,6 +80,7 @@ static int dwc2_backup_host_registers(struct dwc2_hsotg *hsotg) | |||
| 90 | 80 | ||
| 91 | hr->hprt0 = readl(hsotg->regs + HPRT0); | 81 | hr->hprt0 = readl(hsotg->regs + HPRT0); |
| 92 | hr->hfir = readl(hsotg->regs + HFIR); | 82 | hr->hfir = readl(hsotg->regs + HFIR); |
| 83 | hr->valid = true; | ||
| 93 | 84 | ||
| 94 | return 0; | 85 | return 0; |
| 95 | } | 86 | } |
| @@ -109,12 +100,13 @@ static int dwc2_restore_host_registers(struct dwc2_hsotg *hsotg) | |||
| 109 | dev_dbg(hsotg->dev, "%s\n", __func__); | 100 | dev_dbg(hsotg->dev, "%s\n", __func__); |
| 110 | 101 | ||
| 111 | /* Restore host regs */ | 102 | /* Restore host regs */ |
| 112 | hr = hsotg->hr_backup; | 103 | hr = &hsotg->hr_backup; |
| 113 | if (!hr) { | 104 | if (!hr->valid) { |
| 114 | dev_err(hsotg->dev, "%s: no host registers to restore\n", | 105 | dev_err(hsotg->dev, "%s: no host registers to restore\n", |
| 115 | __func__); | 106 | __func__); |
| 116 | return -EINVAL; | 107 | return -EINVAL; |
| 117 | } | 108 | } |
| 109 | hr->valid = false; | ||
| 118 | 110 | ||
| 119 | writel(hr->hcfg, hsotg->regs + HCFG); | 111 | writel(hr->hcfg, hsotg->regs + HCFG); |
| 120 | writel(hr->haintmsk, hsotg->regs + HAINTMSK); | 112 | writel(hr->haintmsk, hsotg->regs + HAINTMSK); |
| @@ -152,17 +144,7 @@ static int dwc2_backup_device_registers(struct dwc2_hsotg *hsotg) | |||
| 152 | dev_dbg(hsotg->dev, "%s\n", __func__); | 144 | dev_dbg(hsotg->dev, "%s\n", __func__); |
| 153 | 145 | ||
| 154 | /* Backup dev regs */ | 146 | /* Backup dev regs */ |
| 155 | dr = hsotg->dr_backup; | 147 | dr = &hsotg->dr_backup; |
| 156 | if (!dr) { | ||
| 157 | dr = devm_kzalloc(hsotg->dev, sizeof(*dr), GFP_KERNEL); | ||
| 158 | if (!dr) { | ||
| 159 | dev_err(hsotg->dev, "%s: can't allocate device regs\n", | ||
| 160 | __func__); | ||
| 161 | return -ENOMEM; | ||
| 162 | } | ||
| 163 | |||
| 164 | hsotg->dr_backup = dr; | ||
| 165 | } | ||
| 166 | 148 | ||
| 167 | dr->dcfg = readl(hsotg->regs + DCFG); | 149 | dr->dcfg = readl(hsotg->regs + DCFG); |
| 168 | dr->dctl = readl(hsotg->regs + DCTL); | 150 | dr->dctl = readl(hsotg->regs + DCTL); |
| @@ -195,7 +177,7 @@ static int dwc2_backup_device_registers(struct dwc2_hsotg *hsotg) | |||
| 195 | dr->doeptsiz[i] = readl(hsotg->regs + DOEPTSIZ(i)); | 177 | dr->doeptsiz[i] = readl(hsotg->regs + DOEPTSIZ(i)); |
| 196 | dr->doepdma[i] = readl(hsotg->regs + DOEPDMA(i)); | 178 | dr->doepdma[i] = readl(hsotg->regs + DOEPDMA(i)); |
| 197 | } | 179 | } |
| 198 | 180 | dr->valid = true; | |
| 199 | return 0; | 181 | return 0; |
| 200 | } | 182 | } |
| 201 | 183 | ||
| @@ -215,12 +197,13 @@ static int dwc2_restore_device_registers(struct dwc2_hsotg *hsotg) | |||
| 215 | dev_dbg(hsotg->dev, "%s\n", __func__); | 197 | dev_dbg(hsotg->dev, "%s\n", __func__); |
| 216 | 198 | ||
| 217 | /* Restore dev regs */ | 199 | /* Restore dev regs */ |
| 218 | dr = hsotg->dr_backup; | 200 | dr = &hsotg->dr_backup; |
| 219 | if (!dr) { | 201 | if (!dr->valid) { |
| 220 | dev_err(hsotg->dev, "%s: no device registers to restore\n", | 202 | dev_err(hsotg->dev, "%s: no device registers to restore\n", |
| 221 | __func__); | 203 | __func__); |
| 222 | return -EINVAL; | 204 | return -EINVAL; |
| 223 | } | 205 | } |
| 206 | dr->valid = false; | ||
| 224 | 207 | ||
| 225 | writel(dr->dcfg, hsotg->regs + DCFG); | 208 | writel(dr->dcfg, hsotg->regs + DCFG); |
| 226 | writel(dr->dctl, hsotg->regs + DCTL); | 209 | writel(dr->dctl, hsotg->regs + DCTL); |
| @@ -268,17 +251,7 @@ static int dwc2_backup_global_registers(struct dwc2_hsotg *hsotg) | |||
| 268 | int i; | 251 | int i; |
| 269 | 252 | ||
| 270 | /* Backup global regs */ | 253 | /* Backup global regs */ |
| 271 | gr = hsotg->gr_backup; | 254 | gr = &hsotg->gr_backup; |
| 272 | if (!gr) { | ||
| 273 | gr = devm_kzalloc(hsotg->dev, sizeof(*gr), GFP_KERNEL); | ||
| 274 | if (!gr) { | ||
| 275 | dev_err(hsotg->dev, "%s: can't allocate global regs\n", | ||
| 276 | __func__); | ||
| 277 | return -ENOMEM; | ||
| 278 | } | ||
| 279 | |||
| 280 | hsotg->gr_backup = gr; | ||
| 281 | } | ||
| 282 | 255 | ||
| 283 | gr->gotgctl = readl(hsotg->regs + GOTGCTL); | 256 | gr->gotgctl = readl(hsotg->regs + GOTGCTL); |
| 284 | gr->gintmsk = readl(hsotg->regs + GINTMSK); | 257 | gr->gintmsk = readl(hsotg->regs + GINTMSK); |
| @@ -291,6 +264,7 @@ static int dwc2_backup_global_registers(struct dwc2_hsotg *hsotg) | |||
| 291 | for (i = 0; i < MAX_EPS_CHANNELS; i++) | 264 | for (i = 0; i < MAX_EPS_CHANNELS; i++) |
| 292 | gr->dtxfsiz[i] = readl(hsotg->regs + DPTXFSIZN(i)); | 265 | gr->dtxfsiz[i] = readl(hsotg->regs + DPTXFSIZN(i)); |
| 293 | 266 | ||
| 267 | gr->valid = true; | ||
| 294 | return 0; | 268 | return 0; |
| 295 | } | 269 | } |
| 296 | 270 | ||
| @@ -309,12 +283,13 @@ static int dwc2_restore_global_registers(struct dwc2_hsotg *hsotg) | |||
| 309 | dev_dbg(hsotg->dev, "%s\n", __func__); | 283 | dev_dbg(hsotg->dev, "%s\n", __func__); |
| 310 | 284 | ||
| 311 | /* Restore global regs */ | 285 | /* Restore global regs */ |
| 312 | gr = hsotg->gr_backup; | 286 | gr = &hsotg->gr_backup; |
| 313 | if (!gr) { | 287 | if (!gr->valid) { |
| 314 | dev_err(hsotg->dev, "%s: no global registers to restore\n", | 288 | dev_err(hsotg->dev, "%s: no global registers to restore\n", |
| 315 | __func__); | 289 | __func__); |
| 316 | return -EINVAL; | 290 | return -EINVAL; |
| 317 | } | 291 | } |
| 292 | gr->valid = false; | ||
| 318 | 293 | ||
| 319 | writel(0xffffffff, hsotg->regs + GINTSTS); | 294 | writel(0xffffffff, hsotg->regs + GINTSTS); |
| 320 | writel(gr->gotgctl, hsotg->regs + GOTGCTL); | 295 | writel(gr->gotgctl, hsotg->regs + GOTGCTL); |
diff --git a/drivers/usb/dwc2/core.h b/drivers/usb/dwc2/core.h index 53b8de03f102..0ed87620941b 100644 --- a/drivers/usb/dwc2/core.h +++ b/drivers/usb/dwc2/core.h | |||
| @@ -492,6 +492,7 @@ struct dwc2_gregs_backup { | |||
| 492 | u32 gdfifocfg; | 492 | u32 gdfifocfg; |
| 493 | u32 dtxfsiz[MAX_EPS_CHANNELS]; | 493 | u32 dtxfsiz[MAX_EPS_CHANNELS]; |
| 494 | u32 gpwrdn; | 494 | u32 gpwrdn; |
| 495 | bool valid; | ||
| 495 | }; | 496 | }; |
| 496 | 497 | ||
| 497 | /** | 498 | /** |
| @@ -521,6 +522,7 @@ struct dwc2_dregs_backup { | |||
| 521 | u32 doepctl[MAX_EPS_CHANNELS]; | 522 | u32 doepctl[MAX_EPS_CHANNELS]; |
| 522 | u32 doeptsiz[MAX_EPS_CHANNELS]; | 523 | u32 doeptsiz[MAX_EPS_CHANNELS]; |
| 523 | u32 doepdma[MAX_EPS_CHANNELS]; | 524 | u32 doepdma[MAX_EPS_CHANNELS]; |
| 525 | bool valid; | ||
| 524 | }; | 526 | }; |
| 525 | 527 | ||
| 526 | /** | 528 | /** |
| @@ -538,6 +540,7 @@ struct dwc2_hregs_backup { | |||
| 538 | u32 hcintmsk[MAX_EPS_CHANNELS]; | 540 | u32 hcintmsk[MAX_EPS_CHANNELS]; |
| 539 | u32 hprt0; | 541 | u32 hprt0; |
| 540 | u32 hfir; | 542 | u32 hfir; |
| 543 | bool valid; | ||
| 541 | }; | 544 | }; |
| 542 | 545 | ||
| 543 | /** | 546 | /** |
| @@ -705,9 +708,9 @@ struct dwc2_hsotg { | |||
| 705 | struct work_struct wf_otg; | 708 | struct work_struct wf_otg; |
| 706 | struct timer_list wkp_timer; | 709 | struct timer_list wkp_timer; |
| 707 | enum dwc2_lx_state lx_state; | 710 | enum dwc2_lx_state lx_state; |
| 708 | struct dwc2_gregs_backup *gr_backup; | 711 | struct dwc2_gregs_backup gr_backup; |
| 709 | struct dwc2_dregs_backup *dr_backup; | 712 | struct dwc2_dregs_backup dr_backup; |
| 710 | struct dwc2_hregs_backup *hr_backup; | 713 | struct dwc2_hregs_backup hr_backup; |
| 711 | 714 | ||
| 712 | struct dentry *debug_root; | 715 | struct dentry *debug_root; |
| 713 | struct debugfs_regset32 *regset; | 716 | struct debugfs_regset32 *regset; |
diff --git a/drivers/usb/dwc2/hcd.c b/drivers/usb/dwc2/hcd.c index b10377c65064..f845c41fe9e5 100644 --- a/drivers/usb/dwc2/hcd.c +++ b/drivers/usb/dwc2/hcd.c | |||
| @@ -359,10 +359,9 @@ void dwc2_hcd_stop(struct dwc2_hsotg *hsotg) | |||
| 359 | 359 | ||
| 360 | /* Caller must hold driver lock */ | 360 | /* Caller must hold driver lock */ |
| 361 | static int dwc2_hcd_urb_enqueue(struct dwc2_hsotg *hsotg, | 361 | static int dwc2_hcd_urb_enqueue(struct dwc2_hsotg *hsotg, |
| 362 | struct dwc2_hcd_urb *urb, void **ep_handle, | 362 | struct dwc2_hcd_urb *urb, struct dwc2_qh *qh, |
| 363 | gfp_t mem_flags) | 363 | struct dwc2_qtd *qtd) |
| 364 | { | 364 | { |
| 365 | struct dwc2_qtd *qtd; | ||
| 366 | u32 intr_mask; | 365 | u32 intr_mask; |
| 367 | int retval; | 366 | int retval; |
| 368 | int dev_speed; | 367 | int dev_speed; |
| @@ -386,18 +385,15 @@ static int dwc2_hcd_urb_enqueue(struct dwc2_hsotg *hsotg, | |||
| 386 | return -ENODEV; | 385 | return -ENODEV; |
| 387 | } | 386 | } |
| 388 | 387 | ||
| 389 | qtd = kzalloc(sizeof(*qtd), mem_flags); | ||
| 390 | if (!qtd) | 388 | if (!qtd) |
| 391 | return -ENOMEM; | 389 | return -EINVAL; |
| 392 | 390 | ||
| 393 | dwc2_hcd_qtd_init(qtd, urb); | 391 | dwc2_hcd_qtd_init(qtd, urb); |
| 394 | retval = dwc2_hcd_qtd_add(hsotg, qtd, (struct dwc2_qh **)ep_handle, | 392 | retval = dwc2_hcd_qtd_add(hsotg, qtd, qh); |
| 395 | mem_flags); | ||
| 396 | if (retval) { | 393 | if (retval) { |
| 397 | dev_err(hsotg->dev, | 394 | dev_err(hsotg->dev, |
| 398 | "DWC OTG HCD URB Enqueue failed adding QTD. Error status %d\n", | 395 | "DWC OTG HCD URB Enqueue failed adding QTD. Error status %d\n", |
| 399 | retval); | 396 | retval); |
| 400 | kfree(qtd); | ||
| 401 | return retval; | 397 | return retval; |
| 402 | } | 398 | } |
| 403 | 399 | ||
| @@ -2445,6 +2441,9 @@ static int _dwc2_hcd_urb_enqueue(struct usb_hcd *hcd, struct urb *urb, | |||
| 2445 | u32 tflags = 0; | 2441 | u32 tflags = 0; |
| 2446 | void *buf; | 2442 | void *buf; |
| 2447 | unsigned long flags; | 2443 | unsigned long flags; |
| 2444 | struct dwc2_qh *qh; | ||
| 2445 | bool qh_allocated = false; | ||
| 2446 | struct dwc2_qtd *qtd; | ||
| 2448 | 2447 | ||
| 2449 | if (dbg_urb(urb)) { | 2448 | if (dbg_urb(urb)) { |
| 2450 | dev_vdbg(hsotg->dev, "DWC OTG HCD URB Enqueue\n"); | 2449 | dev_vdbg(hsotg->dev, "DWC OTG HCD URB Enqueue\n"); |
| @@ -2523,15 +2522,32 @@ static int _dwc2_hcd_urb_enqueue(struct usb_hcd *hcd, struct urb *urb, | |||
| 2523 | urb->iso_frame_desc[i].length); | 2522 | urb->iso_frame_desc[i].length); |
| 2524 | 2523 | ||
| 2525 | urb->hcpriv = dwc2_urb; | 2524 | urb->hcpriv = dwc2_urb; |
| 2525 | qh = (struct dwc2_qh *) ep->hcpriv; | ||
| 2526 | /* Create QH for the endpoint if it doesn't exist */ | ||
| 2527 | if (!qh) { | ||
| 2528 | qh = dwc2_hcd_qh_create(hsotg, dwc2_urb, mem_flags); | ||
| 2529 | if (!qh) { | ||
| 2530 | retval = -ENOMEM; | ||
| 2531 | goto fail0; | ||
| 2532 | } | ||
| 2533 | ep->hcpriv = qh; | ||
| 2534 | qh_allocated = true; | ||
| 2535 | } | ||
| 2536 | |||
| 2537 | qtd = kzalloc(sizeof(*qtd), mem_flags); | ||
| 2538 | if (!qtd) { | ||
| 2539 | retval = -ENOMEM; | ||
| 2540 | goto fail1; | ||
| 2541 | } | ||
| 2526 | 2542 | ||
| 2527 | spin_lock_irqsave(&hsotg->lock, flags); | 2543 | spin_lock_irqsave(&hsotg->lock, flags); |
| 2528 | retval = usb_hcd_link_urb_to_ep(hcd, urb); | 2544 | retval = usb_hcd_link_urb_to_ep(hcd, urb); |
| 2529 | if (retval) | 2545 | if (retval) |
| 2530 | goto fail1; | 2546 | goto fail2; |
| 2531 | 2547 | ||
| 2532 | retval = dwc2_hcd_urb_enqueue(hsotg, dwc2_urb, &ep->hcpriv, mem_flags); | 2548 | retval = dwc2_hcd_urb_enqueue(hsotg, dwc2_urb, qh, qtd); |
| 2533 | if (retval) | 2549 | if (retval) |
| 2534 | goto fail2; | 2550 | goto fail3; |
| 2535 | 2551 | ||
| 2536 | if (alloc_bandwidth) { | 2552 | if (alloc_bandwidth) { |
| 2537 | dwc2_allocate_bus_bandwidth(hcd, | 2553 | dwc2_allocate_bus_bandwidth(hcd, |
| @@ -2543,12 +2559,25 @@ static int _dwc2_hcd_urb_enqueue(struct usb_hcd *hcd, struct urb *urb, | |||
| 2543 | 2559 | ||
| 2544 | return 0; | 2560 | return 0; |
| 2545 | 2561 | ||
| 2546 | fail2: | 2562 | fail3: |
| 2547 | dwc2_urb->priv = NULL; | 2563 | dwc2_urb->priv = NULL; |
| 2548 | usb_hcd_unlink_urb_from_ep(hcd, urb); | 2564 | usb_hcd_unlink_urb_from_ep(hcd, urb); |
| 2549 | fail1: | 2565 | fail2: |
| 2550 | spin_unlock_irqrestore(&hsotg->lock, flags); | 2566 | spin_unlock_irqrestore(&hsotg->lock, flags); |
| 2551 | urb->hcpriv = NULL; | 2567 | urb->hcpriv = NULL; |
| 2568 | kfree(qtd); | ||
| 2569 | fail1: | ||
| 2570 | if (qh_allocated) { | ||
| 2571 | struct dwc2_qtd *qtd2, *qtd2_tmp; | ||
| 2572 | |||
| 2573 | ep->hcpriv = NULL; | ||
| 2574 | dwc2_hcd_qh_unlink(hsotg, qh); | ||
| 2575 | /* Free each QTD in the QH's QTD list */ | ||
| 2576 | list_for_each_entry_safe(qtd2, qtd2_tmp, &qh->qtd_list, | ||
| 2577 | qtd_list_entry) | ||
| 2578 | dwc2_hcd_qtd_unlink_and_free(hsotg, qtd2, qh); | ||
| 2579 | dwc2_hcd_qh_free(hsotg, qh); | ||
| 2580 | } | ||
| 2552 | fail0: | 2581 | fail0: |
| 2553 | kfree(dwc2_urb); | 2582 | kfree(dwc2_urb); |
| 2554 | 2583 | ||
diff --git a/drivers/usb/dwc2/hcd.h b/drivers/usb/dwc2/hcd.h index 7b5841c40033..fc1054965552 100644 --- a/drivers/usb/dwc2/hcd.h +++ b/drivers/usb/dwc2/hcd.h | |||
| @@ -463,6 +463,9 @@ extern void dwc2_hcd_queue_transactions(struct dwc2_hsotg *hsotg, | |||
| 463 | /* Schedule Queue Functions */ | 463 | /* Schedule Queue Functions */ |
| 464 | /* Implemented in hcd_queue.c */ | 464 | /* Implemented in hcd_queue.c */ |
| 465 | extern void dwc2_hcd_init_usecs(struct dwc2_hsotg *hsotg); | 465 | extern void dwc2_hcd_init_usecs(struct dwc2_hsotg *hsotg); |
| 466 | extern struct dwc2_qh *dwc2_hcd_qh_create(struct dwc2_hsotg *hsotg, | ||
| 467 | struct dwc2_hcd_urb *urb, | ||
| 468 | gfp_t mem_flags); | ||
| 466 | extern void dwc2_hcd_qh_free(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh); | 469 | extern void dwc2_hcd_qh_free(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh); |
| 467 | extern int dwc2_hcd_qh_add(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh); | 470 | extern int dwc2_hcd_qh_add(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh); |
| 468 | extern void dwc2_hcd_qh_unlink(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh); | 471 | extern void dwc2_hcd_qh_unlink(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh); |
| @@ -471,7 +474,7 @@ extern void dwc2_hcd_qh_deactivate(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh, | |||
| 471 | 474 | ||
| 472 | extern void dwc2_hcd_qtd_init(struct dwc2_qtd *qtd, struct dwc2_hcd_urb *urb); | 475 | extern void dwc2_hcd_qtd_init(struct dwc2_qtd *qtd, struct dwc2_hcd_urb *urb); |
| 473 | extern int dwc2_hcd_qtd_add(struct dwc2_hsotg *hsotg, struct dwc2_qtd *qtd, | 476 | extern int dwc2_hcd_qtd_add(struct dwc2_hsotg *hsotg, struct dwc2_qtd *qtd, |
| 474 | struct dwc2_qh **qh, gfp_t mem_flags); | 477 | struct dwc2_qh *qh); |
| 475 | 478 | ||
| 476 | /* Unlinks and frees a QTD */ | 479 | /* Unlinks and frees a QTD */ |
| 477 | static inline void dwc2_hcd_qtd_unlink_and_free(struct dwc2_hsotg *hsotg, | 480 | static inline void dwc2_hcd_qtd_unlink_and_free(struct dwc2_hsotg *hsotg, |
diff --git a/drivers/usb/dwc2/hcd_queue.c b/drivers/usb/dwc2/hcd_queue.c index 9b5c36256627..3ad63d392e13 100644 --- a/drivers/usb/dwc2/hcd_queue.c +++ b/drivers/usb/dwc2/hcd_queue.c | |||
| @@ -191,7 +191,7 @@ static void dwc2_qh_init(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh, | |||
| 191 | * | 191 | * |
| 192 | * Return: Pointer to the newly allocated QH, or NULL on error | 192 | * Return: Pointer to the newly allocated QH, or NULL on error |
| 193 | */ | 193 | */ |
| 194 | static struct dwc2_qh *dwc2_hcd_qh_create(struct dwc2_hsotg *hsotg, | 194 | struct dwc2_qh *dwc2_hcd_qh_create(struct dwc2_hsotg *hsotg, |
| 195 | struct dwc2_hcd_urb *urb, | 195 | struct dwc2_hcd_urb *urb, |
| 196 | gfp_t mem_flags) | 196 | gfp_t mem_flags) |
| 197 | { | 197 | { |
| @@ -767,57 +767,32 @@ void dwc2_hcd_qtd_init(struct dwc2_qtd *qtd, struct dwc2_hcd_urb *urb) | |||
| 767 | * | 767 | * |
| 768 | * @hsotg: The DWC HCD structure | 768 | * @hsotg: The DWC HCD structure |
| 769 | * @qtd: The QTD to add | 769 | * @qtd: The QTD to add |
| 770 | * @qh: Out parameter to return queue head | 770 | * @qh: Queue head to add qtd to |
| 771 | * @atomic_alloc: Flag to do atomic alloc if needed | ||
| 772 | * | 771 | * |
| 773 | * Return: 0 if successful, negative error code otherwise | 772 | * Return: 0 if successful, negative error code otherwise |
| 774 | * | 773 | * |
| 775 | * Finds the correct QH to place the QTD into. If it does not find a QH, it | 774 | * If the QH to which the QTD is added is not currently scheduled, it is placed |
| 776 | * will create a new QH. If the QH to which the QTD is added is not currently | 775 | * into the proper schedule based on its EP type. |
| 777 | * scheduled, it is placed into the proper schedule based on its EP type. | ||
| 778 | */ | 776 | */ |
| 779 | int dwc2_hcd_qtd_add(struct dwc2_hsotg *hsotg, struct dwc2_qtd *qtd, | 777 | int dwc2_hcd_qtd_add(struct dwc2_hsotg *hsotg, struct dwc2_qtd *qtd, |
| 780 | struct dwc2_qh **qh, gfp_t mem_flags) | 778 | struct dwc2_qh *qh) |
| 781 | { | 779 | { |
| 782 | struct dwc2_hcd_urb *urb = qtd->urb; | ||
| 783 | int allocated = 0; | ||
| 784 | int retval; | 780 | int retval; |
| 785 | 781 | ||
| 786 | /* | 782 | if (unlikely(!qh)) { |
| 787 | * Get the QH which holds the QTD-list to insert to. Create QH if it | 783 | dev_err(hsotg->dev, "%s: Invalid QH\n", __func__); |
| 788 | * doesn't exist. | 784 | retval = -EINVAL; |
| 789 | */ | 785 | goto fail; |
| 790 | if (*qh == NULL) { | ||
| 791 | *qh = dwc2_hcd_qh_create(hsotg, urb, mem_flags); | ||
| 792 | if (*qh == NULL) | ||
| 793 | return -ENOMEM; | ||
| 794 | allocated = 1; | ||
| 795 | } | 786 | } |
| 796 | 787 | ||
| 797 | retval = dwc2_hcd_qh_add(hsotg, *qh); | 788 | retval = dwc2_hcd_qh_add(hsotg, qh); |
| 798 | if (retval) | 789 | if (retval) |
| 799 | goto fail; | 790 | goto fail; |
| 800 | 791 | ||
| 801 | qtd->qh = *qh; | 792 | qtd->qh = qh; |
| 802 | list_add_tail(&qtd->qtd_list_entry, &(*qh)->qtd_list); | 793 | list_add_tail(&qtd->qtd_list_entry, &qh->qtd_list); |
| 803 | 794 | ||
| 804 | return 0; | 795 | return 0; |
| 805 | |||
| 806 | fail: | 796 | fail: |
| 807 | if (allocated) { | ||
| 808 | struct dwc2_qtd *qtd2, *qtd2_tmp; | ||
| 809 | struct dwc2_qh *qh_tmp = *qh; | ||
| 810 | |||
| 811 | *qh = NULL; | ||
| 812 | dwc2_hcd_qh_unlink(hsotg, qh_tmp); | ||
| 813 | |||
| 814 | /* Free each QTD in the QH's QTD list */ | ||
| 815 | list_for_each_entry_safe(qtd2, qtd2_tmp, &qh_tmp->qtd_list, | ||
| 816 | qtd_list_entry) | ||
| 817 | dwc2_hcd_qtd_unlink_and_free(hsotg, qtd2, qh_tmp); | ||
| 818 | |||
| 819 | dwc2_hcd_qh_free(hsotg, qh_tmp); | ||
| 820 | } | ||
| 821 | |||
| 822 | return retval; | 797 | return retval; |
| 823 | } | 798 | } |
diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c index 5c110d8e293b..ff5773c66b84 100644 --- a/drivers/usb/dwc3/core.c +++ b/drivers/usb/dwc3/core.c | |||
| @@ -446,10 +446,12 @@ static int dwc3_phy_setup(struct dwc3 *dwc) | |||
| 446 | /* Select the HS PHY interface */ | 446 | /* Select the HS PHY interface */ |
| 447 | switch (DWC3_GHWPARAMS3_HSPHY_IFC(dwc->hwparams.hwparams3)) { | 447 | switch (DWC3_GHWPARAMS3_HSPHY_IFC(dwc->hwparams.hwparams3)) { |
| 448 | case DWC3_GHWPARAMS3_HSPHY_IFC_UTMI_ULPI: | 448 | case DWC3_GHWPARAMS3_HSPHY_IFC_UTMI_ULPI: |
| 449 | if (!strncmp(dwc->hsphy_interface, "utmi", 4)) { | 449 | if (dwc->hsphy_interface && |
| 450 | !strncmp(dwc->hsphy_interface, "utmi", 4)) { | ||
| 450 | reg &= ~DWC3_GUSB2PHYCFG_ULPI_UTMI; | 451 | reg &= ~DWC3_GUSB2PHYCFG_ULPI_UTMI; |
| 451 | break; | 452 | break; |
| 452 | } else if (!strncmp(dwc->hsphy_interface, "ulpi", 4)) { | 453 | } else if (dwc->hsphy_interface && |
| 454 | !strncmp(dwc->hsphy_interface, "ulpi", 4)) { | ||
| 453 | reg |= DWC3_GUSB2PHYCFG_ULPI_UTMI; | 455 | reg |= DWC3_GUSB2PHYCFG_ULPI_UTMI; |
| 454 | dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(0), reg); | 456 | dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(0), reg); |
| 455 | } else { | 457 | } else { |
diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c index 4e3447bbd097..58b4657fc721 100644 --- a/drivers/usb/gadget/composite.c +++ b/drivers/usb/gadget/composite.c | |||
| @@ -1758,10 +1758,13 @@ unknown: | |||
| 1758 | * take such requests too, if that's ever needed: to work | 1758 | * take such requests too, if that's ever needed: to work |
| 1759 | * in config 0, etc. | 1759 | * in config 0, etc. |
| 1760 | */ | 1760 | */ |
| 1761 | list_for_each_entry(f, &cdev->config->functions, list) | 1761 | if (cdev->config) { |
| 1762 | if (f->req_match && f->req_match(f, ctrl)) | 1762 | list_for_each_entry(f, &cdev->config->functions, list) |
| 1763 | goto try_fun_setup; | 1763 | if (f->req_match && f->req_match(f, ctrl)) |
| 1764 | f = NULL; | 1764 | goto try_fun_setup; |
| 1765 | f = NULL; | ||
| 1766 | } | ||
| 1767 | |||
| 1765 | switch (ctrl->bRequestType & USB_RECIP_MASK) { | 1768 | switch (ctrl->bRequestType & USB_RECIP_MASK) { |
| 1766 | case USB_RECIP_INTERFACE: | 1769 | case USB_RECIP_INTERFACE: |
| 1767 | if (!cdev->config || intf >= MAX_CONFIG_INTERFACES) | 1770 | if (!cdev->config || intf >= MAX_CONFIG_INTERFACES) |
diff --git a/drivers/usb/gadget/configfs.c b/drivers/usb/gadget/configfs.c index 0495c94a23d7..289e20119fea 100644 --- a/drivers/usb/gadget/configfs.c +++ b/drivers/usb/gadget/configfs.c | |||
| @@ -571,7 +571,7 @@ static struct config_group *function_make( | |||
| 571 | if (IS_ERR(fi)) | 571 | if (IS_ERR(fi)) |
| 572 | return ERR_CAST(fi); | 572 | return ERR_CAST(fi); |
| 573 | 573 | ||
| 574 | ret = config_item_set_name(&fi->group.cg_item, name); | 574 | ret = config_item_set_name(&fi->group.cg_item, "%s", name); |
| 575 | if (ret) { | 575 | if (ret) { |
| 576 | usb_put_function_instance(fi); | 576 | usb_put_function_instance(fi); |
| 577 | return ERR_PTR(ret); | 577 | return ERR_PTR(ret); |
diff --git a/drivers/usb/gadget/function/f_fs.c b/drivers/usb/gadget/function/f_fs.c index 45b8c8b338df..6e7be91e6097 100644 --- a/drivers/usb/gadget/function/f_fs.c +++ b/drivers/usb/gadget/function/f_fs.c | |||
| @@ -924,7 +924,8 @@ static ssize_t ffs_epfile_write_iter(struct kiocb *kiocb, struct iov_iter *from) | |||
| 924 | 924 | ||
| 925 | kiocb->private = p; | 925 | kiocb->private = p; |
| 926 | 926 | ||
| 927 | kiocb_set_cancel_fn(kiocb, ffs_aio_cancel); | 927 | if (p->aio) |
| 928 | kiocb_set_cancel_fn(kiocb, ffs_aio_cancel); | ||
| 928 | 929 | ||
| 929 | res = ffs_epfile_io(kiocb->ki_filp, p); | 930 | res = ffs_epfile_io(kiocb->ki_filp, p); |
| 930 | if (res == -EIOCBQUEUED) | 931 | if (res == -EIOCBQUEUED) |
| @@ -968,7 +969,8 @@ static ssize_t ffs_epfile_read_iter(struct kiocb *kiocb, struct iov_iter *to) | |||
| 968 | 969 | ||
| 969 | kiocb->private = p; | 970 | kiocb->private = p; |
| 970 | 971 | ||
| 971 | kiocb_set_cancel_fn(kiocb, ffs_aio_cancel); | 972 | if (p->aio) |
| 973 | kiocb_set_cancel_fn(kiocb, ffs_aio_cancel); | ||
| 972 | 974 | ||
| 973 | res = ffs_epfile_io(kiocb->ki_filp, p); | 975 | res = ffs_epfile_io(kiocb->ki_filp, p); |
| 974 | if (res == -EIOCBQUEUED) | 976 | if (res == -EIOCBQUEUED) |
diff --git a/drivers/usb/gadget/function/f_mass_storage.c b/drivers/usb/gadget/function/f_mass_storage.c index d2259c663996..f936268d26c6 100644 --- a/drivers/usb/gadget/function/f_mass_storage.c +++ b/drivers/usb/gadget/function/f_mass_storage.c | |||
| @@ -2786,7 +2786,7 @@ int fsg_common_set_nluns(struct fsg_common *common, int nluns) | |||
| 2786 | return -EINVAL; | 2786 | return -EINVAL; |
| 2787 | } | 2787 | } |
| 2788 | 2788 | ||
| 2789 | curlun = kcalloc(nluns, sizeof(*curlun), GFP_KERNEL); | 2789 | curlun = kcalloc(FSG_MAX_LUNS, sizeof(*curlun), GFP_KERNEL); |
| 2790 | if (unlikely(!curlun)) | 2790 | if (unlikely(!curlun)) |
| 2791 | return -ENOMEM; | 2791 | return -ENOMEM; |
| 2792 | 2792 | ||
| @@ -2796,8 +2796,6 @@ int fsg_common_set_nluns(struct fsg_common *common, int nluns) | |||
| 2796 | common->luns = curlun; | 2796 | common->luns = curlun; |
| 2797 | common->nluns = nluns; | 2797 | common->nluns = nluns; |
| 2798 | 2798 | ||
| 2799 | pr_info("Number of LUNs=%d\n", common->nluns); | ||
| 2800 | |||
| 2801 | return 0; | 2799 | return 0; |
| 2802 | } | 2800 | } |
| 2803 | EXPORT_SYMBOL_GPL(fsg_common_set_nluns); | 2801 | EXPORT_SYMBOL_GPL(fsg_common_set_nluns); |
| @@ -3563,14 +3561,26 @@ static struct usb_function *fsg_alloc(struct usb_function_instance *fi) | |||
| 3563 | struct fsg_opts *opts = fsg_opts_from_func_inst(fi); | 3561 | struct fsg_opts *opts = fsg_opts_from_func_inst(fi); |
| 3564 | struct fsg_common *common = opts->common; | 3562 | struct fsg_common *common = opts->common; |
| 3565 | struct fsg_dev *fsg; | 3563 | struct fsg_dev *fsg; |
| 3564 | unsigned nluns, i; | ||
| 3566 | 3565 | ||
| 3567 | fsg = kzalloc(sizeof(*fsg), GFP_KERNEL); | 3566 | fsg = kzalloc(sizeof(*fsg), GFP_KERNEL); |
| 3568 | if (unlikely(!fsg)) | 3567 | if (unlikely(!fsg)) |
| 3569 | return ERR_PTR(-ENOMEM); | 3568 | return ERR_PTR(-ENOMEM); |
| 3570 | 3569 | ||
| 3571 | mutex_lock(&opts->lock); | 3570 | mutex_lock(&opts->lock); |
| 3571 | if (!opts->refcnt) { | ||
| 3572 | for (nluns = i = 0; i < FSG_MAX_LUNS; ++i) | ||
| 3573 | if (common->luns[i]) | ||
| 3574 | nluns = i + 1; | ||
| 3575 | if (!nluns) | ||
| 3576 | pr_warn("No LUNS defined, continuing anyway\n"); | ||
| 3577 | else | ||
| 3578 | common->nluns = nluns; | ||
| 3579 | pr_info("Number of LUNs=%u\n", common->nluns); | ||
| 3580 | } | ||
| 3572 | opts->refcnt++; | 3581 | opts->refcnt++; |
| 3573 | mutex_unlock(&opts->lock); | 3582 | mutex_unlock(&opts->lock); |
| 3583 | |||
| 3574 | fsg->function.name = FSG_DRIVER_DESC; | 3584 | fsg->function.name = FSG_DRIVER_DESC; |
| 3575 | fsg->function.bind = fsg_bind; | 3585 | fsg->function.bind = fsg_bind; |
| 3576 | fsg->function.unbind = fsg_unbind; | 3586 | fsg->function.unbind = fsg_unbind; |
diff --git a/drivers/usb/gadget/function/f_midi.c b/drivers/usb/gadget/function/f_midi.c index 6316aa5b1c49..ad50a67c1465 100644 --- a/drivers/usb/gadget/function/f_midi.c +++ b/drivers/usb/gadget/function/f_midi.c | |||
| @@ -1145,7 +1145,7 @@ static struct usb_function *f_midi_alloc(struct usb_function_instance *fi) | |||
| 1145 | if (opts->id && !midi->id) { | 1145 | if (opts->id && !midi->id) { |
| 1146 | status = -ENOMEM; | 1146 | status = -ENOMEM; |
| 1147 | mutex_unlock(&opts->lock); | 1147 | mutex_unlock(&opts->lock); |
| 1148 | goto kstrdup_fail; | 1148 | goto setup_fail; |
| 1149 | } | 1149 | } |
| 1150 | midi->in_ports = opts->in_ports; | 1150 | midi->in_ports = opts->in_ports; |
| 1151 | midi->out_ports = opts->out_ports; | 1151 | midi->out_ports = opts->out_ports; |
| @@ -1164,8 +1164,6 @@ static struct usb_function *f_midi_alloc(struct usb_function_instance *fi) | |||
| 1164 | 1164 | ||
| 1165 | return &midi->func; | 1165 | return &midi->func; |
| 1166 | 1166 | ||
| 1167 | kstrdup_fail: | ||
| 1168 | f_midi_unregister_card(midi); | ||
| 1169 | setup_fail: | 1167 | setup_fail: |
| 1170 | for (--i; i >= 0; i--) | 1168 | for (--i; i >= 0; i--) |
| 1171 | kfree(midi->in_port[i]); | 1169 | kfree(midi->in_port[i]); |
diff --git a/drivers/usb/gadget/udc/fotg210-udc.c b/drivers/usb/gadget/udc/fotg210-udc.c index e547ea7f56b1..1137e3384218 100644 --- a/drivers/usb/gadget/udc/fotg210-udc.c +++ b/drivers/usb/gadget/udc/fotg210-udc.c | |||
| @@ -1171,7 +1171,7 @@ static int fotg210_udc_probe(struct platform_device *pdev) | |||
| 1171 | udc_name, fotg210); | 1171 | udc_name, fotg210); |
| 1172 | if (ret < 0) { | 1172 | if (ret < 0) { |
| 1173 | pr_err("request_irq error (%d)\n", ret); | 1173 | pr_err("request_irq error (%d)\n", ret); |
| 1174 | goto err_irq; | 1174 | goto err_req; |
| 1175 | } | 1175 | } |
| 1176 | 1176 | ||
| 1177 | ret = usb_add_gadget_udc(&pdev->dev, &fotg210->gadget); | 1177 | ret = usb_add_gadget_udc(&pdev->dev, &fotg210->gadget); |
| @@ -1183,7 +1183,6 @@ static int fotg210_udc_probe(struct platform_device *pdev) | |||
| 1183 | return 0; | 1183 | return 0; |
| 1184 | 1184 | ||
| 1185 | err_add_udc: | 1185 | err_add_udc: |
| 1186 | err_irq: | ||
| 1187 | free_irq(ires->start, fotg210); | 1186 | free_irq(ires->start, fotg210); |
| 1188 | 1187 | ||
| 1189 | err_req: | 1188 | err_req: |
diff --git a/drivers/usb/musb/musb_virthub.c b/drivers/usb/musb/musb_virthub.c index 30842bc195f5..92d5f718659b 100644 --- a/drivers/usb/musb/musb_virthub.c +++ b/drivers/usb/musb/musb_virthub.c | |||
| @@ -275,9 +275,7 @@ static int musb_has_gadget(struct musb *musb) | |||
| 275 | #ifdef CONFIG_USB_MUSB_HOST | 275 | #ifdef CONFIG_USB_MUSB_HOST |
| 276 | return 1; | 276 | return 1; |
| 277 | #else | 277 | #else |
| 278 | if (musb->port_mode == MUSB_PORT_MODE_HOST) | 278 | return musb->port_mode == MUSB_PORT_MODE_HOST; |
| 279 | return 1; | ||
| 280 | return musb->g.dev.driver != NULL; | ||
| 281 | #endif | 279 | #endif |
| 282 | } | 280 | } |
| 283 | 281 | ||
diff --git a/drivers/usb/phy/phy-mxs-usb.c b/drivers/usb/phy/phy-mxs-usb.c index 8f7cb068d29b..3fcc0483a081 100644 --- a/drivers/usb/phy/phy-mxs-usb.c +++ b/drivers/usb/phy/phy-mxs-usb.c | |||
| @@ -217,6 +217,9 @@ static bool mxs_phy_get_vbus_status(struct mxs_phy *mxs_phy) | |||
| 217 | { | 217 | { |
| 218 | unsigned int vbus_value; | 218 | unsigned int vbus_value; |
| 219 | 219 | ||
| 220 | if (!mxs_phy->regmap_anatop) | ||
| 221 | return false; | ||
| 222 | |||
| 220 | if (mxs_phy->port_id == 0) | 223 | if (mxs_phy->port_id == 0) |
| 221 | regmap_read(mxs_phy->regmap_anatop, | 224 | regmap_read(mxs_phy->regmap_anatop, |
| 222 | ANADIG_USB1_VBUS_DET_STAT, | 225 | ANADIG_USB1_VBUS_DET_STAT, |
diff --git a/drivers/usb/serial/cp210x.c b/drivers/usb/serial/cp210x.c index ffd739e31bfc..eac7ccaa3c85 100644 --- a/drivers/usb/serial/cp210x.c +++ b/drivers/usb/serial/cp210x.c | |||
| @@ -187,6 +187,7 @@ static const struct usb_device_id id_table[] = { | |||
| 187 | { USB_DEVICE(0x1FB9, 0x0602) }, /* Lake Shore Model 648 Magnet Power Supply */ | 187 | { USB_DEVICE(0x1FB9, 0x0602) }, /* Lake Shore Model 648 Magnet Power Supply */ |
| 188 | { USB_DEVICE(0x1FB9, 0x0700) }, /* Lake Shore Model 737 VSM Controller */ | 188 | { USB_DEVICE(0x1FB9, 0x0700) }, /* Lake Shore Model 737 VSM Controller */ |
| 189 | { USB_DEVICE(0x1FB9, 0x0701) }, /* Lake Shore Model 776 Hall Matrix */ | 189 | { USB_DEVICE(0x1FB9, 0x0701) }, /* Lake Shore Model 776 Hall Matrix */ |
| 190 | { USB_DEVICE(0x2626, 0xEA60) }, /* Aruba Networks 7xxx USB Serial Console */ | ||
| 190 | { USB_DEVICE(0x3195, 0xF190) }, /* Link Instruments MSO-19 */ | 191 | { USB_DEVICE(0x3195, 0xF190) }, /* Link Instruments MSO-19 */ |
| 191 | { USB_DEVICE(0x3195, 0xF280) }, /* Link Instruments MSO-28 */ | 192 | { USB_DEVICE(0x3195, 0xF280) }, /* Link Instruments MSO-28 */ |
| 192 | { USB_DEVICE(0x3195, 0xF281) }, /* Link Instruments MSO-28 */ | 193 | { USB_DEVICE(0x3195, 0xF281) }, /* Link Instruments MSO-28 */ |
diff --git a/drivers/usb/serial/mos7720.c b/drivers/usb/serial/mos7720.c index 4f70df33975a..78b4f64c6b00 100644 --- a/drivers/usb/serial/mos7720.c +++ b/drivers/usb/serial/mos7720.c | |||
| @@ -121,26 +121,26 @@ static DEFINE_SPINLOCK(release_lock); | |||
| 121 | static const unsigned int dummy; /* for clarity in register access fns */ | 121 | static const unsigned int dummy; /* for clarity in register access fns */ |
| 122 | 122 | ||
| 123 | enum mos_regs { | 123 | enum mos_regs { |
| 124 | THR, /* serial port regs */ | 124 | MOS7720_THR, /* serial port regs */ |
| 125 | RHR, | 125 | MOS7720_RHR, |
| 126 | IER, | 126 | MOS7720_IER, |
| 127 | FCR, | 127 | MOS7720_FCR, |
| 128 | ISR, | 128 | MOS7720_ISR, |
| 129 | LCR, | 129 | MOS7720_LCR, |
| 130 | MCR, | 130 | MOS7720_MCR, |
| 131 | LSR, | 131 | MOS7720_LSR, |
| 132 | MSR, | 132 | MOS7720_MSR, |
| 133 | SPR, | 133 | MOS7720_SPR, |
| 134 | DLL, | 134 | MOS7720_DLL, |
| 135 | DLM, | 135 | MOS7720_DLM, |
| 136 | DPR, /* parallel port regs */ | 136 | MOS7720_DPR, /* parallel port regs */ |
| 137 | DSR, | 137 | MOS7720_DSR, |
| 138 | DCR, | 138 | MOS7720_DCR, |
| 139 | ECR, | 139 | MOS7720_ECR, |
| 140 | SP1_REG, /* device control regs */ | 140 | MOS7720_SP1_REG, /* device control regs */ |
| 141 | SP2_REG, /* serial port 2 (7720 only) */ | 141 | MOS7720_SP2_REG, /* serial port 2 (7720 only) */ |
| 142 | PP_REG, | 142 | MOS7720_PP_REG, |
| 143 | SP_CONTROL_REG, | 143 | MOS7720_SP_CONTROL_REG, |
| 144 | }; | 144 | }; |
| 145 | 145 | ||
| 146 | /* | 146 | /* |
| @@ -150,26 +150,26 @@ enum mos_regs { | |||
| 150 | static inline __u16 get_reg_index(enum mos_regs reg) | 150 | static inline __u16 get_reg_index(enum mos_regs reg) |
| 151 | { | 151 | { |
| 152 | static const __u16 mos7715_index_lookup_table[] = { | 152 | static const __u16 mos7715_index_lookup_table[] = { |
| 153 | 0x00, /* THR */ | 153 | 0x00, /* MOS7720_THR */ |
| 154 | 0x00, /* RHR */ | 154 | 0x00, /* MOS7720_RHR */ |
| 155 | 0x01, /* IER */ | 155 | 0x01, /* MOS7720_IER */ |
| 156 | 0x02, /* FCR */ | 156 | 0x02, /* MOS7720_FCR */ |
| 157 | 0x02, /* ISR */ | 157 | 0x02, /* MOS7720_ISR */ |
| 158 | 0x03, /* LCR */ | 158 | 0x03, /* MOS7720_LCR */ |
| 159 | 0x04, /* MCR */ | 159 | 0x04, /* MOS7720_MCR */ |
| 160 | 0x05, /* LSR */ | 160 | 0x05, /* MOS7720_LSR */ |
| 161 | 0x06, /* MSR */ | 161 | 0x06, /* MOS7720_MSR */ |
| 162 | 0x07, /* SPR */ | 162 | 0x07, /* MOS7720_SPR */ |
| 163 | 0x00, /* DLL */ | 163 | 0x00, /* MOS7720_DLL */ |
| 164 | 0x01, /* DLM */ | 164 | 0x01, /* MOS7720_DLM */ |
| 165 | 0x00, /* DPR */ | 165 | 0x00, /* MOS7720_DPR */ |
| 166 | 0x01, /* DSR */ | 166 | 0x01, /* MOS7720_DSR */ |
| 167 | 0x02, /* DCR */ | 167 | 0x02, /* MOS7720_DCR */ |
| 168 | 0x0a, /* ECR */ | 168 | 0x0a, /* MOS7720_ECR */ |
| 169 | 0x01, /* SP1_REG */ | 169 | 0x01, /* MOS7720_SP1_REG */ |
| 170 | 0x02, /* SP2_REG (7720 only) */ | 170 | 0x02, /* MOS7720_SP2_REG (7720 only) */ |
| 171 | 0x04, /* PP_REG (7715 only) */ | 171 | 0x04, /* MOS7720_PP_REG (7715 only) */ |
| 172 | 0x08, /* SP_CONTROL_REG */ | 172 | 0x08, /* MOS7720_SP_CONTROL_REG */ |
| 173 | }; | 173 | }; |
| 174 | return mos7715_index_lookup_table[reg]; | 174 | return mos7715_index_lookup_table[reg]; |
| 175 | } | 175 | } |
| @@ -181,10 +181,10 @@ static inline __u16 get_reg_index(enum mos_regs reg) | |||
| 181 | static inline __u16 get_reg_value(enum mos_regs reg, | 181 | static inline __u16 get_reg_value(enum mos_regs reg, |
| 182 | unsigned int serial_portnum) | 182 | unsigned int serial_portnum) |
| 183 | { | 183 | { |
| 184 | if (reg >= SP1_REG) /* control reg */ | 184 | if (reg >= MOS7720_SP1_REG) /* control reg */ |
| 185 | return 0x0000; | 185 | return 0x0000; |
| 186 | 186 | ||
| 187 | else if (reg >= DPR) /* parallel port reg (7715 only) */ | 187 | else if (reg >= MOS7720_DPR) /* parallel port reg (7715 only) */ |
| 188 | return 0x0100; | 188 | return 0x0100; |
| 189 | 189 | ||
| 190 | else /* serial port reg */ | 190 | else /* serial port reg */ |
| @@ -252,7 +252,8 @@ static inline int mos7715_change_mode(struct mos7715_parport *mos_parport, | |||
| 252 | enum mos7715_pp_modes mode) | 252 | enum mos7715_pp_modes mode) |
| 253 | { | 253 | { |
| 254 | mos_parport->shadowECR = mode; | 254 | mos_parport->shadowECR = mode; |
| 255 | write_mos_reg(mos_parport->serial, dummy, ECR, mos_parport->shadowECR); | 255 | write_mos_reg(mos_parport->serial, dummy, MOS7720_ECR, |
| 256 | mos_parport->shadowECR); | ||
| 256 | return 0; | 257 | return 0; |
| 257 | } | 258 | } |
| 258 | 259 | ||
| @@ -486,7 +487,7 @@ static void parport_mos7715_write_data(struct parport *pp, unsigned char d) | |||
| 486 | if (parport_prologue(pp) < 0) | 487 | if (parport_prologue(pp) < 0) |
| 487 | return; | 488 | return; |
| 488 | mos7715_change_mode(mos_parport, SPP); | 489 | mos7715_change_mode(mos_parport, SPP); |
| 489 | write_mos_reg(mos_parport->serial, dummy, DPR, (__u8)d); | 490 | write_mos_reg(mos_parport->serial, dummy, MOS7720_DPR, (__u8)d); |
| 490 | parport_epilogue(pp); | 491 | parport_epilogue(pp); |
| 491 | } | 492 | } |
| 492 | 493 | ||
| @@ -497,7 +498,7 @@ static unsigned char parport_mos7715_read_data(struct parport *pp) | |||
| 497 | 498 | ||
| 498 | if (parport_prologue(pp) < 0) | 499 | if (parport_prologue(pp) < 0) |
| 499 | return 0; | 500 | return 0; |
| 500 | read_mos_reg(mos_parport->serial, dummy, DPR, &d); | 501 | read_mos_reg(mos_parport->serial, dummy, MOS7720_DPR, &d); |
| 501 | parport_epilogue(pp); | 502 | parport_epilogue(pp); |
| 502 | return d; | 503 | return d; |
| 503 | } | 504 | } |
| @@ -510,7 +511,7 @@ static void parport_mos7715_write_control(struct parport *pp, unsigned char d) | |||
| 510 | if (parport_prologue(pp) < 0) | 511 | if (parport_prologue(pp) < 0) |
| 511 | return; | 512 | return; |
| 512 | data = ((__u8)d & 0x0f) | (mos_parport->shadowDCR & 0xf0); | 513 | data = ((__u8)d & 0x0f) | (mos_parport->shadowDCR & 0xf0); |
| 513 | write_mos_reg(mos_parport->serial, dummy, DCR, data); | 514 | write_mos_reg(mos_parport->serial, dummy, MOS7720_DCR, data); |
| 514 | mos_parport->shadowDCR = data; | 515 | mos_parport->shadowDCR = data; |
| 515 | parport_epilogue(pp); | 516 | parport_epilogue(pp); |
| 516 | } | 517 | } |
| @@ -543,7 +544,8 @@ static unsigned char parport_mos7715_frob_control(struct parport *pp, | |||
| 543 | if (parport_prologue(pp) < 0) | 544 | if (parport_prologue(pp) < 0) |
| 544 | return 0; | 545 | return 0; |
| 545 | mos_parport->shadowDCR = (mos_parport->shadowDCR & (~mask)) ^ val; | 546 | mos_parport->shadowDCR = (mos_parport->shadowDCR & (~mask)) ^ val; |
| 546 | write_mos_reg(mos_parport->serial, dummy, DCR, mos_parport->shadowDCR); | 547 | write_mos_reg(mos_parport->serial, dummy, MOS7720_DCR, |
| 548 | mos_parport->shadowDCR); | ||
| 547 | dcr = mos_parport->shadowDCR & 0x0f; | 549 | dcr = mos_parport->shadowDCR & 0x0f; |
| 548 | parport_epilogue(pp); | 550 | parport_epilogue(pp); |
| 549 | return dcr; | 551 | return dcr; |
| @@ -581,7 +583,8 @@ static void parport_mos7715_data_forward(struct parport *pp) | |||
| 581 | return; | 583 | return; |
| 582 | mos7715_change_mode(mos_parport, PS2); | 584 | mos7715_change_mode(mos_parport, PS2); |
| 583 | mos_parport->shadowDCR &= ~0x20; | 585 | mos_parport->shadowDCR &= ~0x20; |
| 584 | write_mos_reg(mos_parport->serial, dummy, DCR, mos_parport->shadowDCR); | 586 | write_mos_reg(mos_parport->serial, dummy, MOS7720_DCR, |
| 587 | mos_parport->shadowDCR); | ||
| 585 | parport_epilogue(pp); | 588 | parport_epilogue(pp); |
| 586 | } | 589 | } |
| 587 | 590 | ||
| @@ -593,7 +596,8 @@ static void parport_mos7715_data_reverse(struct parport *pp) | |||
| 593 | return; | 596 | return; |
| 594 | mos7715_change_mode(mos_parport, PS2); | 597 | mos7715_change_mode(mos_parport, PS2); |
| 595 | mos_parport->shadowDCR |= 0x20; | 598 | mos_parport->shadowDCR |= 0x20; |
| 596 | write_mos_reg(mos_parport->serial, dummy, DCR, mos_parport->shadowDCR); | 599 | write_mos_reg(mos_parport->serial, dummy, MOS7720_DCR, |
| 600 | mos_parport->shadowDCR); | ||
| 597 | parport_epilogue(pp); | 601 | parport_epilogue(pp); |
| 598 | } | 602 | } |
| 599 | 603 | ||
| @@ -633,8 +637,10 @@ static void parport_mos7715_restore_state(struct parport *pp, | |||
| 633 | spin_unlock(&release_lock); | 637 | spin_unlock(&release_lock); |
| 634 | return; | 638 | return; |
| 635 | } | 639 | } |
| 636 | write_parport_reg_nonblock(mos_parport, DCR, mos_parport->shadowDCR); | 640 | write_parport_reg_nonblock(mos_parport, MOS7720_DCR, |
| 637 | write_parport_reg_nonblock(mos_parport, ECR, mos_parport->shadowECR); | 641 | mos_parport->shadowDCR); |
| 642 | write_parport_reg_nonblock(mos_parport, MOS7720_ECR, | ||
| 643 | mos_parport->shadowECR); | ||
| 638 | spin_unlock(&release_lock); | 644 | spin_unlock(&release_lock); |
| 639 | } | 645 | } |
| 640 | 646 | ||
| @@ -714,14 +720,16 @@ static int mos7715_parport_init(struct usb_serial *serial) | |||
| 714 | init_completion(&mos_parport->syncmsg_compl); | 720 | init_completion(&mos_parport->syncmsg_compl); |
| 715 | 721 | ||
| 716 | /* cycle parallel port reset bit */ | 722 | /* cycle parallel port reset bit */ |
| 717 | write_mos_reg(mos_parport->serial, dummy, PP_REG, (__u8)0x80); | 723 | write_mos_reg(mos_parport->serial, dummy, MOS7720_PP_REG, (__u8)0x80); |
| 718 | write_mos_reg(mos_parport->serial, dummy, PP_REG, (__u8)0x00); | 724 | write_mos_reg(mos_parport->serial, dummy, MOS7720_PP_REG, (__u8)0x00); |
| 719 | 725 | ||
| 720 | /* initialize device registers */ | 726 | /* initialize device registers */ |
| 721 | mos_parport->shadowDCR = DCR_INIT_VAL; | 727 | mos_parport->shadowDCR = DCR_INIT_VAL; |
| 722 | write_mos_reg(mos_parport->serial, dummy, DCR, mos_parport->shadowDCR); | 728 | write_mos_reg(mos_parport->serial, dummy, MOS7720_DCR, |
| 729 | mos_parport->shadowDCR); | ||
| 723 | mos_parport->shadowECR = ECR_INIT_VAL; | 730 | mos_parport->shadowECR = ECR_INIT_VAL; |
| 724 | write_mos_reg(mos_parport->serial, dummy, ECR, mos_parport->shadowECR); | 731 | write_mos_reg(mos_parport->serial, dummy, MOS7720_ECR, |
| 732 | mos_parport->shadowECR); | ||
| 725 | 733 | ||
| 726 | /* register with parport core */ | 734 | /* register with parport core */ |
| 727 | mos_parport->pp = parport_register_port(0, PARPORT_IRQ_NONE, | 735 | mos_parport->pp = parport_register_port(0, PARPORT_IRQ_NONE, |
| @@ -1033,45 +1041,49 @@ static int mos7720_open(struct tty_struct *tty, struct usb_serial_port *port) | |||
| 1033 | /* Initialize MCS7720 -- Write Init values to corresponding Registers | 1041 | /* Initialize MCS7720 -- Write Init values to corresponding Registers |
| 1034 | * | 1042 | * |
| 1035 | * Register Index | 1043 | * Register Index |
| 1036 | * 0 : THR/RHR | 1044 | * 0 : MOS7720_THR/MOS7720_RHR |
| 1037 | * 1 : IER | 1045 | * 1 : MOS7720_IER |
| 1038 | * 2 : FCR | 1046 | * 2 : MOS7720_FCR |
| 1039 | * 3 : LCR | 1047 | * 3 : MOS7720_LCR |
| 1040 | * 4 : MCR | 1048 | * 4 : MOS7720_MCR |
| 1041 | * 5 : LSR | 1049 | * 5 : MOS7720_LSR |
| 1042 | * 6 : MSR | 1050 | * 6 : MOS7720_MSR |
| 1043 | * 7 : SPR | 1051 | * 7 : MOS7720_SPR |
| 1044 | * | 1052 | * |
| 1045 | * 0x08 : SP1/2 Control Reg | 1053 | * 0x08 : SP1/2 Control Reg |
| 1046 | */ | 1054 | */ |
| 1047 | port_number = port->port_number; | 1055 | port_number = port->port_number; |
| 1048 | read_mos_reg(serial, port_number, LSR, &data); | 1056 | read_mos_reg(serial, port_number, MOS7720_LSR, &data); |
| 1049 | 1057 | ||
| 1050 | dev_dbg(&port->dev, "SS::%p LSR:%x\n", mos7720_port, data); | 1058 | dev_dbg(&port->dev, "SS::%p LSR:%x\n", mos7720_port, data); |
| 1051 | 1059 | ||
| 1052 | write_mos_reg(serial, dummy, SP1_REG, 0x02); | 1060 | write_mos_reg(serial, dummy, MOS7720_SP1_REG, 0x02); |
| 1053 | write_mos_reg(serial, dummy, SP2_REG, 0x02); | 1061 | write_mos_reg(serial, dummy, MOS7720_SP2_REG, 0x02); |
| 1054 | 1062 | ||
| 1055 | write_mos_reg(serial, port_number, IER, 0x00); | 1063 | write_mos_reg(serial, port_number, MOS7720_IER, 0x00); |
| 1056 | write_mos_reg(serial, port_number, FCR, 0x00); | 1064 | write_mos_reg(serial, port_number, MOS7720_FCR, 0x00); |
| 1057 | 1065 | ||
| 1058 | write_mos_reg(serial, port_number, FCR, 0xcf); | 1066 | write_mos_reg(serial, port_number, MOS7720_FCR, 0xcf); |
| 1059 | mos7720_port->shadowLCR = 0x03; | 1067 | mos7720_port->shadowLCR = 0x03; |
| 1060 | write_mos_reg(serial, port_number, LCR, mos7720_port->shadowLCR); | 1068 | write_mos_reg(serial, port_number, MOS7720_LCR, |
| 1069 | mos7720_port->shadowLCR); | ||
| 1061 | mos7720_port->shadowMCR = 0x0b; | 1070 | mos7720_port->shadowMCR = 0x0b; |
| 1062 | write_mos_reg(serial, port_number, MCR, mos7720_port->shadowMCR); | 1071 | write_mos_reg(serial, port_number, MOS7720_MCR, |
| 1072 | mos7720_port->shadowMCR); | ||
| 1063 | 1073 | ||
| 1064 | write_mos_reg(serial, port_number, SP_CONTROL_REG, 0x00); | 1074 | write_mos_reg(serial, port_number, MOS7720_SP_CONTROL_REG, 0x00); |
| 1065 | read_mos_reg(serial, dummy, SP_CONTROL_REG, &data); | 1075 | read_mos_reg(serial, dummy, MOS7720_SP_CONTROL_REG, &data); |
| 1066 | data = data | (port->port_number + 1); | 1076 | data = data | (port->port_number + 1); |
| 1067 | write_mos_reg(serial, dummy, SP_CONTROL_REG, data); | 1077 | write_mos_reg(serial, dummy, MOS7720_SP_CONTROL_REG, data); |
| 1068 | mos7720_port->shadowLCR = 0x83; | 1078 | mos7720_port->shadowLCR = 0x83; |
| 1069 | write_mos_reg(serial, port_number, LCR, mos7720_port->shadowLCR); | 1079 | write_mos_reg(serial, port_number, MOS7720_LCR, |
| 1070 | write_mos_reg(serial, port_number, THR, 0x0c); | 1080 | mos7720_port->shadowLCR); |
| 1071 | write_mos_reg(serial, port_number, IER, 0x00); | 1081 | write_mos_reg(serial, port_number, MOS7720_THR, 0x0c); |
| 1082 | write_mos_reg(serial, port_number, MOS7720_IER, 0x00); | ||
| 1072 | mos7720_port->shadowLCR = 0x03; | 1083 | mos7720_port->shadowLCR = 0x03; |
| 1073 | write_mos_reg(serial, port_number, LCR, mos7720_port->shadowLCR); | 1084 | write_mos_reg(serial, port_number, MOS7720_LCR, |
| 1074 | write_mos_reg(serial, port_number, IER, 0x0c); | 1085 | mos7720_port->shadowLCR); |
| 1086 | write_mos_reg(serial, port_number, MOS7720_IER, 0x0c); | ||
| 1075 | 1087 | ||
| 1076 | response = usb_submit_urb(port->read_urb, GFP_KERNEL); | 1088 | response = usb_submit_urb(port->read_urb, GFP_KERNEL); |
| 1077 | if (response) | 1089 | if (response) |
| @@ -1144,8 +1156,8 @@ static void mos7720_close(struct usb_serial_port *port) | |||
| 1144 | usb_kill_urb(port->write_urb); | 1156 | usb_kill_urb(port->write_urb); |
| 1145 | usb_kill_urb(port->read_urb); | 1157 | usb_kill_urb(port->read_urb); |
| 1146 | 1158 | ||
| 1147 | write_mos_reg(serial, port->port_number, MCR, 0x00); | 1159 | write_mos_reg(serial, port->port_number, MOS7720_MCR, 0x00); |
| 1148 | write_mos_reg(serial, port->port_number, IER, 0x00); | 1160 | write_mos_reg(serial, port->port_number, MOS7720_IER, 0x00); |
| 1149 | 1161 | ||
| 1150 | mos7720_port->open = 0; | 1162 | mos7720_port->open = 0; |
| 1151 | } | 1163 | } |
| @@ -1169,7 +1181,8 @@ static void mos7720_break(struct tty_struct *tty, int break_state) | |||
| 1169 | data = mos7720_port->shadowLCR & ~UART_LCR_SBC; | 1181 | data = mos7720_port->shadowLCR & ~UART_LCR_SBC; |
| 1170 | 1182 | ||
| 1171 | mos7720_port->shadowLCR = data; | 1183 | mos7720_port->shadowLCR = data; |
| 1172 | write_mos_reg(serial, port->port_number, LCR, mos7720_port->shadowLCR); | 1184 | write_mos_reg(serial, port->port_number, MOS7720_LCR, |
| 1185 | mos7720_port->shadowLCR); | ||
| 1173 | } | 1186 | } |
| 1174 | 1187 | ||
| 1175 | /* | 1188 | /* |
| @@ -1297,7 +1310,7 @@ static void mos7720_throttle(struct tty_struct *tty) | |||
| 1297 | /* if we are implementing RTS/CTS, toggle that line */ | 1310 | /* if we are implementing RTS/CTS, toggle that line */ |
| 1298 | if (tty->termios.c_cflag & CRTSCTS) { | 1311 | if (tty->termios.c_cflag & CRTSCTS) { |
| 1299 | mos7720_port->shadowMCR &= ~UART_MCR_RTS; | 1312 | mos7720_port->shadowMCR &= ~UART_MCR_RTS; |
| 1300 | write_mos_reg(port->serial, port->port_number, MCR, | 1313 | write_mos_reg(port->serial, port->port_number, MOS7720_MCR, |
| 1301 | mos7720_port->shadowMCR); | 1314 | mos7720_port->shadowMCR); |
| 1302 | } | 1315 | } |
| 1303 | } | 1316 | } |
| @@ -1327,7 +1340,7 @@ static void mos7720_unthrottle(struct tty_struct *tty) | |||
| 1327 | /* if we are implementing RTS/CTS, toggle that line */ | 1340 | /* if we are implementing RTS/CTS, toggle that line */ |
| 1328 | if (tty->termios.c_cflag & CRTSCTS) { | 1341 | if (tty->termios.c_cflag & CRTSCTS) { |
| 1329 | mos7720_port->shadowMCR |= UART_MCR_RTS; | 1342 | mos7720_port->shadowMCR |= UART_MCR_RTS; |
| 1330 | write_mos_reg(port->serial, port->port_number, MCR, | 1343 | write_mos_reg(port->serial, port->port_number, MOS7720_MCR, |
| 1331 | mos7720_port->shadowMCR); | 1344 | mos7720_port->shadowMCR); |
| 1332 | } | 1345 | } |
| 1333 | } | 1346 | } |
| @@ -1352,35 +1365,39 @@ static int set_higher_rates(struct moschip_port *mos7720_port, | |||
| 1352 | dev_dbg(&port->dev, "Sending Setting Commands ..........\n"); | 1365 | dev_dbg(&port->dev, "Sending Setting Commands ..........\n"); |
| 1353 | port_number = port->port_number; | 1366 | port_number = port->port_number; |
| 1354 | 1367 | ||
| 1355 | write_mos_reg(serial, port_number, IER, 0x00); | 1368 | write_mos_reg(serial, port_number, MOS7720_IER, 0x00); |
| 1356 | write_mos_reg(serial, port_number, FCR, 0x00); | 1369 | write_mos_reg(serial, port_number, MOS7720_FCR, 0x00); |
| 1357 | write_mos_reg(serial, port_number, FCR, 0xcf); | 1370 | write_mos_reg(serial, port_number, MOS7720_FCR, 0xcf); |
| 1358 | mos7720_port->shadowMCR = 0x0b; | 1371 | mos7720_port->shadowMCR = 0x0b; |
| 1359 | write_mos_reg(serial, port_number, MCR, mos7720_port->shadowMCR); | 1372 | write_mos_reg(serial, port_number, MOS7720_MCR, |
| 1360 | write_mos_reg(serial, dummy, SP_CONTROL_REG, 0x00); | 1373 | mos7720_port->shadowMCR); |
| 1374 | write_mos_reg(serial, dummy, MOS7720_SP_CONTROL_REG, 0x00); | ||
| 1361 | 1375 | ||
| 1362 | /*********************************************** | 1376 | /*********************************************** |
| 1363 | * Set for higher rates * | 1377 | * Set for higher rates * |
| 1364 | ***********************************************/ | 1378 | ***********************************************/ |
| 1365 | /* writing baud rate verbatum into uart clock field clearly not right */ | 1379 | /* writing baud rate verbatum into uart clock field clearly not right */ |
| 1366 | if (port_number == 0) | 1380 | if (port_number == 0) |
| 1367 | sp_reg = SP1_REG; | 1381 | sp_reg = MOS7720_SP1_REG; |
| 1368 | else | 1382 | else |
| 1369 | sp_reg = SP2_REG; | 1383 | sp_reg = MOS7720_SP2_REG; |
| 1370 | write_mos_reg(serial, dummy, sp_reg, baud * 0x10); | 1384 | write_mos_reg(serial, dummy, sp_reg, baud * 0x10); |
| 1371 | write_mos_reg(serial, dummy, SP_CONTROL_REG, 0x03); | 1385 | write_mos_reg(serial, dummy, MOS7720_SP_CONTROL_REG, 0x03); |
| 1372 | mos7720_port->shadowMCR = 0x2b; | 1386 | mos7720_port->shadowMCR = 0x2b; |
| 1373 | write_mos_reg(serial, port_number, MCR, mos7720_port->shadowMCR); | 1387 | write_mos_reg(serial, port_number, MOS7720_MCR, |
| 1388 | mos7720_port->shadowMCR); | ||
| 1374 | 1389 | ||
| 1375 | /*********************************************** | 1390 | /*********************************************** |
| 1376 | * Set DLL/DLM | 1391 | * Set DLL/DLM |
| 1377 | ***********************************************/ | 1392 | ***********************************************/ |
| 1378 | mos7720_port->shadowLCR = mos7720_port->shadowLCR | UART_LCR_DLAB; | 1393 | mos7720_port->shadowLCR = mos7720_port->shadowLCR | UART_LCR_DLAB; |
| 1379 | write_mos_reg(serial, port_number, LCR, mos7720_port->shadowLCR); | 1394 | write_mos_reg(serial, port_number, MOS7720_LCR, |
| 1380 | write_mos_reg(serial, port_number, DLL, 0x01); | 1395 | mos7720_port->shadowLCR); |
| 1381 | write_mos_reg(serial, port_number, DLM, 0x00); | 1396 | write_mos_reg(serial, port_number, MOS7720_DLL, 0x01); |
| 1397 | write_mos_reg(serial, port_number, MOS7720_DLM, 0x00); | ||
| 1382 | mos7720_port->shadowLCR = mos7720_port->shadowLCR & ~UART_LCR_DLAB; | 1398 | mos7720_port->shadowLCR = mos7720_port->shadowLCR & ~UART_LCR_DLAB; |
| 1383 | write_mos_reg(serial, port_number, LCR, mos7720_port->shadowLCR); | 1399 | write_mos_reg(serial, port_number, MOS7720_LCR, |
| 1400 | mos7720_port->shadowLCR); | ||
| 1384 | 1401 | ||
| 1385 | return 0; | 1402 | return 0; |
| 1386 | } | 1403 | } |
| @@ -1488,15 +1505,16 @@ static int send_cmd_write_baud_rate(struct moschip_port *mos7720_port, | |||
| 1488 | 1505 | ||
| 1489 | /* Enable access to divisor latch */ | 1506 | /* Enable access to divisor latch */ |
| 1490 | mos7720_port->shadowLCR = mos7720_port->shadowLCR | UART_LCR_DLAB; | 1507 | mos7720_port->shadowLCR = mos7720_port->shadowLCR | UART_LCR_DLAB; |
| 1491 | write_mos_reg(serial, number, LCR, mos7720_port->shadowLCR); | 1508 | write_mos_reg(serial, number, MOS7720_LCR, mos7720_port->shadowLCR); |
| 1492 | 1509 | ||
| 1493 | /* Write the divisor */ | 1510 | /* Write the divisor */ |
| 1494 | write_mos_reg(serial, number, DLL, (__u8)(divisor & 0xff)); | 1511 | write_mos_reg(serial, number, MOS7720_DLL, (__u8)(divisor & 0xff)); |
| 1495 | write_mos_reg(serial, number, DLM, (__u8)((divisor & 0xff00) >> 8)); | 1512 | write_mos_reg(serial, number, MOS7720_DLM, |
| 1513 | (__u8)((divisor & 0xff00) >> 8)); | ||
| 1496 | 1514 | ||
| 1497 | /* Disable access to divisor latch */ | 1515 | /* Disable access to divisor latch */ |
| 1498 | mos7720_port->shadowLCR = mos7720_port->shadowLCR & ~UART_LCR_DLAB; | 1516 | mos7720_port->shadowLCR = mos7720_port->shadowLCR & ~UART_LCR_DLAB; |
| 1499 | write_mos_reg(serial, number, LCR, mos7720_port->shadowLCR); | 1517 | write_mos_reg(serial, number, MOS7720_LCR, mos7720_port->shadowLCR); |
| 1500 | 1518 | ||
| 1501 | return status; | 1519 | return status; |
| 1502 | } | 1520 | } |
| @@ -1600,14 +1618,16 @@ static void change_port_settings(struct tty_struct *tty, | |||
| 1600 | 1618 | ||
| 1601 | 1619 | ||
| 1602 | /* Disable Interrupts */ | 1620 | /* Disable Interrupts */ |
| 1603 | write_mos_reg(serial, port_number, IER, 0x00); | 1621 | write_mos_reg(serial, port_number, MOS7720_IER, 0x00); |
| 1604 | write_mos_reg(serial, port_number, FCR, 0x00); | 1622 | write_mos_reg(serial, port_number, MOS7720_FCR, 0x00); |
| 1605 | write_mos_reg(serial, port_number, FCR, 0xcf); | 1623 | write_mos_reg(serial, port_number, MOS7720_FCR, 0xcf); |
| 1606 | 1624 | ||
| 1607 | /* Send the updated LCR value to the mos7720 */ | 1625 | /* Send the updated LCR value to the mos7720 */ |
| 1608 | write_mos_reg(serial, port_number, LCR, mos7720_port->shadowLCR); | 1626 | write_mos_reg(serial, port_number, MOS7720_LCR, |
| 1627 | mos7720_port->shadowLCR); | ||
| 1609 | mos7720_port->shadowMCR = 0x0b; | 1628 | mos7720_port->shadowMCR = 0x0b; |
| 1610 | write_mos_reg(serial, port_number, MCR, mos7720_port->shadowMCR); | 1629 | write_mos_reg(serial, port_number, MOS7720_MCR, |
| 1630 | mos7720_port->shadowMCR); | ||
| 1611 | 1631 | ||
| 1612 | /* set up the MCR register and send it to the mos7720 */ | 1632 | /* set up the MCR register and send it to the mos7720 */ |
| 1613 | mos7720_port->shadowMCR = UART_MCR_OUT2; | 1633 | mos7720_port->shadowMCR = UART_MCR_OUT2; |
| @@ -1619,14 +1639,17 @@ static void change_port_settings(struct tty_struct *tty, | |||
| 1619 | /* To set hardware flow control to the specified * | 1639 | /* To set hardware flow control to the specified * |
| 1620 | * serial port, in SP1/2_CONTROL_REG */ | 1640 | * serial port, in SP1/2_CONTROL_REG */ |
| 1621 | if (port_number) | 1641 | if (port_number) |
| 1622 | write_mos_reg(serial, dummy, SP_CONTROL_REG, 0x01); | 1642 | write_mos_reg(serial, dummy, MOS7720_SP_CONTROL_REG, |
| 1643 | 0x01); | ||
| 1623 | else | 1644 | else |
| 1624 | write_mos_reg(serial, dummy, SP_CONTROL_REG, 0x02); | 1645 | write_mos_reg(serial, dummy, MOS7720_SP_CONTROL_REG, |
| 1646 | 0x02); | ||
| 1625 | 1647 | ||
| 1626 | } else | 1648 | } else |
| 1627 | mos7720_port->shadowMCR &= ~(UART_MCR_XONANY); | 1649 | mos7720_port->shadowMCR &= ~(UART_MCR_XONANY); |
| 1628 | 1650 | ||
| 1629 | write_mos_reg(serial, port_number, MCR, mos7720_port->shadowMCR); | 1651 | write_mos_reg(serial, port_number, MOS7720_MCR, |
| 1652 | mos7720_port->shadowMCR); | ||
| 1630 | 1653 | ||
| 1631 | /* Determine divisor based on baud rate */ | 1654 | /* Determine divisor based on baud rate */ |
| 1632 | baud = tty_get_baud_rate(tty); | 1655 | baud = tty_get_baud_rate(tty); |
| @@ -1639,7 +1662,7 @@ static void change_port_settings(struct tty_struct *tty, | |||
| 1639 | if (baud >= 230400) { | 1662 | if (baud >= 230400) { |
| 1640 | set_higher_rates(mos7720_port, baud); | 1663 | set_higher_rates(mos7720_port, baud); |
| 1641 | /* Enable Interrupts */ | 1664 | /* Enable Interrupts */ |
| 1642 | write_mos_reg(serial, port_number, IER, 0x0c); | 1665 | write_mos_reg(serial, port_number, MOS7720_IER, 0x0c); |
| 1643 | return; | 1666 | return; |
| 1644 | } | 1667 | } |
| 1645 | 1668 | ||
| @@ -1650,7 +1673,7 @@ static void change_port_settings(struct tty_struct *tty, | |||
| 1650 | if (cflag & CBAUD) | 1673 | if (cflag & CBAUD) |
| 1651 | tty_encode_baud_rate(tty, baud, baud); | 1674 | tty_encode_baud_rate(tty, baud, baud); |
| 1652 | /* Enable Interrupts */ | 1675 | /* Enable Interrupts */ |
| 1653 | write_mos_reg(serial, port_number, IER, 0x0c); | 1676 | write_mos_reg(serial, port_number, MOS7720_IER, 0x0c); |
| 1654 | 1677 | ||
| 1655 | if (port->read_urb->status != -EINPROGRESS) { | 1678 | if (port->read_urb->status != -EINPROGRESS) { |
| 1656 | status = usb_submit_urb(port->read_urb, GFP_KERNEL); | 1679 | status = usb_submit_urb(port->read_urb, GFP_KERNEL); |
| @@ -1725,7 +1748,7 @@ static int get_lsr_info(struct tty_struct *tty, | |||
| 1725 | 1748 | ||
| 1726 | count = mos7720_chars_in_buffer(tty); | 1749 | count = mos7720_chars_in_buffer(tty); |
| 1727 | if (count == 0) { | 1750 | if (count == 0) { |
| 1728 | read_mos_reg(port->serial, port_number, LSR, &data); | 1751 | read_mos_reg(port->serial, port_number, MOS7720_LSR, &data); |
| 1729 | if ((data & (UART_LSR_TEMT | UART_LSR_THRE)) | 1752 | if ((data & (UART_LSR_TEMT | UART_LSR_THRE)) |
| 1730 | == (UART_LSR_TEMT | UART_LSR_THRE)) { | 1753 | == (UART_LSR_TEMT | UART_LSR_THRE)) { |
| 1731 | dev_dbg(&port->dev, "%s -- Empty\n", __func__); | 1754 | dev_dbg(&port->dev, "%s -- Empty\n", __func__); |
| @@ -1782,7 +1805,7 @@ static int mos7720_tiocmset(struct tty_struct *tty, | |||
| 1782 | mcr &= ~UART_MCR_LOOP; | 1805 | mcr &= ~UART_MCR_LOOP; |
| 1783 | 1806 | ||
| 1784 | mos7720_port->shadowMCR = mcr; | 1807 | mos7720_port->shadowMCR = mcr; |
| 1785 | write_mos_reg(port->serial, port->port_number, MCR, | 1808 | write_mos_reg(port->serial, port->port_number, MOS7720_MCR, |
| 1786 | mos7720_port->shadowMCR); | 1809 | mos7720_port->shadowMCR); |
| 1787 | 1810 | ||
| 1788 | return 0; | 1811 | return 0; |
| @@ -1827,7 +1850,7 @@ static int set_modem_info(struct moschip_port *mos7720_port, unsigned int cmd, | |||
| 1827 | } | 1850 | } |
| 1828 | 1851 | ||
| 1829 | mos7720_port->shadowMCR = mcr; | 1852 | mos7720_port->shadowMCR = mcr; |
| 1830 | write_mos_reg(port->serial, port->port_number, MCR, | 1853 | write_mos_reg(port->serial, port->port_number, MOS7720_MCR, |
| 1831 | mos7720_port->shadowMCR); | 1854 | mos7720_port->shadowMCR); |
| 1832 | 1855 | ||
| 1833 | return 0; | 1856 | return 0; |
| @@ -1942,7 +1965,7 @@ static int mos7720_startup(struct usb_serial *serial) | |||
| 1942 | } | 1965 | } |
| 1943 | #endif | 1966 | #endif |
| 1944 | /* LSR For Port 1 */ | 1967 | /* LSR For Port 1 */ |
| 1945 | read_mos_reg(serial, 0, LSR, &data); | 1968 | read_mos_reg(serial, 0, MOS7720_LSR, &data); |
| 1946 | dev_dbg(&dev->dev, "LSR:%x\n", data); | 1969 | dev_dbg(&dev->dev, "LSR:%x\n", data); |
| 1947 | 1970 | ||
| 1948 | return 0; | 1971 | return 0; |
diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index f0c0c53359ad..19b85ee98a72 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c | |||
| @@ -1765,6 +1765,7 @@ static const struct usb_device_id option_ids[] = { | |||
| 1765 | { USB_DEVICE_AND_INTERFACE_INFO(0x2001, 0x7d03, 0xff, 0x00, 0x00) }, | 1765 | { USB_DEVICE_AND_INTERFACE_INFO(0x2001, 0x7d03, 0xff, 0x00, 0x00) }, |
| 1766 | { USB_DEVICE_AND_INTERFACE_INFO(0x07d1, 0x3e01, 0xff, 0xff, 0xff) }, /* D-Link DWM-152/C1 */ | 1766 | { USB_DEVICE_AND_INTERFACE_INFO(0x07d1, 0x3e01, 0xff, 0xff, 0xff) }, /* D-Link DWM-152/C1 */ |
| 1767 | { USB_DEVICE_AND_INTERFACE_INFO(0x07d1, 0x3e02, 0xff, 0xff, 0xff) }, /* D-Link DWM-156/C1 */ | 1767 | { USB_DEVICE_AND_INTERFACE_INFO(0x07d1, 0x3e02, 0xff, 0xff, 0xff) }, /* D-Link DWM-156/C1 */ |
| 1768 | { USB_DEVICE_INTERFACE_CLASS(0x2020, 0x4000, 0xff) }, /* OLICARD300 - MT6225 */ | ||
| 1768 | { USB_DEVICE(INOVIA_VENDOR_ID, INOVIA_SEW858) }, | 1769 | { USB_DEVICE(INOVIA_VENDOR_ID, INOVIA_SEW858) }, |
| 1769 | { USB_DEVICE(VIATELECOM_VENDOR_ID, VIATELECOM_PRODUCT_CDS7) }, | 1770 | { USB_DEVICE(VIATELECOM_VENDOR_ID, VIATELECOM_PRODUCT_CDS7) }, |
| 1770 | { } /* Terminating entry */ | 1771 | { } /* Terminating entry */ |
diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c index 529066bbc7e8..46f1f13b41f1 100644 --- a/drivers/usb/serial/usb-serial.c +++ b/drivers/usb/serial/usb-serial.c | |||
| @@ -1306,6 +1306,7 @@ static void __exit usb_serial_exit(void) | |||
| 1306 | tty_unregister_driver(usb_serial_tty_driver); | 1306 | tty_unregister_driver(usb_serial_tty_driver); |
| 1307 | put_tty_driver(usb_serial_tty_driver); | 1307 | put_tty_driver(usb_serial_tty_driver); |
| 1308 | bus_unregister(&usb_serial_bus_type); | 1308 | bus_unregister(&usb_serial_bus_type); |
| 1309 | idr_destroy(&serial_minors); | ||
| 1309 | } | 1310 | } |
| 1310 | 1311 | ||
| 1311 | 1312 | ||
diff --git a/drivers/watchdog/sp805_wdt.c b/drivers/watchdog/sp805_wdt.c index c1b03f4235b9..4e7fec36f5c3 100644 --- a/drivers/watchdog/sp805_wdt.c +++ b/drivers/watchdog/sp805_wdt.c | |||
| @@ -4,7 +4,7 @@ | |||
| 4 | * Watchdog driver for ARM SP805 watchdog module | 4 | * Watchdog driver for ARM SP805 watchdog module |
| 5 | * | 5 | * |
| 6 | * Copyright (C) 2010 ST Microelectronics | 6 | * Copyright (C) 2010 ST Microelectronics |
| 7 | * Viresh Kumar <viresh.linux@gmail.com> | 7 | * Viresh Kumar <vireshk@kernel.org> |
| 8 | * | 8 | * |
| 9 | * This file is licensed under the terms of the GNU General Public | 9 | * This file is licensed under the terms of the GNU General Public |
| 10 | * License version 2 or later. This program is licensed "as is" without any | 10 | * License version 2 or later. This program is licensed "as is" without any |
| @@ -303,6 +303,6 @@ static struct amba_driver sp805_wdt_driver = { | |||
| 303 | 303 | ||
| 304 | module_amba_driver(sp805_wdt_driver); | 304 | module_amba_driver(sp805_wdt_driver); |
| 305 | 305 | ||
| 306 | MODULE_AUTHOR("Viresh Kumar <viresh.linux@gmail.com>"); | 306 | MODULE_AUTHOR("Viresh Kumar <vireshk@kernel.org>"); |
| 307 | MODULE_DESCRIPTION("ARM SP805 Watchdog Driver"); | 307 | MODULE_DESCRIPTION("ARM SP805 Watchdog Driver"); |
| 308 | MODULE_LICENSE("GPL"); | 308 | MODULE_LICENSE("GPL"); |
