diff options
Diffstat (limited to 'drivers')
227 files changed, 3280 insertions, 3536 deletions
diff --git a/drivers/acpi/acpi_pnp.c b/drivers/acpi/acpi_pnp.c index b193f8425999..ff6d8adc9cda 100644 --- a/drivers/acpi/acpi_pnp.c +++ b/drivers/acpi/acpi_pnp.c | |||
| @@ -304,6 +304,8 @@ static const struct acpi_device_id acpi_pnp_device_ids[] = { | |||
| 304 | {"PNPb006"}, | 304 | {"PNPb006"}, |
| 305 | /* cs423x-pnpbios */ | 305 | /* cs423x-pnpbios */ |
| 306 | {"CSC0100"}, | 306 | {"CSC0100"}, |
| 307 | {"CSC0103"}, | ||
| 308 | {"CSC0110"}, | ||
| 307 | {"CSC0000"}, | 309 | {"CSC0000"}, |
| 308 | {"GIM0100"}, /* Guillemot Turtlebeach something appears to be cs4232 compatible */ | 310 | {"GIM0100"}, /* Guillemot Turtlebeach something appears to be cs4232 compatible */ |
| 309 | /* es18xx-pnpbios */ | 311 | /* es18xx-pnpbios */ |
diff --git a/drivers/acpi/acpica/utglobal.c b/drivers/acpi/acpica/utglobal.c index a72685c1e819..5e8df9177da4 100644 --- a/drivers/acpi/acpica/utglobal.c +++ b/drivers/acpi/acpica/utglobal.c | |||
| @@ -102,19 +102,12 @@ const struct acpi_predefined_names acpi_gbl_pre_defined_names[] = { | |||
| 102 | {"_SB_", ACPI_TYPE_DEVICE, NULL}, | 102 | {"_SB_", ACPI_TYPE_DEVICE, NULL}, |
| 103 | {"_SI_", ACPI_TYPE_LOCAL_SCOPE, NULL}, | 103 | {"_SI_", ACPI_TYPE_LOCAL_SCOPE, NULL}, |
| 104 | {"_TZ_", ACPI_TYPE_DEVICE, NULL}, | 104 | {"_TZ_", ACPI_TYPE_DEVICE, NULL}, |
| 105 | /* | 105 | {"_REV", ACPI_TYPE_INTEGER, (char *)ACPI_CA_SUPPORT_LEVEL}, |
| 106 | * March, 2015: | ||
| 107 | * The _REV object is in the process of being deprecated, because | ||
| 108 | * other ACPI implementations permanently return 2. Thus, it | ||
| 109 | * has little or no value. Return 2 for compatibility with | ||
| 110 | * other ACPI implementations. | ||
| 111 | */ | ||
| 112 | {"_REV", ACPI_TYPE_INTEGER, ACPI_CAST_PTR(char, 2)}, | ||
| 113 | {"_OS_", ACPI_TYPE_STRING, ACPI_OS_NAME}, | 106 | {"_OS_", ACPI_TYPE_STRING, ACPI_OS_NAME}, |
| 114 | {"_GL_", ACPI_TYPE_MUTEX, ACPI_CAST_PTR(char, 1)}, | 107 | {"_GL_", ACPI_TYPE_MUTEX, (char *)1}, |
| 115 | 108 | ||
| 116 | #if !defined (ACPI_NO_METHOD_EXECUTION) || defined (ACPI_CONSTANT_EVAL_ONLY) | 109 | #if !defined (ACPI_NO_METHOD_EXECUTION) || defined (ACPI_CONSTANT_EVAL_ONLY) |
| 117 | {"_OSI", ACPI_TYPE_METHOD, ACPI_CAST_PTR(char, 1)}, | 110 | {"_OSI", ACPI_TYPE_METHOD, (char *)1}, |
| 118 | #endif | 111 | #endif |
| 119 | 112 | ||
| 120 | /* Table terminator */ | 113 | /* Table terminator */ |
diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c index 39748bb3a543..7ccba395c9dd 100644 --- a/drivers/acpi/osl.c +++ b/drivers/acpi/osl.c | |||
| @@ -182,7 +182,7 @@ static void __init acpi_request_region (struct acpi_generic_address *gas, | |||
| 182 | request_mem_region(addr, length, desc); | 182 | request_mem_region(addr, length, desc); |
| 183 | } | 183 | } |
| 184 | 184 | ||
| 185 | static int __init acpi_reserve_resources(void) | 185 | static void __init acpi_reserve_resources(void) |
| 186 | { | 186 | { |
| 187 | acpi_request_region(&acpi_gbl_FADT.xpm1a_event_block, acpi_gbl_FADT.pm1_event_length, | 187 | acpi_request_region(&acpi_gbl_FADT.xpm1a_event_block, acpi_gbl_FADT.pm1_event_length, |
| 188 | "ACPI PM1a_EVT_BLK"); | 188 | "ACPI PM1a_EVT_BLK"); |
| @@ -211,10 +211,7 @@ static int __init acpi_reserve_resources(void) | |||
| 211 | if (!(acpi_gbl_FADT.gpe1_block_length & 0x1)) | 211 | if (!(acpi_gbl_FADT.gpe1_block_length & 0x1)) |
| 212 | acpi_request_region(&acpi_gbl_FADT.xgpe1_block, | 212 | acpi_request_region(&acpi_gbl_FADT.xgpe1_block, |
| 213 | acpi_gbl_FADT.gpe1_block_length, "ACPI GPE1_BLK"); | 213 | acpi_gbl_FADT.gpe1_block_length, "ACPI GPE1_BLK"); |
| 214 | |||
| 215 | return 0; | ||
| 216 | } | 214 | } |
| 217 | device_initcall(acpi_reserve_resources); | ||
| 218 | 215 | ||
| 219 | void acpi_os_printf(const char *fmt, ...) | 216 | void acpi_os_printf(const char *fmt, ...) |
| 220 | { | 217 | { |
| @@ -1845,6 +1842,7 @@ acpi_status __init acpi_os_initialize(void) | |||
| 1845 | 1842 | ||
| 1846 | acpi_status __init acpi_os_initialize1(void) | 1843 | acpi_status __init acpi_os_initialize1(void) |
| 1847 | { | 1844 | { |
| 1845 | acpi_reserve_resources(); | ||
| 1848 | kacpid_wq = alloc_workqueue("kacpid", 0, 1); | 1846 | kacpid_wq = alloc_workqueue("kacpid", 0, 1); |
| 1849 | kacpi_notify_wq = alloc_workqueue("kacpi_notify", 0, 1); | 1847 | kacpi_notify_wq = alloc_workqueue("kacpi_notify", 0, 1); |
| 1850 | kacpi_hotplug_wq = alloc_ordered_workqueue("kacpi_hotplug", 0); | 1848 | kacpi_hotplug_wq = alloc_ordered_workqueue("kacpi_hotplug", 0); |
diff --git a/drivers/acpi/resource.c b/drivers/acpi/resource.c index 5589a6e2a023..8244f013f210 100644 --- a/drivers/acpi/resource.c +++ b/drivers/acpi/resource.c | |||
| @@ -573,7 +573,7 @@ EXPORT_SYMBOL_GPL(acpi_dev_get_resources); | |||
| 573 | * @ares: Input ACPI resource object. | 573 | * @ares: Input ACPI resource object. |
| 574 | * @types: Valid resource types of IORESOURCE_XXX | 574 | * @types: Valid resource types of IORESOURCE_XXX |
| 575 | * | 575 | * |
| 576 | * This is a hepler function to support acpi_dev_get_resources(), which filters | 576 | * This is a helper function to support acpi_dev_get_resources(), which filters |
| 577 | * ACPI resource objects according to resource types. | 577 | * ACPI resource objects according to resource types. |
| 578 | */ | 578 | */ |
| 579 | int acpi_dev_filter_resource_type(struct acpi_resource *ares, | 579 | int acpi_dev_filter_resource_type(struct acpi_resource *ares, |
diff --git a/drivers/acpi/sbshc.c b/drivers/acpi/sbshc.c index 26e5b5060523..bf034f8b7c1a 100644 --- a/drivers/acpi/sbshc.c +++ b/drivers/acpi/sbshc.c | |||
| @@ -14,6 +14,7 @@ | |||
| 14 | #include <linux/delay.h> | 14 | #include <linux/delay.h> |
| 15 | #include <linux/module.h> | 15 | #include <linux/module.h> |
| 16 | #include <linux/interrupt.h> | 16 | #include <linux/interrupt.h> |
| 17 | #include <linux/dmi.h> | ||
| 17 | #include "sbshc.h" | 18 | #include "sbshc.h" |
| 18 | 19 | ||
| 19 | #define PREFIX "ACPI: " | 20 | #define PREFIX "ACPI: " |
| @@ -87,6 +88,8 @@ enum acpi_smb_offset { | |||
| 87 | ACPI_SMB_ALARM_DATA = 0x26, /* 2 bytes alarm data */ | 88 | ACPI_SMB_ALARM_DATA = 0x26, /* 2 bytes alarm data */ |
| 88 | }; | 89 | }; |
| 89 | 90 | ||
| 91 | static bool macbook; | ||
| 92 | |||
| 90 | static inline int smb_hc_read(struct acpi_smb_hc *hc, u8 address, u8 *data) | 93 | static inline int smb_hc_read(struct acpi_smb_hc *hc, u8 address, u8 *data) |
| 91 | { | 94 | { |
| 92 | return ec_read(hc->offset + address, data); | 95 | return ec_read(hc->offset + address, data); |
| @@ -132,6 +135,8 @@ static int acpi_smbus_transaction(struct acpi_smb_hc *hc, u8 protocol, | |||
| 132 | } | 135 | } |
| 133 | 136 | ||
| 134 | mutex_lock(&hc->lock); | 137 | mutex_lock(&hc->lock); |
| 138 | if (macbook) | ||
| 139 | udelay(5); | ||
| 135 | if (smb_hc_read(hc, ACPI_SMB_PROTOCOL, &temp)) | 140 | if (smb_hc_read(hc, ACPI_SMB_PROTOCOL, &temp)) |
| 136 | goto end; | 141 | goto end; |
| 137 | if (temp) { | 142 | if (temp) { |
| @@ -257,12 +262,29 @@ extern int acpi_ec_add_query_handler(struct acpi_ec *ec, u8 query_bit, | |||
| 257 | acpi_handle handle, acpi_ec_query_func func, | 262 | acpi_handle handle, acpi_ec_query_func func, |
| 258 | void *data); | 263 | void *data); |
| 259 | 264 | ||
| 265 | static int macbook_dmi_match(const struct dmi_system_id *d) | ||
| 266 | { | ||
| 267 | pr_debug("Detected MacBook, enabling workaround\n"); | ||
| 268 | macbook = true; | ||
| 269 | return 0; | ||
| 270 | } | ||
| 271 | |||
| 272 | static struct dmi_system_id acpi_smbus_dmi_table[] = { | ||
| 273 | { macbook_dmi_match, "Apple MacBook", { | ||
| 274 | DMI_MATCH(DMI_BOARD_VENDOR, "Apple"), | ||
| 275 | DMI_MATCH(DMI_PRODUCT_NAME, "MacBook") }, | ||
| 276 | }, | ||
| 277 | { }, | ||
| 278 | }; | ||
| 279 | |||
| 260 | static int acpi_smbus_hc_add(struct acpi_device *device) | 280 | static int acpi_smbus_hc_add(struct acpi_device *device) |
| 261 | { | 281 | { |
| 262 | int status; | 282 | int status; |
| 263 | unsigned long long val; | 283 | unsigned long long val; |
| 264 | struct acpi_smb_hc *hc; | 284 | struct acpi_smb_hc *hc; |
| 265 | 285 | ||
| 286 | dmi_check_system(acpi_smbus_dmi_table); | ||
| 287 | |||
| 266 | if (!device) | 288 | if (!device) |
| 267 | return -EINVAL; | 289 | return -EINVAL; |
| 268 | 290 | ||
diff --git a/drivers/ata/Kconfig b/drivers/ata/Kconfig index 5f601553b9b0..9dca4b995be0 100644 --- a/drivers/ata/Kconfig +++ b/drivers/ata/Kconfig | |||
| @@ -270,6 +270,7 @@ config ATA_PIIX | |||
| 270 | config SATA_DWC | 270 | config SATA_DWC |
| 271 | tristate "DesignWare Cores SATA support" | 271 | tristate "DesignWare Cores SATA support" |
| 272 | depends on 460EX | 272 | depends on 460EX |
| 273 | select DW_DMAC | ||
| 273 | help | 274 | help |
| 274 | This option enables support for the on-chip SATA controller of the | 275 | This option enables support for the on-chip SATA controller of the |
| 275 | AppliedMicro processor 460EX. | 276 | AppliedMicro processor 460EX. |
| @@ -729,15 +730,6 @@ config PATA_SC1200 | |||
| 729 | 730 | ||
| 730 | If unsure, say N. | 731 | If unsure, say N. |
| 731 | 732 | ||
| 732 | config PATA_SCC | ||
| 733 | tristate "Toshiba's Cell Reference Set IDE support" | ||
| 734 | depends on PCI && PPC_CELLEB | ||
| 735 | help | ||
| 736 | This option enables support for the built-in IDE controller on | ||
| 737 | Toshiba Cell Reference Board. | ||
| 738 | |||
| 739 | If unsure, say N. | ||
| 740 | |||
| 741 | config PATA_SCH | 733 | config PATA_SCH |
| 742 | tristate "Intel SCH PATA support" | 734 | tristate "Intel SCH PATA support" |
| 743 | depends on PCI | 735 | depends on PCI |
diff --git a/drivers/ata/Makefile b/drivers/ata/Makefile index b67e995179a9..40f7865f20a1 100644 --- a/drivers/ata/Makefile +++ b/drivers/ata/Makefile | |||
| @@ -75,7 +75,6 @@ obj-$(CONFIG_PATA_PDC_OLD) += pata_pdc202xx_old.o | |||
| 75 | obj-$(CONFIG_PATA_RADISYS) += pata_radisys.o | 75 | obj-$(CONFIG_PATA_RADISYS) += pata_radisys.o |
| 76 | obj-$(CONFIG_PATA_RDC) += pata_rdc.o | 76 | obj-$(CONFIG_PATA_RDC) += pata_rdc.o |
| 77 | obj-$(CONFIG_PATA_SC1200) += pata_sc1200.o | 77 | obj-$(CONFIG_PATA_SC1200) += pata_sc1200.o |
| 78 | obj-$(CONFIG_PATA_SCC) += pata_scc.o | ||
| 79 | obj-$(CONFIG_PATA_SCH) += pata_sch.o | 78 | obj-$(CONFIG_PATA_SCH) += pata_sch.o |
| 80 | obj-$(CONFIG_PATA_SERVERWORKS) += pata_serverworks.o | 79 | obj-$(CONFIG_PATA_SERVERWORKS) += pata_serverworks.o |
| 81 | obj-$(CONFIG_PATA_SIL680) += pata_sil680.o | 80 | obj-$(CONFIG_PATA_SIL680) += pata_sil680.o |
diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c index c7a92a743ed0..65ee94454bbd 100644 --- a/drivers/ata/ahci.c +++ b/drivers/ata/ahci.c | |||
| @@ -66,6 +66,7 @@ enum board_ids { | |||
| 66 | board_ahci_yes_fbs, | 66 | board_ahci_yes_fbs, |
| 67 | 67 | ||
| 68 | /* board IDs for specific chipsets in alphabetical order */ | 68 | /* board IDs for specific chipsets in alphabetical order */ |
| 69 | board_ahci_avn, | ||
| 69 | board_ahci_mcp65, | 70 | board_ahci_mcp65, |
| 70 | board_ahci_mcp77, | 71 | board_ahci_mcp77, |
| 71 | board_ahci_mcp89, | 72 | board_ahci_mcp89, |
| @@ -84,6 +85,8 @@ enum board_ids { | |||
| 84 | static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent); | 85 | static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent); |
| 85 | static int ahci_vt8251_hardreset(struct ata_link *link, unsigned int *class, | 86 | static int ahci_vt8251_hardreset(struct ata_link *link, unsigned int *class, |
| 86 | unsigned long deadline); | 87 | unsigned long deadline); |
| 88 | static int ahci_avn_hardreset(struct ata_link *link, unsigned int *class, | ||
| 89 | unsigned long deadline); | ||
| 87 | static void ahci_mcp89_apple_enable(struct pci_dev *pdev); | 90 | static void ahci_mcp89_apple_enable(struct pci_dev *pdev); |
| 88 | static bool is_mcp89_apple(struct pci_dev *pdev); | 91 | static bool is_mcp89_apple(struct pci_dev *pdev); |
| 89 | static int ahci_p5wdh_hardreset(struct ata_link *link, unsigned int *class, | 92 | static int ahci_p5wdh_hardreset(struct ata_link *link, unsigned int *class, |
| @@ -107,6 +110,11 @@ static struct ata_port_operations ahci_p5wdh_ops = { | |||
| 107 | .hardreset = ahci_p5wdh_hardreset, | 110 | .hardreset = ahci_p5wdh_hardreset, |
| 108 | }; | 111 | }; |
| 109 | 112 | ||
| 113 | static struct ata_port_operations ahci_avn_ops = { | ||
| 114 | .inherits = &ahci_ops, | ||
| 115 | .hardreset = ahci_avn_hardreset, | ||
| 116 | }; | ||
| 117 | |||
| 110 | static const struct ata_port_info ahci_port_info[] = { | 118 | static const struct ata_port_info ahci_port_info[] = { |
| 111 | /* by features */ | 119 | /* by features */ |
| 112 | [board_ahci] = { | 120 | [board_ahci] = { |
| @@ -151,6 +159,12 @@ static const struct ata_port_info ahci_port_info[] = { | |||
| 151 | .port_ops = &ahci_ops, | 159 | .port_ops = &ahci_ops, |
| 152 | }, | 160 | }, |
| 153 | /* by chipsets */ | 161 | /* by chipsets */ |
| 162 | [board_ahci_avn] = { | ||
| 163 | .flags = AHCI_FLAG_COMMON, | ||
| 164 | .pio_mask = ATA_PIO4, | ||
| 165 | .udma_mask = ATA_UDMA6, | ||
| 166 | .port_ops = &ahci_avn_ops, | ||
| 167 | }, | ||
| 154 | [board_ahci_mcp65] = { | 168 | [board_ahci_mcp65] = { |
| 155 | AHCI_HFLAGS (AHCI_HFLAG_NO_FPDMA_AA | AHCI_HFLAG_NO_PMP | | 169 | AHCI_HFLAGS (AHCI_HFLAG_NO_FPDMA_AA | AHCI_HFLAG_NO_PMP | |
| 156 | AHCI_HFLAG_YES_NCQ), | 170 | AHCI_HFLAG_YES_NCQ), |
| @@ -290,14 +304,14 @@ static const struct pci_device_id ahci_pci_tbl[] = { | |||
| 290 | { PCI_VDEVICE(INTEL, 0x1f27), board_ahci }, /* Avoton RAID */ | 304 | { PCI_VDEVICE(INTEL, 0x1f27), board_ahci }, /* Avoton RAID */ |
| 291 | { PCI_VDEVICE(INTEL, 0x1f2e), board_ahci }, /* Avoton RAID */ | 305 | { PCI_VDEVICE(INTEL, 0x1f2e), board_ahci }, /* Avoton RAID */ |
| 292 | { PCI_VDEVICE(INTEL, 0x1f2f), board_ahci }, /* Avoton RAID */ | 306 | { PCI_VDEVICE(INTEL, 0x1f2f), board_ahci }, /* Avoton RAID */ |
| 293 | { PCI_VDEVICE(INTEL, 0x1f32), board_ahci }, /* Avoton AHCI */ | 307 | { PCI_VDEVICE(INTEL, 0x1f32), board_ahci_avn }, /* Avoton AHCI */ |
| 294 | { PCI_VDEVICE(INTEL, 0x1f33), board_ahci }, /* Avoton AHCI */ | 308 | { PCI_VDEVICE(INTEL, 0x1f33), board_ahci_avn }, /* Avoton AHCI */ |
| 295 | { PCI_VDEVICE(INTEL, 0x1f34), board_ahci }, /* Avoton RAID */ | 309 | { PCI_VDEVICE(INTEL, 0x1f34), board_ahci_avn }, /* Avoton RAID */ |
| 296 | { PCI_VDEVICE(INTEL, 0x1f35), board_ahci }, /* Avoton RAID */ | 310 | { PCI_VDEVICE(INTEL, 0x1f35), board_ahci_avn }, /* Avoton RAID */ |
| 297 | { PCI_VDEVICE(INTEL, 0x1f36), board_ahci }, /* Avoton RAID */ | 311 | { PCI_VDEVICE(INTEL, 0x1f36), board_ahci_avn }, /* Avoton RAID */ |
| 298 | { PCI_VDEVICE(INTEL, 0x1f37), board_ahci }, /* Avoton RAID */ | 312 | { PCI_VDEVICE(INTEL, 0x1f37), board_ahci_avn }, /* Avoton RAID */ |
| 299 | { PCI_VDEVICE(INTEL, 0x1f3e), board_ahci }, /* Avoton RAID */ | 313 | { PCI_VDEVICE(INTEL, 0x1f3e), board_ahci_avn }, /* Avoton RAID */ |
| 300 | { PCI_VDEVICE(INTEL, 0x1f3f), board_ahci }, /* Avoton RAID */ | 314 | { PCI_VDEVICE(INTEL, 0x1f3f), board_ahci_avn }, /* Avoton RAID */ |
| 301 | { PCI_VDEVICE(INTEL, 0x2823), board_ahci }, /* Wellsburg RAID */ | 315 | { PCI_VDEVICE(INTEL, 0x2823), board_ahci }, /* Wellsburg RAID */ |
| 302 | { PCI_VDEVICE(INTEL, 0x2827), board_ahci }, /* Wellsburg RAID */ | 316 | { PCI_VDEVICE(INTEL, 0x2827), board_ahci }, /* Wellsburg RAID */ |
| 303 | { PCI_VDEVICE(INTEL, 0x8d02), board_ahci }, /* Wellsburg AHCI */ | 317 | { PCI_VDEVICE(INTEL, 0x8d02), board_ahci }, /* Wellsburg AHCI */ |
| @@ -670,6 +684,79 @@ static int ahci_p5wdh_hardreset(struct ata_link *link, unsigned int *class, | |||
| 670 | return rc; | 684 | return rc; |
| 671 | } | 685 | } |
| 672 | 686 | ||
| 687 | /* | ||
| 688 | * ahci_avn_hardreset - attempt more aggressive recovery of Avoton ports. | ||
| 689 | * | ||
| 690 | * It has been observed with some SSDs that the timing of events in the | ||
| 691 | * link synchronization phase can leave the port in a state that can not | ||
| 692 | * be recovered by a SATA-hard-reset alone. The failing signature is | ||
| 693 | * SStatus.DET stuck at 1 ("Device presence detected but Phy | ||
| 694 | * communication not established"). It was found that unloading and | ||
| 695 | * reloading the driver when this problem occurs allows the drive | ||
| 696 | * connection to be recovered (DET advanced to 0x3). The critical | ||
| 697 | * component of reloading the driver is that the port state machines are | ||
| 698 | * reset by bouncing "port enable" in the AHCI PCS configuration | ||
| 699 | * register. So, reproduce that effect by bouncing a port whenever we | ||
| 700 | * see DET==1 after a reset. | ||
| 701 | */ | ||
| 702 | static int ahci_avn_hardreset(struct ata_link *link, unsigned int *class, | ||
| 703 | unsigned long deadline) | ||
| 704 | { | ||
| 705 | const unsigned long *timing = sata_ehc_deb_timing(&link->eh_context); | ||
| 706 | struct ata_port *ap = link->ap; | ||
| 707 | struct ahci_port_priv *pp = ap->private_data; | ||
| 708 | struct ahci_host_priv *hpriv = ap->host->private_data; | ||
| 709 | u8 *d2h_fis = pp->rx_fis + RX_FIS_D2H_REG; | ||
| 710 | unsigned long tmo = deadline - jiffies; | ||
| 711 | struct ata_taskfile tf; | ||
| 712 | bool online; | ||
| 713 | int rc, i; | ||
| 714 | |||
| 715 | DPRINTK("ENTER\n"); | ||
| 716 | |||
| 717 | ahci_stop_engine(ap); | ||
| 718 | |||
| 719 | for (i = 0; i < 2; i++) { | ||
| 720 | u16 val; | ||
| 721 | u32 sstatus; | ||
| 722 | int port = ap->port_no; | ||
| 723 | struct ata_host *host = ap->host; | ||
| 724 | struct pci_dev *pdev = to_pci_dev(host->dev); | ||
| 725 | |||
| 726 | /* clear D2H reception area to properly wait for D2H FIS */ | ||
| 727 | ata_tf_init(link->device, &tf); | ||
| 728 | tf.command = ATA_BUSY; | ||
| 729 | ata_tf_to_fis(&tf, 0, 0, d2h_fis); | ||
| 730 | |||
| 731 | rc = sata_link_hardreset(link, timing, deadline, &online, | ||
| 732 | ahci_check_ready); | ||
| 733 | |||
| 734 | if (sata_scr_read(link, SCR_STATUS, &sstatus) != 0 || | ||
| 735 | (sstatus & 0xf) != 1) | ||
| 736 | break; | ||
| 737 | |||
| 738 | ata_link_printk(link, KERN_INFO, "avn bounce port%d\n", | ||
| 739 | port); | ||
| 740 | |||
| 741 | pci_read_config_word(pdev, 0x92, &val); | ||
| 742 | val &= ~(1 << port); | ||
| 743 | pci_write_config_word(pdev, 0x92, val); | ||
| 744 | ata_msleep(ap, 1000); | ||
| 745 | val |= 1 << port; | ||
| 746 | pci_write_config_word(pdev, 0x92, val); | ||
| 747 | deadline += tmo; | ||
| 748 | } | ||
| 749 | |||
| 750 | hpriv->start_engine(ap); | ||
| 751 | |||
| 752 | if (online) | ||
| 753 | *class = ahci_dev_classify(ap); | ||
| 754 | |||
| 755 | DPRINTK("EXIT, rc=%d, class=%u\n", rc, *class); | ||
| 756 | return rc; | ||
| 757 | } | ||
| 758 | |||
| 759 | |||
| 673 | #ifdef CONFIG_PM | 760 | #ifdef CONFIG_PM |
| 674 | static int ahci_pci_device_suspend(struct pci_dev *pdev, pm_message_t mesg) | 761 | static int ahci_pci_device_suspend(struct pci_dev *pdev, pm_message_t mesg) |
| 675 | { | 762 | { |
diff --git a/drivers/ata/ahci_st.c b/drivers/ata/ahci_st.c index ea0ff005b86c..8ff428fe8e0f 100644 --- a/drivers/ata/ahci_st.c +++ b/drivers/ata/ahci_st.c | |||
| @@ -37,7 +37,6 @@ struct st_ahci_drv_data { | |||
| 37 | struct reset_control *pwr; | 37 | struct reset_control *pwr; |
| 38 | struct reset_control *sw_rst; | 38 | struct reset_control *sw_rst; |
| 39 | struct reset_control *pwr_rst; | 39 | struct reset_control *pwr_rst; |
| 40 | struct ahci_host_priv *hpriv; | ||
| 41 | }; | 40 | }; |
| 42 | 41 | ||
| 43 | static void st_ahci_configure_oob(void __iomem *mmio) | 42 | static void st_ahci_configure_oob(void __iomem *mmio) |
| @@ -55,9 +54,10 @@ static void st_ahci_configure_oob(void __iomem *mmio) | |||
| 55 | writel(new_val, mmio + ST_AHCI_OOBR); | 54 | writel(new_val, mmio + ST_AHCI_OOBR); |
| 56 | } | 55 | } |
| 57 | 56 | ||
| 58 | static int st_ahci_deassert_resets(struct device *dev) | 57 | static int st_ahci_deassert_resets(struct ahci_host_priv *hpriv, |
| 58 | struct device *dev) | ||
| 59 | { | 59 | { |
| 60 | struct st_ahci_drv_data *drv_data = dev_get_drvdata(dev); | 60 | struct st_ahci_drv_data *drv_data = hpriv->plat_data; |
| 61 | int err; | 61 | int err; |
| 62 | 62 | ||
| 63 | if (drv_data->pwr) { | 63 | if (drv_data->pwr) { |
| @@ -90,8 +90,8 @@ static int st_ahci_deassert_resets(struct device *dev) | |||
| 90 | static void st_ahci_host_stop(struct ata_host *host) | 90 | static void st_ahci_host_stop(struct ata_host *host) |
| 91 | { | 91 | { |
| 92 | struct ahci_host_priv *hpriv = host->private_data; | 92 | struct ahci_host_priv *hpriv = host->private_data; |
| 93 | struct st_ahci_drv_data *drv_data = hpriv->plat_data; | ||
| 93 | struct device *dev = host->dev; | 94 | struct device *dev = host->dev; |
| 94 | struct st_ahci_drv_data *drv_data = dev_get_drvdata(dev); | ||
| 95 | int err; | 95 | int err; |
| 96 | 96 | ||
| 97 | if (drv_data->pwr) { | 97 | if (drv_data->pwr) { |
| @@ -103,29 +103,30 @@ static void st_ahci_host_stop(struct ata_host *host) | |||
| 103 | ahci_platform_disable_resources(hpriv); | 103 | ahci_platform_disable_resources(hpriv); |
| 104 | } | 104 | } |
| 105 | 105 | ||
| 106 | static int st_ahci_probe_resets(struct platform_device *pdev) | 106 | static int st_ahci_probe_resets(struct ahci_host_priv *hpriv, |
| 107 | struct device *dev) | ||
| 107 | { | 108 | { |
| 108 | struct st_ahci_drv_data *drv_data = platform_get_drvdata(pdev); | 109 | struct st_ahci_drv_data *drv_data = hpriv->plat_data; |
| 109 | 110 | ||
| 110 | drv_data->pwr = devm_reset_control_get(&pdev->dev, "pwr-dwn"); | 111 | drv_data->pwr = devm_reset_control_get(dev, "pwr-dwn"); |
| 111 | if (IS_ERR(drv_data->pwr)) { | 112 | if (IS_ERR(drv_data->pwr)) { |
| 112 | dev_info(&pdev->dev, "power reset control not defined\n"); | 113 | dev_info(dev, "power reset control not defined\n"); |
| 113 | drv_data->pwr = NULL; | 114 | drv_data->pwr = NULL; |
| 114 | } | 115 | } |
| 115 | 116 | ||
| 116 | drv_data->sw_rst = devm_reset_control_get(&pdev->dev, "sw-rst"); | 117 | drv_data->sw_rst = devm_reset_control_get(dev, "sw-rst"); |
| 117 | if (IS_ERR(drv_data->sw_rst)) { | 118 | if (IS_ERR(drv_data->sw_rst)) { |
| 118 | dev_info(&pdev->dev, "soft reset control not defined\n"); | 119 | dev_info(dev, "soft reset control not defined\n"); |
| 119 | drv_data->sw_rst = NULL; | 120 | drv_data->sw_rst = NULL; |
| 120 | } | 121 | } |
| 121 | 122 | ||
| 122 | drv_data->pwr_rst = devm_reset_control_get(&pdev->dev, "pwr-rst"); | 123 | drv_data->pwr_rst = devm_reset_control_get(dev, "pwr-rst"); |
| 123 | if (IS_ERR(drv_data->pwr_rst)) { | 124 | if (IS_ERR(drv_data->pwr_rst)) { |
| 124 | dev_dbg(&pdev->dev, "power soft reset control not defined\n"); | 125 | dev_dbg(dev, "power soft reset control not defined\n"); |
| 125 | drv_data->pwr_rst = NULL; | 126 | drv_data->pwr_rst = NULL; |
| 126 | } | 127 | } |
| 127 | 128 | ||
| 128 | return st_ahci_deassert_resets(&pdev->dev); | 129 | return st_ahci_deassert_resets(hpriv, dev); |
| 129 | } | 130 | } |
| 130 | 131 | ||
| 131 | static struct ata_port_operations st_ahci_port_ops = { | 132 | static struct ata_port_operations st_ahci_port_ops = { |
| @@ -154,15 +155,12 @@ static int st_ahci_probe(struct platform_device *pdev) | |||
| 154 | if (!drv_data) | 155 | if (!drv_data) |
| 155 | return -ENOMEM; | 156 | return -ENOMEM; |
| 156 | 157 | ||
| 157 | platform_set_drvdata(pdev, drv_data); | ||
| 158 | |||
| 159 | hpriv = ahci_platform_get_resources(pdev); | 158 | hpriv = ahci_platform_get_resources(pdev); |
| 160 | if (IS_ERR(hpriv)) | 159 | if (IS_ERR(hpriv)) |
| 161 | return PTR_ERR(hpriv); | 160 | return PTR_ERR(hpriv); |
| 161 | hpriv->plat_data = drv_data; | ||
| 162 | 162 | ||
| 163 | drv_data->hpriv = hpriv; | 163 | err = st_ahci_probe_resets(hpriv, &pdev->dev); |
| 164 | |||
| 165 | err = st_ahci_probe_resets(pdev); | ||
| 166 | if (err) | 164 | if (err) |
| 167 | return err; | 165 | return err; |
| 168 | 166 | ||
| @@ -170,7 +168,7 @@ static int st_ahci_probe(struct platform_device *pdev) | |||
| 170 | if (err) | 168 | if (err) |
| 171 | return err; | 169 | return err; |
| 172 | 170 | ||
| 173 | st_ahci_configure_oob(drv_data->hpriv->mmio); | 171 | st_ahci_configure_oob(hpriv->mmio); |
| 174 | 172 | ||
| 175 | err = ahci_platform_init_host(pdev, hpriv, &st_ahci_port_info, | 173 | err = ahci_platform_init_host(pdev, hpriv, &st_ahci_port_info, |
| 176 | &ahci_platform_sht); | 174 | &ahci_platform_sht); |
| @@ -185,8 +183,9 @@ static int st_ahci_probe(struct platform_device *pdev) | |||
| 185 | #ifdef CONFIG_PM_SLEEP | 183 | #ifdef CONFIG_PM_SLEEP |
| 186 | static int st_ahci_suspend(struct device *dev) | 184 | static int st_ahci_suspend(struct device *dev) |
| 187 | { | 185 | { |
| 188 | struct st_ahci_drv_data *drv_data = dev_get_drvdata(dev); | 186 | struct ata_host *host = dev_get_drvdata(dev); |
| 189 | struct ahci_host_priv *hpriv = drv_data->hpriv; | 187 | struct ahci_host_priv *hpriv = host->private_data; |
| 188 | struct st_ahci_drv_data *drv_data = hpriv->plat_data; | ||
| 190 | int err; | 189 | int err; |
| 191 | 190 | ||
| 192 | err = ahci_platform_suspend_host(dev); | 191 | err = ahci_platform_suspend_host(dev); |
| @@ -208,21 +207,21 @@ static int st_ahci_suspend(struct device *dev) | |||
| 208 | 207 | ||
| 209 | static int st_ahci_resume(struct device *dev) | 208 | static int st_ahci_resume(struct device *dev) |
| 210 | { | 209 | { |
| 211 | struct st_ahci_drv_data *drv_data = dev_get_drvdata(dev); | 210 | struct ata_host *host = dev_get_drvdata(dev); |
| 212 | struct ahci_host_priv *hpriv = drv_data->hpriv; | 211 | struct ahci_host_priv *hpriv = host->private_data; |
| 213 | int err; | 212 | int err; |
| 214 | 213 | ||
| 215 | err = ahci_platform_enable_resources(hpriv); | 214 | err = ahci_platform_enable_resources(hpriv); |
| 216 | if (err) | 215 | if (err) |
| 217 | return err; | 216 | return err; |
| 218 | 217 | ||
| 219 | err = st_ahci_deassert_resets(dev); | 218 | err = st_ahci_deassert_resets(hpriv, dev); |
| 220 | if (err) { | 219 | if (err) { |
| 221 | ahci_platform_disable_resources(hpriv); | 220 | ahci_platform_disable_resources(hpriv); |
| 222 | return err; | 221 | return err; |
| 223 | } | 222 | } |
| 224 | 223 | ||
| 225 | st_ahci_configure_oob(drv_data->hpriv->mmio); | 224 | st_ahci_configure_oob(hpriv->mmio); |
| 226 | 225 | ||
| 227 | return ahci_platform_resume_host(dev); | 226 | return ahci_platform_resume_host(dev); |
| 228 | } | 227 | } |
diff --git a/drivers/ata/libahci.c b/drivers/ata/libahci.c index 61a9c07e0dff..287c4ba0219f 100644 --- a/drivers/ata/libahci.c +++ b/drivers/ata/libahci.c | |||
| @@ -1707,8 +1707,7 @@ static void ahci_handle_port_interrupt(struct ata_port *ap, | |||
| 1707 | if (unlikely(resetting)) | 1707 | if (unlikely(resetting)) |
| 1708 | status &= ~PORT_IRQ_BAD_PMP; | 1708 | status &= ~PORT_IRQ_BAD_PMP; |
| 1709 | 1709 | ||
| 1710 | /* if LPM is enabled, PHYRDY doesn't mean anything */ | 1710 | if (sata_lpm_ignore_phy_events(&ap->link)) { |
| 1711 | if (ap->link.lpm_policy > ATA_LPM_MAX_POWER) { | ||
| 1712 | status &= ~PORT_IRQ_PHYRDY; | 1711 | status &= ~PORT_IRQ_PHYRDY; |
| 1713 | ahci_scr_write(&ap->link, SCR_ERROR, SERR_PHYRDY_CHG); | 1712 | ahci_scr_write(&ap->link, SCR_ERROR, SERR_PHYRDY_CHG); |
| 1714 | } | 1713 | } |
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index f6cb1f1b30b7..577849c6611a 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c | |||
| @@ -4235,7 +4235,7 @@ static const struct ata_blacklist_entry ata_device_blacklist [] = { | |||
| 4235 | ATA_HORKAGE_ZERO_AFTER_TRIM, }, | 4235 | ATA_HORKAGE_ZERO_AFTER_TRIM, }, |
| 4236 | { "Crucial_CT*MX100*", "MU01", ATA_HORKAGE_NO_NCQ_TRIM | | 4236 | { "Crucial_CT*MX100*", "MU01", ATA_HORKAGE_NO_NCQ_TRIM | |
| 4237 | ATA_HORKAGE_ZERO_AFTER_TRIM, }, | 4237 | ATA_HORKAGE_ZERO_AFTER_TRIM, }, |
| 4238 | { "Samsung SSD 850 PRO*", NULL, ATA_HORKAGE_NO_NCQ_TRIM | | 4238 | { "Samsung SSD 8*", NULL, ATA_HORKAGE_NO_NCQ_TRIM | |
| 4239 | ATA_HORKAGE_ZERO_AFTER_TRIM, }, | 4239 | ATA_HORKAGE_ZERO_AFTER_TRIM, }, |
| 4240 | 4240 | ||
| 4241 | /* | 4241 | /* |
| @@ -6752,6 +6752,38 @@ u32 ata_wait_register(struct ata_port *ap, void __iomem *reg, u32 mask, u32 val, | |||
| 6752 | return tmp; | 6752 | return tmp; |
| 6753 | } | 6753 | } |
| 6754 | 6754 | ||
| 6755 | /** | ||
| 6756 | * sata_lpm_ignore_phy_events - test if PHY event should be ignored | ||
| 6757 | * @link: Link receiving the event | ||
| 6758 | * | ||
| 6759 | * Test whether the received PHY event has to be ignored or not. | ||
| 6760 | * | ||
| 6761 | * LOCKING: | ||
| 6762 | * None: | ||
| 6763 | * | ||
| 6764 | * RETURNS: | ||
| 6765 | * True if the event has to be ignored. | ||
| 6766 | */ | ||
| 6767 | bool sata_lpm_ignore_phy_events(struct ata_link *link) | ||
| 6768 | { | ||
| 6769 | unsigned long lpm_timeout = link->last_lpm_change + | ||
| 6770 | msecs_to_jiffies(ATA_TMOUT_SPURIOUS_PHY); | ||
| 6771 | |||
| 6772 | /* if LPM is enabled, PHYRDY doesn't mean anything */ | ||
| 6773 | if (link->lpm_policy > ATA_LPM_MAX_POWER) | ||
| 6774 | return true; | ||
| 6775 | |||
| 6776 | /* ignore the first PHY event after the LPM policy changed | ||
| 6777 | * as it is might be spurious | ||
| 6778 | */ | ||
| 6779 | if ((link->flags & ATA_LFLAG_CHANGED) && | ||
| 6780 | time_before(jiffies, lpm_timeout)) | ||
| 6781 | return true; | ||
| 6782 | |||
| 6783 | return false; | ||
| 6784 | } | ||
| 6785 | EXPORT_SYMBOL_GPL(sata_lpm_ignore_phy_events); | ||
| 6786 | |||
| 6755 | /* | 6787 | /* |
| 6756 | * Dummy port_ops | 6788 | * Dummy port_ops |
| 6757 | */ | 6789 | */ |
diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c index 07f41be38fbe..cf0022ec07f2 100644 --- a/drivers/ata/libata-eh.c +++ b/drivers/ata/libata-eh.c | |||
| @@ -3597,6 +3597,9 @@ static int ata_eh_set_lpm(struct ata_link *link, enum ata_lpm_policy policy, | |||
| 3597 | } | 3597 | } |
| 3598 | } | 3598 | } |
| 3599 | 3599 | ||
| 3600 | link->last_lpm_change = jiffies; | ||
| 3601 | link->flags |= ATA_LFLAG_CHANGED; | ||
| 3602 | |||
| 3600 | return 0; | 3603 | return 0; |
| 3601 | 3604 | ||
| 3602 | fail: | 3605 | fail: |
diff --git a/drivers/ata/pata_scc.c b/drivers/ata/pata_scc.c deleted file mode 100644 index 5cd60d6388ec..000000000000 --- a/drivers/ata/pata_scc.c +++ /dev/null | |||
| @@ -1,1110 +0,0 @@ | |||
| 1 | /* | ||
| 2 | * Support for IDE interfaces on Celleb platform | ||
| 3 | * | ||
| 4 | * (C) Copyright 2006 TOSHIBA CORPORATION | ||
| 5 | * | ||
| 6 | * This code is based on drivers/ata/ata_piix.c: | ||
| 7 | * Copyright 2003-2005 Red Hat Inc | ||
| 8 | * Copyright 2003-2005 Jeff Garzik | ||
| 9 | * Copyright (C) 1998-1999 Andrzej Krzysztofowicz, Author and Maintainer | ||
| 10 | * Copyright (C) 1998-2000 Andre Hedrick <andre@linux-ide.org> | ||
| 11 | * Copyright (C) 2003 Red Hat Inc | ||
| 12 | * | ||
| 13 | * and drivers/ata/ahci.c: | ||
| 14 | * Copyright 2004-2005 Red Hat, Inc. | ||
| 15 | * | ||
| 16 | * and drivers/ata/libata-core.c: | ||
| 17 | * Copyright 2003-2004 Red Hat, Inc. All rights reserved. | ||
| 18 | * Copyright 2003-2004 Jeff Garzik | ||
| 19 | * | ||
| 20 | * This program is free software; you can redistribute it and/or modify | ||
| 21 | * it under the terms of the GNU General Public License as published by | ||
| 22 | * the Free Software Foundation; either version 2 of the License, or | ||
| 23 | * (at your option) any later version. | ||
| 24 | * | ||
| 25 | * This program is distributed in the hope that it will be useful, | ||
| 26 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 27 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 28 | * GNU General Public License for more details. | ||
| 29 | * | ||
| 30 | * You should have received a copy of the GNU General Public License along | ||
| 31 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
| 32 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | ||
| 33 | */ | ||
| 34 | |||
| 35 | #include <linux/kernel.h> | ||
| 36 | #include <linux/module.h> | ||
| 37 | #include <linux/pci.h> | ||
| 38 | #include <linux/blkdev.h> | ||
| 39 | #include <linux/delay.h> | ||
| 40 | #include <linux/device.h> | ||
| 41 | #include <scsi/scsi_host.h> | ||
| 42 | #include <linux/libata.h> | ||
| 43 | |||
| 44 | #define DRV_NAME "pata_scc" | ||
| 45 | #define DRV_VERSION "0.3" | ||
| 46 | |||
| 47 | #define PCI_DEVICE_ID_TOSHIBA_SCC_ATA 0x01b4 | ||
| 48 | |||
| 49 | /* PCI BARs */ | ||
| 50 | #define SCC_CTRL_BAR 0 | ||
| 51 | #define SCC_BMID_BAR 1 | ||
| 52 | |||
| 53 | /* offset of CTRL registers */ | ||
| 54 | #define SCC_CTL_PIOSHT 0x000 | ||
| 55 | #define SCC_CTL_PIOCT 0x004 | ||
| 56 | #define SCC_CTL_MDMACT 0x008 | ||
| 57 | #define SCC_CTL_MCRCST 0x00C | ||
| 58 | #define SCC_CTL_SDMACT 0x010 | ||
| 59 | #define SCC_CTL_SCRCST 0x014 | ||
| 60 | #define SCC_CTL_UDENVT 0x018 | ||
| 61 | #define SCC_CTL_TDVHSEL 0x020 | ||
| 62 | #define SCC_CTL_MODEREG 0x024 | ||
| 63 | #define SCC_CTL_ECMODE 0xF00 | ||
| 64 | #define SCC_CTL_MAEA0 0xF50 | ||
| 65 | #define SCC_CTL_MAEC0 0xF54 | ||
| 66 | #define SCC_CTL_CCKCTRL 0xFF0 | ||
| 67 | |||
| 68 | /* offset of BMID registers */ | ||
| 69 | #define SCC_DMA_CMD 0x000 | ||
| 70 | #define SCC_DMA_STATUS 0x004 | ||
| 71 | #define SCC_DMA_TABLE_OFS 0x008 | ||
| 72 | #define SCC_DMA_INTMASK 0x010 | ||
| 73 | #define SCC_DMA_INTST 0x014 | ||
| 74 | #define SCC_DMA_PTERADD 0x018 | ||
| 75 | #define SCC_REG_CMD_ADDR 0x020 | ||
| 76 | #define SCC_REG_DATA 0x000 | ||
| 77 | #define SCC_REG_ERR 0x004 | ||
| 78 | #define SCC_REG_FEATURE 0x004 | ||
| 79 | #define SCC_REG_NSECT 0x008 | ||
| 80 | #define SCC_REG_LBAL 0x00C | ||
| 81 | #define SCC_REG_LBAM 0x010 | ||
| 82 | #define SCC_REG_LBAH 0x014 | ||
| 83 | #define SCC_REG_DEVICE 0x018 | ||
| 84 | #define SCC_REG_STATUS 0x01C | ||
| 85 | #define SCC_REG_CMD 0x01C | ||
| 86 | #define SCC_REG_ALTSTATUS 0x020 | ||
| 87 | |||
| 88 | /* register value */ | ||
| 89 | #define TDVHSEL_MASTER 0x00000001 | ||
| 90 | #define TDVHSEL_SLAVE 0x00000004 | ||
| 91 | |||
| 92 | #define MODE_JCUSFEN 0x00000080 | ||
| 93 | |||
| 94 | #define ECMODE_VALUE 0x01 | ||
| 95 | |||
| 96 | #define CCKCTRL_ATARESET 0x00040000 | ||
| 97 | #define CCKCTRL_BUFCNT 0x00020000 | ||
| 98 | #define CCKCTRL_CRST 0x00010000 | ||
| 99 | #define CCKCTRL_OCLKEN 0x00000100 | ||
| 100 | #define CCKCTRL_ATACLKOEN 0x00000002 | ||
| 101 | #define CCKCTRL_LCLKEN 0x00000001 | ||
| 102 | |||
| 103 | #define QCHCD_IOS_SS 0x00000001 | ||
| 104 | |||
| 105 | #define QCHSD_STPDIAG 0x00020000 | ||
| 106 | |||
| 107 | #define INTMASK_MSK 0xD1000012 | ||
| 108 | #define INTSTS_SERROR 0x80000000 | ||
| 109 | #define INTSTS_PRERR 0x40000000 | ||
| 110 | #define INTSTS_RERR 0x10000000 | ||
| 111 | #define INTSTS_ICERR 0x01000000 | ||
| 112 | #define INTSTS_BMSINT 0x00000010 | ||
| 113 | #define INTSTS_BMHE 0x00000008 | ||
| 114 | #define INTSTS_IOIRQS 0x00000004 | ||
| 115 | #define INTSTS_INTRQ 0x00000002 | ||
| 116 | #define INTSTS_ACTEINT 0x00000001 | ||
| 117 | |||
| 118 | |||
| 119 | /* PIO transfer mode table */ | ||
| 120 | /* JCHST */ | ||
| 121 | static const unsigned long JCHSTtbl[2][7] = { | ||
| 122 | {0x0E, 0x05, 0x02, 0x03, 0x02, 0x00, 0x00}, /* 100MHz */ | ||
| 123 | {0x13, 0x07, 0x04, 0x04, 0x03, 0x00, 0x00} /* 133MHz */ | ||
| 124 | }; | ||
| 125 | |||
| 126 | /* JCHHT */ | ||
| 127 | static const unsigned long JCHHTtbl[2][7] = { | ||
| 128 | {0x0E, 0x02, 0x02, 0x02, 0x02, 0x00, 0x00}, /* 100MHz */ | ||
| 129 | {0x13, 0x03, 0x03, 0x03, 0x03, 0x00, 0x00} /* 133MHz */ | ||
| 130 | }; | ||
| 131 | |||
| 132 | /* JCHCT */ | ||
| 133 | static const unsigned long JCHCTtbl[2][7] = { | ||
| 134 | {0x1D, 0x1D, 0x1C, 0x0B, 0x06, 0x00, 0x00}, /* 100MHz */ | ||
| 135 | {0x27, 0x26, 0x26, 0x0E, 0x09, 0x00, 0x00} /* 133MHz */ | ||
| 136 | }; | ||
| 137 | |||
| 138 | /* DMA transfer mode table */ | ||
| 139 | /* JCHDCTM/JCHDCTS */ | ||
| 140 | static const unsigned long JCHDCTxtbl[2][7] = { | ||
| 141 | {0x0A, 0x06, 0x04, 0x03, 0x01, 0x00, 0x00}, /* 100MHz */ | ||
| 142 | {0x0E, 0x09, 0x06, 0x04, 0x02, 0x01, 0x00} /* 133MHz */ | ||
| 143 | }; | ||
| 144 | |||
| 145 | /* JCSTWTM/JCSTWTS */ | ||
| 146 | static const unsigned long JCSTWTxtbl[2][7] = { | ||
| 147 | {0x06, 0x04, 0x03, 0x02, 0x02, 0x02, 0x00}, /* 100MHz */ | ||
| 148 | {0x09, 0x06, 0x04, 0x02, 0x02, 0x02, 0x02} /* 133MHz */ | ||
| 149 | }; | ||
| 150 | |||
| 151 | /* JCTSS */ | ||
| 152 | static const unsigned long JCTSStbl[2][7] = { | ||
| 153 | {0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x00}, /* 100MHz */ | ||
| 154 | {0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05} /* 133MHz */ | ||
| 155 | }; | ||
| 156 | |||
| 157 | /* JCENVT */ | ||
| 158 | static const unsigned long JCENVTtbl[2][7] = { | ||
| 159 | {0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00}, /* 100MHz */ | ||
| 160 | {0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02} /* 133MHz */ | ||
| 161 | }; | ||
| 162 | |||
| 163 | /* JCACTSELS/JCACTSELM */ | ||
| 164 | static const unsigned long JCACTSELtbl[2][7] = { | ||
| 165 | {0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00}, /* 100MHz */ | ||
| 166 | {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01} /* 133MHz */ | ||
| 167 | }; | ||
| 168 | |||
| 169 | static const struct pci_device_id scc_pci_tbl[] = { | ||
| 170 | { PCI_VDEVICE(TOSHIBA_2, PCI_DEVICE_ID_TOSHIBA_SCC_ATA), 0}, | ||
| 171 | { } /* terminate list */ | ||
| 172 | }; | ||
| 173 | |||
| 174 | /** | ||
| 175 | * scc_set_piomode - Initialize host controller PATA PIO timings | ||
| 176 | * @ap: Port whose timings we are configuring | ||
| 177 | * @adev: um | ||
| 178 | * | ||
| 179 | * Set PIO mode for device. | ||
| 180 | * | ||
| 181 | * LOCKING: | ||
| 182 | * None (inherited from caller). | ||
| 183 | */ | ||
| 184 | |||
| 185 | static void scc_set_piomode (struct ata_port *ap, struct ata_device *adev) | ||
| 186 | { | ||
| 187 | unsigned int pio = adev->pio_mode - XFER_PIO_0; | ||
| 188 | void __iomem *ctrl_base = ap->host->iomap[SCC_CTRL_BAR]; | ||
| 189 | void __iomem *cckctrl_port = ctrl_base + SCC_CTL_CCKCTRL; | ||
| 190 | void __iomem *piosht_port = ctrl_base + SCC_CTL_PIOSHT; | ||
| 191 | void __iomem *pioct_port = ctrl_base + SCC_CTL_PIOCT; | ||
| 192 | unsigned long reg; | ||
| 193 | int offset; | ||
| 194 | |||
| 195 | reg = in_be32(cckctrl_port); | ||
| 196 | if (reg & CCKCTRL_ATACLKOEN) | ||
| 197 | offset = 1; /* 133MHz */ | ||
| 198 | else | ||
| 199 | offset = 0; /* 100MHz */ | ||
| 200 | |||
| 201 | reg = JCHSTtbl[offset][pio] << 16 | JCHHTtbl[offset][pio]; | ||
| 202 | out_be32(piosht_port, reg); | ||
| 203 | reg = JCHCTtbl[offset][pio]; | ||
| 204 | out_be32(pioct_port, reg); | ||
| 205 | } | ||
| 206 | |||
| 207 | /** | ||
| 208 | * scc_set_dmamode - Initialize host controller PATA DMA timings | ||
| 209 | * @ap: Port whose timings we are configuring | ||
| 210 | * @adev: um | ||
| 211 | * | ||
| 212 | * Set UDMA mode for device. | ||
| 213 | * | ||
| 214 | * LOCKING: | ||
| 215 | * None (inherited from caller). | ||
| 216 | */ | ||
| 217 | |||
| 218 | static void scc_set_dmamode (struct ata_port *ap, struct ata_device *adev) | ||
| 219 | { | ||
| 220 | unsigned int udma = adev->dma_mode; | ||
| 221 | unsigned int is_slave = (adev->devno != 0); | ||
| 222 | u8 speed = udma; | ||
| 223 | void __iomem *ctrl_base = ap->host->iomap[SCC_CTRL_BAR]; | ||
| 224 | void __iomem *cckctrl_port = ctrl_base + SCC_CTL_CCKCTRL; | ||
| 225 | void __iomem *mdmact_port = ctrl_base + SCC_CTL_MDMACT; | ||
| 226 | void __iomem *mcrcst_port = ctrl_base + SCC_CTL_MCRCST; | ||
| 227 | void __iomem *sdmact_port = ctrl_base + SCC_CTL_SDMACT; | ||
| 228 | void __iomem *scrcst_port = ctrl_base + SCC_CTL_SCRCST; | ||
| 229 | void __iomem *udenvt_port = ctrl_base + SCC_CTL_UDENVT; | ||
| 230 | void __iomem *tdvhsel_port = ctrl_base + SCC_CTL_TDVHSEL; | ||
| 231 | int offset, idx; | ||
| 232 | |||
| 233 | if (in_be32(cckctrl_port) & CCKCTRL_ATACLKOEN) | ||
| 234 | offset = 1; /* 133MHz */ | ||
| 235 | else | ||
| 236 | offset = 0; /* 100MHz */ | ||
| 237 | |||
| 238 | if (speed >= XFER_UDMA_0) | ||
| 239 | idx = speed - XFER_UDMA_0; | ||
| 240 | else | ||
| 241 | return; | ||
| 242 | |||
| 243 | if (is_slave) { | ||
| 244 | out_be32(sdmact_port, JCHDCTxtbl[offset][idx]); | ||
| 245 | out_be32(scrcst_port, JCSTWTxtbl[offset][idx]); | ||
| 246 | out_be32(tdvhsel_port, | ||
| 247 | (in_be32(tdvhsel_port) & ~TDVHSEL_SLAVE) | (JCACTSELtbl[offset][idx] << 2)); | ||
| 248 | } else { | ||
| 249 | out_be32(mdmact_port, JCHDCTxtbl[offset][idx]); | ||
| 250 | out_be32(mcrcst_port, JCSTWTxtbl[offset][idx]); | ||
| 251 | out_be32(tdvhsel_port, | ||
| 252 | (in_be32(tdvhsel_port) & ~TDVHSEL_MASTER) | JCACTSELtbl[offset][idx]); | ||
| 253 | } | ||
| 254 | out_be32(udenvt_port, | ||
| 255 | JCTSStbl[offset][idx] << 16 | JCENVTtbl[offset][idx]); | ||
| 256 | } | ||
| 257 | |||
| 258 | unsigned long scc_mode_filter(struct ata_device *adev, unsigned long mask) | ||
| 259 | { | ||
| 260 | /* errata A308 workaround: limit ATAPI UDMA mode to UDMA4 */ | ||
| 261 | if (adev->class == ATA_DEV_ATAPI && | ||
| 262 | (mask & (0xE0 << ATA_SHIFT_UDMA))) { | ||
| 263 | printk(KERN_INFO "%s: limit ATAPI UDMA to UDMA4\n", DRV_NAME); | ||
| 264 | mask &= ~(0xE0 << ATA_SHIFT_UDMA); | ||
| 265 | } | ||
| 266 | return mask; | ||
| 267 | } | ||
| 268 | |||
| 269 | /** | ||
| 270 | * scc_tf_load - send taskfile registers to host controller | ||
| 271 | * @ap: Port to which output is sent | ||
| 272 | * @tf: ATA taskfile register set | ||
| 273 | * | ||
| 274 | * Note: Original code is ata_sff_tf_load(). | ||
| 275 | */ | ||
| 276 | |||
| 277 | static void scc_tf_load (struct ata_port *ap, const struct ata_taskfile *tf) | ||
| 278 | { | ||
| 279 | struct ata_ioports *ioaddr = &ap->ioaddr; | ||
| 280 | unsigned int is_addr = tf->flags & ATA_TFLAG_ISADDR; | ||
| 281 | |||
| 282 | if (tf->ctl != ap->last_ctl) { | ||
| 283 | out_be32(ioaddr->ctl_addr, tf->ctl); | ||
| 284 | ap->last_ctl = tf->ctl; | ||
| 285 | ata_wait_idle(ap); | ||
| 286 | } | ||
| 287 | |||
| 288 | if (is_addr && (tf->flags & ATA_TFLAG_LBA48)) { | ||
| 289 | out_be32(ioaddr->feature_addr, tf->hob_feature); | ||
| 290 | out_be32(ioaddr->nsect_addr, tf->hob_nsect); | ||
| 291 | out_be32(ioaddr->lbal_addr, tf->hob_lbal); | ||
| 292 | out_be32(ioaddr->lbam_addr, tf->hob_lbam); | ||
| 293 | out_be32(ioaddr->lbah_addr, tf->hob_lbah); | ||
| 294 | VPRINTK("hob: feat 0x%X nsect 0x%X, lba 0x%X 0x%X 0x%X\n", | ||
| 295 | tf->hob_feature, | ||
| 296 | tf->hob_nsect, | ||
| 297 | tf->hob_lbal, | ||
| 298 | tf->hob_lbam, | ||
| 299 | tf->hob_lbah); | ||
| 300 | } | ||
| 301 | |||
| 302 | if (is_addr) { | ||
| 303 | out_be32(ioaddr->feature_addr, tf->feature); | ||
| 304 | out_be32(ioaddr->nsect_addr, tf->nsect); | ||
| 305 | out_be32(ioaddr->lbal_addr, tf->lbal); | ||
| 306 | out_be32(ioaddr->lbam_addr, tf->lbam); | ||
| 307 | out_be32(ioaddr->lbah_addr, tf->lbah); | ||
| 308 | VPRINTK("feat 0x%X nsect 0x%X lba 0x%X 0x%X 0x%X\n", | ||
| 309 | tf->feature, | ||
| 310 | tf->nsect, | ||
| 311 | tf->lbal, | ||
| 312 | tf->lbam, | ||
| 313 | tf->lbah); | ||
| 314 | } | ||
| 315 | |||
| 316 | if (tf->flags & ATA_TFLAG_DEVICE) { | ||
| 317 | out_be32(ioaddr->device_addr, tf->device); | ||
| 318 | VPRINTK("device 0x%X\n", tf->device); | ||
| 319 | } | ||
| 320 | |||
| 321 | ata_wait_idle(ap); | ||
| 322 | } | ||
| 323 | |||
| 324 | /** | ||
| 325 | * scc_check_status - Read device status reg & clear interrupt | ||
| 326 | * @ap: port where the device is | ||
| 327 | * | ||
| 328 | * Note: Original code is ata_check_status(). | ||
| 329 | */ | ||
| 330 | |||
| 331 | static u8 scc_check_status (struct ata_port *ap) | ||
| 332 | { | ||
| 333 | return in_be32(ap->ioaddr.status_addr); | ||
| 334 | } | ||
| 335 | |||
| 336 | /** | ||
| 337 | * scc_tf_read - input device's ATA taskfile shadow registers | ||
| 338 | * @ap: Port from which input is read | ||
| 339 | * @tf: ATA taskfile register set for storing input | ||
| 340 | * | ||
| 341 | * Note: Original code is ata_sff_tf_read(). | ||
| 342 | */ | ||
| 343 | |||
| 344 | static void scc_tf_read (struct ata_port *ap, struct ata_taskfile *tf) | ||
| 345 | { | ||
| 346 | struct ata_ioports *ioaddr = &ap->ioaddr; | ||
| 347 | |||
| 348 | tf->command = scc_check_status(ap); | ||
| 349 | tf->feature = in_be32(ioaddr->error_addr); | ||
| 350 | tf->nsect = in_be32(ioaddr->nsect_addr); | ||
| 351 | tf->lbal = in_be32(ioaddr->lbal_addr); | ||
| 352 | tf->lbam = in_be32(ioaddr->lbam_addr); | ||
| 353 | tf->lbah = in_be32(ioaddr->lbah_addr); | ||
| 354 | tf->device = in_be32(ioaddr->device_addr); | ||
| 355 | |||
| 356 | if (tf->flags & ATA_TFLAG_LBA48) { | ||
| 357 | out_be32(ioaddr->ctl_addr, tf->ctl | ATA_HOB); | ||
| 358 | tf->hob_feature = in_be32(ioaddr->error_addr); | ||
| 359 | tf->hob_nsect = in_be32(ioaddr->nsect_addr); | ||
| 360 | tf->hob_lbal = in_be32(ioaddr->lbal_addr); | ||
| 361 | tf->hob_lbam = in_be32(ioaddr->lbam_addr); | ||
| 362 | tf->hob_lbah = in_be32(ioaddr->lbah_addr); | ||
| 363 | out_be32(ioaddr->ctl_addr, tf->ctl); | ||
| 364 | ap->last_ctl = tf->ctl; | ||
| 365 | } | ||
| 366 | } | ||
| 367 | |||
| 368 | /** | ||
| 369 | * scc_exec_command - issue ATA command to host controller | ||
| 370 | * @ap: port to which command is being issued | ||
| 371 | * @tf: ATA taskfile register set | ||
| 372 | * | ||
| 373 | * Note: Original code is ata_sff_exec_command(). | ||
| 374 | */ | ||
| 375 | |||
| 376 | static void scc_exec_command (struct ata_port *ap, | ||
| 377 | const struct ata_taskfile *tf) | ||
| 378 | { | ||
| 379 | DPRINTK("ata%u: cmd 0x%X\n", ap->print_id, tf->command); | ||
| 380 | |||
| 381 | out_be32(ap->ioaddr.command_addr, tf->command); | ||
| 382 | ata_sff_pause(ap); | ||
| 383 | } | ||
| 384 | |||
| 385 | /** | ||
| 386 | * scc_check_altstatus - Read device alternate status reg | ||
| 387 | * @ap: port where the device is | ||
| 388 | */ | ||
| 389 | |||
| 390 | static u8 scc_check_altstatus (struct ata_port *ap) | ||
| 391 | { | ||
| 392 | return in_be32(ap->ioaddr.altstatus_addr); | ||
| 393 | } | ||
| 394 | |||
| 395 | /** | ||
| 396 | * scc_dev_select - Select device 0/1 on ATA bus | ||
| 397 | * @ap: ATA channel to manipulate | ||
| 398 | * @device: ATA device (numbered from zero) to select | ||
| 399 | * | ||
| 400 | * Note: Original code is ata_sff_dev_select(). | ||
| 401 | */ | ||
| 402 | |||
| 403 | static void scc_dev_select (struct ata_port *ap, unsigned int device) | ||
| 404 | { | ||
| 405 | u8 tmp; | ||
| 406 | |||
| 407 | if (device == 0) | ||
| 408 | tmp = ATA_DEVICE_OBS; | ||
| 409 | else | ||
| 410 | tmp = ATA_DEVICE_OBS | ATA_DEV1; | ||
| 411 | |||
| 412 | out_be32(ap->ioaddr.device_addr, tmp); | ||
| 413 | ata_sff_pause(ap); | ||
| 414 | } | ||
| 415 | |||
| 416 | /** | ||
| 417 | * scc_set_devctl - Write device control reg | ||
| 418 | * @ap: port where the device is | ||
| 419 | * @ctl: value to write | ||
| 420 | */ | ||
| 421 | |||
| 422 | static void scc_set_devctl(struct ata_port *ap, u8 ctl) | ||
| 423 | { | ||
| 424 | out_be32(ap->ioaddr.ctl_addr, ctl); | ||
| 425 | } | ||
| 426 | |||
| 427 | /** | ||
| 428 | * scc_bmdma_setup - Set up PCI IDE BMDMA transaction | ||
| 429 | * @qc: Info associated with this ATA transaction. | ||
| 430 | * | ||
| 431 | * Note: Original code is ata_bmdma_setup(). | ||
| 432 | */ | ||
| 433 | |||
| 434 | static void scc_bmdma_setup (struct ata_queued_cmd *qc) | ||
| 435 | { | ||
| 436 | struct ata_port *ap = qc->ap; | ||
| 437 | unsigned int rw = (qc->tf.flags & ATA_TFLAG_WRITE); | ||
| 438 | u8 dmactl; | ||
| 439 | void __iomem *mmio = ap->ioaddr.bmdma_addr; | ||
| 440 | |||
| 441 | /* load PRD table addr */ | ||
| 442 | out_be32(mmio + SCC_DMA_TABLE_OFS, ap->bmdma_prd_dma); | ||
| 443 | |||
| 444 | /* specify data direction, triple-check start bit is clear */ | ||
| 445 | dmactl = in_be32(mmio + SCC_DMA_CMD); | ||
| 446 | dmactl &= ~(ATA_DMA_WR | ATA_DMA_START); | ||
| 447 | if (!rw) | ||
| 448 | dmactl |= ATA_DMA_WR; | ||
| 449 | out_be32(mmio + SCC_DMA_CMD, dmactl); | ||
| 450 | |||
| 451 | /* issue r/w command */ | ||
| 452 | ap->ops->sff_exec_command(ap, &qc->tf); | ||
| 453 | } | ||
| 454 | |||
| 455 | /** | ||
| 456 | * scc_bmdma_start - Start a PCI IDE BMDMA transaction | ||
| 457 | * @qc: Info associated with this ATA transaction. | ||
| 458 | * | ||
| 459 | * Note: Original code is ata_bmdma_start(). | ||
| 460 | */ | ||
| 461 | |||
| 462 | static void scc_bmdma_start (struct ata_queued_cmd *qc) | ||
| 463 | { | ||
| 464 | struct ata_port *ap = qc->ap; | ||
| 465 | u8 dmactl; | ||
| 466 | void __iomem *mmio = ap->ioaddr.bmdma_addr; | ||
| 467 | |||
| 468 | /* start host DMA transaction */ | ||
| 469 | dmactl = in_be32(mmio + SCC_DMA_CMD); | ||
| 470 | out_be32(mmio + SCC_DMA_CMD, dmactl | ATA_DMA_START); | ||
| 471 | } | ||
| 472 | |||
| 473 | /** | ||
| 474 | * scc_devchk - PATA device presence detection | ||
| 475 | * @ap: ATA channel to examine | ||
| 476 | * @device: Device to examine (starting at zero) | ||
| 477 | * | ||
| 478 | * Note: Original code is ata_devchk(). | ||
| 479 | */ | ||
| 480 | |||
| 481 | static unsigned int scc_devchk (struct ata_port *ap, | ||
| 482 | unsigned int device) | ||
| 483 | { | ||
| 484 | struct ata_ioports *ioaddr = &ap->ioaddr; | ||
| 485 | u8 nsect, lbal; | ||
| 486 | |||
| 487 | ap->ops->sff_dev_select(ap, device); | ||
| 488 | |||
| 489 | out_be32(ioaddr->nsect_addr, 0x55); | ||
| 490 | out_be32(ioaddr->lbal_addr, 0xaa); | ||
| 491 | |||
| 492 | out_be32(ioaddr->nsect_addr, 0xaa); | ||
| 493 | out_be32(ioaddr->lbal_addr, 0x55); | ||
| 494 | |||
| 495 | out_be32(ioaddr->nsect_addr, 0x55); | ||
| 496 | out_be32(ioaddr->lbal_addr, 0xaa); | ||
| 497 | |||
| 498 | nsect = in_be32(ioaddr->nsect_addr); | ||
| 499 | lbal = in_be32(ioaddr->lbal_addr); | ||
| 500 | |||
| 501 | if ((nsect == 0x55) && (lbal == 0xaa)) | ||
| 502 | return 1; /* we found a device */ | ||
| 503 | |||
| 504 | return 0; /* nothing found */ | ||
| 505 | } | ||
| 506 | |||
| 507 | /** | ||
| 508 | * scc_wait_after_reset - wait for devices to become ready after reset | ||
| 509 | * | ||
| 510 | * Note: Original code is ata_sff_wait_after_reset | ||
| 511 | */ | ||
| 512 | |||
| 513 | static int scc_wait_after_reset(struct ata_link *link, unsigned int devmask, | ||
| 514 | unsigned long deadline) | ||
| 515 | { | ||
| 516 | struct ata_port *ap = link->ap; | ||
| 517 | struct ata_ioports *ioaddr = &ap->ioaddr; | ||
| 518 | unsigned int dev0 = devmask & (1 << 0); | ||
| 519 | unsigned int dev1 = devmask & (1 << 1); | ||
| 520 | int rc, ret = 0; | ||
| 521 | |||
| 522 | /* Spec mandates ">= 2ms" before checking status. We wait | ||
| 523 | * 150ms, because that was the magic delay used for ATAPI | ||
| 524 | * devices in Hale Landis's ATADRVR, for the period of time | ||
| 525 | * between when the ATA command register is written, and then | ||
| 526 | * status is checked. Because waiting for "a while" before | ||
| 527 | * checking status is fine, post SRST, we perform this magic | ||
| 528 | * delay here as well. | ||
| 529 | * | ||
| 530 | * Old drivers/ide uses the 2mS rule and then waits for ready. | ||
| 531 | */ | ||
| 532 | ata_msleep(ap, 150); | ||
| 533 | |||
| 534 | /* always check readiness of the master device */ | ||
| 535 | rc = ata_sff_wait_ready(link, deadline); | ||
| 536 | /* -ENODEV means the odd clown forgot the D7 pulldown resistor | ||
| 537 | * and TF status is 0xff, bail out on it too. | ||
| 538 | */ | ||
| 539 | if (rc) | ||
| 540 | return rc; | ||
| 541 | |||
| 542 | /* if device 1 was found in ata_devchk, wait for register | ||
| 543 | * access briefly, then wait for BSY to clear. | ||
| 544 | */ | ||
| 545 | if (dev1) { | ||
| 546 | int i; | ||
| 547 | |||
| 548 | ap->ops->sff_dev_select(ap, 1); | ||
| 549 | |||
| 550 | /* Wait for register access. Some ATAPI devices fail | ||
| 551 | * to set nsect/lbal after reset, so don't waste too | ||
| 552 | * much time on it. We're gonna wait for !BSY anyway. | ||
| 553 | */ | ||
| 554 | for (i = 0; i < 2; i++) { | ||
| 555 | u8 nsect, lbal; | ||
| 556 | |||
| 557 | nsect = in_be32(ioaddr->nsect_addr); | ||
| 558 | lbal = in_be32(ioaddr->lbal_addr); | ||
| 559 | if ((nsect == 1) && (lbal == 1)) | ||
| 560 | break; | ||
| 561 | ata_msleep(ap, 50); /* give drive a breather */ | ||
| 562 | } | ||
| 563 | |||
| 564 | rc = ata_sff_wait_ready(link, deadline); | ||
| 565 | if (rc) { | ||
| 566 | if (rc != -ENODEV) | ||
| 567 | return rc; | ||
| 568 | ret = rc; | ||
| 569 | } | ||
| 570 | } | ||
| 571 | |||
| 572 | /* is all this really necessary? */ | ||
| 573 | ap->ops->sff_dev_select(ap, 0); | ||
| 574 | if (dev1) | ||
| 575 | ap->ops->sff_dev_select(ap, 1); | ||
| 576 | if (dev0) | ||
| 577 | ap->ops->sff_dev_select(ap, 0); | ||
| 578 | |||
| 579 | return ret; | ||
| 580 | } | ||
| 581 | |||
| 582 | /** | ||
| 583 | * scc_bus_softreset - PATA device software reset | ||
| 584 | * | ||
| 585 | * Note: Original code is ata_bus_softreset(). | ||
| 586 | */ | ||
| 587 | |||
| 588 | static int scc_bus_softreset(struct ata_port *ap, unsigned int devmask, | ||
| 589 | unsigned long deadline) | ||
| 590 | { | ||
| 591 | struct ata_ioports *ioaddr = &ap->ioaddr; | ||
| 592 | |||
| 593 | DPRINTK("ata%u: bus reset via SRST\n", ap->print_id); | ||
| 594 | |||
| 595 | /* software reset. causes dev0 to be selected */ | ||
| 596 | out_be32(ioaddr->ctl_addr, ap->ctl); | ||
| 597 | udelay(20); | ||
| 598 | out_be32(ioaddr->ctl_addr, ap->ctl | ATA_SRST); | ||
| 599 | udelay(20); | ||
| 600 | out_be32(ioaddr->ctl_addr, ap->ctl); | ||
| 601 | |||
| 602 | return scc_wait_after_reset(&ap->link, devmask, deadline); | ||
| 603 | } | ||
| 604 | |||
| 605 | /** | ||
| 606 | * scc_softreset - reset host port via ATA SRST | ||
| 607 | * @ap: port to reset | ||
| 608 | * @classes: resulting classes of attached devices | ||
| 609 | * @deadline: deadline jiffies for the operation | ||
| 610 | * | ||
| 611 | * Note: Original code is ata_sff_softreset(). | ||
| 612 | */ | ||
| 613 | |||
| 614 | static int scc_softreset(struct ata_link *link, unsigned int *classes, | ||
| 615 | unsigned long deadline) | ||
| 616 | { | ||
| 617 | struct ata_port *ap = link->ap; | ||
| 618 | unsigned int slave_possible = ap->flags & ATA_FLAG_SLAVE_POSS; | ||
| 619 | unsigned int devmask = 0; | ||
| 620 | int rc; | ||
| 621 | u8 err; | ||
| 622 | |||
| 623 | DPRINTK("ENTER\n"); | ||
| 624 | |||
| 625 | /* determine if device 0/1 are present */ | ||
| 626 | if (scc_devchk(ap, 0)) | ||
| 627 | devmask |= (1 << 0); | ||
| 628 | if (slave_possible && scc_devchk(ap, 1)) | ||
| 629 | devmask |= (1 << 1); | ||
| 630 | |||
| 631 | /* select device 0 again */ | ||
| 632 | ap->ops->sff_dev_select(ap, 0); | ||
| 633 | |||
| 634 | /* issue bus reset */ | ||
| 635 | DPRINTK("about to softreset, devmask=%x\n", devmask); | ||
| 636 | rc = scc_bus_softreset(ap, devmask, deadline); | ||
| 637 | if (rc) { | ||
| 638 | ata_port_err(ap, "SRST failed (err_mask=0x%x)\n", rc); | ||
| 639 | return -EIO; | ||
| 640 | } | ||
| 641 | |||
| 642 | /* determine by signature whether we have ATA or ATAPI devices */ | ||
| 643 | classes[0] = ata_sff_dev_classify(&ap->link.device[0], | ||
| 644 | devmask & (1 << 0), &err); | ||
| 645 | if (slave_possible && err != 0x81) | ||
| 646 | classes[1] = ata_sff_dev_classify(&ap->link.device[1], | ||
| 647 | devmask & (1 << 1), &err); | ||
| 648 | |||
| 649 | DPRINTK("EXIT, classes[0]=%u [1]=%u\n", classes[0], classes[1]); | ||
| 650 | return 0; | ||
| 651 | } | ||
| 652 | |||
| 653 | /** | ||
| 654 | * scc_bmdma_stop - Stop PCI IDE BMDMA transfer | ||
| 655 | * @qc: Command we are ending DMA for | ||
| 656 | */ | ||
| 657 | |||
| 658 | static void scc_bmdma_stop (struct ata_queued_cmd *qc) | ||
| 659 | { | ||
| 660 | struct ata_port *ap = qc->ap; | ||
| 661 | void __iomem *ctrl_base = ap->host->iomap[SCC_CTRL_BAR]; | ||
| 662 | void __iomem *bmid_base = ap->host->iomap[SCC_BMID_BAR]; | ||
| 663 | u32 reg; | ||
| 664 | |||
| 665 | while (1) { | ||
| 666 | reg = in_be32(bmid_base + SCC_DMA_INTST); | ||
| 667 | |||
| 668 | if (reg & INTSTS_SERROR) { | ||
| 669 | printk(KERN_WARNING "%s: SERROR\n", DRV_NAME); | ||
| 670 | out_be32(bmid_base + SCC_DMA_INTST, INTSTS_SERROR|INTSTS_BMSINT); | ||
| 671 | out_be32(bmid_base + SCC_DMA_CMD, | ||
| 672 | in_be32(bmid_base + SCC_DMA_CMD) & ~ATA_DMA_START); | ||
| 673 | continue; | ||
| 674 | } | ||
| 675 | |||
| 676 | if (reg & INTSTS_PRERR) { | ||
| 677 | u32 maea0, maec0; | ||
| 678 | maea0 = in_be32(ctrl_base + SCC_CTL_MAEA0); | ||
| 679 | maec0 = in_be32(ctrl_base + SCC_CTL_MAEC0); | ||
| 680 | printk(KERN_WARNING "%s: PRERR [addr:%x cmd:%x]\n", DRV_NAME, maea0, maec0); | ||
| 681 | out_be32(bmid_base + SCC_DMA_INTST, INTSTS_PRERR|INTSTS_BMSINT); | ||
| 682 | out_be32(bmid_base + SCC_DMA_CMD, | ||
| 683 | in_be32(bmid_base + SCC_DMA_CMD) & ~ATA_DMA_START); | ||
| 684 | continue; | ||
| 685 | } | ||
| 686 | |||
| 687 | if (reg & INTSTS_RERR) { | ||
| 688 | printk(KERN_WARNING "%s: Response Error\n", DRV_NAME); | ||
| 689 | out_be32(bmid_base + SCC_DMA_INTST, INTSTS_RERR|INTSTS_BMSINT); | ||
| 690 | out_be32(bmid_base + SCC_DMA_CMD, | ||
| 691 | in_be32(bmid_base + SCC_DMA_CMD) & ~ATA_DMA_START); | ||
| 692 | continue; | ||
| 693 | } | ||
| 694 | |||
| 695 | if (reg & INTSTS_ICERR) { | ||
| 696 | out_be32(bmid_base + SCC_DMA_CMD, | ||
| 697 | in_be32(bmid_base + SCC_DMA_CMD) & ~ATA_DMA_START); | ||
| 698 | printk(KERN_WARNING "%s: Illegal Configuration\n", DRV_NAME); | ||
| 699 | out_be32(bmid_base + SCC_DMA_INTST, INTSTS_ICERR|INTSTS_BMSINT); | ||
| 700 | continue; | ||
| 701 | } | ||
| 702 | |||
| 703 | if (reg & INTSTS_BMSINT) { | ||
| 704 | unsigned int classes; | ||
| 705 | unsigned long deadline = ata_deadline(jiffies, ATA_TMOUT_BOOT); | ||
| 706 | printk(KERN_WARNING "%s: Internal Bus Error\n", DRV_NAME); | ||
| 707 | out_be32(bmid_base + SCC_DMA_INTST, INTSTS_BMSINT); | ||
| 708 | /* TBD: SW reset */ | ||
| 709 | scc_softreset(&ap->link, &classes, deadline); | ||
| 710 | continue; | ||
| 711 | } | ||
| 712 | |||
| 713 | if (reg & INTSTS_BMHE) { | ||
| 714 | out_be32(bmid_base + SCC_DMA_INTST, INTSTS_BMHE); | ||
| 715 | continue; | ||
| 716 | } | ||
| 717 | |||
| 718 | if (reg & INTSTS_ACTEINT) { | ||
| 719 | out_be32(bmid_base + SCC_DMA_INTST, INTSTS_ACTEINT); | ||
| 720 | continue; | ||
| 721 | } | ||
| 722 | |||
| 723 | if (reg & INTSTS_IOIRQS) { | ||
| 724 | out_be32(bmid_base + SCC_DMA_INTST, INTSTS_IOIRQS); | ||
| 725 | continue; | ||
| 726 | } | ||
| 727 | break; | ||
| 728 | } | ||
| 729 | |||
| 730 | /* clear start/stop bit */ | ||
| 731 | out_be32(bmid_base + SCC_DMA_CMD, | ||
| 732 | in_be32(bmid_base + SCC_DMA_CMD) & ~ATA_DMA_START); | ||
| 733 | |||
| 734 | /* one-PIO-cycle guaranteed wait, per spec, for HDMA1:0 transition */ | ||
| 735 | ata_sff_dma_pause(ap); /* dummy read */ | ||
| 736 | } | ||
| 737 | |||
| 738 | /** | ||
| 739 | * scc_bmdma_status - Read PCI IDE BMDMA status | ||
| 740 | * @ap: Port associated with this ATA transaction. | ||
| 741 | */ | ||
| 742 | |||
| 743 | static u8 scc_bmdma_status (struct ata_port *ap) | ||
| 744 | { | ||
| 745 | void __iomem *mmio = ap->ioaddr.bmdma_addr; | ||
| 746 | u8 host_stat = in_be32(mmio + SCC_DMA_STATUS); | ||
| 747 | u32 int_status = in_be32(mmio + SCC_DMA_INTST); | ||
| 748 | struct ata_queued_cmd *qc = ata_qc_from_tag(ap, ap->link.active_tag); | ||
| 749 | static int retry = 0; | ||
| 750 | |||
| 751 | /* return if IOS_SS is cleared */ | ||
| 752 | if (!(in_be32(mmio + SCC_DMA_CMD) & ATA_DMA_START)) | ||
| 753 | return host_stat; | ||
| 754 | |||
| 755 | /* errata A252,A308 workaround: Step4 */ | ||
| 756 | if ((scc_check_altstatus(ap) & ATA_ERR) | ||
| 757 | && (int_status & INTSTS_INTRQ)) | ||
| 758 | return (host_stat | ATA_DMA_INTR); | ||
| 759 | |||
| 760 | /* errata A308 workaround Step5 */ | ||
| 761 | if (int_status & INTSTS_IOIRQS) { | ||
| 762 | host_stat |= ATA_DMA_INTR; | ||
| 763 | |||
| 764 | /* We don't check ATAPI DMA because it is limited to UDMA4 */ | ||
| 765 | if ((qc->tf.protocol == ATA_PROT_DMA && | ||
| 766 | qc->dev->xfer_mode > XFER_UDMA_4)) { | ||
| 767 | if (!(int_status & INTSTS_ACTEINT)) { | ||
| 768 | printk(KERN_WARNING "ata%u: operation failed (transfer data loss)\n", | ||
| 769 | ap->print_id); | ||
| 770 | host_stat |= ATA_DMA_ERR; | ||
| 771 | if (retry++) | ||
| 772 | ap->udma_mask &= ~(1 << qc->dev->xfer_mode); | ||
| 773 | } else | ||
| 774 | retry = 0; | ||
| 775 | } | ||
| 776 | } | ||
| 777 | |||
| 778 | return host_stat; | ||
| 779 | } | ||
| 780 | |||
| 781 | /** | ||
| 782 | * scc_data_xfer - Transfer data by PIO | ||
| 783 | * @dev: device for this I/O | ||
| 784 | * @buf: data buffer | ||
| 785 | * @buflen: buffer length | ||
| 786 | * @rw: read/write | ||
| 787 | * | ||
| 788 | * Note: Original code is ata_sff_data_xfer(). | ||
| 789 | */ | ||
| 790 | |||
| 791 | static unsigned int scc_data_xfer (struct ata_device *dev, unsigned char *buf, | ||
| 792 | unsigned int buflen, int rw) | ||
| 793 | { | ||
| 794 | struct ata_port *ap = dev->link->ap; | ||
| 795 | unsigned int words = buflen >> 1; | ||
| 796 | unsigned int i; | ||
| 797 | __le16 *buf16 = (__le16 *) buf; | ||
| 798 | void __iomem *mmio = ap->ioaddr.data_addr; | ||
| 799 | |||
| 800 | /* Transfer multiple of 2 bytes */ | ||
| 801 | if (rw == READ) | ||
| 802 | for (i = 0; i < words; i++) | ||
| 803 | buf16[i] = cpu_to_le16(in_be32(mmio)); | ||
| 804 | else | ||
| 805 | for (i = 0; i < words; i++) | ||
| 806 | out_be32(mmio, le16_to_cpu(buf16[i])); | ||
| 807 | |||
| 808 | /* Transfer trailing 1 byte, if any. */ | ||
| 809 | if (unlikely(buflen & 0x01)) { | ||
| 810 | __le16 align_buf[1] = { 0 }; | ||
| 811 | unsigned char *trailing_buf = buf + buflen - 1; | ||
| 812 | |||
| 813 | if (rw == READ) { | ||
| 814 | align_buf[0] = cpu_to_le16(in_be32(mmio)); | ||
| 815 | memcpy(trailing_buf, align_buf, 1); | ||
| 816 | } else { | ||
| 817 | memcpy(align_buf, trailing_buf, 1); | ||
| 818 | out_be32(mmio, le16_to_cpu(align_buf[0])); | ||
| 819 | } | ||
| 820 | words++; | ||
| 821 | } | ||
| 822 | |||
| 823 | return words << 1; | ||
| 824 | } | ||
| 825 | |||
| 826 | /** | ||
| 827 | * scc_postreset - standard postreset callback | ||
| 828 | * @ap: the target ata_port | ||
| 829 | * @classes: classes of attached devices | ||
| 830 | * | ||
| 831 | * Note: Original code is ata_sff_postreset(). | ||
| 832 | */ | ||
| 833 | |||
| 834 | static void scc_postreset(struct ata_link *link, unsigned int *classes) | ||
| 835 | { | ||
| 836 | struct ata_port *ap = link->ap; | ||
| 837 | |||
| 838 | DPRINTK("ENTER\n"); | ||
| 839 | |||
| 840 | /* is double-select really necessary? */ | ||
| 841 | if (classes[0] != ATA_DEV_NONE) | ||
| 842 | ap->ops->sff_dev_select(ap, 1); | ||
| 843 | if (classes[1] != ATA_DEV_NONE) | ||
| 844 | ap->ops->sff_dev_select(ap, 0); | ||
| 845 | |||
| 846 | /* bail out if no device is present */ | ||
| 847 | if (classes[0] == ATA_DEV_NONE && classes[1] == ATA_DEV_NONE) { | ||
| 848 | DPRINTK("EXIT, no device\n"); | ||
| 849 | return; | ||
| 850 | } | ||
| 851 | |||
| 852 | /* set up device control */ | ||
| 853 | out_be32(ap->ioaddr.ctl_addr, ap->ctl); | ||
| 854 | |||
| 855 | DPRINTK("EXIT\n"); | ||
| 856 | } | ||
| 857 | |||
| 858 | /** | ||
| 859 | * scc_irq_clear - Clear PCI IDE BMDMA interrupt. | ||
| 860 | * @ap: Port associated with this ATA transaction. | ||
| 861 | * | ||
| 862 | * Note: Original code is ata_bmdma_irq_clear(). | ||
| 863 | */ | ||
| 864 | |||
| 865 | static void scc_irq_clear (struct ata_port *ap) | ||
| 866 | { | ||
| 867 | void __iomem *mmio = ap->ioaddr.bmdma_addr; | ||
| 868 | |||
| 869 | if (!mmio) | ||
| 870 | return; | ||
| 871 | |||
| 872 | out_be32(mmio + SCC_DMA_STATUS, in_be32(mmio + SCC_DMA_STATUS)); | ||
| 873 | } | ||
| 874 | |||
| 875 | /** | ||
| 876 | * scc_port_start - Set port up for dma. | ||
| 877 | * @ap: Port to initialize | ||
| 878 | * | ||
| 879 | * Allocate space for PRD table using ata_bmdma_port_start(). | ||
| 880 | * Set PRD table address for PTERADD. (PRD Transfer End Read) | ||
| 881 | */ | ||
| 882 | |||
| 883 | static int scc_port_start (struct ata_port *ap) | ||
| 884 | { | ||
| 885 | void __iomem *mmio = ap->ioaddr.bmdma_addr; | ||
| 886 | int rc; | ||
| 887 | |||
| 888 | rc = ata_bmdma_port_start(ap); | ||
| 889 | if (rc) | ||
| 890 | return rc; | ||
| 891 | |||
| 892 | out_be32(mmio + SCC_DMA_PTERADD, ap->bmdma_prd_dma); | ||
| 893 | return 0; | ||
| 894 | } | ||
| 895 | |||
| 896 | /** | ||
| 897 | * scc_port_stop - Undo scc_port_start() | ||
| 898 | * @ap: Port to shut down | ||
| 899 | * | ||
| 900 | * Reset PTERADD. | ||
| 901 | */ | ||
| 902 | |||
| 903 | static void scc_port_stop (struct ata_port *ap) | ||
| 904 | { | ||
| 905 | void __iomem *mmio = ap->ioaddr.bmdma_addr; | ||
| 906 | |||
| 907 | out_be32(mmio + SCC_DMA_PTERADD, 0); | ||
| 908 | } | ||
| 909 | |||
| 910 | static struct scsi_host_template scc_sht = { | ||
| 911 | ATA_BMDMA_SHT(DRV_NAME), | ||
| 912 | }; | ||
| 913 | |||
| 914 | static struct ata_port_operations scc_pata_ops = { | ||
| 915 | .inherits = &ata_bmdma_port_ops, | ||
| 916 | |||
| 917 | .set_piomode = scc_set_piomode, | ||
| 918 | .set_dmamode = scc_set_dmamode, | ||
| 919 | .mode_filter = scc_mode_filter, | ||
| 920 | |||
| 921 | .sff_tf_load = scc_tf_load, | ||
| 922 | .sff_tf_read = scc_tf_read, | ||
| 923 | .sff_exec_command = scc_exec_command, | ||
| 924 | .sff_check_status = scc_check_status, | ||
| 925 | .sff_check_altstatus = scc_check_altstatus, | ||
| 926 | .sff_dev_select = scc_dev_select, | ||
| 927 | .sff_set_devctl = scc_set_devctl, | ||
| 928 | |||
| 929 | .bmdma_setup = scc_bmdma_setup, | ||
| 930 | .bmdma_start = scc_bmdma_start, | ||
| 931 | .bmdma_stop = scc_bmdma_stop, | ||
| 932 | .bmdma_status = scc_bmdma_status, | ||
| 933 | .sff_data_xfer = scc_data_xfer, | ||
| 934 | |||
| 935 | .cable_detect = ata_cable_80wire, | ||
| 936 | .softreset = scc_softreset, | ||
| 937 | .postreset = scc_postreset, | ||
| 938 | |||
| 939 | .sff_irq_clear = scc_irq_clear, | ||
| 940 | |||
| 941 | .port_start = scc_port_start, | ||
| 942 | .port_stop = scc_port_stop, | ||
| 943 | }; | ||
| 944 | |||
| 945 | static struct ata_port_info scc_port_info[] = { | ||
| 946 | { | ||
| 947 | .flags = ATA_FLAG_SLAVE_POSS, | ||
| 948 | .pio_mask = ATA_PIO4, | ||
| 949 | /* No MWDMA */ | ||
| 950 | .udma_mask = ATA_UDMA6, | ||
| 951 | .port_ops = &scc_pata_ops, | ||
| 952 | }, | ||
| 953 | }; | ||
| 954 | |||
| 955 | /** | ||
| 956 | * scc_reset_controller - initialize SCC PATA controller. | ||
| 957 | */ | ||
| 958 | |||
| 959 | static int scc_reset_controller(struct ata_host *host) | ||
| 960 | { | ||
| 961 | void __iomem *ctrl_base = host->iomap[SCC_CTRL_BAR]; | ||
| 962 | void __iomem *bmid_base = host->iomap[SCC_BMID_BAR]; | ||
| 963 | void __iomem *cckctrl_port = ctrl_base + SCC_CTL_CCKCTRL; | ||
| 964 | void __iomem *mode_port = ctrl_base + SCC_CTL_MODEREG; | ||
| 965 | void __iomem *ecmode_port = ctrl_base + SCC_CTL_ECMODE; | ||
| 966 | void __iomem *intmask_port = bmid_base + SCC_DMA_INTMASK; | ||
| 967 | void __iomem *dmastatus_port = bmid_base + SCC_DMA_STATUS; | ||
| 968 | u32 reg = 0; | ||
| 969 | |||
| 970 | out_be32(cckctrl_port, reg); | ||
| 971 | reg |= CCKCTRL_ATACLKOEN; | ||
| 972 | out_be32(cckctrl_port, reg); | ||
| 973 | reg |= CCKCTRL_LCLKEN | CCKCTRL_OCLKEN; | ||
| 974 | out_be32(cckctrl_port, reg); | ||
| 975 | reg |= CCKCTRL_CRST; | ||
| 976 | out_be32(cckctrl_port, reg); | ||
| 977 | |||
| 978 | for (;;) { | ||
| 979 | reg = in_be32(cckctrl_port); | ||
| 980 | if (reg & CCKCTRL_CRST) | ||
| 981 | break; | ||
| 982 | udelay(5000); | ||
| 983 | } | ||
| 984 | |||
| 985 | reg |= CCKCTRL_ATARESET; | ||
| 986 | out_be32(cckctrl_port, reg); | ||
| 987 | out_be32(ecmode_port, ECMODE_VALUE); | ||
| 988 | out_be32(mode_port, MODE_JCUSFEN); | ||
| 989 | out_be32(intmask_port, INTMASK_MSK); | ||
| 990 | |||
| 991 | if (in_be32(dmastatus_port) & QCHSD_STPDIAG) { | ||
| 992 | printk(KERN_WARNING "%s: failed to detect 80c cable. (PDIAG# is high)\n", DRV_NAME); | ||
| 993 | return -EIO; | ||
| 994 | } | ||
| 995 | |||
| 996 | return 0; | ||
| 997 | } | ||
| 998 | |||
| 999 | /** | ||
| 1000 | * scc_setup_ports - initialize ioaddr with SCC PATA port offsets. | ||
| 1001 | * @ioaddr: IO address structure to be initialized | ||
| 1002 | * @base: base address of BMID region | ||
| 1003 | */ | ||
| 1004 | |||
| 1005 | static void scc_setup_ports (struct ata_ioports *ioaddr, void __iomem *base) | ||
| 1006 | { | ||
| 1007 | ioaddr->cmd_addr = base + SCC_REG_CMD_ADDR; | ||
| 1008 | ioaddr->altstatus_addr = ioaddr->cmd_addr + SCC_REG_ALTSTATUS; | ||
| 1009 | ioaddr->ctl_addr = ioaddr->cmd_addr + SCC_REG_ALTSTATUS; | ||
| 1010 | ioaddr->bmdma_addr = base; | ||
| 1011 | ioaddr->data_addr = ioaddr->cmd_addr + SCC_REG_DATA; | ||
| 1012 | ioaddr->error_addr = ioaddr->cmd_addr + SCC_REG_ERR; | ||
| 1013 | ioaddr->feature_addr = ioaddr->cmd_addr + SCC_REG_FEATURE; | ||
| 1014 | ioaddr->nsect_addr = ioaddr->cmd_addr + SCC_REG_NSECT; | ||
| 1015 | ioaddr->lbal_addr = ioaddr->cmd_addr + SCC_REG_LBAL; | ||
| 1016 | ioaddr->lbam_addr = ioaddr->cmd_addr + SCC_REG_LBAM; | ||
| 1017 | ioaddr->lbah_addr = ioaddr->cmd_addr + SCC_REG_LBAH; | ||
| 1018 | ioaddr->device_addr = ioaddr->cmd_addr + SCC_REG_DEVICE; | ||
| 1019 | ioaddr->status_addr = ioaddr->cmd_addr + SCC_REG_STATUS; | ||
| 1020 | ioaddr->command_addr = ioaddr->cmd_addr + SCC_REG_CMD; | ||
| 1021 | } | ||
| 1022 | |||
| 1023 | static int scc_host_init(struct ata_host *host) | ||
| 1024 | { | ||
| 1025 | struct pci_dev *pdev = to_pci_dev(host->dev); | ||
| 1026 | int rc; | ||
| 1027 | |||
| 1028 | rc = scc_reset_controller(host); | ||
| 1029 | if (rc) | ||
| 1030 | return rc; | ||
| 1031 | |||
| 1032 | rc = dma_set_mask(&pdev->dev, ATA_DMA_MASK); | ||
| 1033 | if (rc) | ||
| 1034 | return rc; | ||
| 1035 | rc = dma_set_coherent_mask(&pdev->dev, ATA_DMA_MASK); | ||
| 1036 | if (rc) | ||
| 1037 | return rc; | ||
| 1038 | |||
| 1039 | scc_setup_ports(&host->ports[0]->ioaddr, host->iomap[SCC_BMID_BAR]); | ||
| 1040 | |||
| 1041 | pci_set_master(pdev); | ||
| 1042 | |||
| 1043 | return 0; | ||
| 1044 | } | ||
| 1045 | |||
| 1046 | /** | ||
| 1047 | * scc_init_one - Register SCC PATA device with kernel services | ||
| 1048 | * @pdev: PCI device to register | ||
| 1049 | * @ent: Entry in scc_pci_tbl matching with @pdev | ||
| 1050 | * | ||
| 1051 | * LOCKING: | ||
| 1052 | * Inherited from PCI layer (may sleep). | ||
| 1053 | * | ||
| 1054 | * RETURNS: | ||
| 1055 | * Zero on success, or -ERRNO value. | ||
| 1056 | */ | ||
| 1057 | |||
| 1058 | static int scc_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) | ||
| 1059 | { | ||
| 1060 | unsigned int board_idx = (unsigned int) ent->driver_data; | ||
| 1061 | const struct ata_port_info *ppi[] = { &scc_port_info[board_idx], NULL }; | ||
| 1062 | struct ata_host *host; | ||
| 1063 | int rc; | ||
| 1064 | |||
| 1065 | ata_print_version_once(&pdev->dev, DRV_VERSION); | ||
| 1066 | |||
| 1067 | host = ata_host_alloc_pinfo(&pdev->dev, ppi, 1); | ||
| 1068 | if (!host) | ||
| 1069 | return -ENOMEM; | ||
| 1070 | |||
| 1071 | rc = pcim_enable_device(pdev); | ||
| 1072 | if (rc) | ||
| 1073 | return rc; | ||
| 1074 | |||
| 1075 | rc = pcim_iomap_regions(pdev, (1 << SCC_CTRL_BAR) | (1 << SCC_BMID_BAR), DRV_NAME); | ||
| 1076 | if (rc == -EBUSY) | ||
| 1077 | pcim_pin_device(pdev); | ||
| 1078 | if (rc) | ||
| 1079 | return rc; | ||
| 1080 | host->iomap = pcim_iomap_table(pdev); | ||
| 1081 | |||
| 1082 | ata_port_pbar_desc(host->ports[0], SCC_CTRL_BAR, -1, "ctrl"); | ||
| 1083 | ata_port_pbar_desc(host->ports[0], SCC_BMID_BAR, -1, "bmid"); | ||
| 1084 | |||
| 1085 | rc = scc_host_init(host); | ||
| 1086 | if (rc) | ||
| 1087 | return rc; | ||
| 1088 | |||
| 1089 | return ata_host_activate(host, pdev->irq, ata_bmdma_interrupt, | ||
| 1090 | IRQF_SHARED, &scc_sht); | ||
| 1091 | } | ||
| 1092 | |||
| 1093 | static struct pci_driver scc_pci_driver = { | ||
| 1094 | .name = DRV_NAME, | ||
| 1095 | .id_table = scc_pci_tbl, | ||
| 1096 | .probe = scc_init_one, | ||
| 1097 | .remove = ata_pci_remove_one, | ||
| 1098 | #ifdef CONFIG_PM_SLEEP | ||
| 1099 | .suspend = ata_pci_device_suspend, | ||
| 1100 | .resume = ata_pci_device_resume, | ||
| 1101 | #endif | ||
| 1102 | }; | ||
| 1103 | |||
| 1104 | module_pci_driver(scc_pci_driver); | ||
| 1105 | |||
| 1106 | MODULE_AUTHOR("Toshiba corp"); | ||
| 1107 | MODULE_DESCRIPTION("SCSI low-level driver for Toshiba SCC PATA controller"); | ||
| 1108 | MODULE_LICENSE("GPL"); | ||
| 1109 | MODULE_DEVICE_TABLE(pci, scc_pci_tbl); | ||
| 1110 | MODULE_VERSION(DRV_VERSION); | ||
diff --git a/drivers/block/loop.c b/drivers/block/loop.c index ae3fcb4199e9..d7173cb1ea76 100644 --- a/drivers/block/loop.c +++ b/drivers/block/loop.c | |||
| @@ -1620,8 +1620,8 @@ out: | |||
| 1620 | 1620 | ||
| 1621 | static void loop_remove(struct loop_device *lo) | 1621 | static void loop_remove(struct loop_device *lo) |
| 1622 | { | 1622 | { |
| 1623 | del_gendisk(lo->lo_disk); | ||
| 1624 | blk_cleanup_queue(lo->lo_queue); | 1623 | blk_cleanup_queue(lo->lo_queue); |
| 1624 | del_gendisk(lo->lo_disk); | ||
| 1625 | blk_mq_free_tag_set(&lo->tag_set); | 1625 | blk_mq_free_tag_set(&lo->tag_set); |
| 1626 | put_disk(lo->lo_disk); | 1626 | put_disk(lo->lo_disk); |
| 1627 | kfree(lo); | 1627 | kfree(lo); |
diff --git a/drivers/block/nvme-scsi.c b/drivers/block/nvme-scsi.c index 6b736b00f63e..88f13c525712 100644 --- a/drivers/block/nvme-scsi.c +++ b/drivers/block/nvme-scsi.c | |||
| @@ -944,7 +944,8 @@ static int nvme_trans_ext_inq_page(struct nvme_ns *ns, struct sg_io_hdr *hdr, | |||
| 944 | static int nvme_trans_bdev_limits_page(struct nvme_ns *ns, struct sg_io_hdr *hdr, | 944 | static int nvme_trans_bdev_limits_page(struct nvme_ns *ns, struct sg_io_hdr *hdr, |
| 945 | u8 *inq_response, int alloc_len) | 945 | u8 *inq_response, int alloc_len) |
| 946 | { | 946 | { |
| 947 | __be32 max_sectors = cpu_to_be32(queue_max_hw_sectors(ns->queue)); | 947 | __be32 max_sectors = cpu_to_be32( |
| 948 | nvme_block_nr(ns, queue_max_hw_sectors(ns->queue))); | ||
| 948 | __be32 max_discard = cpu_to_be32(ns->queue->limits.max_discard_sectors); | 949 | __be32 max_discard = cpu_to_be32(ns->queue->limits.max_discard_sectors); |
| 949 | __be32 discard_desc_count = cpu_to_be32(0x100); | 950 | __be32 discard_desc_count = cpu_to_be32(0x100); |
| 950 | 951 | ||
diff --git a/drivers/block/xen-blkback/blkback.c b/drivers/block/xen-blkback/blkback.c index bd2b3bbbb22c..713fc9ff1149 100644 --- a/drivers/block/xen-blkback/blkback.c +++ b/drivers/block/xen-blkback/blkback.c | |||
| @@ -265,17 +265,6 @@ static void put_persistent_gnt(struct xen_blkif *blkif, | |||
| 265 | atomic_dec(&blkif->persistent_gnt_in_use); | 265 | atomic_dec(&blkif->persistent_gnt_in_use); |
| 266 | } | 266 | } |
| 267 | 267 | ||
| 268 | static void free_persistent_gnts_unmap_callback(int result, | ||
| 269 | struct gntab_unmap_queue_data *data) | ||
| 270 | { | ||
| 271 | struct completion *c = data->data; | ||
| 272 | |||
| 273 | /* BUG_ON used to reproduce existing behaviour, | ||
| 274 | but is this the best way to deal with this? */ | ||
| 275 | BUG_ON(result); | ||
| 276 | complete(c); | ||
| 277 | } | ||
| 278 | |||
| 279 | static void free_persistent_gnts(struct xen_blkif *blkif, struct rb_root *root, | 268 | static void free_persistent_gnts(struct xen_blkif *blkif, struct rb_root *root, |
| 280 | unsigned int num) | 269 | unsigned int num) |
| 281 | { | 270 | { |
| @@ -285,12 +274,7 @@ static void free_persistent_gnts(struct xen_blkif *blkif, struct rb_root *root, | |||
| 285 | struct rb_node *n; | 274 | struct rb_node *n; |
| 286 | int segs_to_unmap = 0; | 275 | int segs_to_unmap = 0; |
| 287 | struct gntab_unmap_queue_data unmap_data; | 276 | struct gntab_unmap_queue_data unmap_data; |
| 288 | struct completion unmap_completion; | ||
| 289 | 277 | ||
| 290 | init_completion(&unmap_completion); | ||
| 291 | |||
| 292 | unmap_data.data = &unmap_completion; | ||
| 293 | unmap_data.done = &free_persistent_gnts_unmap_callback; | ||
| 294 | unmap_data.pages = pages; | 278 | unmap_data.pages = pages; |
| 295 | unmap_data.unmap_ops = unmap; | 279 | unmap_data.unmap_ops = unmap; |
| 296 | unmap_data.kunmap_ops = NULL; | 280 | unmap_data.kunmap_ops = NULL; |
| @@ -310,8 +294,7 @@ static void free_persistent_gnts(struct xen_blkif *blkif, struct rb_root *root, | |||
| 310 | !rb_next(&persistent_gnt->node)) { | 294 | !rb_next(&persistent_gnt->node)) { |
| 311 | 295 | ||
| 312 | unmap_data.count = segs_to_unmap; | 296 | unmap_data.count = segs_to_unmap; |
| 313 | gnttab_unmap_refs_async(&unmap_data); | 297 | BUG_ON(gnttab_unmap_refs_sync(&unmap_data)); |
| 314 | wait_for_completion(&unmap_completion); | ||
| 315 | 298 | ||
| 316 | put_free_pages(blkif, pages, segs_to_unmap); | 299 | put_free_pages(blkif, pages, segs_to_unmap); |
| 317 | segs_to_unmap = 0; | 300 | segs_to_unmap = 0; |
| @@ -329,8 +312,13 @@ void xen_blkbk_unmap_purged_grants(struct work_struct *work) | |||
| 329 | struct gnttab_unmap_grant_ref unmap[BLKIF_MAX_SEGMENTS_PER_REQUEST]; | 312 | struct gnttab_unmap_grant_ref unmap[BLKIF_MAX_SEGMENTS_PER_REQUEST]; |
| 330 | struct page *pages[BLKIF_MAX_SEGMENTS_PER_REQUEST]; | 313 | struct page *pages[BLKIF_MAX_SEGMENTS_PER_REQUEST]; |
| 331 | struct persistent_gnt *persistent_gnt; | 314 | struct persistent_gnt *persistent_gnt; |
| 332 | int ret, segs_to_unmap = 0; | 315 | int segs_to_unmap = 0; |
| 333 | struct xen_blkif *blkif = container_of(work, typeof(*blkif), persistent_purge_work); | 316 | struct xen_blkif *blkif = container_of(work, typeof(*blkif), persistent_purge_work); |
| 317 | struct gntab_unmap_queue_data unmap_data; | ||
| 318 | |||
| 319 | unmap_data.pages = pages; | ||
| 320 | unmap_data.unmap_ops = unmap; | ||
| 321 | unmap_data.kunmap_ops = NULL; | ||
| 334 | 322 | ||
| 335 | while(!list_empty(&blkif->persistent_purge_list)) { | 323 | while(!list_empty(&blkif->persistent_purge_list)) { |
| 336 | persistent_gnt = list_first_entry(&blkif->persistent_purge_list, | 324 | persistent_gnt = list_first_entry(&blkif->persistent_purge_list, |
| @@ -346,17 +334,16 @@ void xen_blkbk_unmap_purged_grants(struct work_struct *work) | |||
| 346 | pages[segs_to_unmap] = persistent_gnt->page; | 334 | pages[segs_to_unmap] = persistent_gnt->page; |
| 347 | 335 | ||
| 348 | if (++segs_to_unmap == BLKIF_MAX_SEGMENTS_PER_REQUEST) { | 336 | if (++segs_to_unmap == BLKIF_MAX_SEGMENTS_PER_REQUEST) { |
| 349 | ret = gnttab_unmap_refs(unmap, NULL, pages, | 337 | unmap_data.count = segs_to_unmap; |
| 350 | segs_to_unmap); | 338 | BUG_ON(gnttab_unmap_refs_sync(&unmap_data)); |
| 351 | BUG_ON(ret); | ||
| 352 | put_free_pages(blkif, pages, segs_to_unmap); | 339 | put_free_pages(blkif, pages, segs_to_unmap); |
| 353 | segs_to_unmap = 0; | 340 | segs_to_unmap = 0; |
| 354 | } | 341 | } |
| 355 | kfree(persistent_gnt); | 342 | kfree(persistent_gnt); |
| 356 | } | 343 | } |
| 357 | if (segs_to_unmap > 0) { | 344 | if (segs_to_unmap > 0) { |
| 358 | ret = gnttab_unmap_refs(unmap, NULL, pages, segs_to_unmap); | 345 | unmap_data.count = segs_to_unmap; |
| 359 | BUG_ON(ret); | 346 | BUG_ON(gnttab_unmap_refs_sync(&unmap_data)); |
| 360 | put_free_pages(blkif, pages, segs_to_unmap); | 347 | put_free_pages(blkif, pages, segs_to_unmap); |
| 361 | } | 348 | } |
| 362 | } | 349 | } |
diff --git a/drivers/block/zram/zram_drv.c b/drivers/block/zram/zram_drv.c index c94386aa563d..8dcbced0eafd 100644 --- a/drivers/block/zram/zram_drv.c +++ b/drivers/block/zram/zram_drv.c | |||
| @@ -74,6 +74,27 @@ static inline struct zram *dev_to_zram(struct device *dev) | |||
| 74 | return (struct zram *)dev_to_disk(dev)->private_data; | 74 | return (struct zram *)dev_to_disk(dev)->private_data; |
| 75 | } | 75 | } |
| 76 | 76 | ||
| 77 | static ssize_t compact_store(struct device *dev, | ||
| 78 | struct device_attribute *attr, const char *buf, size_t len) | ||
| 79 | { | ||
| 80 | unsigned long nr_migrated; | ||
| 81 | struct zram *zram = dev_to_zram(dev); | ||
| 82 | struct zram_meta *meta; | ||
| 83 | |||
| 84 | down_read(&zram->init_lock); | ||
| 85 | if (!init_done(zram)) { | ||
| 86 | up_read(&zram->init_lock); | ||
| 87 | return -EINVAL; | ||
| 88 | } | ||
| 89 | |||
| 90 | meta = zram->meta; | ||
| 91 | nr_migrated = zs_compact(meta->mem_pool); | ||
| 92 | atomic64_add(nr_migrated, &zram->stats.num_migrated); | ||
| 93 | up_read(&zram->init_lock); | ||
| 94 | |||
| 95 | return len; | ||
| 96 | } | ||
| 97 | |||
| 77 | static ssize_t disksize_show(struct device *dev, | 98 | static ssize_t disksize_show(struct device *dev, |
| 78 | struct device_attribute *attr, char *buf) | 99 | struct device_attribute *attr, char *buf) |
| 79 | { | 100 | { |
| @@ -1038,6 +1059,7 @@ static const struct block_device_operations zram_devops = { | |||
| 1038 | .owner = THIS_MODULE | 1059 | .owner = THIS_MODULE |
| 1039 | }; | 1060 | }; |
| 1040 | 1061 | ||
| 1062 | static DEVICE_ATTR_WO(compact); | ||
| 1041 | static DEVICE_ATTR_RW(disksize); | 1063 | static DEVICE_ATTR_RW(disksize); |
| 1042 | static DEVICE_ATTR_RO(initstate); | 1064 | static DEVICE_ATTR_RO(initstate); |
| 1043 | static DEVICE_ATTR_WO(reset); | 1065 | static DEVICE_ATTR_WO(reset); |
| @@ -1114,6 +1136,7 @@ static struct attribute *zram_disk_attrs[] = { | |||
| 1114 | &dev_attr_num_writes.attr, | 1136 | &dev_attr_num_writes.attr, |
| 1115 | &dev_attr_failed_reads.attr, | 1137 | &dev_attr_failed_reads.attr, |
| 1116 | &dev_attr_failed_writes.attr, | 1138 | &dev_attr_failed_writes.attr, |
| 1139 | &dev_attr_compact.attr, | ||
| 1117 | &dev_attr_invalid_io.attr, | 1140 | &dev_attr_invalid_io.attr, |
| 1118 | &dev_attr_notify_free.attr, | 1141 | &dev_attr_notify_free.attr, |
| 1119 | &dev_attr_zero_pages.attr, | 1142 | &dev_attr_zero_pages.attr, |
diff --git a/drivers/bluetooth/bt3c_cs.c b/drivers/bluetooth/bt3c_cs.c index 4f7e8d400bc0..6de97b3871b0 100644 --- a/drivers/bluetooth/bt3c_cs.c +++ b/drivers/bluetooth/bt3c_cs.c | |||
| @@ -227,7 +227,6 @@ static void bt3c_receive(struct bt3c_info *info) | |||
| 227 | iobase = info->p_dev->resource[0]->start; | 227 | iobase = info->p_dev->resource[0]->start; |
| 228 | 228 | ||
| 229 | avail = bt3c_read(iobase, 0x7006); | 229 | avail = bt3c_read(iobase, 0x7006); |
| 230 | //printk("bt3c_cs: receiving %d bytes\n", avail); | ||
| 231 | 230 | ||
| 232 | bt3c_address(iobase, 0x7480); | 231 | bt3c_address(iobase, 0x7480); |
| 233 | while (size < avail) { | 232 | while (size < avail) { |
| @@ -250,7 +249,6 @@ static void bt3c_receive(struct bt3c_info *info) | |||
| 250 | 249 | ||
| 251 | bt_cb(info->rx_skb)->pkt_type = inb(iobase + DATA_L); | 250 | bt_cb(info->rx_skb)->pkt_type = inb(iobase + DATA_L); |
| 252 | inb(iobase + DATA_H); | 251 | inb(iobase + DATA_H); |
| 253 | //printk("bt3c: PACKET_TYPE=%02x\n", bt_cb(info->rx_skb)->pkt_type); | ||
| 254 | 252 | ||
| 255 | switch (bt_cb(info->rx_skb)->pkt_type) { | 253 | switch (bt_cb(info->rx_skb)->pkt_type) { |
| 256 | 254 | ||
| @@ -364,7 +362,6 @@ static irqreturn_t bt3c_interrupt(int irq, void *dev_inst) | |||
| 364 | if (stat & 0x0001) | 362 | if (stat & 0x0001) |
| 365 | bt3c_receive(info); | 363 | bt3c_receive(info); |
| 366 | if (stat & 0x0002) { | 364 | if (stat & 0x0002) { |
| 367 | //BT_ERR("Ack (stat=0x%04x)", stat); | ||
| 368 | clear_bit(XMIT_SENDING, &(info->tx_state)); | 365 | clear_bit(XMIT_SENDING, &(info->tx_state)); |
| 369 | bt3c_write_wakeup(info); | 366 | bt3c_write_wakeup(info); |
| 370 | } | 367 | } |
diff --git a/drivers/bluetooth/btbcm.c b/drivers/bluetooth/btbcm.c index d0741f3ed7ec..4bba86677adc 100644 --- a/drivers/bluetooth/btbcm.c +++ b/drivers/bluetooth/btbcm.c | |||
| @@ -95,6 +95,78 @@ int btbcm_set_bdaddr(struct hci_dev *hdev, const bdaddr_t *bdaddr) | |||
| 95 | } | 95 | } |
| 96 | EXPORT_SYMBOL_GPL(btbcm_set_bdaddr); | 96 | EXPORT_SYMBOL_GPL(btbcm_set_bdaddr); |
| 97 | 97 | ||
| 98 | int btbcm_patchram(struct hci_dev *hdev, const char *firmware) | ||
| 99 | { | ||
| 100 | const struct hci_command_hdr *cmd; | ||
| 101 | const struct firmware *fw; | ||
| 102 | const u8 *fw_ptr; | ||
| 103 | size_t fw_size; | ||
| 104 | struct sk_buff *skb; | ||
| 105 | u16 opcode; | ||
| 106 | int err; | ||
| 107 | |||
| 108 | err = request_firmware(&fw, firmware, &hdev->dev); | ||
| 109 | if (err < 0) { | ||
| 110 | BT_INFO("%s: BCM: Patch %s not found", hdev->name, firmware); | ||
| 111 | return err; | ||
| 112 | } | ||
| 113 | |||
| 114 | /* Start Download */ | ||
| 115 | skb = __hci_cmd_sync(hdev, 0xfc2e, 0, NULL, HCI_INIT_TIMEOUT); | ||
| 116 | if (IS_ERR(skb)) { | ||
| 117 | err = PTR_ERR(skb); | ||
| 118 | BT_ERR("%s: BCM: Download Minidrv command failed (%d)", | ||
| 119 | hdev->name, err); | ||
| 120 | goto done; | ||
| 121 | } | ||
| 122 | kfree_skb(skb); | ||
| 123 | |||
| 124 | /* 50 msec delay after Download Minidrv completes */ | ||
| 125 | msleep(50); | ||
| 126 | |||
| 127 | fw_ptr = fw->data; | ||
| 128 | fw_size = fw->size; | ||
| 129 | |||
| 130 | while (fw_size >= sizeof(*cmd)) { | ||
| 131 | const u8 *cmd_param; | ||
| 132 | |||
| 133 | cmd = (struct hci_command_hdr *)fw_ptr; | ||
| 134 | fw_ptr += sizeof(*cmd); | ||
| 135 | fw_size -= sizeof(*cmd); | ||
| 136 | |||
| 137 | if (fw_size < cmd->plen) { | ||
| 138 | BT_ERR("%s: BCM: Patch %s is corrupted", hdev->name, | ||
| 139 | firmware); | ||
| 140 | err = -EINVAL; | ||
| 141 | goto done; | ||
| 142 | } | ||
| 143 | |||
| 144 | cmd_param = fw_ptr; | ||
| 145 | fw_ptr += cmd->plen; | ||
| 146 | fw_size -= cmd->plen; | ||
| 147 | |||
| 148 | opcode = le16_to_cpu(cmd->opcode); | ||
| 149 | |||
| 150 | skb = __hci_cmd_sync(hdev, opcode, cmd->plen, cmd_param, | ||
| 151 | HCI_INIT_TIMEOUT); | ||
| 152 | if (IS_ERR(skb)) { | ||
| 153 | err = PTR_ERR(skb); | ||
| 154 | BT_ERR("%s: BCM: Patch command %04x failed (%d)", | ||
| 155 | hdev->name, opcode, err); | ||
| 156 | goto done; | ||
| 157 | } | ||
| 158 | kfree_skb(skb); | ||
| 159 | } | ||
| 160 | |||
| 161 | /* 250 msec delay after Launch Ram completes */ | ||
| 162 | msleep(250); | ||
| 163 | |||
| 164 | done: | ||
| 165 | release_firmware(fw); | ||
| 166 | return err; | ||
| 167 | } | ||
| 168 | EXPORT_SYMBOL(btbcm_patchram); | ||
| 169 | |||
| 98 | static int btbcm_reset(struct hci_dev *hdev) | 170 | static int btbcm_reset(struct hci_dev *hdev) |
| 99 | { | 171 | { |
| 100 | struct sk_buff *skb; | 172 | struct sk_buff *skb; |
| @@ -198,12 +270,8 @@ static const struct { | |||
| 198 | 270 | ||
| 199 | int btbcm_setup_patchram(struct hci_dev *hdev) | 271 | int btbcm_setup_patchram(struct hci_dev *hdev) |
| 200 | { | 272 | { |
| 201 | const struct hci_command_hdr *cmd; | ||
| 202 | const struct firmware *fw; | ||
| 203 | const u8 *fw_ptr; | ||
| 204 | size_t fw_size; | ||
| 205 | char fw_name[64]; | 273 | char fw_name[64]; |
| 206 | u16 opcode, subver, rev, pid, vid; | 274 | u16 subver, rev, pid, vid; |
| 207 | const char *hw_name = NULL; | 275 | const char *hw_name = NULL; |
| 208 | struct sk_buff *skb; | 276 | struct sk_buff *skb; |
| 209 | struct hci_rp_read_local_version *ver; | 277 | struct hci_rp_read_local_version *ver; |
| @@ -273,74 +341,19 @@ int btbcm_setup_patchram(struct hci_dev *hdev) | |||
| 273 | hw_name ? : "BCM", (subver & 0x7000) >> 13, | 341 | hw_name ? : "BCM", (subver & 0x7000) >> 13, |
| 274 | (subver & 0x1f00) >> 8, (subver & 0x00ff), rev & 0x0fff); | 342 | (subver & 0x1f00) >> 8, (subver & 0x00ff), rev & 0x0fff); |
| 275 | 343 | ||
| 276 | err = request_firmware(&fw, fw_name, &hdev->dev); | 344 | err = btbcm_patchram(hdev, fw_name); |
| 277 | if (err < 0) { | 345 | if (err == -ENOENT) |
| 278 | BT_INFO("%s: BCM: patch %s not found", hdev->name, fw_name); | ||
| 279 | return 0; | 346 | return 0; |
| 280 | } | ||
| 281 | |||
| 282 | /* Start Download */ | ||
| 283 | skb = __hci_cmd_sync(hdev, 0xfc2e, 0, NULL, HCI_INIT_TIMEOUT); | ||
| 284 | if (IS_ERR(skb)) { | ||
| 285 | err = PTR_ERR(skb); | ||
| 286 | BT_ERR("%s: BCM: Download Minidrv command failed (%d)", | ||
| 287 | hdev->name, err); | ||
| 288 | goto reset; | ||
| 289 | } | ||
| 290 | kfree_skb(skb); | ||
| 291 | |||
| 292 | /* 50 msec delay after Download Minidrv completes */ | ||
| 293 | msleep(50); | ||
| 294 | |||
| 295 | fw_ptr = fw->data; | ||
| 296 | fw_size = fw->size; | ||
| 297 | |||
| 298 | while (fw_size >= sizeof(*cmd)) { | ||
| 299 | const u8 *cmd_param; | ||
| 300 | |||
| 301 | cmd = (struct hci_command_hdr *)fw_ptr; | ||
| 302 | fw_ptr += sizeof(*cmd); | ||
| 303 | fw_size -= sizeof(*cmd); | ||
| 304 | |||
| 305 | if (fw_size < cmd->plen) { | ||
| 306 | BT_ERR("%s: BCM: patch %s is corrupted", hdev->name, | ||
| 307 | fw_name); | ||
| 308 | err = -EINVAL; | ||
| 309 | goto reset; | ||
| 310 | } | ||
| 311 | 347 | ||
| 312 | cmd_param = fw_ptr; | ||
| 313 | fw_ptr += cmd->plen; | ||
| 314 | fw_size -= cmd->plen; | ||
| 315 | |||
| 316 | opcode = le16_to_cpu(cmd->opcode); | ||
| 317 | |||
| 318 | skb = __hci_cmd_sync(hdev, opcode, cmd->plen, cmd_param, | ||
| 319 | HCI_INIT_TIMEOUT); | ||
| 320 | if (IS_ERR(skb)) { | ||
| 321 | err = PTR_ERR(skb); | ||
| 322 | BT_ERR("%s: BCM: patch command %04x failed (%d)", | ||
| 323 | hdev->name, opcode, err); | ||
| 324 | goto reset; | ||
| 325 | } | ||
| 326 | kfree_skb(skb); | ||
| 327 | } | ||
| 328 | |||
| 329 | /* 250 msec delay after Launch Ram completes */ | ||
| 330 | msleep(250); | ||
| 331 | |||
| 332 | reset: | ||
| 333 | /* Reset */ | 348 | /* Reset */ |
| 334 | err = btbcm_reset(hdev); | 349 | err = btbcm_reset(hdev); |
| 335 | if (err) | 350 | if (err) |
| 336 | goto done; | 351 | return err; |
| 337 | 352 | ||
| 338 | /* Read Local Version Info */ | 353 | /* Read Local Version Info */ |
| 339 | skb = btbcm_read_local_version(hdev); | 354 | skb = btbcm_read_local_version(hdev); |
| 340 | if (IS_ERR(skb)) { | 355 | if (IS_ERR(skb)) |
| 341 | err = PTR_ERR(skb); | 356 | return PTR_ERR(skb); |
| 342 | goto done; | ||
| 343 | } | ||
| 344 | 357 | ||
| 345 | ver = (struct hci_rp_read_local_version *)skb->data; | 358 | ver = (struct hci_rp_read_local_version *)skb->data; |
| 346 | rev = le16_to_cpu(ver->hci_rev); | 359 | rev = le16_to_cpu(ver->hci_rev); |
| @@ -355,10 +368,7 @@ reset: | |||
| 355 | 368 | ||
| 356 | set_bit(HCI_QUIRK_STRICT_DUPLICATE_FILTER, &hdev->quirks); | 369 | set_bit(HCI_QUIRK_STRICT_DUPLICATE_FILTER, &hdev->quirks); |
| 357 | 370 | ||
| 358 | done: | 371 | return 0; |
| 359 | release_firmware(fw); | ||
| 360 | |||
| 361 | return err; | ||
| 362 | } | 372 | } |
| 363 | EXPORT_SYMBOL_GPL(btbcm_setup_patchram); | 373 | EXPORT_SYMBOL_GPL(btbcm_setup_patchram); |
| 364 | 374 | ||
diff --git a/drivers/bluetooth/btbcm.h b/drivers/bluetooth/btbcm.h index 34268ae3eb46..eb6ab5f9483d 100644 --- a/drivers/bluetooth/btbcm.h +++ b/drivers/bluetooth/btbcm.h | |||
| @@ -25,6 +25,7 @@ | |||
| 25 | 25 | ||
| 26 | int btbcm_check_bdaddr(struct hci_dev *hdev); | 26 | int btbcm_check_bdaddr(struct hci_dev *hdev); |
| 27 | int btbcm_set_bdaddr(struct hci_dev *hdev, const bdaddr_t *bdaddr); | 27 | int btbcm_set_bdaddr(struct hci_dev *hdev, const bdaddr_t *bdaddr); |
| 28 | int btbcm_patchram(struct hci_dev *hdev, const char *firmware); | ||
| 28 | 29 | ||
| 29 | int btbcm_setup_patchram(struct hci_dev *hdev); | 30 | int btbcm_setup_patchram(struct hci_dev *hdev); |
| 30 | int btbcm_setup_apple(struct hci_dev *hdev); | 31 | int btbcm_setup_apple(struct hci_dev *hdev); |
| @@ -41,6 +42,11 @@ static inline int btbcm_set_bdaddr(struct hci_dev *hdev, const bdaddr_t *bdaddr) | |||
| 41 | return -EOPNOTSUPP; | 42 | return -EOPNOTSUPP; |
| 42 | } | 43 | } |
| 43 | 44 | ||
| 45 | static inline int btbcm_patchram(struct hci_dev *hdev, const char *firmware) | ||
| 46 | { | ||
| 47 | return -EOPNOTSUPP; | ||
| 48 | } | ||
| 49 | |||
| 44 | static inline int btbcm_setup_patchram(struct hci_dev *hdev) | 50 | static inline int btbcm_setup_patchram(struct hci_dev *hdev) |
| 45 | { | 51 | { |
| 46 | return 0; | 52 | return 0; |
diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c index de7b236eeae7..d21f3b4176d3 100644 --- a/drivers/bluetooth/btusb.c +++ b/drivers/bluetooth/btusb.c | |||
| @@ -24,6 +24,7 @@ | |||
| 24 | #include <linux/module.h> | 24 | #include <linux/module.h> |
| 25 | #include <linux/usb.h> | 25 | #include <linux/usb.h> |
| 26 | #include <linux/firmware.h> | 26 | #include <linux/firmware.h> |
| 27 | #include <asm/unaligned.h> | ||
| 27 | 28 | ||
| 28 | #include <net/bluetooth/bluetooth.h> | 29 | #include <net/bluetooth/bluetooth.h> |
| 29 | #include <net/bluetooth/hci_core.h> | 30 | #include <net/bluetooth/hci_core.h> |
| @@ -57,6 +58,7 @@ static struct usb_driver btusb_driver; | |||
| 57 | #define BTUSB_AMP 0x4000 | 58 | #define BTUSB_AMP 0x4000 |
| 58 | #define BTUSB_QCA_ROME 0x8000 | 59 | #define BTUSB_QCA_ROME 0x8000 |
| 59 | #define BTUSB_BCM_APPLE 0x10000 | 60 | #define BTUSB_BCM_APPLE 0x10000 |
| 61 | #define BTUSB_REALTEK 0x20000 | ||
| 60 | 62 | ||
| 61 | static const struct usb_device_id btusb_table[] = { | 63 | static const struct usb_device_id btusb_table[] = { |
| 62 | /* Generic Bluetooth USB device */ | 64 | /* Generic Bluetooth USB device */ |
| @@ -288,6 +290,28 @@ static const struct usb_device_id blacklist_table[] = { | |||
| 288 | { USB_VENDOR_AND_INTERFACE_INFO(0x8087, 0xe0, 0x01, 0x01), | 290 | { USB_VENDOR_AND_INTERFACE_INFO(0x8087, 0xe0, 0x01, 0x01), |
| 289 | .driver_info = BTUSB_IGNORE }, | 291 | .driver_info = BTUSB_IGNORE }, |
| 290 | 292 | ||
| 293 | /* Realtek Bluetooth devices */ | ||
| 294 | { USB_VENDOR_AND_INTERFACE_INFO(0x0bda, 0xe0, 0x01, 0x01), | ||
| 295 | .driver_info = BTUSB_REALTEK }, | ||
| 296 | |||
| 297 | /* Additional Realtek 8723AE Bluetooth devices */ | ||
| 298 | { USB_DEVICE(0x0930, 0x021d), .driver_info = BTUSB_REALTEK }, | ||
| 299 | { USB_DEVICE(0x13d3, 0x3394), .driver_info = BTUSB_REALTEK }, | ||
| 300 | |||
| 301 | /* Additional Realtek 8723BE Bluetooth devices */ | ||
| 302 | { USB_DEVICE(0x0489, 0xe085), .driver_info = BTUSB_REALTEK }, | ||
| 303 | { USB_DEVICE(0x0489, 0xe08b), .driver_info = BTUSB_REALTEK }, | ||
| 304 | { USB_DEVICE(0x13d3, 0x3410), .driver_info = BTUSB_REALTEK }, | ||
| 305 | { USB_DEVICE(0x13d3, 0x3416), .driver_info = BTUSB_REALTEK }, | ||
| 306 | { USB_DEVICE(0x13d3, 0x3459), .driver_info = BTUSB_REALTEK }, | ||
| 307 | |||
| 308 | /* Additional Realtek 8821AE Bluetooth devices */ | ||
| 309 | { USB_DEVICE(0x0b05, 0x17dc), .driver_info = BTUSB_REALTEK }, | ||
| 310 | { USB_DEVICE(0x13d3, 0x3414), .driver_info = BTUSB_REALTEK }, | ||
| 311 | { USB_DEVICE(0x13d3, 0x3458), .driver_info = BTUSB_REALTEK }, | ||
| 312 | { USB_DEVICE(0x13d3, 0x3461), .driver_info = BTUSB_REALTEK }, | ||
| 313 | { USB_DEVICE(0x13d3, 0x3462), .driver_info = BTUSB_REALTEK }, | ||
| 314 | |||
| 291 | { } /* Terminating entry */ | 315 | { } /* Terminating entry */ |
| 292 | }; | 316 | }; |
| 293 | 317 | ||
| @@ -892,7 +916,7 @@ static int btusb_open(struct hci_dev *hdev) | |||
| 892 | */ | 916 | */ |
| 893 | if (data->setup_on_usb) { | 917 | if (data->setup_on_usb) { |
| 894 | err = data->setup_on_usb(hdev); | 918 | err = data->setup_on_usb(hdev); |
| 895 | if (err <0) | 919 | if (err < 0) |
| 896 | return err; | 920 | return err; |
| 897 | } | 921 | } |
| 898 | 922 | ||
| @@ -1345,6 +1369,378 @@ static int btusb_setup_csr(struct hci_dev *hdev) | |||
| 1345 | return ret; | 1369 | return ret; |
| 1346 | } | 1370 | } |
| 1347 | 1371 | ||
| 1372 | #define RTL_FRAG_LEN 252 | ||
| 1373 | |||
| 1374 | struct rtl_download_cmd { | ||
| 1375 | __u8 index; | ||
| 1376 | __u8 data[RTL_FRAG_LEN]; | ||
| 1377 | } __packed; | ||
| 1378 | |||
| 1379 | struct rtl_download_response { | ||
| 1380 | __u8 status; | ||
| 1381 | __u8 index; | ||
| 1382 | } __packed; | ||
| 1383 | |||
| 1384 | struct rtl_rom_version_evt { | ||
| 1385 | __u8 status; | ||
| 1386 | __u8 version; | ||
| 1387 | } __packed; | ||
| 1388 | |||
| 1389 | struct rtl_epatch_header { | ||
| 1390 | __u8 signature[8]; | ||
| 1391 | __le32 fw_version; | ||
| 1392 | __le16 num_patches; | ||
| 1393 | } __packed; | ||
| 1394 | |||
| 1395 | #define RTL_EPATCH_SIGNATURE "Realtech" | ||
| 1396 | #define RTL_ROM_LMP_3499 0x3499 | ||
| 1397 | #define RTL_ROM_LMP_8723A 0x1200 | ||
| 1398 | #define RTL_ROM_LMP_8723B 0x8723 | ||
| 1399 | #define RTL_ROM_LMP_8821A 0x8821 | ||
| 1400 | #define RTL_ROM_LMP_8761A 0x8761 | ||
| 1401 | |||
| 1402 | static int rtl_read_rom_version(struct hci_dev *hdev, u8 *version) | ||
| 1403 | { | ||
| 1404 | struct rtl_rom_version_evt *rom_version; | ||
| 1405 | struct sk_buff *skb; | ||
| 1406 | int ret; | ||
| 1407 | |||
| 1408 | /* Read RTL ROM version command */ | ||
| 1409 | skb = __hci_cmd_sync(hdev, 0xfc6d, 0, NULL, HCI_INIT_TIMEOUT); | ||
| 1410 | if (IS_ERR(skb)) { | ||
| 1411 | BT_ERR("%s: Read ROM version failed (%ld)", | ||
| 1412 | hdev->name, PTR_ERR(skb)); | ||
| 1413 | return PTR_ERR(skb); | ||
| 1414 | } | ||
| 1415 | |||
| 1416 | if (skb->len != sizeof(*rom_version)) { | ||
| 1417 | BT_ERR("%s: RTL version event length mismatch", hdev->name); | ||
| 1418 | kfree_skb(skb); | ||
| 1419 | return -EIO; | ||
| 1420 | } | ||
| 1421 | |||
| 1422 | rom_version = (struct rtl_rom_version_evt *)skb->data; | ||
| 1423 | BT_INFO("%s: rom_version status=%x version=%x", | ||
| 1424 | hdev->name, rom_version->status, rom_version->version); | ||
| 1425 | |||
| 1426 | ret = rom_version->status; | ||
| 1427 | if (ret == 0) | ||
| 1428 | *version = rom_version->version; | ||
| 1429 | |||
| 1430 | kfree_skb(skb); | ||
| 1431 | return ret; | ||
| 1432 | } | ||
| 1433 | |||
| 1434 | static int rtl8723b_parse_firmware(struct hci_dev *hdev, u16 lmp_subver, | ||
| 1435 | const struct firmware *fw, | ||
| 1436 | unsigned char **_buf) | ||
| 1437 | { | ||
| 1438 | const u8 extension_sig[] = { 0x51, 0x04, 0xfd, 0x77 }; | ||
| 1439 | struct rtl_epatch_header *epatch_info; | ||
| 1440 | unsigned char *buf; | ||
| 1441 | int i, ret, len; | ||
| 1442 | size_t min_size; | ||
| 1443 | u8 opcode, length, data, rom_version = 0; | ||
| 1444 | int project_id = -1; | ||
| 1445 | const unsigned char *fwptr, *chip_id_base; | ||
| 1446 | const unsigned char *patch_length_base, *patch_offset_base; | ||
| 1447 | u32 patch_offset = 0; | ||
| 1448 | u16 patch_length, num_patches; | ||
| 1449 | const u16 project_id_to_lmp_subver[] = { | ||
| 1450 | RTL_ROM_LMP_8723A, | ||
| 1451 | RTL_ROM_LMP_8723B, | ||
| 1452 | RTL_ROM_LMP_8821A, | ||
| 1453 | RTL_ROM_LMP_8761A | ||
| 1454 | }; | ||
| 1455 | |||
| 1456 | ret = rtl_read_rom_version(hdev, &rom_version); | ||
| 1457 | if (ret) | ||
| 1458 | return -bt_to_errno(ret); | ||
| 1459 | |||
| 1460 | min_size = sizeof(struct rtl_epatch_header) + sizeof(extension_sig) + 3; | ||
| 1461 | if (fw->size < min_size) | ||
| 1462 | return -EINVAL; | ||
| 1463 | |||
| 1464 | fwptr = fw->data + fw->size - sizeof(extension_sig); | ||
| 1465 | if (memcmp(fwptr, extension_sig, sizeof(extension_sig)) != 0) { | ||
| 1466 | BT_ERR("%s: extension section signature mismatch", hdev->name); | ||
| 1467 | return -EINVAL; | ||
| 1468 | } | ||
| 1469 | |||
| 1470 | /* Loop from the end of the firmware parsing instructions, until | ||
| 1471 | * we find an instruction that identifies the "project ID" for the | ||
| 1472 | * hardware supported by this firwmare file. | ||
| 1473 | * Once we have that, we double-check that that project_id is suitable | ||
| 1474 | * for the hardware we are working with. | ||
| 1475 | */ | ||
| 1476 | while (fwptr >= fw->data + (sizeof(struct rtl_epatch_header) + 3)) { | ||
| 1477 | opcode = *--fwptr; | ||
| 1478 | length = *--fwptr; | ||
| 1479 | data = *--fwptr; | ||
| 1480 | |||
| 1481 | BT_DBG("check op=%x len=%x data=%x", opcode, length, data); | ||
| 1482 | |||
| 1483 | if (opcode == 0xff) /* EOF */ | ||
| 1484 | break; | ||
| 1485 | |||
| 1486 | if (length == 0) { | ||
| 1487 | BT_ERR("%s: found instruction with length 0", | ||
| 1488 | hdev->name); | ||
| 1489 | return -EINVAL; | ||
| 1490 | } | ||
| 1491 | |||
| 1492 | if (opcode == 0 && length == 1) { | ||
| 1493 | project_id = data; | ||
| 1494 | break; | ||
| 1495 | } | ||
| 1496 | |||
| 1497 | fwptr -= length; | ||
| 1498 | } | ||
| 1499 | |||
| 1500 | if (project_id < 0) { | ||
| 1501 | BT_ERR("%s: failed to find version instruction", hdev->name); | ||
| 1502 | return -EINVAL; | ||
| 1503 | } | ||
| 1504 | |||
| 1505 | if (project_id >= ARRAY_SIZE(project_id_to_lmp_subver)) { | ||
| 1506 | BT_ERR("%s: unknown project id %d", hdev->name, project_id); | ||
| 1507 | return -EINVAL; | ||
| 1508 | } | ||
| 1509 | |||
| 1510 | if (lmp_subver != project_id_to_lmp_subver[project_id]) { | ||
| 1511 | BT_ERR("%s: firmware is for %x but this is a %x", hdev->name, | ||
| 1512 | project_id_to_lmp_subver[project_id], lmp_subver); | ||
| 1513 | return -EINVAL; | ||
| 1514 | } | ||
| 1515 | |||
| 1516 | epatch_info = (struct rtl_epatch_header *)fw->data; | ||
| 1517 | if (memcmp(epatch_info->signature, RTL_EPATCH_SIGNATURE, 8) != 0) { | ||
| 1518 | BT_ERR("%s: bad EPATCH signature", hdev->name); | ||
| 1519 | return -EINVAL; | ||
| 1520 | } | ||
| 1521 | |||
| 1522 | num_patches = le16_to_cpu(epatch_info->num_patches); | ||
| 1523 | BT_DBG("fw_version=%x, num_patches=%d", | ||
| 1524 | le32_to_cpu(epatch_info->fw_version), num_patches); | ||
| 1525 | |||
| 1526 | /* After the rtl_epatch_header there is a funky patch metadata section. | ||
| 1527 | * Assuming 2 patches, the layout is: | ||
| 1528 | * ChipID1 ChipID2 PatchLength1 PatchLength2 PatchOffset1 PatchOffset2 | ||
| 1529 | * | ||
| 1530 | * Find the right patch for this chip. | ||
| 1531 | */ | ||
| 1532 | min_size += 8 * num_patches; | ||
| 1533 | if (fw->size < min_size) | ||
| 1534 | return -EINVAL; | ||
| 1535 | |||
| 1536 | chip_id_base = fw->data + sizeof(struct rtl_epatch_header); | ||
| 1537 | patch_length_base = chip_id_base + (sizeof(u16) * num_patches); | ||
| 1538 | patch_offset_base = patch_length_base + (sizeof(u16) * num_patches); | ||
| 1539 | for (i = 0; i < num_patches; i++) { | ||
| 1540 | u16 chip_id = get_unaligned_le16(chip_id_base + | ||
| 1541 | (i * sizeof(u16))); | ||
| 1542 | if (chip_id == rom_version + 1) { | ||
| 1543 | patch_length = get_unaligned_le16(patch_length_base + | ||
| 1544 | (i * sizeof(u16))); | ||
| 1545 | patch_offset = get_unaligned_le32(patch_offset_base + | ||
| 1546 | (i * sizeof(u32))); | ||
| 1547 | break; | ||
| 1548 | } | ||
| 1549 | } | ||
| 1550 | |||
| 1551 | if (!patch_offset) { | ||
| 1552 | BT_ERR("%s: didn't find patch for chip id %d", | ||
| 1553 | hdev->name, rom_version); | ||
| 1554 | return -EINVAL; | ||
| 1555 | } | ||
| 1556 | |||
| 1557 | BT_DBG("length=%x offset=%x index %d", patch_length, patch_offset, i); | ||
| 1558 | min_size = patch_offset + patch_length; | ||
| 1559 | if (fw->size < min_size) | ||
| 1560 | return -EINVAL; | ||
| 1561 | |||
| 1562 | /* Copy the firmware into a new buffer and write the version at | ||
| 1563 | * the end. | ||
| 1564 | */ | ||
| 1565 | len = patch_length; | ||
| 1566 | buf = kmemdup(fw->data + patch_offset, patch_length, GFP_KERNEL); | ||
| 1567 | if (!buf) | ||
| 1568 | return -ENOMEM; | ||
| 1569 | |||
| 1570 | memcpy(buf + patch_length - 4, &epatch_info->fw_version, 4); | ||
| 1571 | |||
| 1572 | *_buf = buf; | ||
| 1573 | return len; | ||
| 1574 | } | ||
| 1575 | |||
| 1576 | static int rtl_download_firmware(struct hci_dev *hdev, | ||
| 1577 | const unsigned char *data, int fw_len) | ||
| 1578 | { | ||
| 1579 | struct rtl_download_cmd *dl_cmd; | ||
| 1580 | int frag_num = fw_len / RTL_FRAG_LEN + 1; | ||
| 1581 | int frag_len = RTL_FRAG_LEN; | ||
| 1582 | int ret = 0; | ||
| 1583 | int i; | ||
| 1584 | |||
| 1585 | dl_cmd = kmalloc(sizeof(struct rtl_download_cmd), GFP_KERNEL); | ||
| 1586 | if (!dl_cmd) | ||
| 1587 | return -ENOMEM; | ||
| 1588 | |||
| 1589 | for (i = 0; i < frag_num; i++) { | ||
| 1590 | struct rtl_download_response *dl_resp; | ||
| 1591 | struct sk_buff *skb; | ||
| 1592 | |||
| 1593 | BT_DBG("download fw (%d/%d)", i, frag_num); | ||
| 1594 | |||
| 1595 | dl_cmd->index = i; | ||
| 1596 | if (i == (frag_num - 1)) { | ||
| 1597 | dl_cmd->index |= 0x80; /* data end */ | ||
| 1598 | frag_len = fw_len % RTL_FRAG_LEN; | ||
| 1599 | } | ||
| 1600 | memcpy(dl_cmd->data, data, frag_len); | ||
| 1601 | |||
| 1602 | /* Send download command */ | ||
| 1603 | skb = __hci_cmd_sync(hdev, 0xfc20, frag_len + 1, dl_cmd, | ||
| 1604 | HCI_INIT_TIMEOUT); | ||
| 1605 | if (IS_ERR(skb)) { | ||
| 1606 | BT_ERR("%s: download fw command failed (%ld)", | ||
| 1607 | hdev->name, PTR_ERR(skb)); | ||
| 1608 | ret = -PTR_ERR(skb); | ||
| 1609 | goto out; | ||
| 1610 | } | ||
| 1611 | |||
| 1612 | if (skb->len != sizeof(*dl_resp)) { | ||
| 1613 | BT_ERR("%s: download fw event length mismatch", | ||
| 1614 | hdev->name); | ||
| 1615 | kfree_skb(skb); | ||
| 1616 | ret = -EIO; | ||
| 1617 | goto out; | ||
| 1618 | } | ||
| 1619 | |||
| 1620 | dl_resp = (struct rtl_download_response *)skb->data; | ||
| 1621 | if (dl_resp->status != 0) { | ||
| 1622 | kfree_skb(skb); | ||
| 1623 | ret = bt_to_errno(dl_resp->status); | ||
| 1624 | goto out; | ||
| 1625 | } | ||
| 1626 | |||
| 1627 | kfree_skb(skb); | ||
| 1628 | data += RTL_FRAG_LEN; | ||
| 1629 | } | ||
| 1630 | |||
| 1631 | out: | ||
| 1632 | kfree(dl_cmd); | ||
| 1633 | return ret; | ||
| 1634 | } | ||
| 1635 | |||
| 1636 | static int btusb_setup_rtl8723a(struct hci_dev *hdev) | ||
| 1637 | { | ||
| 1638 | struct btusb_data *data = dev_get_drvdata(&hdev->dev); | ||
| 1639 | struct usb_device *udev = interface_to_usbdev(data->intf); | ||
| 1640 | const struct firmware *fw; | ||
| 1641 | int ret; | ||
| 1642 | |||
| 1643 | BT_INFO("%s: rtl: loading rtl_bt/rtl8723a_fw.bin", hdev->name); | ||
| 1644 | ret = request_firmware(&fw, "rtl_bt/rtl8723a_fw.bin", &udev->dev); | ||
| 1645 | if (ret < 0) { | ||
| 1646 | BT_ERR("%s: Failed to load rtl_bt/rtl8723a_fw.bin", hdev->name); | ||
| 1647 | return ret; | ||
| 1648 | } | ||
| 1649 | |||
| 1650 | if (fw->size < 8) { | ||
| 1651 | ret = -EINVAL; | ||
| 1652 | goto out; | ||
| 1653 | } | ||
| 1654 | |||
| 1655 | /* Check that the firmware doesn't have the epatch signature | ||
| 1656 | * (which is only for RTL8723B and newer). | ||
| 1657 | */ | ||
| 1658 | if (!memcmp(fw->data, RTL_EPATCH_SIGNATURE, 8)) { | ||
| 1659 | BT_ERR("%s: unexpected EPATCH signature!", hdev->name); | ||
| 1660 | ret = -EINVAL; | ||
| 1661 | goto out; | ||
| 1662 | } | ||
| 1663 | |||
| 1664 | ret = rtl_download_firmware(hdev, fw->data, fw->size); | ||
| 1665 | |||
| 1666 | out: | ||
| 1667 | release_firmware(fw); | ||
| 1668 | return ret; | ||
| 1669 | } | ||
| 1670 | |||
| 1671 | static int btusb_setup_rtl8723b(struct hci_dev *hdev, u16 lmp_subver, | ||
| 1672 | const char *fw_name) | ||
| 1673 | { | ||
| 1674 | struct btusb_data *data = dev_get_drvdata(&hdev->dev); | ||
| 1675 | struct usb_device *udev = interface_to_usbdev(data->intf); | ||
| 1676 | unsigned char *fw_data = NULL; | ||
| 1677 | const struct firmware *fw; | ||
| 1678 | int ret; | ||
| 1679 | |||
| 1680 | BT_INFO("%s: rtl: loading %s", hdev->name, fw_name); | ||
| 1681 | ret = request_firmware(&fw, fw_name, &udev->dev); | ||
| 1682 | if (ret < 0) { | ||
| 1683 | BT_ERR("%s: Failed to load %s", hdev->name, fw_name); | ||
| 1684 | return ret; | ||
| 1685 | } | ||
| 1686 | |||
| 1687 | ret = rtl8723b_parse_firmware(hdev, lmp_subver, fw, &fw_data); | ||
| 1688 | if (ret < 0) | ||
| 1689 | goto out; | ||
| 1690 | |||
| 1691 | ret = rtl_download_firmware(hdev, fw_data, ret); | ||
| 1692 | kfree(fw_data); | ||
| 1693 | if (ret < 0) | ||
| 1694 | goto out; | ||
| 1695 | |||
| 1696 | out: | ||
| 1697 | release_firmware(fw); | ||
| 1698 | return ret; | ||
| 1699 | } | ||
| 1700 | |||
| 1701 | static int btusb_setup_realtek(struct hci_dev *hdev) | ||
| 1702 | { | ||
| 1703 | struct sk_buff *skb; | ||
| 1704 | struct hci_rp_read_local_version *resp; | ||
| 1705 | u16 lmp_subver; | ||
| 1706 | |||
| 1707 | skb = btusb_read_local_version(hdev); | ||
| 1708 | if (IS_ERR(skb)) | ||
| 1709 | return -PTR_ERR(skb); | ||
| 1710 | |||
| 1711 | resp = (struct hci_rp_read_local_version *)skb->data; | ||
| 1712 | BT_INFO("%s: rtl: examining hci_ver=%02x hci_rev=%04x lmp_ver=%02x " | ||
| 1713 | "lmp_subver=%04x", hdev->name, resp->hci_ver, resp->hci_rev, | ||
| 1714 | resp->lmp_ver, resp->lmp_subver); | ||
| 1715 | |||
| 1716 | lmp_subver = le16_to_cpu(resp->lmp_subver); | ||
| 1717 | kfree_skb(skb); | ||
| 1718 | |||
| 1719 | /* Match a set of subver values that correspond to stock firmware, | ||
| 1720 | * which is not compatible with standard btusb. | ||
| 1721 | * If matched, upload an alternative firmware that does conform to | ||
| 1722 | * standard btusb. Once that firmware is uploaded, the subver changes | ||
| 1723 | * to a different value. | ||
| 1724 | */ | ||
| 1725 | switch (lmp_subver) { | ||
| 1726 | case RTL_ROM_LMP_8723A: | ||
| 1727 | case RTL_ROM_LMP_3499: | ||
| 1728 | return btusb_setup_rtl8723a(hdev); | ||
| 1729 | case RTL_ROM_LMP_8723B: | ||
| 1730 | return btusb_setup_rtl8723b(hdev, lmp_subver, | ||
| 1731 | "rtl_bt/rtl8723b_fw.bin"); | ||
| 1732 | case RTL_ROM_LMP_8821A: | ||
| 1733 | return btusb_setup_rtl8723b(hdev, lmp_subver, | ||
| 1734 | "rtl_bt/rtl8821a_fw.bin"); | ||
| 1735 | case RTL_ROM_LMP_8761A: | ||
| 1736 | return btusb_setup_rtl8723b(hdev, lmp_subver, | ||
| 1737 | "rtl_bt/rtl8761a_fw.bin"); | ||
| 1738 | default: | ||
| 1739 | BT_INFO("rtl: assuming no firmware upload needed."); | ||
| 1740 | return 0; | ||
| 1741 | } | ||
| 1742 | } | ||
| 1743 | |||
| 1348 | static const struct firmware *btusb_setup_intel_get_fw(struct hci_dev *hdev, | 1744 | static const struct firmware *btusb_setup_intel_get_fw(struct hci_dev *hdev, |
| 1349 | struct intel_version *ver) | 1745 | struct intel_version *ver) |
| 1350 | { | 1746 | { |
| @@ -2577,7 +2973,7 @@ static int btusb_setup_qca(struct hci_dev *hdev) | |||
| 2577 | int i, err; | 2973 | int i, err; |
| 2578 | 2974 | ||
| 2579 | err = btusb_qca_send_vendor_req(hdev, QCA_GET_TARGET_VERSION, &ver, | 2975 | err = btusb_qca_send_vendor_req(hdev, QCA_GET_TARGET_VERSION, &ver, |
| 2580 | sizeof(ver)); | 2976 | sizeof(ver)); |
| 2581 | if (err < 0) | 2977 | if (err < 0) |
| 2582 | return err; | 2978 | return err; |
| 2583 | 2979 | ||
| @@ -2776,6 +3172,9 @@ static int btusb_probe(struct usb_interface *intf, | |||
| 2776 | hdev->set_bdaddr = btusb_set_bdaddr_ath3012; | 3172 | hdev->set_bdaddr = btusb_set_bdaddr_ath3012; |
| 2777 | } | 3173 | } |
| 2778 | 3174 | ||
| 3175 | if (id->driver_info & BTUSB_REALTEK) | ||
| 3176 | hdev->setup = btusb_setup_realtek; | ||
| 3177 | |||
| 2779 | if (id->driver_info & BTUSB_AMP) { | 3178 | if (id->driver_info & BTUSB_AMP) { |
| 2780 | /* AMP controllers do not support SCO packets */ | 3179 | /* AMP controllers do not support SCO packets */ |
| 2781 | data->isoc = NULL; | 3180 | data->isoc = NULL; |
diff --git a/drivers/bluetooth/hci_ath.c b/drivers/bluetooth/hci_ath.c index 1b3f8647ea2f..ec8fa0e0f036 100644 --- a/drivers/bluetooth/hci_ath.c +++ b/drivers/bluetooth/hci_ath.c | |||
| @@ -95,7 +95,6 @@ static void ath_hci_uart_work(struct work_struct *work) | |||
| 95 | hci_uart_tx_wakeup(hu); | 95 | hci_uart_tx_wakeup(hu); |
| 96 | } | 96 | } |
| 97 | 97 | ||
| 98 | /* Initialize protocol */ | ||
| 99 | static int ath_open(struct hci_uart *hu) | 98 | static int ath_open(struct hci_uart *hu) |
| 100 | { | 99 | { |
| 101 | struct ath_struct *ath; | 100 | struct ath_struct *ath; |
| @@ -116,8 +115,7 @@ static int ath_open(struct hci_uart *hu) | |||
| 116 | return 0; | 115 | return 0; |
| 117 | } | 116 | } |
| 118 | 117 | ||
| 119 | /* Flush protocol data */ | 118 | static int ath_close(struct hci_uart *hu) |
| 120 | static int ath_flush(struct hci_uart *hu) | ||
| 121 | { | 119 | { |
| 122 | struct ath_struct *ath = hu->priv; | 120 | struct ath_struct *ath = hu->priv; |
| 123 | 121 | ||
| @@ -125,11 +123,17 @@ static int ath_flush(struct hci_uart *hu) | |||
| 125 | 123 | ||
| 126 | skb_queue_purge(&ath->txq); | 124 | skb_queue_purge(&ath->txq); |
| 127 | 125 | ||
| 126 | kfree_skb(ath->rx_skb); | ||
| 127 | |||
| 128 | cancel_work_sync(&ath->ctxtsw); | ||
| 129 | |||
| 130 | hu->priv = NULL; | ||
| 131 | kfree(ath); | ||
| 132 | |||
| 128 | return 0; | 133 | return 0; |
| 129 | } | 134 | } |
| 130 | 135 | ||
| 131 | /* Close protocol */ | 136 | static int ath_flush(struct hci_uart *hu) |
| 132 | static int ath_close(struct hci_uart *hu) | ||
| 133 | { | 137 | { |
| 134 | struct ath_struct *ath = hu->priv; | 138 | struct ath_struct *ath = hu->priv; |
| 135 | 139 | ||
| @@ -137,19 +141,65 @@ static int ath_close(struct hci_uart *hu) | |||
| 137 | 141 | ||
| 138 | skb_queue_purge(&ath->txq); | 142 | skb_queue_purge(&ath->txq); |
| 139 | 143 | ||
| 140 | kfree_skb(ath->rx_skb); | 144 | return 0; |
| 145 | } | ||
| 141 | 146 | ||
| 142 | cancel_work_sync(&ath->ctxtsw); | 147 | static int ath_set_bdaddr(struct hci_dev *hdev, const bdaddr_t *bdaddr) |
| 148 | { | ||
| 149 | struct sk_buff *skb; | ||
| 150 | u8 buf[10]; | ||
| 151 | int err; | ||
| 152 | |||
| 153 | buf[0] = 0x01; | ||
| 154 | buf[1] = 0x01; | ||
| 155 | buf[2] = 0x00; | ||
| 156 | buf[3] = sizeof(bdaddr_t); | ||
| 157 | memcpy(buf + 4, bdaddr, sizeof(bdaddr_t)); | ||
| 158 | |||
| 159 | skb = __hci_cmd_sync(hdev, 0xfc0b, sizeof(buf), buf, HCI_INIT_TIMEOUT); | ||
| 160 | if (IS_ERR(skb)) { | ||
| 161 | err = PTR_ERR(skb); | ||
| 162 | BT_ERR("%s: Change address command failed (%d)", | ||
| 163 | hdev->name, err); | ||
| 164 | return err; | ||
| 165 | } | ||
| 166 | kfree_skb(skb); | ||
| 143 | 167 | ||
| 144 | hu->priv = NULL; | 168 | return 0; |
| 145 | kfree(ath); | 169 | } |
| 170 | |||
| 171 | static int ath_setup(struct hci_uart *hu) | ||
| 172 | { | ||
| 173 | BT_DBG("hu %p", hu); | ||
| 174 | |||
| 175 | hu->hdev->set_bdaddr = ath_set_bdaddr; | ||
| 146 | 176 | ||
| 147 | return 0; | 177 | return 0; |
| 148 | } | 178 | } |
| 149 | 179 | ||
| 180 | static const struct h4_recv_pkt ath_recv_pkts[] = { | ||
| 181 | { H4_RECV_ACL, .recv = hci_recv_frame }, | ||
| 182 | { H4_RECV_SCO, .recv = hci_recv_frame }, | ||
| 183 | { H4_RECV_EVENT, .recv = hci_recv_frame }, | ||
| 184 | }; | ||
| 185 | |||
| 186 | static int ath_recv(struct hci_uart *hu, const void *data, int count) | ||
| 187 | { | ||
| 188 | struct ath_struct *ath = hu->priv; | ||
| 189 | |||
| 190 | ath->rx_skb = h4_recv_buf(hu->hdev, ath->rx_skb, data, count, | ||
| 191 | ath_recv_pkts, ARRAY_SIZE(ath_recv_pkts)); | ||
| 192 | if (IS_ERR(ath->rx_skb)) { | ||
| 193 | int err = PTR_ERR(ath->rx_skb); | ||
| 194 | BT_ERR("%s: Frame reassembly failed (%d)", hu->hdev->name, err); | ||
| 195 | return err; | ||
| 196 | } | ||
| 197 | |||
| 198 | return count; | ||
| 199 | } | ||
| 200 | |||
| 150 | #define HCI_OP_ATH_SLEEP 0xFC04 | 201 | #define HCI_OP_ATH_SLEEP 0xFC04 |
| 151 | 202 | ||
| 152 | /* Enqueue frame for transmittion */ | ||
| 153 | static int ath_enqueue(struct hci_uart *hu, struct sk_buff *skb) | 203 | static int ath_enqueue(struct hci_uart *hu, struct sk_buff *skb) |
| 154 | { | 204 | { |
| 155 | struct ath_struct *ath = hu->priv; | 205 | struct ath_struct *ath = hu->priv; |
| @@ -159,8 +209,7 @@ static int ath_enqueue(struct hci_uart *hu, struct sk_buff *skb) | |||
| 159 | return 0; | 209 | return 0; |
| 160 | } | 210 | } |
| 161 | 211 | ||
| 162 | /* | 212 | /* Update power management enable flag with parameters of |
| 163 | * Update power management enable flag with parameters of | ||
| 164 | * HCI sleep enable vendor specific HCI command. | 213 | * HCI sleep enable vendor specific HCI command. |
| 165 | */ | 214 | */ |
| 166 | if (bt_cb(skb)->pkt_type == HCI_COMMAND_PKT) { | 215 | if (bt_cb(skb)->pkt_type == HCI_COMMAND_PKT) { |
| @@ -190,37 +239,16 @@ static struct sk_buff *ath_dequeue(struct hci_uart *hu) | |||
| 190 | return skb_dequeue(&ath->txq); | 239 | return skb_dequeue(&ath->txq); |
| 191 | } | 240 | } |
| 192 | 241 | ||
| 193 | static const struct h4_recv_pkt ath_recv_pkts[] = { | ||
| 194 | { H4_RECV_ACL, .recv = hci_recv_frame }, | ||
| 195 | { H4_RECV_SCO, .recv = hci_recv_frame }, | ||
| 196 | { H4_RECV_EVENT, .recv = hci_recv_frame }, | ||
| 197 | }; | ||
| 198 | |||
| 199 | /* Recv data */ | ||
| 200 | static int ath_recv(struct hci_uart *hu, const void *data, int count) | ||
| 201 | { | ||
| 202 | struct ath_struct *ath = hu->priv; | ||
| 203 | |||
| 204 | ath->rx_skb = h4_recv_buf(hu->hdev, ath->rx_skb, data, count, | ||
| 205 | ath_recv_pkts, ARRAY_SIZE(ath_recv_pkts)); | ||
| 206 | if (IS_ERR(ath->rx_skb)) { | ||
| 207 | int err = PTR_ERR(ath->rx_skb); | ||
| 208 | BT_ERR("%s: Frame reassembly failed (%d)", hu->hdev->name, err); | ||
| 209 | return err; | ||
| 210 | } | ||
| 211 | |||
| 212 | return count; | ||
| 213 | } | ||
| 214 | |||
| 215 | static const struct hci_uart_proto athp = { | 242 | static const struct hci_uart_proto athp = { |
| 216 | .id = HCI_UART_ATH3K, | 243 | .id = HCI_UART_ATH3K, |
| 217 | .name = "ATH3K", | 244 | .name = "ATH3K", |
| 218 | .open = ath_open, | 245 | .open = ath_open, |
| 219 | .close = ath_close, | 246 | .close = ath_close, |
| 247 | .flush = ath_flush, | ||
| 248 | .setup = ath_setup, | ||
| 220 | .recv = ath_recv, | 249 | .recv = ath_recv, |
| 221 | .enqueue = ath_enqueue, | 250 | .enqueue = ath_enqueue, |
| 222 | .dequeue = ath_dequeue, | 251 | .dequeue = ath_dequeue, |
| 223 | .flush = ath_flush, | ||
| 224 | }; | 252 | }; |
| 225 | 253 | ||
| 226 | int __init ath_init(void) | 254 | int __init ath_init(void) |
diff --git a/drivers/bus/arm-cci.c b/drivers/bus/arm-cci.c index b854125e4831..5340604b23a4 100644 --- a/drivers/bus/arm-cci.c +++ b/drivers/bus/arm-cci.c | |||
| @@ -660,7 +660,7 @@ validate_group(struct perf_event *event) | |||
| 660 | * Initialise the fake PMU. We only need to populate the | 660 | * Initialise the fake PMU. We only need to populate the |
| 661 | * used_mask for the purposes of validation. | 661 | * used_mask for the purposes of validation. |
| 662 | */ | 662 | */ |
| 663 | .used_mask = CPU_BITS_NONE, | 663 | .used_mask = { 0 }, |
| 664 | }; | 664 | }; |
| 665 | 665 | ||
| 666 | if (!validate_event(event->pmu, &fake_pmu, leader)) | 666 | if (!validate_event(event->pmu, &fake_pmu, leader)) |
diff --git a/drivers/bus/omap_l3_noc.c b/drivers/bus/omap_l3_noc.c index 11f7982cbdb3..ebee57d715d2 100644 --- a/drivers/bus/omap_l3_noc.c +++ b/drivers/bus/omap_l3_noc.c | |||
| @@ -1,7 +1,7 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * OMAP L3 Interconnect error handling driver | 2 | * OMAP L3 Interconnect error handling driver |
| 3 | * | 3 | * |
| 4 | * Copyright (C) 2011-2014 Texas Instruments Incorporated - http://www.ti.com/ | 4 | * Copyright (C) 2011-2015 Texas Instruments Incorporated - http://www.ti.com/ |
| 5 | * Santosh Shilimkar <santosh.shilimkar@ti.com> | 5 | * Santosh Shilimkar <santosh.shilimkar@ti.com> |
| 6 | * Sricharan <r.sricharan@ti.com> | 6 | * Sricharan <r.sricharan@ti.com> |
| 7 | * | 7 | * |
| @@ -233,7 +233,8 @@ static irqreturn_t l3_interrupt_handler(int irq, void *_l3) | |||
| 233 | } | 233 | } |
| 234 | 234 | ||
| 235 | static const struct of_device_id l3_noc_match[] = { | 235 | static const struct of_device_id l3_noc_match[] = { |
| 236 | {.compatible = "ti,omap4-l3-noc", .data = &omap_l3_data}, | 236 | {.compatible = "ti,omap4-l3-noc", .data = &omap4_l3_data}, |
| 237 | {.compatible = "ti,omap5-l3-noc", .data = &omap5_l3_data}, | ||
| 237 | {.compatible = "ti,dra7-l3-noc", .data = &dra_l3_data}, | 238 | {.compatible = "ti,dra7-l3-noc", .data = &dra_l3_data}, |
| 238 | {.compatible = "ti,am4372-l3-noc", .data = &am4372_l3_data}, | 239 | {.compatible = "ti,am4372-l3-noc", .data = &am4372_l3_data}, |
| 239 | {}, | 240 | {}, |
diff --git a/drivers/bus/omap_l3_noc.h b/drivers/bus/omap_l3_noc.h index 95254585db86..73431f81da28 100644 --- a/drivers/bus/omap_l3_noc.h +++ b/drivers/bus/omap_l3_noc.h | |||
| @@ -1,7 +1,7 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * OMAP L3 Interconnect error handling driver header | 2 | * OMAP L3 Interconnect error handling driver header |
| 3 | * | 3 | * |
| 4 | * Copyright (C) 2011-2014 Texas Instruments Incorporated - http://www.ti.com/ | 4 | * Copyright (C) 2011-2015 Texas Instruments Incorporated - http://www.ti.com/ |
| 5 | * Santosh Shilimkar <santosh.shilimkar@ti.com> | 5 | * Santosh Shilimkar <santosh.shilimkar@ti.com> |
| 6 | * sricharan <r.sricharan@ti.com> | 6 | * sricharan <r.sricharan@ti.com> |
| 7 | * | 7 | * |
| @@ -175,16 +175,14 @@ static struct l3_flagmux_data omap_l3_flagmux_clk2 = { | |||
| 175 | }; | 175 | }; |
| 176 | 176 | ||
| 177 | 177 | ||
| 178 | static struct l3_target_data omap_l3_target_data_clk3[] = { | 178 | static struct l3_target_data omap4_l3_target_data_clk3[] = { |
| 179 | {0x0100, "EMUSS",}, | 179 | {0x0100, "DEBUGSS",}, |
| 180 | {0x0300, "DEBUG SOURCE",}, | ||
| 181 | {0x0, "HOST CLK3",}, | ||
| 182 | }; | 180 | }; |
| 183 | 181 | ||
| 184 | static struct l3_flagmux_data omap_l3_flagmux_clk3 = { | 182 | static struct l3_flagmux_data omap4_l3_flagmux_clk3 = { |
| 185 | .offset = 0x0200, | 183 | .offset = 0x0200, |
| 186 | .l3_targ = omap_l3_target_data_clk3, | 184 | .l3_targ = omap4_l3_target_data_clk3, |
| 187 | .num_targ_data = ARRAY_SIZE(omap_l3_target_data_clk3), | 185 | .num_targ_data = ARRAY_SIZE(omap4_l3_target_data_clk3), |
| 188 | }; | 186 | }; |
| 189 | 187 | ||
| 190 | static struct l3_masters_data omap_l3_masters[] = { | 188 | static struct l3_masters_data omap_l3_masters[] = { |
| @@ -215,21 +213,49 @@ static struct l3_masters_data omap_l3_masters[] = { | |||
| 215 | { 0x32, "USBHOSTFS"} | 213 | { 0x32, "USBHOSTFS"} |
| 216 | }; | 214 | }; |
| 217 | 215 | ||
| 218 | static struct l3_flagmux_data *omap_l3_flagmux[] = { | 216 | static struct l3_flagmux_data *omap4_l3_flagmux[] = { |
| 219 | &omap_l3_flagmux_clk1, | 217 | &omap_l3_flagmux_clk1, |
| 220 | &omap_l3_flagmux_clk2, | 218 | &omap_l3_flagmux_clk2, |
| 221 | &omap_l3_flagmux_clk3, | 219 | &omap4_l3_flagmux_clk3, |
| 222 | }; | 220 | }; |
| 223 | 221 | ||
| 224 | static const struct omap_l3 omap_l3_data = { | 222 | static const struct omap_l3 omap4_l3_data = { |
| 225 | .l3_flagmux = omap_l3_flagmux, | 223 | .l3_flagmux = omap4_l3_flagmux, |
| 226 | .num_modules = ARRAY_SIZE(omap_l3_flagmux), | 224 | .num_modules = ARRAY_SIZE(omap4_l3_flagmux), |
| 227 | .l3_masters = omap_l3_masters, | 225 | .l3_masters = omap_l3_masters, |
| 228 | .num_masters = ARRAY_SIZE(omap_l3_masters), | 226 | .num_masters = ARRAY_SIZE(omap_l3_masters), |
| 229 | /* The 6 MSBs of register field used to distinguish initiator */ | 227 | /* The 6 MSBs of register field used to distinguish initiator */ |
| 230 | .mst_addr_mask = 0xFC, | 228 | .mst_addr_mask = 0xFC, |
| 231 | }; | 229 | }; |
| 232 | 230 | ||
| 231 | /* OMAP5 data */ | ||
| 232 | static struct l3_target_data omap5_l3_target_data_clk3[] = { | ||
| 233 | {0x0100, "L3INSTR",}, | ||
| 234 | {0x0300, "DEBUGSS",}, | ||
| 235 | {0x0, "HOSTCLK3",}, | ||
| 236 | }; | ||
| 237 | |||
| 238 | static struct l3_flagmux_data omap5_l3_flagmux_clk3 = { | ||
| 239 | .offset = 0x0200, | ||
| 240 | .l3_targ = omap5_l3_target_data_clk3, | ||
| 241 | .num_targ_data = ARRAY_SIZE(omap5_l3_target_data_clk3), | ||
| 242 | }; | ||
| 243 | |||
| 244 | static struct l3_flagmux_data *omap5_l3_flagmux[] = { | ||
| 245 | &omap_l3_flagmux_clk1, | ||
| 246 | &omap_l3_flagmux_clk2, | ||
| 247 | &omap5_l3_flagmux_clk3, | ||
| 248 | }; | ||
| 249 | |||
| 250 | static const struct omap_l3 omap5_l3_data = { | ||
| 251 | .l3_flagmux = omap5_l3_flagmux, | ||
| 252 | .num_modules = ARRAY_SIZE(omap5_l3_flagmux), | ||
| 253 | .l3_masters = omap_l3_masters, | ||
| 254 | .num_masters = ARRAY_SIZE(omap_l3_masters), | ||
| 255 | /* The 6 MSBs of register field used to distinguish initiator */ | ||
| 256 | .mst_addr_mask = 0x7E0, | ||
| 257 | }; | ||
| 258 | |||
| 233 | /* DRA7 data */ | 259 | /* DRA7 data */ |
| 234 | static struct l3_target_data dra_l3_target_data_clk1[] = { | 260 | static struct l3_target_data dra_l3_target_data_clk1[] = { |
| 235 | {0x2a00, "AES1",}, | 261 | {0x2a00, "AES1",}, |
| @@ -274,7 +300,7 @@ static struct l3_flagmux_data dra_l3_flagmux_clk1 = { | |||
| 274 | 300 | ||
| 275 | static struct l3_target_data dra_l3_target_data_clk2[] = { | 301 | static struct l3_target_data dra_l3_target_data_clk2[] = { |
| 276 | {0x0, "HOST CLK1",}, | 302 | {0x0, "HOST CLK1",}, |
| 277 | {0x0, "HOST CLK2",}, | 303 | {0x800000, "HOST CLK2",}, |
| 278 | {0xdead, L3_TARGET_NOT_SUPPORTED,}, | 304 | {0xdead, L3_TARGET_NOT_SUPPORTED,}, |
| 279 | {0x3400, "SHA2_2",}, | 305 | {0x3400, "SHA2_2",}, |
| 280 | {0x0900, "BB2D",}, | 306 | {0x0900, "BB2D",}, |
diff --git a/drivers/char/hw_random/bcm63xx-rng.c b/drivers/char/hw_random/bcm63xx-rng.c index d1494ecd9e11..4b31f1387f37 100644 --- a/drivers/char/hw_random/bcm63xx-rng.c +++ b/drivers/char/hw_random/bcm63xx-rng.c | |||
| @@ -57,7 +57,7 @@ static void bcm63xx_rng_cleanup(struct hwrng *rng) | |||
| 57 | val &= ~RNG_EN; | 57 | val &= ~RNG_EN; |
| 58 | __raw_writel(val, priv->regs + RNG_CTRL); | 58 | __raw_writel(val, priv->regs + RNG_CTRL); |
| 59 | 59 | ||
| 60 | clk_didsable_unprepare(prov->clk); | 60 | clk_disable_unprepare(priv->clk); |
| 61 | } | 61 | } |
| 62 | 62 | ||
| 63 | static int bcm63xx_rng_data_present(struct hwrng *rng, int wait) | 63 | static int bcm63xx_rng_data_present(struct hwrng *rng, int wait) |
| @@ -97,14 +97,14 @@ static int bcm63xx_rng_probe(struct platform_device *pdev) | |||
| 97 | priv->rng.name = pdev->name; | 97 | priv->rng.name = pdev->name; |
| 98 | priv->rng.init = bcm63xx_rng_init; | 98 | priv->rng.init = bcm63xx_rng_init; |
| 99 | priv->rng.cleanup = bcm63xx_rng_cleanup; | 99 | priv->rng.cleanup = bcm63xx_rng_cleanup; |
| 100 | prov->rng.data_present = bcm63xx_rng_data_present; | 100 | priv->rng.data_present = bcm63xx_rng_data_present; |
| 101 | priv->rng.data_read = bcm63xx_rng_data_read; | 101 | priv->rng.data_read = bcm63xx_rng_data_read; |
| 102 | 102 | ||
| 103 | priv->clk = devm_clk_get(&pdev->dev, "ipsec"); | 103 | priv->clk = devm_clk_get(&pdev->dev, "ipsec"); |
| 104 | if (IS_ERR(priv->clk)) { | 104 | if (IS_ERR(priv->clk)) { |
| 105 | error = PTR_ERR(priv->clk); | 105 | ret = PTR_ERR(priv->clk); |
| 106 | dev_err(&pdev->dev, "no clock for device: %d\n", error); | 106 | dev_err(&pdev->dev, "no clock for device: %d\n", ret); |
| 107 | return error; | 107 | return ret; |
| 108 | } | 108 | } |
| 109 | 109 | ||
| 110 | if (!devm_request_mem_region(&pdev->dev, r->start, | 110 | if (!devm_request_mem_region(&pdev->dev, r->start, |
| @@ -120,11 +120,11 @@ static int bcm63xx_rng_probe(struct platform_device *pdev) | |||
| 120 | return -ENOMEM; | 120 | return -ENOMEM; |
| 121 | } | 121 | } |
| 122 | 122 | ||
| 123 | error = devm_hwrng_register(&pdev->dev, &priv->rng); | 123 | ret = devm_hwrng_register(&pdev->dev, &priv->rng); |
| 124 | if (error) { | 124 | if (ret) { |
| 125 | dev_err(&pdev->dev, "failed to register rng device: %d\n", | 125 | dev_err(&pdev->dev, "failed to register rng device: %d\n", |
| 126 | error); | 126 | ret); |
| 127 | return error; | 127 | return ret; |
| 128 | } | 128 | } |
| 129 | 129 | ||
| 130 | dev_info(&pdev->dev, "registered RNG driver\n"); | 130 | dev_info(&pdev->dev, "registered RNG driver\n"); |
diff --git a/drivers/char/ipmi/ipmi_msghandler.c b/drivers/char/ipmi/ipmi_msghandler.c index 9bb592872532..bf75f6361773 100644 --- a/drivers/char/ipmi/ipmi_msghandler.c +++ b/drivers/char/ipmi/ipmi_msghandler.c | |||
| @@ -2000,7 +2000,7 @@ static int smi_ipmb_proc_show(struct seq_file *m, void *v) | |||
| 2000 | seq_printf(m, " %x", intf->channels[i].address); | 2000 | seq_printf(m, " %x", intf->channels[i].address); |
| 2001 | seq_putc(m, '\n'); | 2001 | seq_putc(m, '\n'); |
| 2002 | 2002 | ||
| 2003 | return seq_has_overflowed(m); | 2003 | return 0; |
| 2004 | } | 2004 | } |
| 2005 | 2005 | ||
| 2006 | static int smi_ipmb_proc_open(struct inode *inode, struct file *file) | 2006 | static int smi_ipmb_proc_open(struct inode *inode, struct file *file) |
| @@ -2023,7 +2023,7 @@ static int smi_version_proc_show(struct seq_file *m, void *v) | |||
| 2023 | ipmi_version_major(&intf->bmc->id), | 2023 | ipmi_version_major(&intf->bmc->id), |
| 2024 | ipmi_version_minor(&intf->bmc->id)); | 2024 | ipmi_version_minor(&intf->bmc->id)); |
| 2025 | 2025 | ||
| 2026 | return seq_has_overflowed(m); | 2026 | return 0; |
| 2027 | } | 2027 | } |
| 2028 | 2028 | ||
| 2029 | static int smi_version_proc_open(struct inode *inode, struct file *file) | 2029 | static int smi_version_proc_open(struct inode *inode, struct file *file) |
diff --git a/drivers/char/ipmi/ipmi_si_intf.c b/drivers/char/ipmi/ipmi_si_intf.c index 5e90a18afbaf..8a45e92ff60c 100644 --- a/drivers/char/ipmi/ipmi_si_intf.c +++ b/drivers/char/ipmi/ipmi_si_intf.c | |||
| @@ -942,8 +942,7 @@ static void sender(void *send_info, | |||
| 942 | * If we are running to completion, start it and run | 942 | * If we are running to completion, start it and run |
| 943 | * transactions until everything is clear. | 943 | * transactions until everything is clear. |
| 944 | */ | 944 | */ |
| 945 | smi_info->curr_msg = msg; | 945 | smi_info->waiting_msg = msg; |
| 946 | smi_info->waiting_msg = NULL; | ||
| 947 | 946 | ||
| 948 | /* | 947 | /* |
| 949 | * Run to completion means we are single-threaded, no | 948 | * Run to completion means we are single-threaded, no |
| @@ -2244,7 +2243,7 @@ static int ipmi_pnp_probe(struct pnp_dev *dev, | |||
| 2244 | acpi_handle handle; | 2243 | acpi_handle handle; |
| 2245 | acpi_status status; | 2244 | acpi_status status; |
| 2246 | unsigned long long tmp; | 2245 | unsigned long long tmp; |
| 2247 | int rv; | 2246 | int rv = -EINVAL; |
| 2248 | 2247 | ||
| 2249 | acpi_dev = pnp_acpi_device(dev); | 2248 | acpi_dev = pnp_acpi_device(dev); |
| 2250 | if (!acpi_dev) | 2249 | if (!acpi_dev) |
| @@ -2262,8 +2261,10 @@ static int ipmi_pnp_probe(struct pnp_dev *dev, | |||
| 2262 | 2261 | ||
| 2263 | /* _IFT tells us the interface type: KCS, BT, etc */ | 2262 | /* _IFT tells us the interface type: KCS, BT, etc */ |
| 2264 | status = acpi_evaluate_integer(handle, "_IFT", NULL, &tmp); | 2263 | status = acpi_evaluate_integer(handle, "_IFT", NULL, &tmp); |
| 2265 | if (ACPI_FAILURE(status)) | 2264 | if (ACPI_FAILURE(status)) { |
| 2265 | dev_err(&dev->dev, "Could not find ACPI IPMI interface type\n"); | ||
| 2266 | goto err_free; | 2266 | goto err_free; |
| 2267 | } | ||
| 2267 | 2268 | ||
| 2268 | switch (tmp) { | 2269 | switch (tmp) { |
| 2269 | case 1: | 2270 | case 1: |
| @@ -2276,6 +2277,7 @@ static int ipmi_pnp_probe(struct pnp_dev *dev, | |||
| 2276 | info->si_type = SI_BT; | 2277 | info->si_type = SI_BT; |
| 2277 | break; | 2278 | break; |
| 2278 | case 4: /* SSIF, just ignore */ | 2279 | case 4: /* SSIF, just ignore */ |
| 2280 | rv = -ENODEV; | ||
| 2279 | goto err_free; | 2281 | goto err_free; |
| 2280 | default: | 2282 | default: |
| 2281 | dev_info(&dev->dev, "unknown IPMI type %lld\n", tmp); | 2283 | dev_info(&dev->dev, "unknown IPMI type %lld\n", tmp); |
| @@ -2336,7 +2338,7 @@ static int ipmi_pnp_probe(struct pnp_dev *dev, | |||
| 2336 | 2338 | ||
| 2337 | err_free: | 2339 | err_free: |
| 2338 | kfree(info); | 2340 | kfree(info); |
| 2339 | return -EINVAL; | 2341 | return rv; |
| 2340 | } | 2342 | } |
| 2341 | 2343 | ||
| 2342 | static void ipmi_pnp_remove(struct pnp_dev *dev) | 2344 | static void ipmi_pnp_remove(struct pnp_dev *dev) |
| @@ -3080,7 +3082,7 @@ static int smi_type_proc_show(struct seq_file *m, void *v) | |||
| 3080 | 3082 | ||
| 3081 | seq_printf(m, "%s\n", si_to_str[smi->si_type]); | 3083 | seq_printf(m, "%s\n", si_to_str[smi->si_type]); |
| 3082 | 3084 | ||
| 3083 | return seq_has_overflowed(m); | 3085 | return 0; |
| 3084 | } | 3086 | } |
| 3085 | 3087 | ||
| 3086 | static int smi_type_proc_open(struct inode *inode, struct file *file) | 3088 | static int smi_type_proc_open(struct inode *inode, struct file *file) |
| @@ -3153,7 +3155,7 @@ static int smi_params_proc_show(struct seq_file *m, void *v) | |||
| 3153 | smi->irq, | 3155 | smi->irq, |
| 3154 | smi->slave_addr); | 3156 | smi->slave_addr); |
| 3155 | 3157 | ||
| 3156 | return seq_has_overflowed(m); | 3158 | return 0; |
| 3157 | } | 3159 | } |
| 3158 | 3160 | ||
| 3159 | static int smi_params_proc_open(struct inode *inode, struct file *file) | 3161 | static int smi_params_proc_open(struct inode *inode, struct file *file) |
diff --git a/drivers/char/ipmi/ipmi_ssif.c b/drivers/char/ipmi/ipmi_ssif.c index f40e3bd2c69c..207689c444a8 100644 --- a/drivers/char/ipmi/ipmi_ssif.c +++ b/drivers/char/ipmi/ipmi_ssif.c | |||
| @@ -31,7 +31,6 @@ | |||
| 31 | * interface into the I2C driver, I believe. | 31 | * interface into the I2C driver, I believe. |
| 32 | */ | 32 | */ |
| 33 | 33 | ||
| 34 | #include <linux/version.h> | ||
| 35 | #if defined(MODVERSIONS) | 34 | #if defined(MODVERSIONS) |
| 36 | #include <linux/modversions.h> | 35 | #include <linux/modversions.h> |
| 37 | #endif | 36 | #endif |
| @@ -166,6 +165,9 @@ enum ssif_stat_indexes { | |||
| 166 | /* Number of watchdog pretimeouts. */ | 165 | /* Number of watchdog pretimeouts. */ |
| 167 | SSIF_STAT_watchdog_pretimeouts, | 166 | SSIF_STAT_watchdog_pretimeouts, |
| 168 | 167 | ||
| 168 | /* Number of alers received. */ | ||
| 169 | SSIF_STAT_alerts, | ||
| 170 | |||
| 169 | /* Always add statistics before this value, it must be last. */ | 171 | /* Always add statistics before this value, it must be last. */ |
| 170 | SSIF_NUM_STATS | 172 | SSIF_NUM_STATS |
| 171 | }; | 173 | }; |
| @@ -214,7 +216,16 @@ struct ssif_info { | |||
| 214 | #define WDT_PRE_TIMEOUT_INT 0x08 | 216 | #define WDT_PRE_TIMEOUT_INT 0x08 |
| 215 | unsigned char msg_flags; | 217 | unsigned char msg_flags; |
| 216 | 218 | ||
| 219 | u8 global_enables; | ||
| 217 | bool has_event_buffer; | 220 | bool has_event_buffer; |
| 221 | bool supports_alert; | ||
| 222 | |||
| 223 | /* | ||
| 224 | * Used to tell what we should do with alerts. If we are | ||
| 225 | * waiting on a response, read the data immediately. | ||
| 226 | */ | ||
| 227 | bool got_alert; | ||
| 228 | bool waiting_alert; | ||
| 218 | 229 | ||
| 219 | /* | 230 | /* |
| 220 | * If set to true, this will request events the next time the | 231 | * If set to true, this will request events the next time the |
| @@ -478,13 +489,13 @@ static int ipmi_ssif_thread(void *data) | |||
| 478 | 489 | ||
| 479 | if (ssif_info->i2c_read_write == I2C_SMBUS_WRITE) { | 490 | if (ssif_info->i2c_read_write == I2C_SMBUS_WRITE) { |
| 480 | result = i2c_smbus_write_block_data( | 491 | result = i2c_smbus_write_block_data( |
| 481 | ssif_info->client, SSIF_IPMI_REQUEST, | 492 | ssif_info->client, ssif_info->i2c_command, |
| 482 | ssif_info->i2c_data[0], | 493 | ssif_info->i2c_data[0], |
| 483 | ssif_info->i2c_data + 1); | 494 | ssif_info->i2c_data + 1); |
| 484 | ssif_info->done_handler(ssif_info, result, NULL, 0); | 495 | ssif_info->done_handler(ssif_info, result, NULL, 0); |
| 485 | } else { | 496 | } else { |
| 486 | result = i2c_smbus_read_block_data( | 497 | result = i2c_smbus_read_block_data( |
| 487 | ssif_info->client, SSIF_IPMI_RESPONSE, | 498 | ssif_info->client, ssif_info->i2c_command, |
| 488 | ssif_info->i2c_data); | 499 | ssif_info->i2c_data); |
| 489 | if (result < 0) | 500 | if (result < 0) |
| 490 | ssif_info->done_handler(ssif_info, result, | 501 | ssif_info->done_handler(ssif_info, result, |
| @@ -518,15 +529,12 @@ static int ssif_i2c_send(struct ssif_info *ssif_info, | |||
| 518 | static void msg_done_handler(struct ssif_info *ssif_info, int result, | 529 | static void msg_done_handler(struct ssif_info *ssif_info, int result, |
| 519 | unsigned char *data, unsigned int len); | 530 | unsigned char *data, unsigned int len); |
| 520 | 531 | ||
| 521 | static void retry_timeout(unsigned long data) | 532 | static void start_get(struct ssif_info *ssif_info) |
| 522 | { | 533 | { |
| 523 | struct ssif_info *ssif_info = (void *) data; | ||
| 524 | int rv; | 534 | int rv; |
| 525 | 535 | ||
| 526 | if (ssif_info->stopping) | ||
| 527 | return; | ||
| 528 | |||
| 529 | ssif_info->rtc_us_timer = 0; | 536 | ssif_info->rtc_us_timer = 0; |
| 537 | ssif_info->multi_pos = 0; | ||
| 530 | 538 | ||
| 531 | rv = ssif_i2c_send(ssif_info, msg_done_handler, I2C_SMBUS_READ, | 539 | rv = ssif_i2c_send(ssif_info, msg_done_handler, I2C_SMBUS_READ, |
| 532 | SSIF_IPMI_RESPONSE, | 540 | SSIF_IPMI_RESPONSE, |
| @@ -540,6 +548,46 @@ static void retry_timeout(unsigned long data) | |||
| 540 | } | 548 | } |
| 541 | } | 549 | } |
| 542 | 550 | ||
| 551 | static void retry_timeout(unsigned long data) | ||
| 552 | { | ||
| 553 | struct ssif_info *ssif_info = (void *) data; | ||
| 554 | unsigned long oflags, *flags; | ||
| 555 | bool waiting; | ||
| 556 | |||
| 557 | if (ssif_info->stopping) | ||
| 558 | return; | ||
| 559 | |||
| 560 | flags = ipmi_ssif_lock_cond(ssif_info, &oflags); | ||
| 561 | waiting = ssif_info->waiting_alert; | ||
| 562 | ssif_info->waiting_alert = false; | ||
| 563 | ipmi_ssif_unlock_cond(ssif_info, flags); | ||
| 564 | |||
| 565 | if (waiting) | ||
| 566 | start_get(ssif_info); | ||
| 567 | } | ||
| 568 | |||
| 569 | |||
| 570 | static void ssif_alert(struct i2c_client *client, unsigned int data) | ||
| 571 | { | ||
| 572 | struct ssif_info *ssif_info = i2c_get_clientdata(client); | ||
| 573 | unsigned long oflags, *flags; | ||
| 574 | bool do_get = false; | ||
| 575 | |||
| 576 | ssif_inc_stat(ssif_info, alerts); | ||
| 577 | |||
| 578 | flags = ipmi_ssif_lock_cond(ssif_info, &oflags); | ||
| 579 | if (ssif_info->waiting_alert) { | ||
| 580 | ssif_info->waiting_alert = false; | ||
| 581 | del_timer(&ssif_info->retry_timer); | ||
| 582 | do_get = true; | ||
| 583 | } else if (ssif_info->curr_msg) { | ||
| 584 | ssif_info->got_alert = true; | ||
| 585 | } | ||
| 586 | ipmi_ssif_unlock_cond(ssif_info, flags); | ||
| 587 | if (do_get) | ||
| 588 | start_get(ssif_info); | ||
| 589 | } | ||
| 590 | |||
| 543 | static int start_resend(struct ssif_info *ssif_info); | 591 | static int start_resend(struct ssif_info *ssif_info); |
| 544 | 592 | ||
| 545 | static void msg_done_handler(struct ssif_info *ssif_info, int result, | 593 | static void msg_done_handler(struct ssif_info *ssif_info, int result, |
| @@ -559,9 +607,12 @@ static void msg_done_handler(struct ssif_info *ssif_info, int result, | |||
| 559 | if (ssif_info->retries_left > 0) { | 607 | if (ssif_info->retries_left > 0) { |
| 560 | ssif_inc_stat(ssif_info, receive_retries); | 608 | ssif_inc_stat(ssif_info, receive_retries); |
| 561 | 609 | ||
| 610 | flags = ipmi_ssif_lock_cond(ssif_info, &oflags); | ||
| 611 | ssif_info->waiting_alert = true; | ||
| 612 | ssif_info->rtc_us_timer = SSIF_MSG_USEC; | ||
| 562 | mod_timer(&ssif_info->retry_timer, | 613 | mod_timer(&ssif_info->retry_timer, |
| 563 | jiffies + SSIF_MSG_JIFFIES); | 614 | jiffies + SSIF_MSG_JIFFIES); |
| 564 | ssif_info->rtc_us_timer = SSIF_MSG_USEC; | 615 | ipmi_ssif_unlock_cond(ssif_info, flags); |
| 565 | return; | 616 | return; |
| 566 | } | 617 | } |
| 567 | 618 | ||
| @@ -581,9 +632,9 @@ static void msg_done_handler(struct ssif_info *ssif_info, int result, | |||
| 581 | ssif_inc_stat(ssif_info, received_message_parts); | 632 | ssif_inc_stat(ssif_info, received_message_parts); |
| 582 | 633 | ||
| 583 | /* Remove the multi-part read marker. */ | 634 | /* Remove the multi-part read marker. */ |
| 584 | for (i = 0; i < (len-2); i++) | ||
| 585 | ssif_info->data[i] = data[i+2]; | ||
| 586 | len -= 2; | 635 | len -= 2; |
| 636 | for (i = 0; i < len; i++) | ||
| 637 | ssif_info->data[i] = data[i+2]; | ||
| 587 | ssif_info->multi_len = len; | 638 | ssif_info->multi_len = len; |
| 588 | ssif_info->multi_pos = 1; | 639 | ssif_info->multi_pos = 1; |
| 589 | 640 | ||
| @@ -610,9 +661,9 @@ static void msg_done_handler(struct ssif_info *ssif_info, int result, | |||
| 610 | goto continue_op; | 661 | goto continue_op; |
| 611 | } | 662 | } |
| 612 | 663 | ||
| 613 | blocknum = data[ssif_info->multi_len]; | 664 | blocknum = data[0]; |
| 614 | 665 | ||
| 615 | if (ssif_info->multi_len+len-1 > IPMI_MAX_MSG_LENGTH) { | 666 | if (ssif_info->multi_len + len - 1 > IPMI_MAX_MSG_LENGTH) { |
| 616 | /* Received message too big, abort the operation. */ | 667 | /* Received message too big, abort the operation. */ |
| 617 | result = -E2BIG; | 668 | result = -E2BIG; |
| 618 | if (ssif_info->ssif_debug & SSIF_DEBUG_MSG) | 669 | if (ssif_info->ssif_debug & SSIF_DEBUG_MSG) |
| @@ -622,15 +673,15 @@ static void msg_done_handler(struct ssif_info *ssif_info, int result, | |||
| 622 | } | 673 | } |
| 623 | 674 | ||
| 624 | /* Remove the blocknum from the data. */ | 675 | /* Remove the blocknum from the data. */ |
| 625 | for (i = 0; i < (len-1); i++) | ||
| 626 | ssif_info->data[i+ssif_info->multi_len] = data[i+1]; | ||
| 627 | len--; | 676 | len--; |
| 677 | for (i = 0; i < len; i++) | ||
| 678 | ssif_info->data[i + ssif_info->multi_len] = data[i + 1]; | ||
| 628 | ssif_info->multi_len += len; | 679 | ssif_info->multi_len += len; |
| 629 | if (blocknum == 0xff) { | 680 | if (blocknum == 0xff) { |
| 630 | /* End of read */ | 681 | /* End of read */ |
| 631 | len = ssif_info->multi_len; | 682 | len = ssif_info->multi_len; |
| 632 | data = ssif_info->data; | 683 | data = ssif_info->data; |
| 633 | } else if ((blocknum+1) != ssif_info->multi_pos) { | 684 | } else if (blocknum + 1 != ssif_info->multi_pos) { |
| 634 | /* | 685 | /* |
| 635 | * Out of sequence block, just abort. Block | 686 | * Out of sequence block, just abort. Block |
| 636 | * numbers start at zero for the second block, | 687 | * numbers start at zero for the second block, |
| @@ -650,7 +701,7 @@ static void msg_done_handler(struct ssif_info *ssif_info, int result, | |||
| 650 | if (rv < 0) { | 701 | if (rv < 0) { |
| 651 | if (ssif_info->ssif_debug & SSIF_DEBUG_MSG) | 702 | if (ssif_info->ssif_debug & SSIF_DEBUG_MSG) |
| 652 | pr_info(PFX | 703 | pr_info(PFX |
| 653 | "Error from i2c_non_blocking_op(2)\n"); | 704 | "Error from ssif_i2c_send\n"); |
| 654 | 705 | ||
| 655 | result = -EIO; | 706 | result = -EIO; |
| 656 | } else | 707 | } else |
| @@ -830,7 +881,11 @@ static void msg_written_handler(struct ssif_info *ssif_info, int result, | |||
| 830 | } | 881 | } |
| 831 | 882 | ||
| 832 | if (ssif_info->multi_data) { | 883 | if (ssif_info->multi_data) { |
| 833 | /* In the middle of a multi-data write. */ | 884 | /* |
| 885 | * In the middle of a multi-data write. See the comment | ||
| 886 | * in the SSIF_MULTI_n_PART case in the probe function | ||
| 887 | * for details on the intricacies of this. | ||
| 888 | */ | ||
| 834 | int left; | 889 | int left; |
| 835 | 890 | ||
| 836 | ssif_inc_stat(ssif_info, sent_messages_parts); | 891 | ssif_inc_stat(ssif_info, sent_messages_parts); |
| @@ -864,15 +919,32 @@ static void msg_written_handler(struct ssif_info *ssif_info, int result, | |||
| 864 | msg_done_handler(ssif_info, -EIO, NULL, 0); | 919 | msg_done_handler(ssif_info, -EIO, NULL, 0); |
| 865 | } | 920 | } |
| 866 | } else { | 921 | } else { |
| 922 | unsigned long oflags, *flags; | ||
| 923 | bool got_alert; | ||
| 924 | |||
| 867 | ssif_inc_stat(ssif_info, sent_messages); | 925 | ssif_inc_stat(ssif_info, sent_messages); |
| 868 | ssif_inc_stat(ssif_info, sent_messages_parts); | 926 | ssif_inc_stat(ssif_info, sent_messages_parts); |
| 869 | 927 | ||
| 870 | /* Wait a jiffie then request the next message */ | 928 | flags = ipmi_ssif_lock_cond(ssif_info, &oflags); |
| 871 | ssif_info->retries_left = SSIF_RECV_RETRIES; | 929 | got_alert = ssif_info->got_alert; |
| 872 | ssif_info->rtc_us_timer = SSIF_MSG_PART_USEC; | 930 | if (got_alert) { |
| 873 | mod_timer(&ssif_info->retry_timer, | 931 | ssif_info->got_alert = false; |
| 874 | jiffies + SSIF_MSG_PART_JIFFIES); | 932 | ssif_info->waiting_alert = false; |
| 875 | return; | 933 | } |
| 934 | |||
| 935 | if (got_alert) { | ||
| 936 | ipmi_ssif_unlock_cond(ssif_info, flags); | ||
| 937 | /* The alert already happened, try now. */ | ||
| 938 | retry_timeout((unsigned long) ssif_info); | ||
| 939 | } else { | ||
| 940 | /* Wait a jiffie then request the next message */ | ||
| 941 | ssif_info->waiting_alert = true; | ||
| 942 | ssif_info->retries_left = SSIF_RECV_RETRIES; | ||
| 943 | ssif_info->rtc_us_timer = SSIF_MSG_PART_USEC; | ||
| 944 | mod_timer(&ssif_info->retry_timer, | ||
| 945 | jiffies + SSIF_MSG_PART_JIFFIES); | ||
| 946 | ipmi_ssif_unlock_cond(ssif_info, flags); | ||
| 947 | } | ||
| 876 | } | 948 | } |
| 877 | } | 949 | } |
| 878 | 950 | ||
| @@ -881,6 +953,8 @@ static int start_resend(struct ssif_info *ssif_info) | |||
| 881 | int rv; | 953 | int rv; |
| 882 | int command; | 954 | int command; |
| 883 | 955 | ||
| 956 | ssif_info->got_alert = false; | ||
| 957 | |||
| 884 | if (ssif_info->data_len > 32) { | 958 | if (ssif_info->data_len > 32) { |
| 885 | command = SSIF_IPMI_MULTI_PART_REQUEST_START; | 959 | command = SSIF_IPMI_MULTI_PART_REQUEST_START; |
| 886 | ssif_info->multi_data = ssif_info->data; | 960 | ssif_info->multi_data = ssif_info->data; |
| @@ -915,7 +989,7 @@ static int start_send(struct ssif_info *ssif_info, | |||
| 915 | return -E2BIG; | 989 | return -E2BIG; |
| 916 | 990 | ||
| 917 | ssif_info->retries_left = SSIF_SEND_RETRIES; | 991 | ssif_info->retries_left = SSIF_SEND_RETRIES; |
| 918 | memcpy(ssif_info->data+1, data, len); | 992 | memcpy(ssif_info->data + 1, data, len); |
| 919 | ssif_info->data_len = len; | 993 | ssif_info->data_len = len; |
| 920 | return start_resend(ssif_info); | 994 | return start_resend(ssif_info); |
| 921 | } | 995 | } |
| @@ -1200,7 +1274,7 @@ static int smi_type_proc_show(struct seq_file *m, void *v) | |||
| 1200 | { | 1274 | { |
| 1201 | seq_puts(m, "ssif\n"); | 1275 | seq_puts(m, "ssif\n"); |
| 1202 | 1276 | ||
| 1203 | return seq_has_overflowed(m); | 1277 | return 0; |
| 1204 | } | 1278 | } |
| 1205 | 1279 | ||
| 1206 | static int smi_type_proc_open(struct inode *inode, struct file *file) | 1280 | static int smi_type_proc_open(struct inode *inode, struct file *file) |
| @@ -1243,6 +1317,8 @@ static int smi_stats_proc_show(struct seq_file *m, void *v) | |||
| 1243 | ssif_get_stat(ssif_info, events)); | 1317 | ssif_get_stat(ssif_info, events)); |
| 1244 | seq_printf(m, "watchdog_pretimeouts: %u\n", | 1318 | seq_printf(m, "watchdog_pretimeouts: %u\n", |
| 1245 | ssif_get_stat(ssif_info, watchdog_pretimeouts)); | 1319 | ssif_get_stat(ssif_info, watchdog_pretimeouts)); |
| 1320 | seq_printf(m, "alerts: %u\n", | ||
| 1321 | ssif_get_stat(ssif_info, alerts)); | ||
| 1246 | return 0; | 1322 | return 0; |
| 1247 | } | 1323 | } |
| 1248 | 1324 | ||
| @@ -1258,6 +1334,23 @@ static const struct file_operations smi_stats_proc_ops = { | |||
| 1258 | .release = single_release, | 1334 | .release = single_release, |
| 1259 | }; | 1335 | }; |
| 1260 | 1336 | ||
| 1337 | static int strcmp_nospace(char *s1, char *s2) | ||
| 1338 | { | ||
| 1339 | while (*s1 && *s2) { | ||
| 1340 | while (isspace(*s1)) | ||
| 1341 | s1++; | ||
| 1342 | while (isspace(*s2)) | ||
| 1343 | s2++; | ||
| 1344 | if (*s1 > *s2) | ||
| 1345 | return 1; | ||
| 1346 | if (*s1 < *s2) | ||
| 1347 | return -1; | ||
| 1348 | s1++; | ||
| 1349 | s2++; | ||
| 1350 | } | ||
| 1351 | return 0; | ||
| 1352 | } | ||
| 1353 | |||
| 1261 | static struct ssif_addr_info *ssif_info_find(unsigned short addr, | 1354 | static struct ssif_addr_info *ssif_info_find(unsigned short addr, |
| 1262 | char *adapter_name, | 1355 | char *adapter_name, |
| 1263 | bool match_null_name) | 1356 | bool match_null_name) |
| @@ -1272,8 +1365,10 @@ restart: | |||
| 1272 | /* One is NULL and one is not */ | 1365 | /* One is NULL and one is not */ |
| 1273 | continue; | 1366 | continue; |
| 1274 | } | 1367 | } |
| 1275 | if (strcmp(info->adapter_name, adapter_name)) | 1368 | if (adapter_name && |
| 1276 | /* Names to not match */ | 1369 | strcmp_nospace(info->adapter_name, |
| 1370 | adapter_name)) | ||
| 1371 | /* Names do not match */ | ||
| 1277 | continue; | 1372 | continue; |
| 1278 | } | 1373 | } |
| 1279 | found = info; | 1374 | found = info; |
| @@ -1306,6 +1401,12 @@ static bool check_acpi(struct ssif_info *ssif_info, struct device *dev) | |||
| 1306 | return false; | 1401 | return false; |
| 1307 | } | 1402 | } |
| 1308 | 1403 | ||
| 1404 | /* | ||
| 1405 | * Global enables we care about. | ||
| 1406 | */ | ||
| 1407 | #define GLOBAL_ENABLES_MASK (IPMI_BMC_EVT_MSG_BUFF | IPMI_BMC_RCV_MSG_INTR | \ | ||
| 1408 | IPMI_BMC_EVT_MSG_INTR) | ||
| 1409 | |||
| 1309 | static int ssif_probe(struct i2c_client *client, const struct i2c_device_id *id) | 1410 | static int ssif_probe(struct i2c_client *client, const struct i2c_device_id *id) |
| 1310 | { | 1411 | { |
| 1311 | unsigned char msg[3]; | 1412 | unsigned char msg[3]; |
| @@ -1391,13 +1492,33 @@ static int ssif_probe(struct i2c_client *client, const struct i2c_device_id *id) | |||
| 1391 | break; | 1492 | break; |
| 1392 | 1493 | ||
| 1393 | case SSIF_MULTI_2_PART: | 1494 | case SSIF_MULTI_2_PART: |
| 1394 | if (ssif_info->max_xmit_msg_size > 64) | 1495 | if (ssif_info->max_xmit_msg_size > 63) |
| 1395 | ssif_info->max_xmit_msg_size = 64; | 1496 | ssif_info->max_xmit_msg_size = 63; |
| 1396 | if (ssif_info->max_recv_msg_size > 62) | 1497 | if (ssif_info->max_recv_msg_size > 62) |
| 1397 | ssif_info->max_recv_msg_size = 62; | 1498 | ssif_info->max_recv_msg_size = 62; |
| 1398 | break; | 1499 | break; |
| 1399 | 1500 | ||
| 1400 | case SSIF_MULTI_n_PART: | 1501 | case SSIF_MULTI_n_PART: |
| 1502 | /* | ||
| 1503 | * The specification is rather confusing at | ||
| 1504 | * this point, but I think I understand what | ||
| 1505 | * is meant. At least I have a workable | ||
| 1506 | * solution. With multi-part messages, you | ||
| 1507 | * cannot send a message that is a multiple of | ||
| 1508 | * 32-bytes in length, because the start and | ||
| 1509 | * middle messages are 32-bytes and the end | ||
| 1510 | * message must be at least one byte. You | ||
| 1511 | * can't fudge on an extra byte, that would | ||
| 1512 | * screw up things like fru data writes. So | ||
| 1513 | * we limit the length to 63 bytes. That way | ||
| 1514 | * a 32-byte message gets sent as a single | ||
| 1515 | * part. A larger message will be a 32-byte | ||
| 1516 | * start and the next message is always going | ||
| 1517 | * to be 1-31 bytes in length. Not ideal, but | ||
| 1518 | * it should work. | ||
| 1519 | */ | ||
| 1520 | if (ssif_info->max_xmit_msg_size > 63) | ||
| 1521 | ssif_info->max_xmit_msg_size = 63; | ||
| 1401 | break; | 1522 | break; |
| 1402 | 1523 | ||
| 1403 | default: | 1524 | default: |
| @@ -1407,7 +1528,7 @@ static int ssif_probe(struct i2c_client *client, const struct i2c_device_id *id) | |||
| 1407 | } else { | 1528 | } else { |
| 1408 | no_support: | 1529 | no_support: |
| 1409 | /* Assume no multi-part or PEC support */ | 1530 | /* Assume no multi-part or PEC support */ |
| 1410 | pr_info(PFX "Error fetching SSIF: %d %d %2.2x, your system probably doesn't support this command so using defaults\n", | 1531 | pr_info(PFX "Error fetching SSIF: %d %d %2.2x, your system probably doesn't support this command so using defaults\n", |
| 1411 | rv, len, resp[2]); | 1532 | rv, len, resp[2]); |
| 1412 | 1533 | ||
| 1413 | ssif_info->max_xmit_msg_size = 32; | 1534 | ssif_info->max_xmit_msg_size = 32; |
| @@ -1436,6 +1557,8 @@ static int ssif_probe(struct i2c_client *client, const struct i2c_device_id *id) | |||
| 1436 | goto found; | 1557 | goto found; |
| 1437 | } | 1558 | } |
| 1438 | 1559 | ||
| 1560 | ssif_info->global_enables = resp[3]; | ||
| 1561 | |||
| 1439 | if (resp[3] & IPMI_BMC_EVT_MSG_BUFF) { | 1562 | if (resp[3] & IPMI_BMC_EVT_MSG_BUFF) { |
| 1440 | ssif_info->has_event_buffer = true; | 1563 | ssif_info->has_event_buffer = true; |
| 1441 | /* buffer is already enabled, nothing to do. */ | 1564 | /* buffer is already enabled, nothing to do. */ |
| @@ -1444,18 +1567,37 @@ static int ssif_probe(struct i2c_client *client, const struct i2c_device_id *id) | |||
| 1444 | 1567 | ||
| 1445 | msg[0] = IPMI_NETFN_APP_REQUEST << 2; | 1568 | msg[0] = IPMI_NETFN_APP_REQUEST << 2; |
| 1446 | msg[1] = IPMI_SET_BMC_GLOBAL_ENABLES_CMD; | 1569 | msg[1] = IPMI_SET_BMC_GLOBAL_ENABLES_CMD; |
| 1447 | msg[2] = resp[3] | IPMI_BMC_EVT_MSG_BUFF; | 1570 | msg[2] = ssif_info->global_enables | IPMI_BMC_EVT_MSG_BUFF; |
| 1448 | rv = do_cmd(client, 3, msg, &len, resp); | 1571 | rv = do_cmd(client, 3, msg, &len, resp); |
| 1449 | if (rv || (len < 2)) { | 1572 | if (rv || (len < 2)) { |
| 1450 | pr_warn(PFX "Error getting global enables: %d %d %2.2x\n", | 1573 | pr_warn(PFX "Error setting global enables: %d %d %2.2x\n", |
| 1451 | rv, len, resp[2]); | 1574 | rv, len, resp[2]); |
| 1452 | rv = 0; /* Not fatal */ | 1575 | rv = 0; /* Not fatal */ |
| 1453 | goto found; | 1576 | goto found; |
| 1454 | } | 1577 | } |
| 1455 | 1578 | ||
| 1456 | if (resp[2] == 0) | 1579 | if (resp[2] == 0) { |
| 1457 | /* A successful return means the event buffer is supported. */ | 1580 | /* A successful return means the event buffer is supported. */ |
| 1458 | ssif_info->has_event_buffer = true; | 1581 | ssif_info->has_event_buffer = true; |
| 1582 | ssif_info->global_enables |= IPMI_BMC_EVT_MSG_BUFF; | ||
| 1583 | } | ||
| 1584 | |||
| 1585 | msg[0] = IPMI_NETFN_APP_REQUEST << 2; | ||
| 1586 | msg[1] = IPMI_SET_BMC_GLOBAL_ENABLES_CMD; | ||
| 1587 | msg[2] = ssif_info->global_enables | IPMI_BMC_RCV_MSG_INTR; | ||
| 1588 | rv = do_cmd(client, 3, msg, &len, resp); | ||
| 1589 | if (rv || (len < 2)) { | ||
| 1590 | pr_warn(PFX "Error setting global enables: %d %d %2.2x\n", | ||
| 1591 | rv, len, resp[2]); | ||
| 1592 | rv = 0; /* Not fatal */ | ||
| 1593 | goto found; | ||
| 1594 | } | ||
| 1595 | |||
| 1596 | if (resp[2] == 0) { | ||
| 1597 | /* A successful return means the alert is supported. */ | ||
| 1598 | ssif_info->supports_alert = true; | ||
| 1599 | ssif_info->global_enables |= IPMI_BMC_RCV_MSG_INTR; | ||
| 1600 | } | ||
| 1459 | 1601 | ||
| 1460 | found: | 1602 | found: |
| 1461 | ssif_info->intf_num = atomic_inc_return(&next_intf); | 1603 | ssif_info->intf_num = atomic_inc_return(&next_intf); |
| @@ -1813,6 +1955,7 @@ static struct i2c_driver ssif_i2c_driver = { | |||
| 1813 | }, | 1955 | }, |
| 1814 | .probe = ssif_probe, | 1956 | .probe = ssif_probe, |
| 1815 | .remove = ssif_remove, | 1957 | .remove = ssif_remove, |
| 1958 | .alert = ssif_alert, | ||
| 1816 | .id_table = ssif_id, | 1959 | .id_table = ssif_id, |
| 1817 | .detect = ssif_detect | 1960 | .detect = ssif_detect |
| 1818 | }; | 1961 | }; |
| @@ -1832,7 +1975,7 @@ static int init_ipmi_ssif(void) | |||
| 1832 | rv = new_ssif_client(addr[i], adapter_name[i], | 1975 | rv = new_ssif_client(addr[i], adapter_name[i], |
| 1833 | dbg[i], slave_addrs[i], | 1976 | dbg[i], slave_addrs[i], |
| 1834 | SI_HARDCODED); | 1977 | SI_HARDCODED); |
| 1835 | if (!rv) | 1978 | if (rv) |
| 1836 | pr_err(PFX | 1979 | pr_err(PFX |
| 1837 | "Couldn't add hardcoded device at addr 0x%x\n", | 1980 | "Couldn't add hardcoded device at addr 0x%x\n", |
| 1838 | addr[i]); | 1981 | addr[i]); |
diff --git a/drivers/extcon/extcon-usb-gpio.c b/drivers/extcon/extcon-usb-gpio.c index de67fce18984..e45d1f13f445 100644 --- a/drivers/extcon/extcon-usb-gpio.c +++ b/drivers/extcon/extcon-usb-gpio.c | |||
| @@ -119,6 +119,18 @@ static int usb_extcon_probe(struct platform_device *pdev) | |||
| 119 | return PTR_ERR(info->id_gpiod); | 119 | return PTR_ERR(info->id_gpiod); |
| 120 | } | 120 | } |
| 121 | 121 | ||
| 122 | info->edev = devm_extcon_dev_allocate(dev, usb_extcon_cable); | ||
| 123 | if (IS_ERR(info->edev)) { | ||
| 124 | dev_err(dev, "failed to allocate extcon device\n"); | ||
| 125 | return -ENOMEM; | ||
| 126 | } | ||
| 127 | |||
| 128 | ret = devm_extcon_dev_register(dev, info->edev); | ||
| 129 | if (ret < 0) { | ||
| 130 | dev_err(dev, "failed to register extcon device\n"); | ||
| 131 | return ret; | ||
| 132 | } | ||
| 133 | |||
| 122 | ret = gpiod_set_debounce(info->id_gpiod, | 134 | ret = gpiod_set_debounce(info->id_gpiod, |
| 123 | USB_GPIO_DEBOUNCE_MS * 1000); | 135 | USB_GPIO_DEBOUNCE_MS * 1000); |
| 124 | if (ret < 0) | 136 | if (ret < 0) |
| @@ -142,18 +154,6 @@ static int usb_extcon_probe(struct platform_device *pdev) | |||
| 142 | return ret; | 154 | return ret; |
| 143 | } | 155 | } |
| 144 | 156 | ||
| 145 | info->edev = devm_extcon_dev_allocate(dev, usb_extcon_cable); | ||
| 146 | if (IS_ERR(info->edev)) { | ||
| 147 | dev_err(dev, "failed to allocate extcon device\n"); | ||
| 148 | return -ENOMEM; | ||
| 149 | } | ||
| 150 | |||
| 151 | ret = devm_extcon_dev_register(dev, info->edev); | ||
| 152 | if (ret < 0) { | ||
| 153 | dev_err(dev, "failed to register extcon device\n"); | ||
| 154 | return ret; | ||
| 155 | } | ||
| 156 | |||
| 157 | platform_set_drvdata(pdev, info); | 157 | platform_set_drvdata(pdev, info); |
| 158 | device_init_wakeup(dev, 1); | 158 | device_init_wakeup(dev, 1); |
| 159 | 159 | ||
diff --git a/drivers/firmware/dmi_scan.c b/drivers/firmware/dmi_scan.c index 6e45a43ffe84..97b1616aa391 100644 --- a/drivers/firmware/dmi_scan.c +++ b/drivers/firmware/dmi_scan.c | |||
| @@ -499,19 +499,19 @@ static int __init dmi_present(const u8 *buf) | |||
| 499 | buf += 16; | 499 | buf += 16; |
| 500 | 500 | ||
| 501 | if (memcmp(buf, "_DMI_", 5) == 0 && dmi_checksum(buf, 15)) { | 501 | if (memcmp(buf, "_DMI_", 5) == 0 && dmi_checksum(buf, 15)) { |
| 502 | if (smbios_ver) | ||
| 503 | dmi_ver = smbios_ver; | ||
| 504 | else | ||
| 505 | dmi_ver = (buf[14] & 0xF0) << 4 | (buf[14] & 0x0F); | ||
| 502 | dmi_num = get_unaligned_le16(buf + 12); | 506 | dmi_num = get_unaligned_le16(buf + 12); |
| 503 | dmi_len = get_unaligned_le16(buf + 6); | 507 | dmi_len = get_unaligned_le16(buf + 6); |
| 504 | dmi_base = get_unaligned_le32(buf + 8); | 508 | dmi_base = get_unaligned_le32(buf + 8); |
| 505 | 509 | ||
| 506 | if (dmi_walk_early(dmi_decode) == 0) { | 510 | if (dmi_walk_early(dmi_decode) == 0) { |
| 507 | if (smbios_ver) { | 511 | if (smbios_ver) { |
| 508 | dmi_ver = smbios_ver; | 512 | pr_info("SMBIOS %d.%d present.\n", |
| 509 | pr_info("SMBIOS %d.%d%s present.\n", | 513 | dmi_ver >> 8, dmi_ver & 0xFF); |
| 510 | dmi_ver >> 8, dmi_ver & 0xFF, | ||
| 511 | (dmi_ver < 0x0300) ? "" : ".x"); | ||
| 512 | } else { | 514 | } else { |
| 513 | dmi_ver = (buf[14] & 0xF0) << 4 | | ||
| 514 | (buf[14] & 0x0F); | ||
| 515 | pr_info("Legacy DMI %d.%d present.\n", | 515 | pr_info("Legacy DMI %d.%d present.\n", |
| 516 | dmi_ver >> 8, dmi_ver & 0xFF); | 516 | dmi_ver >> 8, dmi_ver & 0xFF); |
| 517 | } | 517 | } |
diff --git a/drivers/firmware/efi/runtime-map.c b/drivers/firmware/efi/runtime-map.c index 87b8e3b900d2..5c55227a34c8 100644 --- a/drivers/firmware/efi/runtime-map.c +++ b/drivers/firmware/efi/runtime-map.c | |||
| @@ -120,7 +120,8 @@ add_sysfs_runtime_map_entry(struct kobject *kobj, int nr) | |||
| 120 | entry = kzalloc(sizeof(*entry), GFP_KERNEL); | 120 | entry = kzalloc(sizeof(*entry), GFP_KERNEL); |
| 121 | if (!entry) { | 121 | if (!entry) { |
| 122 | kset_unregister(map_kset); | 122 | kset_unregister(map_kset); |
| 123 | return entry; | 123 | map_kset = NULL; |
| 124 | return ERR_PTR(-ENOMEM); | ||
| 124 | } | 125 | } |
| 125 | 126 | ||
| 126 | memcpy(&entry->md, efi_runtime_map + nr * efi_memdesc_size, | 127 | memcpy(&entry->md, efi_runtime_map + nr * efi_memdesc_size, |
| @@ -132,6 +133,7 @@ add_sysfs_runtime_map_entry(struct kobject *kobj, int nr) | |||
| 132 | if (ret) { | 133 | if (ret) { |
| 133 | kobject_put(&entry->kobj); | 134 | kobject_put(&entry->kobj); |
| 134 | kset_unregister(map_kset); | 135 | kset_unregister(map_kset); |
| 136 | map_kset = NULL; | ||
| 135 | return ERR_PTR(ret); | 137 | return ERR_PTR(ret); |
| 136 | } | 138 | } |
| 137 | 139 | ||
| @@ -195,8 +197,6 @@ out_add_entry: | |||
| 195 | entry = *(map_entries + j); | 197 | entry = *(map_entries + j); |
| 196 | kobject_put(&entry->kobj); | 198 | kobject_put(&entry->kobj); |
| 197 | } | 199 | } |
| 198 | if (map_kset) | ||
| 199 | kset_unregister(map_kset); | ||
| 200 | out: | 200 | out: |
| 201 | return ret; | 201 | return ret; |
| 202 | } | 202 | } |
diff --git a/drivers/gpio/gpio-omap.c b/drivers/gpio/gpio-omap.c index cd1d5bf48f36..b232397ad7ec 100644 --- a/drivers/gpio/gpio-omap.c +++ b/drivers/gpio/gpio-omap.c | |||
| @@ -1054,38 +1054,8 @@ static void omap_gpio_mod_init(struct gpio_bank *bank) | |||
| 1054 | dev_err(bank->dev, "Could not get gpio dbck\n"); | 1054 | dev_err(bank->dev, "Could not get gpio dbck\n"); |
| 1055 | } | 1055 | } |
| 1056 | 1056 | ||
| 1057 | static void | ||
| 1058 | omap_mpuio_alloc_gc(struct gpio_bank *bank, unsigned int irq_start, | ||
| 1059 | unsigned int num) | ||
| 1060 | { | ||
| 1061 | struct irq_chip_generic *gc; | ||
| 1062 | struct irq_chip_type *ct; | ||
| 1063 | |||
| 1064 | gc = irq_alloc_generic_chip("MPUIO", 1, irq_start, bank->base, | ||
| 1065 | handle_simple_irq); | ||
| 1066 | if (!gc) { | ||
| 1067 | dev_err(bank->dev, "Memory alloc failed for gc\n"); | ||
| 1068 | return; | ||
| 1069 | } | ||
| 1070 | |||
| 1071 | ct = gc->chip_types; | ||
| 1072 | |||
| 1073 | /* NOTE: No ack required, reading IRQ status clears it. */ | ||
| 1074 | ct->chip.irq_mask = irq_gc_mask_set_bit; | ||
| 1075 | ct->chip.irq_unmask = irq_gc_mask_clr_bit; | ||
| 1076 | ct->chip.irq_set_type = omap_gpio_irq_type; | ||
| 1077 | |||
| 1078 | if (bank->regs->wkup_en) | ||
| 1079 | ct->chip.irq_set_wake = omap_gpio_wake_enable; | ||
| 1080 | |||
| 1081 | ct->regs.mask = OMAP_MPUIO_GPIO_INT / bank->stride; | ||
| 1082 | irq_setup_generic_chip(gc, IRQ_MSK(num), IRQ_GC_INIT_MASK_CACHE, | ||
| 1083 | IRQ_NOREQUEST | IRQ_NOPROBE, 0); | ||
| 1084 | } | ||
| 1085 | |||
| 1086 | static int omap_gpio_chip_init(struct gpio_bank *bank, struct irq_chip *irqc) | 1057 | static int omap_gpio_chip_init(struct gpio_bank *bank, struct irq_chip *irqc) |
| 1087 | { | 1058 | { |
| 1088 | int j; | ||
| 1089 | static int gpio; | 1059 | static int gpio; |
| 1090 | int irq_base = 0; | 1060 | int irq_base = 0; |
| 1091 | int ret; | 1061 | int ret; |
| @@ -1132,6 +1102,15 @@ static int omap_gpio_chip_init(struct gpio_bank *bank, struct irq_chip *irqc) | |||
| 1132 | } | 1102 | } |
| 1133 | #endif | 1103 | #endif |
| 1134 | 1104 | ||
| 1105 | /* MPUIO is a bit different, reading IRQ status clears it */ | ||
| 1106 | if (bank->is_mpuio) { | ||
| 1107 | irqc->irq_ack = dummy_irq_chip.irq_ack; | ||
| 1108 | irqc->irq_mask = irq_gc_mask_set_bit; | ||
| 1109 | irqc->irq_unmask = irq_gc_mask_clr_bit; | ||
| 1110 | if (!bank->regs->wkup_en) | ||
| 1111 | irqc->irq_set_wake = NULL; | ||
| 1112 | } | ||
| 1113 | |||
| 1135 | ret = gpiochip_irqchip_add(&bank->chip, irqc, | 1114 | ret = gpiochip_irqchip_add(&bank->chip, irqc, |
| 1136 | irq_base, omap_gpio_irq_handler, | 1115 | irq_base, omap_gpio_irq_handler, |
| 1137 | IRQ_TYPE_NONE); | 1116 | IRQ_TYPE_NONE); |
| @@ -1145,15 +1124,6 @@ static int omap_gpio_chip_init(struct gpio_bank *bank, struct irq_chip *irqc) | |||
| 1145 | gpiochip_set_chained_irqchip(&bank->chip, irqc, | 1124 | gpiochip_set_chained_irqchip(&bank->chip, irqc, |
| 1146 | bank->irq, omap_gpio_irq_handler); | 1125 | bank->irq, omap_gpio_irq_handler); |
| 1147 | 1126 | ||
| 1148 | for (j = 0; j < bank->width; j++) { | ||
| 1149 | int irq = irq_find_mapping(bank->chip.irqdomain, j); | ||
| 1150 | if (bank->is_mpuio) { | ||
| 1151 | omap_mpuio_alloc_gc(bank, irq, bank->width); | ||
| 1152 | irq_set_chip_and_handler(irq, NULL, NULL); | ||
| 1153 | set_irq_flags(irq, 0); | ||
| 1154 | } | ||
| 1155 | } | ||
| 1156 | |||
| 1157 | return 0; | 1127 | return 0; |
| 1158 | } | 1128 | } |
| 1159 | 1129 | ||
diff --git a/drivers/gpio/gpiolib-acpi.c b/drivers/gpio/gpiolib-acpi.c index d2303d50f561..725d16138b74 100644 --- a/drivers/gpio/gpiolib-acpi.c +++ b/drivers/gpio/gpiolib-acpi.c | |||
| @@ -550,7 +550,7 @@ acpi_gpio_adr_space_handler(u32 function, acpi_physical_address address, | |||
| 550 | 550 | ||
| 551 | length = min(agpio->pin_table_length, (u16)(pin_index + bits)); | 551 | length = min(agpio->pin_table_length, (u16)(pin_index + bits)); |
| 552 | for (i = pin_index; i < length; ++i) { | 552 | for (i = pin_index; i < length; ++i) { |
| 553 | unsigned pin = agpio->pin_table[i]; | 553 | int pin = agpio->pin_table[i]; |
| 554 | struct acpi_gpio_connection *conn; | 554 | struct acpi_gpio_connection *conn; |
| 555 | struct gpio_desc *desc; | 555 | struct gpio_desc *desc; |
| 556 | bool found; | 556 | bool found; |
diff --git a/drivers/gpio/gpiolib-sysfs.c b/drivers/gpio/gpiolib-sysfs.c index 7722ed53bd65..af3bc7a8033b 100644 --- a/drivers/gpio/gpiolib-sysfs.c +++ b/drivers/gpio/gpiolib-sysfs.c | |||
| @@ -551,6 +551,7 @@ static struct class gpio_class = { | |||
| 551 | */ | 551 | */ |
| 552 | int gpiod_export(struct gpio_desc *desc, bool direction_may_change) | 552 | int gpiod_export(struct gpio_desc *desc, bool direction_may_change) |
| 553 | { | 553 | { |
| 554 | struct gpio_chip *chip; | ||
| 554 | unsigned long flags; | 555 | unsigned long flags; |
| 555 | int status; | 556 | int status; |
| 556 | const char *ioname = NULL; | 557 | const char *ioname = NULL; |
| @@ -568,8 +569,16 @@ int gpiod_export(struct gpio_desc *desc, bool direction_may_change) | |||
| 568 | return -EINVAL; | 569 | return -EINVAL; |
| 569 | } | 570 | } |
| 570 | 571 | ||
| 572 | chip = desc->chip; | ||
| 573 | |||
| 571 | mutex_lock(&sysfs_lock); | 574 | mutex_lock(&sysfs_lock); |
| 572 | 575 | ||
| 576 | /* check if chip is being removed */ | ||
| 577 | if (!chip || !chip->exported) { | ||
| 578 | status = -ENODEV; | ||
| 579 | goto fail_unlock; | ||
| 580 | } | ||
| 581 | |||
| 573 | spin_lock_irqsave(&gpio_lock, flags); | 582 | spin_lock_irqsave(&gpio_lock, flags); |
| 574 | if (!test_bit(FLAG_REQUESTED, &desc->flags) || | 583 | if (!test_bit(FLAG_REQUESTED, &desc->flags) || |
| 575 | test_bit(FLAG_EXPORT, &desc->flags)) { | 584 | test_bit(FLAG_EXPORT, &desc->flags)) { |
| @@ -783,12 +792,15 @@ void gpiochip_unexport(struct gpio_chip *chip) | |||
| 783 | { | 792 | { |
| 784 | int status; | 793 | int status; |
| 785 | struct device *dev; | 794 | struct device *dev; |
| 795 | struct gpio_desc *desc; | ||
| 796 | unsigned int i; | ||
| 786 | 797 | ||
| 787 | mutex_lock(&sysfs_lock); | 798 | mutex_lock(&sysfs_lock); |
| 788 | dev = class_find_device(&gpio_class, NULL, chip, match_export); | 799 | dev = class_find_device(&gpio_class, NULL, chip, match_export); |
| 789 | if (dev) { | 800 | if (dev) { |
| 790 | put_device(dev); | 801 | put_device(dev); |
| 791 | device_unregister(dev); | 802 | device_unregister(dev); |
| 803 | /* prevent further gpiod exports */ | ||
| 792 | chip->exported = false; | 804 | chip->exported = false; |
| 793 | status = 0; | 805 | status = 0; |
| 794 | } else | 806 | } else |
| @@ -797,6 +809,13 @@ void gpiochip_unexport(struct gpio_chip *chip) | |||
| 797 | 809 | ||
| 798 | if (status) | 810 | if (status) |
| 799 | chip_dbg(chip, "%s: status %d\n", __func__, status); | 811 | chip_dbg(chip, "%s: status %d\n", __func__, status); |
| 812 | |||
| 813 | /* unregister gpiod class devices owned by sysfs */ | ||
| 814 | for (i = 0; i < chip->ngpio; i++) { | ||
| 815 | desc = &chip->desc[i]; | ||
| 816 | if (test_and_clear_bit(FLAG_SYSFS, &desc->flags)) | ||
| 817 | gpiod_free(desc); | ||
| 818 | } | ||
| 800 | } | 819 | } |
| 801 | 820 | ||
| 802 | static int __init gpiolib_sysfs_init(void) | 821 | static int __init gpiolib_sysfs_init(void) |
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c index 69af73f15310..596ee5cd3b84 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c | |||
| @@ -430,9 +430,10 @@ static int unregister_process_nocpsch(struct device_queue_manager *dqm, | |||
| 430 | 430 | ||
| 431 | BUG_ON(!dqm || !qpd); | 431 | BUG_ON(!dqm || !qpd); |
| 432 | 432 | ||
| 433 | BUG_ON(!list_empty(&qpd->queues_list)); | 433 | pr_debug("In func %s\n", __func__); |
| 434 | 434 | ||
| 435 | pr_debug("kfd: In func %s\n", __func__); | 435 | pr_debug("qpd->queues_list is %s\n", |
| 436 | list_empty(&qpd->queues_list) ? "empty" : "not empty"); | ||
| 436 | 437 | ||
| 437 | retval = 0; | 438 | retval = 0; |
| 438 | mutex_lock(&dqm->lock); | 439 | mutex_lock(&dqm->lock); |
| @@ -882,6 +883,8 @@ static int create_queue_cpsch(struct device_queue_manager *dqm, struct queue *q, | |||
| 882 | return -ENOMEM; | 883 | return -ENOMEM; |
| 883 | } | 884 | } |
| 884 | 885 | ||
| 886 | init_sdma_vm(dqm, q, qpd); | ||
| 887 | |||
| 885 | retval = mqd->init_mqd(mqd, &q->mqd, &q->mqd_mem_obj, | 888 | retval = mqd->init_mqd(mqd, &q->mqd, &q->mqd_mem_obj, |
| 886 | &q->gart_mqd_addr, &q->properties); | 889 | &q->gart_mqd_addr, &q->properties); |
| 887 | if (retval != 0) | 890 | if (retval != 0) |
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_topology.c b/drivers/gpu/drm/amd/amdkfd/kfd_topology.c index 661c6605d31b..e469c4b2e8cc 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_topology.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_topology.c | |||
| @@ -728,9 +728,9 @@ static ssize_t node_show(struct kobject *kobj, struct attribute *attr, | |||
| 728 | sysfs_show_32bit_prop(buffer, "max_engine_clk_fcompute", | 728 | sysfs_show_32bit_prop(buffer, "max_engine_clk_fcompute", |
| 729 | dev->gpu->kfd2kgd->get_max_engine_clock_in_mhz( | 729 | dev->gpu->kfd2kgd->get_max_engine_clock_in_mhz( |
| 730 | dev->gpu->kgd)); | 730 | dev->gpu->kgd)); |
| 731 | |||
| 731 | sysfs_show_64bit_prop(buffer, "local_mem_size", | 732 | sysfs_show_64bit_prop(buffer, "local_mem_size", |
| 732 | dev->gpu->kfd2kgd->get_vmem_size( | 733 | (unsigned long long int) 0); |
| 733 | dev->gpu->kgd)); | ||
| 734 | 734 | ||
| 735 | sysfs_show_32bit_prop(buffer, "fw_version", | 735 | sysfs_show_32bit_prop(buffer, "fw_version", |
| 736 | dev->gpu->kfd2kgd->get_fw_version( | 736 | dev->gpu->kfd2kgd->get_fw_version( |
diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c index c8a34476570a..af9662e58272 100644 --- a/drivers/gpu/drm/drm_irq.c +++ b/drivers/gpu/drm/drm_irq.c | |||
| @@ -131,12 +131,11 @@ static void drm_update_vblank_count(struct drm_device *dev, int crtc) | |||
| 131 | 131 | ||
| 132 | /* Reinitialize corresponding vblank timestamp if high-precision query | 132 | /* Reinitialize corresponding vblank timestamp if high-precision query |
| 133 | * available. Skip this step if query unsupported or failed. Will | 133 | * available. Skip this step if query unsupported or failed. Will |
| 134 | * reinitialize delayed at next vblank interrupt in that case. | 134 | * reinitialize delayed at next vblank interrupt in that case and |
| 135 | * assign 0 for now, to mark the vblanktimestamp as invalid. | ||
| 135 | */ | 136 | */ |
| 136 | if (rc) { | 137 | tslot = atomic_read(&vblank->count) + diff; |
| 137 | tslot = atomic_read(&vblank->count) + diff; | 138 | vblanktimestamp(dev, crtc, tslot) = rc ? t_vblank : (struct timeval) {0, 0}; |
| 138 | vblanktimestamp(dev, crtc, tslot) = t_vblank; | ||
| 139 | } | ||
| 140 | 139 | ||
| 141 | smp_mb__before_atomic(); | 140 | smp_mb__before_atomic(); |
| 142 | atomic_add(diff, &vblank->count); | 141 | atomic_add(diff, &vblank->count); |
diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index c302ffb5a168..a19d2c71e205 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c | |||
| @@ -699,6 +699,16 @@ static int i915_drm_resume(struct drm_device *dev) | |||
| 699 | intel_init_pch_refclk(dev); | 699 | intel_init_pch_refclk(dev); |
| 700 | drm_mode_config_reset(dev); | 700 | drm_mode_config_reset(dev); |
| 701 | 701 | ||
| 702 | /* | ||
| 703 | * Interrupts have to be enabled before any batches are run. If not the | ||
| 704 | * GPU will hang. i915_gem_init_hw() will initiate batches to | ||
| 705 | * update/restore the context. | ||
| 706 | * | ||
| 707 | * Modeset enabling in intel_modeset_init_hw() also needs working | ||
| 708 | * interrupts. | ||
| 709 | */ | ||
| 710 | intel_runtime_pm_enable_interrupts(dev_priv); | ||
| 711 | |||
| 702 | mutex_lock(&dev->struct_mutex); | 712 | mutex_lock(&dev->struct_mutex); |
| 703 | if (i915_gem_init_hw(dev)) { | 713 | if (i915_gem_init_hw(dev)) { |
| 704 | DRM_ERROR("failed to re-initialize GPU, declaring wedged!\n"); | 714 | DRM_ERROR("failed to re-initialize GPU, declaring wedged!\n"); |
| @@ -706,9 +716,6 @@ static int i915_drm_resume(struct drm_device *dev) | |||
| 706 | } | 716 | } |
| 707 | mutex_unlock(&dev->struct_mutex); | 717 | mutex_unlock(&dev->struct_mutex); |
| 708 | 718 | ||
| 709 | /* We need working interrupts for modeset enabling ... */ | ||
| 710 | intel_runtime_pm_enable_interrupts(dev_priv); | ||
| 711 | |||
| 712 | intel_modeset_init_hw(dev); | 719 | intel_modeset_init_hw(dev); |
| 713 | 720 | ||
| 714 | spin_lock_irq(&dev_priv->irq_lock); | 721 | spin_lock_irq(&dev_priv->irq_lock); |
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index d547d9c8dda2..d0f3cbc87474 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c | |||
| @@ -13635,9 +13635,6 @@ static const struct intel_dmi_quirk intel_dmi_quirks[] = { | |||
| 13635 | }; | 13635 | }; |
| 13636 | 13636 | ||
| 13637 | static struct intel_quirk intel_quirks[] = { | 13637 | static struct intel_quirk intel_quirks[] = { |
| 13638 | /* HP Mini needs pipe A force quirk (LP: #322104) */ | ||
| 13639 | { 0x27ae, 0x103c, 0x361a, quirk_pipea_force }, | ||
| 13640 | |||
| 13641 | /* Toshiba Protege R-205, S-209 needs pipe A force quirk */ | 13638 | /* Toshiba Protege R-205, S-209 needs pipe A force quirk */ |
| 13642 | { 0x2592, 0x1179, 0x0001, quirk_pipea_force }, | 13639 | { 0x2592, 0x1179, 0x0001, quirk_pipea_force }, |
| 13643 | 13640 | ||
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index d0237102c27e..f27346e907b1 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c | |||
| @@ -1348,7 +1348,7 @@ intel_dp_compute_config(struct intel_encoder *encoder, | |||
| 1348 | 1348 | ||
| 1349 | pipe_config->has_dp_encoder = true; | 1349 | pipe_config->has_dp_encoder = true; |
| 1350 | pipe_config->has_drrs = false; | 1350 | pipe_config->has_drrs = false; |
| 1351 | pipe_config->has_audio = intel_dp->has_audio; | 1351 | pipe_config->has_audio = intel_dp->has_audio && port != PORT_A; |
| 1352 | 1352 | ||
| 1353 | if (is_edp(intel_dp) && intel_connector->panel.fixed_mode) { | 1353 | if (is_edp(intel_dp) && intel_connector->panel.fixed_mode) { |
| 1354 | intel_fixed_panel_mode(intel_connector->panel.fixed_mode, | 1354 | intel_fixed_panel_mode(intel_connector->panel.fixed_mode, |
| @@ -2211,8 +2211,8 @@ static void intel_dp_get_config(struct intel_encoder *encoder, | |||
| 2211 | int dotclock; | 2211 | int dotclock; |
| 2212 | 2212 | ||
| 2213 | tmp = I915_READ(intel_dp->output_reg); | 2213 | tmp = I915_READ(intel_dp->output_reg); |
| 2214 | if (tmp & DP_AUDIO_OUTPUT_ENABLE) | 2214 | |
| 2215 | pipe_config->has_audio = true; | 2215 | pipe_config->has_audio = tmp & DP_AUDIO_OUTPUT_ENABLE && port != PORT_A; |
| 2216 | 2216 | ||
| 2217 | if ((port == PORT_A) || !HAS_PCH_CPT(dev)) { | 2217 | if ((port == PORT_A) || !HAS_PCH_CPT(dev)) { |
| 2218 | if (tmp & DP_SYNC_HS_HIGH) | 2218 | if (tmp & DP_SYNC_HS_HIGH) |
| @@ -3812,7 +3812,8 @@ intel_dp_get_dpcd(struct intel_dp *intel_dp) | |||
| 3812 | if (val == 0) | 3812 | if (val == 0) |
| 3813 | break; | 3813 | break; |
| 3814 | 3814 | ||
| 3815 | intel_dp->sink_rates[i] = val * 200; | 3815 | /* Value read is in kHz while drm clock is saved in deca-kHz */ |
| 3816 | intel_dp->sink_rates[i] = (val * 200) / 10; | ||
| 3816 | } | 3817 | } |
| 3817 | intel_dp->num_sink_rates = i; | 3818 | intel_dp->num_sink_rates = i; |
| 3818 | } | 3819 | } |
diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c index 5abda1d2c018..fbcc7dff0d63 100644 --- a/drivers/gpu/drm/i915/intel_lvds.c +++ b/drivers/gpu/drm/i915/intel_lvds.c | |||
| @@ -813,12 +813,28 @@ static int intel_dual_link_lvds_callback(const struct dmi_system_id *id) | |||
| 813 | static const struct dmi_system_id intel_dual_link_lvds[] = { | 813 | static const struct dmi_system_id intel_dual_link_lvds[] = { |
| 814 | { | 814 | { |
| 815 | .callback = intel_dual_link_lvds_callback, | 815 | .callback = intel_dual_link_lvds_callback, |
| 816 | .ident = "Apple MacBook Pro (Core i5/i7 Series)", | 816 | .ident = "Apple MacBook Pro 15\" (2010)", |
| 817 | .matches = { | ||
| 818 | DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."), | ||
| 819 | DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro6,2"), | ||
| 820 | }, | ||
| 821 | }, | ||
| 822 | { | ||
| 823 | .callback = intel_dual_link_lvds_callback, | ||
| 824 | .ident = "Apple MacBook Pro 15\" (2011)", | ||
| 817 | .matches = { | 825 | .matches = { |
| 818 | DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."), | 826 | DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."), |
| 819 | DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro8,2"), | 827 | DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro8,2"), |
| 820 | }, | 828 | }, |
| 821 | }, | 829 | }, |
| 830 | { | ||
| 831 | .callback = intel_dual_link_lvds_callback, | ||
| 832 | .ident = "Apple MacBook Pro 15\" (2012)", | ||
| 833 | .matches = { | ||
| 834 | DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."), | ||
| 835 | DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro9,1"), | ||
| 836 | }, | ||
| 837 | }, | ||
| 822 | { } /* terminating entry */ | 838 | { } /* terminating entry */ |
| 823 | }; | 839 | }; |
| 824 | 840 | ||
| @@ -848,6 +864,11 @@ static bool compute_is_dual_link_lvds(struct intel_lvds_encoder *lvds_encoder) | |||
| 848 | if (i915.lvds_channel_mode > 0) | 864 | if (i915.lvds_channel_mode > 0) |
| 849 | return i915.lvds_channel_mode == 2; | 865 | return i915.lvds_channel_mode == 2; |
| 850 | 866 | ||
| 867 | /* single channel LVDS is limited to 112 MHz */ | ||
| 868 | if (lvds_encoder->attached_connector->base.panel.fixed_mode->clock | ||
| 869 | > 112999) | ||
| 870 | return true; | ||
| 871 | |||
| 851 | if (dmi_check_system(intel_dual_link_lvds)) | 872 | if (dmi_check_system(intel_dual_link_lvds)) |
| 852 | return true; | 873 | return true; |
| 853 | 874 | ||
| @@ -1111,6 +1132,8 @@ void intel_lvds_init(struct drm_device *dev) | |||
| 1111 | out: | 1132 | out: |
| 1112 | mutex_unlock(&dev->mode_config.mutex); | 1133 | mutex_unlock(&dev->mode_config.mutex); |
| 1113 | 1134 | ||
| 1135 | intel_panel_init(&intel_connector->panel, fixed_mode, downclock_mode); | ||
| 1136 | |||
| 1114 | lvds_encoder->is_dual_link = compute_is_dual_link_lvds(lvds_encoder); | 1137 | lvds_encoder->is_dual_link = compute_is_dual_link_lvds(lvds_encoder); |
| 1115 | DRM_DEBUG_KMS("detected %s-link lvds configuration\n", | 1138 | DRM_DEBUG_KMS("detected %s-link lvds configuration\n", |
| 1116 | lvds_encoder->is_dual_link ? "dual" : "single"); | 1139 | lvds_encoder->is_dual_link ? "dual" : "single"); |
| @@ -1125,7 +1148,6 @@ out: | |||
| 1125 | } | 1148 | } |
| 1126 | drm_connector_register(connector); | 1149 | drm_connector_register(connector); |
| 1127 | 1150 | ||
| 1128 | intel_panel_init(&intel_connector->panel, fixed_mode, downclock_mode); | ||
| 1129 | intel_panel_setup_backlight(connector, INVALID_PIPE); | 1151 | intel_panel_setup_backlight(connector, INVALID_PIPE); |
| 1130 | 1152 | ||
| 1131 | return; | 1153 | return; |
diff --git a/drivers/gpu/drm/radeon/cik.c b/drivers/gpu/drm/radeon/cik.c index 28faea9996f9..a0c35bbc8546 100644 --- a/drivers/gpu/drm/radeon/cik.c +++ b/drivers/gpu/drm/radeon/cik.c | |||
| @@ -5822,7 +5822,7 @@ static int cik_pcie_gart_enable(struct radeon_device *rdev) | |||
| 5822 | L2_CACHE_BIGK_FRAGMENT_SIZE(4)); | 5822 | L2_CACHE_BIGK_FRAGMENT_SIZE(4)); |
| 5823 | /* setup context0 */ | 5823 | /* setup context0 */ |
| 5824 | WREG32(VM_CONTEXT0_PAGE_TABLE_START_ADDR, rdev->mc.gtt_start >> 12); | 5824 | WREG32(VM_CONTEXT0_PAGE_TABLE_START_ADDR, rdev->mc.gtt_start >> 12); |
| 5825 | WREG32(VM_CONTEXT0_PAGE_TABLE_END_ADDR, rdev->mc.gtt_end >> 12); | 5825 | WREG32(VM_CONTEXT0_PAGE_TABLE_END_ADDR, (rdev->mc.gtt_end >> 12) - 1); |
| 5826 | WREG32(VM_CONTEXT0_PAGE_TABLE_BASE_ADDR, rdev->gart.table_addr >> 12); | 5826 | WREG32(VM_CONTEXT0_PAGE_TABLE_BASE_ADDR, rdev->gart.table_addr >> 12); |
| 5827 | WREG32(VM_CONTEXT0_PROTECTION_FAULT_DEFAULT_ADDR, | 5827 | WREG32(VM_CONTEXT0_PROTECTION_FAULT_DEFAULT_ADDR, |
| 5828 | (u32)(rdev->dummy_page.addr >> 12)); | 5828 | (u32)(rdev->dummy_page.addr >> 12)); |
| @@ -5837,7 +5837,7 @@ static int cik_pcie_gart_enable(struct radeon_device *rdev) | |||
| 5837 | /* restore context1-15 */ | 5837 | /* restore context1-15 */ |
| 5838 | /* set vm size, must be a multiple of 4 */ | 5838 | /* set vm size, must be a multiple of 4 */ |
| 5839 | WREG32(VM_CONTEXT1_PAGE_TABLE_START_ADDR, 0); | 5839 | WREG32(VM_CONTEXT1_PAGE_TABLE_START_ADDR, 0); |
| 5840 | WREG32(VM_CONTEXT1_PAGE_TABLE_END_ADDR, rdev->vm_manager.max_pfn); | 5840 | WREG32(VM_CONTEXT1_PAGE_TABLE_END_ADDR, rdev->vm_manager.max_pfn - 1); |
| 5841 | for (i = 1; i < 16; i++) { | 5841 | for (i = 1; i < 16; i++) { |
| 5842 | if (i < 8) | 5842 | if (i < 8) |
| 5843 | WREG32(VM_CONTEXT0_PAGE_TABLE_BASE_ADDR + (i << 2), | 5843 | WREG32(VM_CONTEXT0_PAGE_TABLE_BASE_ADDR + (i << 2), |
diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c index f848acfd3fc8..05e6d6ef5963 100644 --- a/drivers/gpu/drm/radeon/evergreen.c +++ b/drivers/gpu/drm/radeon/evergreen.c | |||
| @@ -2485,7 +2485,7 @@ static int evergreen_pcie_gart_enable(struct radeon_device *rdev) | |||
| 2485 | WREG32(MC_VM_MB_L1_TLB2_CNTL, tmp); | 2485 | WREG32(MC_VM_MB_L1_TLB2_CNTL, tmp); |
| 2486 | WREG32(MC_VM_MB_L1_TLB3_CNTL, tmp); | 2486 | WREG32(MC_VM_MB_L1_TLB3_CNTL, tmp); |
| 2487 | WREG32(VM_CONTEXT0_PAGE_TABLE_START_ADDR, rdev->mc.gtt_start >> 12); | 2487 | WREG32(VM_CONTEXT0_PAGE_TABLE_START_ADDR, rdev->mc.gtt_start >> 12); |
| 2488 | WREG32(VM_CONTEXT0_PAGE_TABLE_END_ADDR, rdev->mc.gtt_end >> 12); | 2488 | WREG32(VM_CONTEXT0_PAGE_TABLE_END_ADDR, (rdev->mc.gtt_end >> 12) - 1); |
| 2489 | WREG32(VM_CONTEXT0_PAGE_TABLE_BASE_ADDR, rdev->gart.table_addr >> 12); | 2489 | WREG32(VM_CONTEXT0_PAGE_TABLE_BASE_ADDR, rdev->gart.table_addr >> 12); |
| 2490 | WREG32(VM_CONTEXT0_CNTL, ENABLE_CONTEXT | PAGE_TABLE_DEPTH(0) | | 2490 | WREG32(VM_CONTEXT0_CNTL, ENABLE_CONTEXT | PAGE_TABLE_DEPTH(0) | |
| 2491 | RANGE_PROTECTION_FAULT_ENABLE_DEFAULT); | 2491 | RANGE_PROTECTION_FAULT_ENABLE_DEFAULT); |
diff --git a/drivers/gpu/drm/radeon/ni.c b/drivers/gpu/drm/radeon/ni.c index e8a496ff007e..aba2f428c0a8 100644 --- a/drivers/gpu/drm/radeon/ni.c +++ b/drivers/gpu/drm/radeon/ni.c | |||
| @@ -1282,7 +1282,7 @@ static int cayman_pcie_gart_enable(struct radeon_device *rdev) | |||
| 1282 | L2_CACHE_BIGK_FRAGMENT_SIZE(6)); | 1282 | L2_CACHE_BIGK_FRAGMENT_SIZE(6)); |
| 1283 | /* setup context0 */ | 1283 | /* setup context0 */ |
| 1284 | WREG32(VM_CONTEXT0_PAGE_TABLE_START_ADDR, rdev->mc.gtt_start >> 12); | 1284 | WREG32(VM_CONTEXT0_PAGE_TABLE_START_ADDR, rdev->mc.gtt_start >> 12); |
| 1285 | WREG32(VM_CONTEXT0_PAGE_TABLE_END_ADDR, rdev->mc.gtt_end >> 12); | 1285 | WREG32(VM_CONTEXT0_PAGE_TABLE_END_ADDR, (rdev->mc.gtt_end >> 12) - 1); |
| 1286 | WREG32(VM_CONTEXT0_PAGE_TABLE_BASE_ADDR, rdev->gart.table_addr >> 12); | 1286 | WREG32(VM_CONTEXT0_PAGE_TABLE_BASE_ADDR, rdev->gart.table_addr >> 12); |
| 1287 | WREG32(VM_CONTEXT0_PROTECTION_FAULT_DEFAULT_ADDR, | 1287 | WREG32(VM_CONTEXT0_PROTECTION_FAULT_DEFAULT_ADDR, |
| 1288 | (u32)(rdev->dummy_page.addr >> 12)); | 1288 | (u32)(rdev->dummy_page.addr >> 12)); |
| @@ -1301,7 +1301,8 @@ static int cayman_pcie_gart_enable(struct radeon_device *rdev) | |||
| 1301 | */ | 1301 | */ |
| 1302 | for (i = 1; i < 8; i++) { | 1302 | for (i = 1; i < 8; i++) { |
| 1303 | WREG32(VM_CONTEXT0_PAGE_TABLE_START_ADDR + (i << 2), 0); | 1303 | WREG32(VM_CONTEXT0_PAGE_TABLE_START_ADDR + (i << 2), 0); |
| 1304 | WREG32(VM_CONTEXT0_PAGE_TABLE_END_ADDR + (i << 2), rdev->vm_manager.max_pfn); | 1304 | WREG32(VM_CONTEXT0_PAGE_TABLE_END_ADDR + (i << 2), |
| 1305 | rdev->vm_manager.max_pfn - 1); | ||
| 1305 | WREG32(VM_CONTEXT0_PAGE_TABLE_BASE_ADDR + (i << 2), | 1306 | WREG32(VM_CONTEXT0_PAGE_TABLE_BASE_ADDR + (i << 2), |
| 1306 | rdev->vm_manager.saved_table_addr[i]); | 1307 | rdev->vm_manager.saved_table_addr[i]); |
| 1307 | } | 1308 | } |
diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c index 8f6d862a1882..25b4ac967742 100644 --- a/drivers/gpu/drm/radeon/r600.c +++ b/drivers/gpu/drm/radeon/r600.c | |||
| @@ -1112,7 +1112,7 @@ static int r600_pcie_gart_enable(struct radeon_device *rdev) | |||
| 1112 | WREG32(MC_VM_L1_TLB_MCB_RD_SEM_CNTL, tmp | ENABLE_SEMAPHORE_MODE); | 1112 | WREG32(MC_VM_L1_TLB_MCB_RD_SEM_CNTL, tmp | ENABLE_SEMAPHORE_MODE); |
| 1113 | WREG32(MC_VM_L1_TLB_MCB_WR_SEM_CNTL, tmp | ENABLE_SEMAPHORE_MODE); | 1113 | WREG32(MC_VM_L1_TLB_MCB_WR_SEM_CNTL, tmp | ENABLE_SEMAPHORE_MODE); |
| 1114 | WREG32(VM_CONTEXT0_PAGE_TABLE_START_ADDR, rdev->mc.gtt_start >> 12); | 1114 | WREG32(VM_CONTEXT0_PAGE_TABLE_START_ADDR, rdev->mc.gtt_start >> 12); |
| 1115 | WREG32(VM_CONTEXT0_PAGE_TABLE_END_ADDR, rdev->mc.gtt_end >> 12); | 1115 | WREG32(VM_CONTEXT0_PAGE_TABLE_END_ADDR, (rdev->mc.gtt_end >> 12) - 1); |
| 1116 | WREG32(VM_CONTEXT0_PAGE_TABLE_BASE_ADDR, rdev->gart.table_addr >> 12); | 1116 | WREG32(VM_CONTEXT0_PAGE_TABLE_BASE_ADDR, rdev->gart.table_addr >> 12); |
| 1117 | WREG32(VM_CONTEXT0_CNTL, ENABLE_CONTEXT | PAGE_TABLE_DEPTH(0) | | 1117 | WREG32(VM_CONTEXT0_CNTL, ENABLE_CONTEXT | PAGE_TABLE_DEPTH(0) | |
| 1118 | RANGE_PROTECTION_FAULT_ENABLE_DEFAULT); | 1118 | RANGE_PROTECTION_FAULT_ENABLE_DEFAULT); |
diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h index d2abe481954f..46eb0fa75a61 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h | |||
| @@ -1673,7 +1673,6 @@ struct radeon_uvd { | |||
| 1673 | struct radeon_bo *vcpu_bo; | 1673 | struct radeon_bo *vcpu_bo; |
| 1674 | void *cpu_addr; | 1674 | void *cpu_addr; |
| 1675 | uint64_t gpu_addr; | 1675 | uint64_t gpu_addr; |
| 1676 | void *saved_bo; | ||
| 1677 | atomic_t handles[RADEON_MAX_UVD_HANDLES]; | 1676 | atomic_t handles[RADEON_MAX_UVD_HANDLES]; |
| 1678 | struct drm_file *filp[RADEON_MAX_UVD_HANDLES]; | 1677 | struct drm_file *filp[RADEON_MAX_UVD_HANDLES]; |
| 1679 | unsigned img_size[RADEON_MAX_UVD_HANDLES]; | 1678 | unsigned img_size[RADEON_MAX_UVD_HANDLES]; |
diff --git a/drivers/gpu/drm/radeon/radeon_asic.c b/drivers/gpu/drm/radeon/radeon_asic.c index fafd8ce4d58f..8dbf5083c4ff 100644 --- a/drivers/gpu/drm/radeon/radeon_asic.c +++ b/drivers/gpu/drm/radeon/radeon_asic.c | |||
| @@ -1202,7 +1202,7 @@ static struct radeon_asic rs780_asic = { | |||
| 1202 | static struct radeon_asic_ring rv770_uvd_ring = { | 1202 | static struct radeon_asic_ring rv770_uvd_ring = { |
| 1203 | .ib_execute = &uvd_v1_0_ib_execute, | 1203 | .ib_execute = &uvd_v1_0_ib_execute, |
| 1204 | .emit_fence = &uvd_v2_2_fence_emit, | 1204 | .emit_fence = &uvd_v2_2_fence_emit, |
| 1205 | .emit_semaphore = &uvd_v1_0_semaphore_emit, | 1205 | .emit_semaphore = &uvd_v2_2_semaphore_emit, |
| 1206 | .cs_parse = &radeon_uvd_cs_parse, | 1206 | .cs_parse = &radeon_uvd_cs_parse, |
| 1207 | .ring_test = &uvd_v1_0_ring_test, | 1207 | .ring_test = &uvd_v1_0_ring_test, |
| 1208 | .ib_test = &uvd_v1_0_ib_test, | 1208 | .ib_test = &uvd_v1_0_ib_test, |
diff --git a/drivers/gpu/drm/radeon/radeon_asic.h b/drivers/gpu/drm/radeon/radeon_asic.h index cf0a90bb61ca..a3ca8cd305c5 100644 --- a/drivers/gpu/drm/radeon/radeon_asic.h +++ b/drivers/gpu/drm/radeon/radeon_asic.h | |||
| @@ -949,6 +949,10 @@ void uvd_v1_0_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib); | |||
| 949 | int uvd_v2_2_resume(struct radeon_device *rdev); | 949 | int uvd_v2_2_resume(struct radeon_device *rdev); |
| 950 | void uvd_v2_2_fence_emit(struct radeon_device *rdev, | 950 | void uvd_v2_2_fence_emit(struct radeon_device *rdev, |
| 951 | struct radeon_fence *fence); | 951 | struct radeon_fence *fence); |
| 952 | bool uvd_v2_2_semaphore_emit(struct radeon_device *rdev, | ||
| 953 | struct radeon_ring *ring, | ||
| 954 | struct radeon_semaphore *semaphore, | ||
| 955 | bool emit_wait); | ||
| 952 | 956 | ||
| 953 | /* uvd v3.1 */ | 957 | /* uvd v3.1 */ |
| 954 | bool uvd_v3_1_semaphore_emit(struct radeon_device *rdev, | 958 | bool uvd_v3_1_semaphore_emit(struct radeon_device *rdev, |
diff --git a/drivers/gpu/drm/radeon/radeon_audio.c b/drivers/gpu/drm/radeon/radeon_audio.c index 8b82abb78df1..dcb779647c57 100644 --- a/drivers/gpu/drm/radeon/radeon_audio.c +++ b/drivers/gpu/drm/radeon/radeon_audio.c | |||
| @@ -464,6 +464,10 @@ void radeon_audio_detect(struct drm_connector *connector, | |||
| 464 | return; | 464 | return; |
| 465 | 465 | ||
| 466 | rdev = connector->encoder->dev->dev_private; | 466 | rdev = connector->encoder->dev->dev_private; |
| 467 | |||
| 468 | if (!radeon_audio_chipset_supported(rdev)) | ||
| 469 | return; | ||
| 470 | |||
| 467 | radeon_encoder = to_radeon_encoder(connector->encoder); | 471 | radeon_encoder = to_radeon_encoder(connector->encoder); |
| 468 | dig = radeon_encoder->enc_priv; | 472 | dig = radeon_encoder->enc_priv; |
| 469 | 473 | ||
diff --git a/drivers/gpu/drm/radeon/radeon_dp_mst.c b/drivers/gpu/drm/radeon/radeon_dp_mst.c index 1017338a49d9..2b98ed3e684d 100644 --- a/drivers/gpu/drm/radeon/radeon_dp_mst.c +++ b/drivers/gpu/drm/radeon/radeon_dp_mst.c | |||
| @@ -666,6 +666,9 @@ radeon_dp_mst_probe(struct radeon_connector *radeon_connector) | |||
| 666 | int ret; | 666 | int ret; |
| 667 | u8 msg[1]; | 667 | u8 msg[1]; |
| 668 | 668 | ||
| 669 | if (!radeon_mst) | ||
| 670 | return 0; | ||
| 671 | |||
| 669 | if (dig_connector->dpcd[DP_DPCD_REV] < 0x12) | 672 | if (dig_connector->dpcd[DP_DPCD_REV] < 0x12) |
| 670 | return 0; | 673 | return 0; |
| 671 | 674 | ||
diff --git a/drivers/gpu/drm/radeon/radeon_mn.c b/drivers/gpu/drm/radeon/radeon_mn.c index 535bf404b725..eef006c48584 100644 --- a/drivers/gpu/drm/radeon/radeon_mn.c +++ b/drivers/gpu/drm/radeon/radeon_mn.c | |||
| @@ -142,6 +142,9 @@ static void radeon_mn_invalidate_range_start(struct mmu_notifier *mn, | |||
| 142 | 142 | ||
| 143 | list_for_each_entry(bo, &node->bos, mn_list) { | 143 | list_for_each_entry(bo, &node->bos, mn_list) { |
| 144 | 144 | ||
| 145 | if (!bo->tbo.ttm || bo->tbo.ttm->state != tt_bound) | ||
| 146 | continue; | ||
| 147 | |||
| 145 | r = radeon_bo_reserve(bo, true); | 148 | r = radeon_bo_reserve(bo, true); |
| 146 | if (r) { | 149 | if (r) { |
| 147 | DRM_ERROR("(%ld) failed to reserve user bo\n", r); | 150 | DRM_ERROR("(%ld) failed to reserve user bo\n", r); |
diff --git a/drivers/gpu/drm/radeon/radeon_ttm.c b/drivers/gpu/drm/radeon/radeon_ttm.c index b292aca0f342..edafd3c2b170 100644 --- a/drivers/gpu/drm/radeon/radeon_ttm.c +++ b/drivers/gpu/drm/radeon/radeon_ttm.c | |||
| @@ -591,8 +591,7 @@ static void radeon_ttm_tt_unpin_userptr(struct ttm_tt *ttm) | |||
| 591 | { | 591 | { |
| 592 | struct radeon_device *rdev = radeon_get_rdev(ttm->bdev); | 592 | struct radeon_device *rdev = radeon_get_rdev(ttm->bdev); |
| 593 | struct radeon_ttm_tt *gtt = (void *)ttm; | 593 | struct radeon_ttm_tt *gtt = (void *)ttm; |
| 594 | struct scatterlist *sg; | 594 | struct sg_page_iter sg_iter; |
| 595 | int i; | ||
| 596 | 595 | ||
| 597 | int write = !(gtt->userflags & RADEON_GEM_USERPTR_READONLY); | 596 | int write = !(gtt->userflags & RADEON_GEM_USERPTR_READONLY); |
| 598 | enum dma_data_direction direction = write ? | 597 | enum dma_data_direction direction = write ? |
| @@ -605,9 +604,8 @@ static void radeon_ttm_tt_unpin_userptr(struct ttm_tt *ttm) | |||
| 605 | /* free the sg table and pages again */ | 604 | /* free the sg table and pages again */ |
| 606 | dma_unmap_sg(rdev->dev, ttm->sg->sgl, ttm->sg->nents, direction); | 605 | dma_unmap_sg(rdev->dev, ttm->sg->sgl, ttm->sg->nents, direction); |
| 607 | 606 | ||
| 608 | for_each_sg(ttm->sg->sgl, sg, ttm->sg->nents, i) { | 607 | for_each_sg_page(ttm->sg->sgl, &sg_iter, ttm->sg->nents, 0) { |
| 609 | struct page *page = sg_page(sg); | 608 | struct page *page = sg_page_iter_page(&sg_iter); |
| 610 | |||
| 611 | if (!(gtt->userflags & RADEON_GEM_USERPTR_READONLY)) | 609 | if (!(gtt->userflags & RADEON_GEM_USERPTR_READONLY)) |
| 612 | set_page_dirty(page); | 610 | set_page_dirty(page); |
| 613 | 611 | ||
diff --git a/drivers/gpu/drm/radeon/radeon_uvd.c b/drivers/gpu/drm/radeon/radeon_uvd.c index c10b2aec6450..6edcb5485092 100644 --- a/drivers/gpu/drm/radeon/radeon_uvd.c +++ b/drivers/gpu/drm/radeon/radeon_uvd.c | |||
| @@ -204,28 +204,32 @@ void radeon_uvd_fini(struct radeon_device *rdev) | |||
| 204 | 204 | ||
| 205 | int radeon_uvd_suspend(struct radeon_device *rdev) | 205 | int radeon_uvd_suspend(struct radeon_device *rdev) |
| 206 | { | 206 | { |
| 207 | unsigned size; | 207 | int i, r; |
| 208 | void *ptr; | ||
| 209 | int i; | ||
| 210 | 208 | ||
| 211 | if (rdev->uvd.vcpu_bo == NULL) | 209 | if (rdev->uvd.vcpu_bo == NULL) |
| 212 | return 0; | 210 | return 0; |
| 213 | 211 | ||
| 214 | for (i = 0; i < RADEON_MAX_UVD_HANDLES; ++i) | 212 | for (i = 0; i < RADEON_MAX_UVD_HANDLES; ++i) { |
| 215 | if (atomic_read(&rdev->uvd.handles[i])) | 213 | uint32_t handle = atomic_read(&rdev->uvd.handles[i]); |
| 216 | break; | 214 | if (handle != 0) { |
| 215 | struct radeon_fence *fence; | ||
| 217 | 216 | ||
| 218 | if (i == RADEON_MAX_UVD_HANDLES) | 217 | radeon_uvd_note_usage(rdev); |
| 219 | return 0; | ||
| 220 | 218 | ||
| 221 | size = radeon_bo_size(rdev->uvd.vcpu_bo); | 219 | r = radeon_uvd_get_destroy_msg(rdev, |
| 222 | size -= rdev->uvd_fw->size; | 220 | R600_RING_TYPE_UVD_INDEX, handle, &fence); |
| 221 | if (r) { | ||
| 222 | DRM_ERROR("Error destroying UVD (%d)!\n", r); | ||
| 223 | continue; | ||
| 224 | } | ||
| 223 | 225 | ||
| 224 | ptr = rdev->uvd.cpu_addr; | 226 | radeon_fence_wait(fence, false); |
| 225 | ptr += rdev->uvd_fw->size; | 227 | radeon_fence_unref(&fence); |
| 226 | 228 | ||
| 227 | rdev->uvd.saved_bo = kmalloc(size, GFP_KERNEL); | 229 | rdev->uvd.filp[i] = NULL; |
| 228 | memcpy(rdev->uvd.saved_bo, ptr, size); | 230 | atomic_set(&rdev->uvd.handles[i], 0); |
| 231 | } | ||
| 232 | } | ||
| 229 | 233 | ||
| 230 | return 0; | 234 | return 0; |
| 231 | } | 235 | } |
| @@ -246,12 +250,7 @@ int radeon_uvd_resume(struct radeon_device *rdev) | |||
| 246 | ptr = rdev->uvd.cpu_addr; | 250 | ptr = rdev->uvd.cpu_addr; |
| 247 | ptr += rdev->uvd_fw->size; | 251 | ptr += rdev->uvd_fw->size; |
| 248 | 252 | ||
| 249 | if (rdev->uvd.saved_bo != NULL) { | 253 | memset(ptr, 0, size); |
| 250 | memcpy(ptr, rdev->uvd.saved_bo, size); | ||
| 251 | kfree(rdev->uvd.saved_bo); | ||
| 252 | rdev->uvd.saved_bo = NULL; | ||
| 253 | } else | ||
| 254 | memset(ptr, 0, size); | ||
| 255 | 254 | ||
| 256 | return 0; | 255 | return 0; |
| 257 | } | 256 | } |
| @@ -396,6 +395,29 @@ static int radeon_uvd_cs_msg_decode(uint32_t *msg, unsigned buf_sizes[]) | |||
| 396 | return 0; | 395 | return 0; |
| 397 | } | 396 | } |
| 398 | 397 | ||
| 398 | static int radeon_uvd_validate_codec(struct radeon_cs_parser *p, | ||
| 399 | unsigned stream_type) | ||
| 400 | { | ||
| 401 | switch (stream_type) { | ||
| 402 | case 0: /* H264 */ | ||
| 403 | case 1: /* VC1 */ | ||
| 404 | /* always supported */ | ||
| 405 | return 0; | ||
| 406 | |||
| 407 | case 3: /* MPEG2 */ | ||
| 408 | case 4: /* MPEG4 */ | ||
| 409 | /* only since UVD 3 */ | ||
| 410 | if (p->rdev->family >= CHIP_PALM) | ||
| 411 | return 0; | ||
| 412 | |||
| 413 | /* fall through */ | ||
| 414 | default: | ||
| 415 | DRM_ERROR("UVD codec not supported by hardware %d!\n", | ||
| 416 | stream_type); | ||
| 417 | return -EINVAL; | ||
| 418 | } | ||
| 419 | } | ||
| 420 | |||
| 399 | static int radeon_uvd_cs_msg(struct radeon_cs_parser *p, struct radeon_bo *bo, | 421 | static int radeon_uvd_cs_msg(struct radeon_cs_parser *p, struct radeon_bo *bo, |
| 400 | unsigned offset, unsigned buf_sizes[]) | 422 | unsigned offset, unsigned buf_sizes[]) |
| 401 | { | 423 | { |
| @@ -436,50 +458,70 @@ static int radeon_uvd_cs_msg(struct radeon_cs_parser *p, struct radeon_bo *bo, | |||
| 436 | return -EINVAL; | 458 | return -EINVAL; |
| 437 | } | 459 | } |
| 438 | 460 | ||
| 439 | if (msg_type == 1) { | 461 | switch (msg_type) { |
| 440 | /* it's a decode msg, calc buffer sizes */ | 462 | case 0: |
| 441 | r = radeon_uvd_cs_msg_decode(msg, buf_sizes); | 463 | /* it's a create msg, calc image size (width * height) */ |
| 442 | /* calc image size (width * height) */ | 464 | img_size = msg[7] * msg[8]; |
| 443 | img_size = msg[6] * msg[7]; | 465 | |
| 466 | r = radeon_uvd_validate_codec(p, msg[4]); | ||
| 444 | radeon_bo_kunmap(bo); | 467 | radeon_bo_kunmap(bo); |
| 445 | if (r) | 468 | if (r) |
| 446 | return r; | 469 | return r; |
| 447 | 470 | ||
| 448 | } else if (msg_type == 2) { | 471 | /* try to alloc a new handle */ |
| 472 | for (i = 0; i < RADEON_MAX_UVD_HANDLES; ++i) { | ||
| 473 | if (atomic_read(&p->rdev->uvd.handles[i]) == handle) { | ||
| 474 | DRM_ERROR("Handle 0x%x already in use!\n", handle); | ||
| 475 | return -EINVAL; | ||
| 476 | } | ||
| 477 | |||
| 478 | if (!atomic_cmpxchg(&p->rdev->uvd.handles[i], 0, handle)) { | ||
| 479 | p->rdev->uvd.filp[i] = p->filp; | ||
| 480 | p->rdev->uvd.img_size[i] = img_size; | ||
| 481 | return 0; | ||
| 482 | } | ||
| 483 | } | ||
| 484 | |||
| 485 | DRM_ERROR("No more free UVD handles!\n"); | ||
| 486 | return -EINVAL; | ||
| 487 | |||
| 488 | case 1: | ||
| 489 | /* it's a decode msg, validate codec and calc buffer sizes */ | ||
| 490 | r = radeon_uvd_validate_codec(p, msg[4]); | ||
| 491 | if (!r) | ||
| 492 | r = radeon_uvd_cs_msg_decode(msg, buf_sizes); | ||
| 493 | radeon_bo_kunmap(bo); | ||
| 494 | if (r) | ||
| 495 | return r; | ||
| 496 | |||
| 497 | /* validate the handle */ | ||
| 498 | for (i = 0; i < RADEON_MAX_UVD_HANDLES; ++i) { | ||
| 499 | if (atomic_read(&p->rdev->uvd.handles[i]) == handle) { | ||
| 500 | if (p->rdev->uvd.filp[i] != p->filp) { | ||
| 501 | DRM_ERROR("UVD handle collision detected!\n"); | ||
| 502 | return -EINVAL; | ||
| 503 | } | ||
| 504 | return 0; | ||
| 505 | } | ||
| 506 | } | ||
| 507 | |||
| 508 | DRM_ERROR("Invalid UVD handle 0x%x!\n", handle); | ||
| 509 | return -ENOENT; | ||
| 510 | |||
| 511 | case 2: | ||
| 449 | /* it's a destroy msg, free the handle */ | 512 | /* it's a destroy msg, free the handle */ |
| 450 | for (i = 0; i < RADEON_MAX_UVD_HANDLES; ++i) | 513 | for (i = 0; i < RADEON_MAX_UVD_HANDLES; ++i) |
| 451 | atomic_cmpxchg(&p->rdev->uvd.handles[i], handle, 0); | 514 | atomic_cmpxchg(&p->rdev->uvd.handles[i], handle, 0); |
| 452 | radeon_bo_kunmap(bo); | 515 | radeon_bo_kunmap(bo); |
| 453 | return 0; | 516 | return 0; |
| 454 | } else { | ||
| 455 | /* it's a create msg, calc image size (width * height) */ | ||
| 456 | img_size = msg[7] * msg[8]; | ||
| 457 | radeon_bo_kunmap(bo); | ||
| 458 | 517 | ||
| 459 | if (msg_type != 0) { | 518 | default: |
| 460 | DRM_ERROR("Illegal UVD message type (%d)!\n", msg_type); | ||
| 461 | return -EINVAL; | ||
| 462 | } | ||
| 463 | |||
| 464 | /* it's a create msg, no special handling needed */ | ||
| 465 | } | ||
| 466 | |||
| 467 | /* create or decode, validate the handle */ | ||
| 468 | for (i = 0; i < RADEON_MAX_UVD_HANDLES; ++i) { | ||
| 469 | if (atomic_read(&p->rdev->uvd.handles[i]) == handle) | ||
| 470 | return 0; | ||
| 471 | } | ||
| 472 | 519 | ||
| 473 | /* handle not found try to alloc a new one */ | 520 | DRM_ERROR("Illegal UVD message type (%d)!\n", msg_type); |
| 474 | for (i = 0; i < RADEON_MAX_UVD_HANDLES; ++i) { | 521 | return -EINVAL; |
| 475 | if (!atomic_cmpxchg(&p->rdev->uvd.handles[i], 0, handle)) { | ||
| 476 | p->rdev->uvd.filp[i] = p->filp; | ||
| 477 | p->rdev->uvd.img_size[i] = img_size; | ||
| 478 | return 0; | ||
| 479 | } | ||
| 480 | } | 522 | } |
| 481 | 523 | ||
| 482 | DRM_ERROR("No more free UVD handles!\n"); | 524 | BUG(); |
| 483 | return -EINVAL; | 525 | return -EINVAL; |
| 484 | } | 526 | } |
| 485 | 527 | ||
diff --git a/drivers/gpu/drm/radeon/radeon_vce.c b/drivers/gpu/drm/radeon/radeon_vce.c index 24f849f888bb..0de5711ac508 100644 --- a/drivers/gpu/drm/radeon/radeon_vce.c +++ b/drivers/gpu/drm/radeon/radeon_vce.c | |||
| @@ -493,18 +493,27 @@ int radeon_vce_cs_reloc(struct radeon_cs_parser *p, int lo, int hi, | |||
| 493 | * | 493 | * |
| 494 | * @p: parser context | 494 | * @p: parser context |
| 495 | * @handle: handle to validate | 495 | * @handle: handle to validate |
| 496 | * @allocated: allocated a new handle? | ||
| 496 | * | 497 | * |
| 497 | * Validates the handle and return the found session index or -EINVAL | 498 | * Validates the handle and return the found session index or -EINVAL |
| 498 | * we we don't have another free session index. | 499 | * we we don't have another free session index. |
| 499 | */ | 500 | */ |
| 500 | int radeon_vce_validate_handle(struct radeon_cs_parser *p, uint32_t handle) | 501 | static int radeon_vce_validate_handle(struct radeon_cs_parser *p, |
| 502 | uint32_t handle, bool *allocated) | ||
| 501 | { | 503 | { |
| 502 | unsigned i; | 504 | unsigned i; |
| 503 | 505 | ||
| 506 | *allocated = false; | ||
| 507 | |||
| 504 | /* validate the handle */ | 508 | /* validate the handle */ |
| 505 | for (i = 0; i < RADEON_MAX_VCE_HANDLES; ++i) { | 509 | for (i = 0; i < RADEON_MAX_VCE_HANDLES; ++i) { |
| 506 | if (atomic_read(&p->rdev->vce.handles[i]) == handle) | 510 | if (atomic_read(&p->rdev->vce.handles[i]) == handle) { |
| 511 | if (p->rdev->vce.filp[i] != p->filp) { | ||
| 512 | DRM_ERROR("VCE handle collision detected!\n"); | ||
| 513 | return -EINVAL; | ||
| 514 | } | ||
| 507 | return i; | 515 | return i; |
| 516 | } | ||
| 508 | } | 517 | } |
| 509 | 518 | ||
| 510 | /* handle not found try to alloc a new one */ | 519 | /* handle not found try to alloc a new one */ |
| @@ -512,6 +521,7 @@ int radeon_vce_validate_handle(struct radeon_cs_parser *p, uint32_t handle) | |||
| 512 | if (!atomic_cmpxchg(&p->rdev->vce.handles[i], 0, handle)) { | 521 | if (!atomic_cmpxchg(&p->rdev->vce.handles[i], 0, handle)) { |
| 513 | p->rdev->vce.filp[i] = p->filp; | 522 | p->rdev->vce.filp[i] = p->filp; |
| 514 | p->rdev->vce.img_size[i] = 0; | 523 | p->rdev->vce.img_size[i] = 0; |
| 524 | *allocated = true; | ||
| 515 | return i; | 525 | return i; |
| 516 | } | 526 | } |
| 517 | } | 527 | } |
| @@ -529,10 +539,10 @@ int radeon_vce_validate_handle(struct radeon_cs_parser *p, uint32_t handle) | |||
| 529 | int radeon_vce_cs_parse(struct radeon_cs_parser *p) | 539 | int radeon_vce_cs_parse(struct radeon_cs_parser *p) |
| 530 | { | 540 | { |
| 531 | int session_idx = -1; | 541 | int session_idx = -1; |
| 532 | bool destroyed = false; | 542 | bool destroyed = false, created = false, allocated = false; |
| 533 | uint32_t tmp, handle = 0; | 543 | uint32_t tmp, handle = 0; |
| 534 | uint32_t *size = &tmp; | 544 | uint32_t *size = &tmp; |
| 535 | int i, r; | 545 | int i, r = 0; |
| 536 | 546 | ||
| 537 | while (p->idx < p->chunk_ib->length_dw) { | 547 | while (p->idx < p->chunk_ib->length_dw) { |
| 538 | uint32_t len = radeon_get_ib_value(p, p->idx); | 548 | uint32_t len = radeon_get_ib_value(p, p->idx); |
| @@ -540,18 +550,21 @@ int radeon_vce_cs_parse(struct radeon_cs_parser *p) | |||
| 540 | 550 | ||
| 541 | if ((len < 8) || (len & 3)) { | 551 | if ((len < 8) || (len & 3)) { |
| 542 | DRM_ERROR("invalid VCE command length (%d)!\n", len); | 552 | DRM_ERROR("invalid VCE command length (%d)!\n", len); |
| 543 | return -EINVAL; | 553 | r = -EINVAL; |
| 554 | goto out; | ||
| 544 | } | 555 | } |
| 545 | 556 | ||
| 546 | if (destroyed) { | 557 | if (destroyed) { |
| 547 | DRM_ERROR("No other command allowed after destroy!\n"); | 558 | DRM_ERROR("No other command allowed after destroy!\n"); |
| 548 | return -EINVAL; | 559 | r = -EINVAL; |
| 560 | goto out; | ||
| 549 | } | 561 | } |
| 550 | 562 | ||
| 551 | switch (cmd) { | 563 | switch (cmd) { |
| 552 | case 0x00000001: // session | 564 | case 0x00000001: // session |
| 553 | handle = radeon_get_ib_value(p, p->idx + 2); | 565 | handle = radeon_get_ib_value(p, p->idx + 2); |
| 554 | session_idx = radeon_vce_validate_handle(p, handle); | 566 | session_idx = radeon_vce_validate_handle(p, handle, |
| 567 | &allocated); | ||
| 555 | if (session_idx < 0) | 568 | if (session_idx < 0) |
| 556 | return session_idx; | 569 | return session_idx; |
| 557 | size = &p->rdev->vce.img_size[session_idx]; | 570 | size = &p->rdev->vce.img_size[session_idx]; |
| @@ -561,6 +574,13 @@ int radeon_vce_cs_parse(struct radeon_cs_parser *p) | |||
| 561 | break; | 574 | break; |
| 562 | 575 | ||
| 563 | case 0x01000001: // create | 576 | case 0x01000001: // create |
| 577 | created = true; | ||
| 578 | if (!allocated) { | ||
| 579 | DRM_ERROR("Handle already in use!\n"); | ||
| 580 | r = -EINVAL; | ||
| 581 | goto out; | ||
| 582 | } | ||
| 583 | |||
| 564 | *size = radeon_get_ib_value(p, p->idx + 8) * | 584 | *size = radeon_get_ib_value(p, p->idx + 8) * |
| 565 | radeon_get_ib_value(p, p->idx + 10) * | 585 | radeon_get_ib_value(p, p->idx + 10) * |
| 566 | 8 * 3 / 2; | 586 | 8 * 3 / 2; |
| @@ -578,12 +598,12 @@ int radeon_vce_cs_parse(struct radeon_cs_parser *p) | |||
| 578 | r = radeon_vce_cs_reloc(p, p->idx + 10, p->idx + 9, | 598 | r = radeon_vce_cs_reloc(p, p->idx + 10, p->idx + 9, |
| 579 | *size); | 599 | *size); |
| 580 | if (r) | 600 | if (r) |
| 581 | return r; | 601 | goto out; |
| 582 | 602 | ||
| 583 | r = radeon_vce_cs_reloc(p, p->idx + 12, p->idx + 11, | 603 | r = radeon_vce_cs_reloc(p, p->idx + 12, p->idx + 11, |
| 584 | *size / 3); | 604 | *size / 3); |
| 585 | if (r) | 605 | if (r) |
| 586 | return r; | 606 | goto out; |
| 587 | break; | 607 | break; |
| 588 | 608 | ||
| 589 | case 0x02000001: // destroy | 609 | case 0x02000001: // destroy |
| @@ -594,7 +614,7 @@ int radeon_vce_cs_parse(struct radeon_cs_parser *p) | |||
| 594 | r = radeon_vce_cs_reloc(p, p->idx + 3, p->idx + 2, | 614 | r = radeon_vce_cs_reloc(p, p->idx + 3, p->idx + 2, |
| 595 | *size * 2); | 615 | *size * 2); |
| 596 | if (r) | 616 | if (r) |
| 597 | return r; | 617 | goto out; |
| 598 | break; | 618 | break; |
| 599 | 619 | ||
| 600 | case 0x05000004: // video bitstream buffer | 620 | case 0x05000004: // video bitstream buffer |
| @@ -602,36 +622,47 @@ int radeon_vce_cs_parse(struct radeon_cs_parser *p) | |||
| 602 | r = radeon_vce_cs_reloc(p, p->idx + 3, p->idx + 2, | 622 | r = radeon_vce_cs_reloc(p, p->idx + 3, p->idx + 2, |
| 603 | tmp); | 623 | tmp); |
| 604 | if (r) | 624 | if (r) |
| 605 | return r; | 625 | goto out; |
| 606 | break; | 626 | break; |
| 607 | 627 | ||
| 608 | case 0x05000005: // feedback buffer | 628 | case 0x05000005: // feedback buffer |
| 609 | r = radeon_vce_cs_reloc(p, p->idx + 3, p->idx + 2, | 629 | r = radeon_vce_cs_reloc(p, p->idx + 3, p->idx + 2, |
| 610 | 4096); | 630 | 4096); |
| 611 | if (r) | 631 | if (r) |
| 612 | return r; | 632 | goto out; |
| 613 | break; | 633 | break; |
| 614 | 634 | ||
| 615 | default: | 635 | default: |
| 616 | DRM_ERROR("invalid VCE command (0x%x)!\n", cmd); | 636 | DRM_ERROR("invalid VCE command (0x%x)!\n", cmd); |
| 617 | return -EINVAL; | 637 | r = -EINVAL; |
| 638 | goto out; | ||
| 618 | } | 639 | } |
| 619 | 640 | ||
| 620 | if (session_idx == -1) { | 641 | if (session_idx == -1) { |
| 621 | DRM_ERROR("no session command at start of IB\n"); | 642 | DRM_ERROR("no session command at start of IB\n"); |
| 622 | return -EINVAL; | 643 | r = -EINVAL; |
| 644 | goto out; | ||
| 623 | } | 645 | } |
| 624 | 646 | ||
| 625 | p->idx += len / 4; | 647 | p->idx += len / 4; |
| 626 | } | 648 | } |
| 627 | 649 | ||
| 628 | if (destroyed) { | 650 | if (allocated && !created) { |
| 629 | /* IB contains a destroy msg, free the handle */ | 651 | DRM_ERROR("New session without create command!\n"); |
| 652 | r = -ENOENT; | ||
| 653 | } | ||
| 654 | |||
| 655 | out: | ||
| 656 | if ((!r && destroyed) || (r && allocated)) { | ||
| 657 | /* | ||
| 658 | * IB contains a destroy msg or we have allocated an | ||
| 659 | * handle and got an error, anyway free the handle | ||
| 660 | */ | ||
| 630 | for (i = 0; i < RADEON_MAX_VCE_HANDLES; ++i) | 661 | for (i = 0; i < RADEON_MAX_VCE_HANDLES; ++i) |
| 631 | atomic_cmpxchg(&p->rdev->vce.handles[i], handle, 0); | 662 | atomic_cmpxchg(&p->rdev->vce.handles[i], handle, 0); |
| 632 | } | 663 | } |
| 633 | 664 | ||
| 634 | return 0; | 665 | return r; |
| 635 | } | 666 | } |
| 636 | 667 | ||
| 637 | /** | 668 | /** |
diff --git a/drivers/gpu/drm/radeon/rv770.c b/drivers/gpu/drm/radeon/rv770.c index 01ee96acb398..c54d6313a46d 100644 --- a/drivers/gpu/drm/radeon/rv770.c +++ b/drivers/gpu/drm/radeon/rv770.c | |||
| @@ -921,7 +921,7 @@ static int rv770_pcie_gart_enable(struct radeon_device *rdev) | |||
| 921 | WREG32(MC_VM_MB_L1_TLB2_CNTL, tmp); | 921 | WREG32(MC_VM_MB_L1_TLB2_CNTL, tmp); |
| 922 | WREG32(MC_VM_MB_L1_TLB3_CNTL, tmp); | 922 | WREG32(MC_VM_MB_L1_TLB3_CNTL, tmp); |
| 923 | WREG32(VM_CONTEXT0_PAGE_TABLE_START_ADDR, rdev->mc.gtt_start >> 12); | 923 | WREG32(VM_CONTEXT0_PAGE_TABLE_START_ADDR, rdev->mc.gtt_start >> 12); |
| 924 | WREG32(VM_CONTEXT0_PAGE_TABLE_END_ADDR, rdev->mc.gtt_end >> 12); | 924 | WREG32(VM_CONTEXT0_PAGE_TABLE_END_ADDR, (rdev->mc.gtt_end >> 12) - 1); |
| 925 | WREG32(VM_CONTEXT0_PAGE_TABLE_BASE_ADDR, rdev->gart.table_addr >> 12); | 925 | WREG32(VM_CONTEXT0_PAGE_TABLE_BASE_ADDR, rdev->gart.table_addr >> 12); |
| 926 | WREG32(VM_CONTEXT0_CNTL, ENABLE_CONTEXT | PAGE_TABLE_DEPTH(0) | | 926 | WREG32(VM_CONTEXT0_CNTL, ENABLE_CONTEXT | PAGE_TABLE_DEPTH(0) | |
| 927 | RANGE_PROTECTION_FAULT_ENABLE_DEFAULT); | 927 | RANGE_PROTECTION_FAULT_ENABLE_DEFAULT); |
diff --git a/drivers/gpu/drm/radeon/rv770d.h b/drivers/gpu/drm/radeon/rv770d.h index 3cf1e2921545..9ef2064b1c9c 100644 --- a/drivers/gpu/drm/radeon/rv770d.h +++ b/drivers/gpu/drm/radeon/rv770d.h | |||
| @@ -989,6 +989,9 @@ | |||
| 989 | ((n) & 0x3FFF) << 16) | 989 | ((n) & 0x3FFF) << 16) |
| 990 | 990 | ||
| 991 | /* UVD */ | 991 | /* UVD */ |
| 992 | #define UVD_SEMA_ADDR_LOW 0xef00 | ||
| 993 | #define UVD_SEMA_ADDR_HIGH 0xef04 | ||
| 994 | #define UVD_SEMA_CMD 0xef08 | ||
| 992 | #define UVD_GPCOM_VCPU_CMD 0xef0c | 995 | #define UVD_GPCOM_VCPU_CMD 0xef0c |
| 993 | #define UVD_GPCOM_VCPU_DATA0 0xef10 | 996 | #define UVD_GPCOM_VCPU_DATA0 0xef10 |
| 994 | #define UVD_GPCOM_VCPU_DATA1 0xef14 | 997 | #define UVD_GPCOM_VCPU_DATA1 0xef14 |
diff --git a/drivers/gpu/drm/radeon/si.c b/drivers/gpu/drm/radeon/si.c index b1d74bc375d8..5326f753e107 100644 --- a/drivers/gpu/drm/radeon/si.c +++ b/drivers/gpu/drm/radeon/si.c | |||
| @@ -4303,7 +4303,7 @@ static int si_pcie_gart_enable(struct radeon_device *rdev) | |||
| 4303 | L2_CACHE_BIGK_FRAGMENT_SIZE(4)); | 4303 | L2_CACHE_BIGK_FRAGMENT_SIZE(4)); |
| 4304 | /* setup context0 */ | 4304 | /* setup context0 */ |
| 4305 | WREG32(VM_CONTEXT0_PAGE_TABLE_START_ADDR, rdev->mc.gtt_start >> 12); | 4305 | WREG32(VM_CONTEXT0_PAGE_TABLE_START_ADDR, rdev->mc.gtt_start >> 12); |
| 4306 | WREG32(VM_CONTEXT0_PAGE_TABLE_END_ADDR, rdev->mc.gtt_end >> 12); | 4306 | WREG32(VM_CONTEXT0_PAGE_TABLE_END_ADDR, (rdev->mc.gtt_end >> 12) - 1); |
| 4307 | WREG32(VM_CONTEXT0_PAGE_TABLE_BASE_ADDR, rdev->gart.table_addr >> 12); | 4307 | WREG32(VM_CONTEXT0_PAGE_TABLE_BASE_ADDR, rdev->gart.table_addr >> 12); |
| 4308 | WREG32(VM_CONTEXT0_PROTECTION_FAULT_DEFAULT_ADDR, | 4308 | WREG32(VM_CONTEXT0_PROTECTION_FAULT_DEFAULT_ADDR, |
| 4309 | (u32)(rdev->dummy_page.addr >> 12)); | 4309 | (u32)(rdev->dummy_page.addr >> 12)); |
| @@ -4318,7 +4318,7 @@ static int si_pcie_gart_enable(struct radeon_device *rdev) | |||
| 4318 | /* empty context1-15 */ | 4318 | /* empty context1-15 */ |
| 4319 | /* set vm size, must be a multiple of 4 */ | 4319 | /* set vm size, must be a multiple of 4 */ |
| 4320 | WREG32(VM_CONTEXT1_PAGE_TABLE_START_ADDR, 0); | 4320 | WREG32(VM_CONTEXT1_PAGE_TABLE_START_ADDR, 0); |
| 4321 | WREG32(VM_CONTEXT1_PAGE_TABLE_END_ADDR, rdev->vm_manager.max_pfn); | 4321 | WREG32(VM_CONTEXT1_PAGE_TABLE_END_ADDR, rdev->vm_manager.max_pfn - 1); |
| 4322 | /* Assign the pt base to something valid for now; the pts used for | 4322 | /* Assign the pt base to something valid for now; the pts used for |
| 4323 | * the VMs are determined by the application and setup and assigned | 4323 | * the VMs are determined by the application and setup and assigned |
| 4324 | * on the fly in the vm part of radeon_gart.c | 4324 | * on the fly in the vm part of radeon_gart.c |
diff --git a/drivers/gpu/drm/radeon/uvd_v1_0.c b/drivers/gpu/drm/radeon/uvd_v1_0.c index e72b3cb59358..c6b1cbca47fc 100644 --- a/drivers/gpu/drm/radeon/uvd_v1_0.c +++ b/drivers/gpu/drm/radeon/uvd_v1_0.c | |||
| @@ -466,18 +466,8 @@ bool uvd_v1_0_semaphore_emit(struct radeon_device *rdev, | |||
| 466 | struct radeon_semaphore *semaphore, | 466 | struct radeon_semaphore *semaphore, |
| 467 | bool emit_wait) | 467 | bool emit_wait) |
| 468 | { | 468 | { |
| 469 | uint64_t addr = semaphore->gpu_addr; | 469 | /* disable semaphores for UVD V1 hardware */ |
| 470 | 470 | return false; | |
| 471 | radeon_ring_write(ring, PACKET0(UVD_SEMA_ADDR_LOW, 0)); | ||
| 472 | radeon_ring_write(ring, (addr >> 3) & 0x000FFFFF); | ||
| 473 | |||
| 474 | radeon_ring_write(ring, PACKET0(UVD_SEMA_ADDR_HIGH, 0)); | ||
| 475 | radeon_ring_write(ring, (addr >> 23) & 0x000FFFFF); | ||
| 476 | |||
| 477 | radeon_ring_write(ring, PACKET0(UVD_SEMA_CMD, 0)); | ||
| 478 | radeon_ring_write(ring, emit_wait ? 1 : 0); | ||
| 479 | |||
| 480 | return true; | ||
| 481 | } | 471 | } |
| 482 | 472 | ||
| 483 | /** | 473 | /** |
diff --git a/drivers/gpu/drm/radeon/uvd_v2_2.c b/drivers/gpu/drm/radeon/uvd_v2_2.c index 89193519f8a1..7ed778cec7c6 100644 --- a/drivers/gpu/drm/radeon/uvd_v2_2.c +++ b/drivers/gpu/drm/radeon/uvd_v2_2.c | |||
| @@ -60,6 +60,35 @@ void uvd_v2_2_fence_emit(struct radeon_device *rdev, | |||
| 60 | } | 60 | } |
| 61 | 61 | ||
| 62 | /** | 62 | /** |
| 63 | * uvd_v2_2_semaphore_emit - emit semaphore command | ||
| 64 | * | ||
| 65 | * @rdev: radeon_device pointer | ||
| 66 | * @ring: radeon_ring pointer | ||
| 67 | * @semaphore: semaphore to emit commands for | ||
| 68 | * @emit_wait: true if we should emit a wait command | ||
| 69 | * | ||
| 70 | * Emit a semaphore command (either wait or signal) to the UVD ring. | ||
| 71 | */ | ||
| 72 | bool uvd_v2_2_semaphore_emit(struct radeon_device *rdev, | ||
| 73 | struct radeon_ring *ring, | ||
| 74 | struct radeon_semaphore *semaphore, | ||
| 75 | bool emit_wait) | ||
| 76 | { | ||
| 77 | uint64_t addr = semaphore->gpu_addr; | ||
| 78 | |||
| 79 | radeon_ring_write(ring, PACKET0(UVD_SEMA_ADDR_LOW, 0)); | ||
| 80 | radeon_ring_write(ring, (addr >> 3) & 0x000FFFFF); | ||
| 81 | |||
| 82 | radeon_ring_write(ring, PACKET0(UVD_SEMA_ADDR_HIGH, 0)); | ||
| 83 | radeon_ring_write(ring, (addr >> 23) & 0x000FFFFF); | ||
| 84 | |||
| 85 | radeon_ring_write(ring, PACKET0(UVD_SEMA_CMD, 0)); | ||
| 86 | radeon_ring_write(ring, emit_wait ? 1 : 0); | ||
| 87 | |||
| 88 | return true; | ||
| 89 | } | ||
| 90 | |||
| 91 | /** | ||
| 63 | * uvd_v2_2_resume - memory controller programming | 92 | * uvd_v2_2_resume - memory controller programming |
| 64 | * | 93 | * |
| 65 | * @rdev: radeon_device pointer | 94 | * @rdev: radeon_device pointer |
diff --git a/drivers/gpu/drm/tegra/drm.c b/drivers/gpu/drm/tegra/drm.c index 1833abd7d3aa..bfad15a913a0 100644 --- a/drivers/gpu/drm/tegra/drm.c +++ b/drivers/gpu/drm/tegra/drm.c | |||
| @@ -173,7 +173,6 @@ static int tegra_drm_load(struct drm_device *drm, unsigned long flags) | |||
| 173 | drm->irq_enabled = true; | 173 | drm->irq_enabled = true; |
| 174 | 174 | ||
| 175 | /* syncpoints are used for full 32-bit hardware VBLANK counters */ | 175 | /* syncpoints are used for full 32-bit hardware VBLANK counters */ |
| 176 | drm->vblank_disable_immediate = true; | ||
| 177 | drm->max_vblank_count = 0xffffffff; | 176 | drm->max_vblank_count = 0xffffffff; |
| 178 | 177 | ||
| 179 | err = drm_vblank_init(drm, drm->mode_config.num_crtc); | 178 | err = drm_vblank_init(drm, drm->mode_config.num_crtc); |
diff --git a/drivers/ide/Kconfig b/drivers/ide/Kconfig index a04c49f2a011..39ea67f9b066 100644 --- a/drivers/ide/Kconfig +++ b/drivers/ide/Kconfig | |||
| @@ -643,15 +643,6 @@ config BLK_DEV_TC86C001 | |||
| 643 | help | 643 | help |
| 644 | This driver adds support for Toshiba TC86C001 GOKU-S chip. | 644 | This driver adds support for Toshiba TC86C001 GOKU-S chip. |
| 645 | 645 | ||
| 646 | config BLK_DEV_CELLEB | ||
| 647 | tristate "Toshiba's Cell Reference Set IDE support" | ||
| 648 | depends on PPC_CELLEB | ||
| 649 | select BLK_DEV_IDEDMA_PCI | ||
| 650 | help | ||
| 651 | This driver provides support for the on-board IDE controller on | ||
| 652 | Toshiba Cell Reference Board. | ||
| 653 | If unsure, say Y. | ||
| 654 | |||
| 655 | endif | 646 | endif |
| 656 | 647 | ||
| 657 | # TODO: BLK_DEV_IDEDMA_PCI -> BLK_DEV_IDEDMA_SFF | 648 | # TODO: BLK_DEV_IDEDMA_PCI -> BLK_DEV_IDEDMA_SFF |
diff --git a/drivers/ide/Makefile b/drivers/ide/Makefile index a04ee82f1c8f..2a8c417d4081 100644 --- a/drivers/ide/Makefile +++ b/drivers/ide/Makefile | |||
| @@ -38,7 +38,6 @@ obj-$(CONFIG_BLK_DEV_AEC62XX) += aec62xx.o | |||
| 38 | obj-$(CONFIG_BLK_DEV_ALI15X3) += alim15x3.o | 38 | obj-$(CONFIG_BLK_DEV_ALI15X3) += alim15x3.o |
| 39 | obj-$(CONFIG_BLK_DEV_AMD74XX) += amd74xx.o | 39 | obj-$(CONFIG_BLK_DEV_AMD74XX) += amd74xx.o |
| 40 | obj-$(CONFIG_BLK_DEV_ATIIXP) += atiixp.o | 40 | obj-$(CONFIG_BLK_DEV_ATIIXP) += atiixp.o |
| 41 | obj-$(CONFIG_BLK_DEV_CELLEB) += scc_pata.o | ||
| 42 | obj-$(CONFIG_BLK_DEV_CMD64X) += cmd64x.o | 41 | obj-$(CONFIG_BLK_DEV_CMD64X) += cmd64x.o |
| 43 | obj-$(CONFIG_BLK_DEV_CS5520) += cs5520.o | 42 | obj-$(CONFIG_BLK_DEV_CS5520) += cs5520.o |
| 44 | obj-$(CONFIG_BLK_DEV_CS5530) += cs5530.o | 43 | obj-$(CONFIG_BLK_DEV_CS5530) += cs5530.o |
diff --git a/drivers/ide/scc_pata.c b/drivers/ide/scc_pata.c deleted file mode 100644 index 2a2d188b5d5b..000000000000 --- a/drivers/ide/scc_pata.c +++ /dev/null | |||
| @@ -1,887 +0,0 @@ | |||
| 1 | /* | ||
| 2 | * Support for IDE interfaces on Celleb platform | ||
| 3 | * | ||
| 4 | * (C) Copyright 2006 TOSHIBA CORPORATION | ||
| 5 | * | ||
| 6 | * This code is based on drivers/ide/pci/siimage.c: | ||
| 7 | * Copyright (C) 2001-2002 Andre Hedrick <andre@linux-ide.org> | ||
| 8 | * Copyright (C) 2003 Red Hat | ||
| 9 | * | ||
| 10 | * This program is free software; you can redistribute it and/or modify | ||
| 11 | * it under the terms of the GNU General Public License as published by | ||
| 12 | * the Free Software Foundation; either version 2 of the License, or | ||
| 13 | * (at your option) any later version. | ||
| 14 | * | ||
| 15 | * This program is distributed in the hope that it will be useful, | ||
| 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 18 | * GNU General Public License for more details. | ||
| 19 | * | ||
| 20 | * You should have received a copy of the GNU General Public License along | ||
| 21 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
| 22 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | ||
| 23 | */ | ||
| 24 | |||
| 25 | #include <linux/types.h> | ||
| 26 | #include <linux/module.h> | ||
| 27 | #include <linux/pci.h> | ||
| 28 | #include <linux/delay.h> | ||
| 29 | #include <linux/ide.h> | ||
| 30 | #include <linux/init.h> | ||
| 31 | |||
| 32 | #define PCI_DEVICE_ID_TOSHIBA_SCC_ATA 0x01b4 | ||
| 33 | |||
| 34 | #define SCC_PATA_NAME "scc IDE" | ||
| 35 | |||
| 36 | #define TDVHSEL_MASTER 0x00000001 | ||
| 37 | #define TDVHSEL_SLAVE 0x00000004 | ||
| 38 | |||
| 39 | #define MODE_JCUSFEN 0x00000080 | ||
| 40 | |||
| 41 | #define CCKCTRL_ATARESET 0x00040000 | ||
| 42 | #define CCKCTRL_BUFCNT 0x00020000 | ||
| 43 | #define CCKCTRL_CRST 0x00010000 | ||
| 44 | #define CCKCTRL_OCLKEN 0x00000100 | ||
| 45 | #define CCKCTRL_ATACLKOEN 0x00000002 | ||
| 46 | #define CCKCTRL_LCLKEN 0x00000001 | ||
| 47 | |||
| 48 | #define QCHCD_IOS_SS 0x00000001 | ||
| 49 | |||
| 50 | #define QCHSD_STPDIAG 0x00020000 | ||
| 51 | |||
| 52 | #define INTMASK_MSK 0xD1000012 | ||
| 53 | #define INTSTS_SERROR 0x80000000 | ||
| 54 | #define INTSTS_PRERR 0x40000000 | ||
| 55 | #define INTSTS_RERR 0x10000000 | ||
| 56 | #define INTSTS_ICERR 0x01000000 | ||
| 57 | #define INTSTS_BMSINT 0x00000010 | ||
| 58 | #define INTSTS_BMHE 0x00000008 | ||
| 59 | #define INTSTS_IOIRQS 0x00000004 | ||
| 60 | #define INTSTS_INTRQ 0x00000002 | ||
| 61 | #define INTSTS_ACTEINT 0x00000001 | ||
| 62 | |||
| 63 | #define ECMODE_VALUE 0x01 | ||
| 64 | |||
| 65 | static struct scc_ports { | ||
| 66 | unsigned long ctl, dma; | ||
| 67 | struct ide_host *host; /* for removing port from system */ | ||
| 68 | } scc_ports[MAX_HWIFS]; | ||
| 69 | |||
| 70 | /* PIO transfer mode table */ | ||
| 71 | /* JCHST */ | ||
| 72 | static unsigned long JCHSTtbl[2][7] = { | ||
| 73 | {0x0E, 0x05, 0x02, 0x03, 0x02, 0x00, 0x00}, /* 100MHz */ | ||
| 74 | {0x13, 0x07, 0x04, 0x04, 0x03, 0x00, 0x00} /* 133MHz */ | ||
| 75 | }; | ||
| 76 | |||
| 77 | /* JCHHT */ | ||
| 78 | static unsigned long JCHHTtbl[2][7] = { | ||
| 79 | {0x0E, 0x02, 0x02, 0x02, 0x02, 0x00, 0x00}, /* 100MHz */ | ||
| 80 | {0x13, 0x03, 0x03, 0x03, 0x03, 0x00, 0x00} /* 133MHz */ | ||
| 81 | }; | ||
| 82 | |||
| 83 | /* JCHCT */ | ||
| 84 | static unsigned long JCHCTtbl[2][7] = { | ||
| 85 | {0x1D, 0x1D, 0x1C, 0x0B, 0x06, 0x00, 0x00}, /* 100MHz */ | ||
| 86 | {0x27, 0x26, 0x26, 0x0E, 0x09, 0x00, 0x00} /* 133MHz */ | ||
| 87 | }; | ||
| 88 | |||
| 89 | |||
| 90 | /* DMA transfer mode table */ | ||
| 91 | /* JCHDCTM/JCHDCTS */ | ||
| 92 | static unsigned long JCHDCTxtbl[2][7] = { | ||
| 93 | {0x0A, 0x06, 0x04, 0x03, 0x01, 0x00, 0x00}, /* 100MHz */ | ||
| 94 | {0x0E, 0x09, 0x06, 0x04, 0x02, 0x01, 0x00} /* 133MHz */ | ||
| 95 | }; | ||
| 96 | |||
| 97 | /* JCSTWTM/JCSTWTS */ | ||
| 98 | static unsigned long JCSTWTxtbl[2][7] = { | ||
| 99 | {0x06, 0x04, 0x03, 0x02, 0x02, 0x02, 0x00}, /* 100MHz */ | ||
| 100 | {0x09, 0x06, 0x04, 0x02, 0x02, 0x02, 0x02} /* 133MHz */ | ||
| 101 | }; | ||
| 102 | |||
| 103 | /* JCTSS */ | ||
| 104 | static unsigned long JCTSStbl[2][7] = { | ||
| 105 | {0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x00}, /* 100MHz */ | ||
| 106 | {0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05} /* 133MHz */ | ||
| 107 | }; | ||
| 108 | |||
| 109 | /* JCENVT */ | ||
| 110 | static unsigned long JCENVTtbl[2][7] = { | ||
| 111 | {0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00}, /* 100MHz */ | ||
| 112 | {0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02} /* 133MHz */ | ||
| 113 | }; | ||
| 114 | |||
| 115 | /* JCACTSELS/JCACTSELM */ | ||
| 116 | static unsigned long JCACTSELtbl[2][7] = { | ||
| 117 | {0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00}, /* 100MHz */ | ||
| 118 | {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01} /* 133MHz */ | ||
| 119 | }; | ||
| 120 | |||
| 121 | |||
| 122 | static u8 scc_ide_inb(unsigned long port) | ||
| 123 | { | ||
| 124 | u32 data = in_be32((void*)port); | ||
| 125 | return (u8)data; | ||
| 126 | } | ||
| 127 | |||
| 128 | static void scc_exec_command(ide_hwif_t *hwif, u8 cmd) | ||
| 129 | { | ||
| 130 | out_be32((void *)hwif->io_ports.command_addr, cmd); | ||
| 131 | eieio(); | ||
| 132 | in_be32((void *)(hwif->dma_base + 0x01c)); | ||
| 133 | eieio(); | ||
| 134 | } | ||
| 135 | |||
| 136 | static u8 scc_read_status(ide_hwif_t *hwif) | ||
| 137 | { | ||
| 138 | return (u8)in_be32((void *)hwif->io_ports.status_addr); | ||
| 139 | } | ||
| 140 | |||
| 141 | static u8 scc_read_altstatus(ide_hwif_t *hwif) | ||
| 142 | { | ||
| 143 | return (u8)in_be32((void *)hwif->io_ports.ctl_addr); | ||
| 144 | } | ||
| 145 | |||
| 146 | static u8 scc_dma_sff_read_status(ide_hwif_t *hwif) | ||
| 147 | { | ||
| 148 | return (u8)in_be32((void *)(hwif->dma_base + 4)); | ||
| 149 | } | ||
| 150 | |||
| 151 | static void scc_write_devctl(ide_hwif_t *hwif, u8 ctl) | ||
| 152 | { | ||
| 153 | out_be32((void *)hwif->io_ports.ctl_addr, ctl); | ||
| 154 | eieio(); | ||
| 155 | in_be32((void *)(hwif->dma_base + 0x01c)); | ||
| 156 | eieio(); | ||
| 157 | } | ||
| 158 | |||
| 159 | static void scc_ide_insw(unsigned long port, void *addr, u32 count) | ||
| 160 | { | ||
| 161 | u16 *ptr = (u16 *)addr; | ||
| 162 | while (count--) { | ||
| 163 | *ptr++ = le16_to_cpu(in_be32((void*)port)); | ||
| 164 | } | ||
| 165 | } | ||
| 166 | |||
| 167 | static void scc_ide_insl(unsigned long port, void *addr, u32 count) | ||
| 168 | { | ||
| 169 | u16 *ptr = (u16 *)addr; | ||
| 170 | while (count--) { | ||
| 171 | *ptr++ = le16_to_cpu(in_be32((void*)port)); | ||
| 172 | *ptr++ = le16_to_cpu(in_be32((void*)port)); | ||
| 173 | } | ||
| 174 | } | ||
| 175 | |||
| 176 | static void scc_ide_outb(u8 addr, unsigned long port) | ||
| 177 | { | ||
| 178 | out_be32((void*)port, addr); | ||
| 179 | } | ||
| 180 | |||
| 181 | static void | ||
| 182 | scc_ide_outsw(unsigned long port, void *addr, u32 count) | ||
| 183 | { | ||
| 184 | u16 *ptr = (u16 *)addr; | ||
| 185 | while (count--) { | ||
| 186 | out_be32((void*)port, cpu_to_le16(*ptr++)); | ||
| 187 | } | ||
| 188 | } | ||
| 189 | |||
| 190 | static void | ||
| 191 | scc_ide_outsl(unsigned long port, void *addr, u32 count) | ||
| 192 | { | ||
| 193 | u16 *ptr = (u16 *)addr; | ||
| 194 | while (count--) { | ||
| 195 | out_be32((void*)port, cpu_to_le16(*ptr++)); | ||
| 196 | out_be32((void*)port, cpu_to_le16(*ptr++)); | ||
| 197 | } | ||
| 198 | } | ||
| 199 | |||
| 200 | /** | ||
| 201 | * scc_set_pio_mode - set host controller for PIO mode | ||
| 202 | * @hwif: port | ||
| 203 | * @drive: drive | ||
| 204 | * | ||
| 205 | * Load the timing settings for this device mode into the | ||
| 206 | * controller. | ||
| 207 | */ | ||
| 208 | |||
| 209 | static void scc_set_pio_mode(ide_hwif_t *hwif, ide_drive_t *drive) | ||
| 210 | { | ||
| 211 | struct scc_ports *ports = ide_get_hwifdata(hwif); | ||
| 212 | unsigned long ctl_base = ports->ctl; | ||
| 213 | unsigned long cckctrl_port = ctl_base + 0xff0; | ||
| 214 | unsigned long piosht_port = ctl_base + 0x000; | ||
| 215 | unsigned long pioct_port = ctl_base + 0x004; | ||
| 216 | unsigned long reg; | ||
| 217 | int offset; | ||
| 218 | const u8 pio = drive->pio_mode - XFER_PIO_0; | ||
| 219 | |||
| 220 | reg = in_be32((void __iomem *)cckctrl_port); | ||
| 221 | if (reg & CCKCTRL_ATACLKOEN) { | ||
| 222 | offset = 1; /* 133MHz */ | ||
| 223 | } else { | ||
| 224 | offset = 0; /* 100MHz */ | ||
| 225 | } | ||
| 226 | reg = JCHSTtbl[offset][pio] << 16 | JCHHTtbl[offset][pio]; | ||
| 227 | out_be32((void __iomem *)piosht_port, reg); | ||
| 228 | reg = JCHCTtbl[offset][pio]; | ||
| 229 | out_be32((void __iomem *)pioct_port, reg); | ||
| 230 | } | ||
| 231 | |||
| 232 | /** | ||
| 233 | * scc_set_dma_mode - set host controller for DMA mode | ||
| 234 | * @hwif: port | ||
| 235 | * @drive: drive | ||
| 236 | * | ||
| 237 | * Load the timing settings for this device mode into the | ||
| 238 | * controller. | ||
| 239 | */ | ||
| 240 | |||
| 241 | static void scc_set_dma_mode(ide_hwif_t *hwif, ide_drive_t *drive) | ||
| 242 | { | ||
| 243 | struct scc_ports *ports = ide_get_hwifdata(hwif); | ||
| 244 | unsigned long ctl_base = ports->ctl; | ||
| 245 | unsigned long cckctrl_port = ctl_base + 0xff0; | ||
| 246 | unsigned long mdmact_port = ctl_base + 0x008; | ||
| 247 | unsigned long mcrcst_port = ctl_base + 0x00c; | ||
| 248 | unsigned long sdmact_port = ctl_base + 0x010; | ||
| 249 | unsigned long scrcst_port = ctl_base + 0x014; | ||
| 250 | unsigned long udenvt_port = ctl_base + 0x018; | ||
| 251 | unsigned long tdvhsel_port = ctl_base + 0x020; | ||
| 252 | int is_slave = drive->dn & 1; | ||
| 253 | int offset, idx; | ||
| 254 | unsigned long reg; | ||
| 255 | unsigned long jcactsel; | ||
| 256 | const u8 speed = drive->dma_mode; | ||
| 257 | |||
| 258 | reg = in_be32((void __iomem *)cckctrl_port); | ||
| 259 | if (reg & CCKCTRL_ATACLKOEN) { | ||
| 260 | offset = 1; /* 133MHz */ | ||
| 261 | } else { | ||
| 262 | offset = 0; /* 100MHz */ | ||
| 263 | } | ||
| 264 | |||
| 265 | idx = speed - XFER_UDMA_0; | ||
| 266 | |||
| 267 | jcactsel = JCACTSELtbl[offset][idx]; | ||
| 268 | if (is_slave) { | ||
| 269 | out_be32((void __iomem *)sdmact_port, JCHDCTxtbl[offset][idx]); | ||
| 270 | out_be32((void __iomem *)scrcst_port, JCSTWTxtbl[offset][idx]); | ||
| 271 | jcactsel = jcactsel << 2; | ||
| 272 | out_be32((void __iomem *)tdvhsel_port, (in_be32((void __iomem *)tdvhsel_port) & ~TDVHSEL_SLAVE) | jcactsel); | ||
| 273 | } else { | ||
| 274 | out_be32((void __iomem *)mdmact_port, JCHDCTxtbl[offset][idx]); | ||
| 275 | out_be32((void __iomem *)mcrcst_port, JCSTWTxtbl[offset][idx]); | ||
| 276 | out_be32((void __iomem *)tdvhsel_port, (in_be32((void __iomem *)tdvhsel_port) & ~TDVHSEL_MASTER) | jcactsel); | ||
| 277 | } | ||
| 278 | reg = JCTSStbl[offset][idx] << 16 | JCENVTtbl[offset][idx]; | ||
| 279 | out_be32((void __iomem *)udenvt_port, reg); | ||
| 280 | } | ||
| 281 | |||
| 282 | static void scc_dma_host_set(ide_drive_t *drive, int on) | ||
| 283 | { | ||
| 284 | ide_hwif_t *hwif = drive->hwif; | ||
| 285 | u8 unit = drive->dn & 1; | ||
| 286 | u8 dma_stat = scc_dma_sff_read_status(hwif); | ||
| 287 | |||
| 288 | if (on) | ||
| 289 | dma_stat |= (1 << (5 + unit)); | ||
| 290 | else | ||
| 291 | dma_stat &= ~(1 << (5 + unit)); | ||
| 292 | |||
| 293 | scc_ide_outb(dma_stat, hwif->dma_base + 4); | ||
| 294 | } | ||
| 295 | |||
| 296 | /** | ||
| 297 | * scc_dma_setup - begin a DMA phase | ||
| 298 | * @drive: target device | ||
| 299 | * @cmd: command | ||
| 300 | * | ||
| 301 | * Build an IDE DMA PRD (IDE speak for scatter gather table) | ||
| 302 | * and then set up the DMA transfer registers. | ||
| 303 | * | ||
| 304 | * Returns 0 on success. If a PIO fallback is required then 1 | ||
| 305 | * is returned. | ||
| 306 | */ | ||
| 307 | |||
| 308 | static int scc_dma_setup(ide_drive_t *drive, struct ide_cmd *cmd) | ||
| 309 | { | ||
| 310 | ide_hwif_t *hwif = drive->hwif; | ||
| 311 | u32 rw = (cmd->tf_flags & IDE_TFLAG_WRITE) ? 0 : ATA_DMA_WR; | ||
| 312 | u8 dma_stat; | ||
| 313 | |||
| 314 | /* fall back to pio! */ | ||
| 315 | if (ide_build_dmatable(drive, cmd) == 0) | ||
| 316 | return 1; | ||
| 317 | |||
| 318 | /* PRD table */ | ||
| 319 | out_be32((void __iomem *)(hwif->dma_base + 8), hwif->dmatable_dma); | ||
| 320 | |||
| 321 | /* specify r/w */ | ||
| 322 | out_be32((void __iomem *)hwif->dma_base, rw); | ||
| 323 | |||
| 324 | /* read DMA status for INTR & ERROR flags */ | ||
| 325 | dma_stat = scc_dma_sff_read_status(hwif); | ||
| 326 | |||
| 327 | /* clear INTR & ERROR flags */ | ||
| 328 | out_be32((void __iomem *)(hwif->dma_base + 4), dma_stat | 6); | ||
| 329 | |||
| 330 | return 0; | ||
| 331 | } | ||
| 332 | |||
| 333 | static void scc_dma_start(ide_drive_t *drive) | ||
| 334 | { | ||
| 335 | ide_hwif_t *hwif = drive->hwif; | ||
| 336 | u8 dma_cmd = scc_ide_inb(hwif->dma_base); | ||
| 337 | |||
| 338 | /* start DMA */ | ||
| 339 | scc_ide_outb(dma_cmd | 1, hwif->dma_base); | ||
| 340 | } | ||
| 341 | |||
| 342 | static int __scc_dma_end(ide_drive_t *drive) | ||
| 343 | { | ||
| 344 | ide_hwif_t *hwif = drive->hwif; | ||
| 345 | u8 dma_stat, dma_cmd; | ||
| 346 | |||
| 347 | /* get DMA command mode */ | ||
| 348 | dma_cmd = scc_ide_inb(hwif->dma_base); | ||
| 349 | /* stop DMA */ | ||
| 350 | scc_ide_outb(dma_cmd & ~1, hwif->dma_base); | ||
| 351 | /* get DMA status */ | ||
| 352 | dma_stat = scc_dma_sff_read_status(hwif); | ||
| 353 | /* clear the INTR & ERROR bits */ | ||
| 354 | scc_ide_outb(dma_stat | 6, hwif->dma_base + 4); | ||
| 355 | /* verify good DMA status */ | ||
| 356 | return (dma_stat & 7) != 4 ? (0x10 | dma_stat) : 0; | ||
| 357 | } | ||
| 358 | |||
| 359 | /** | ||
| 360 | * scc_dma_end - Stop DMA | ||
| 361 | * @drive: IDE drive | ||
| 362 | * | ||
| 363 | * Check and clear INT Status register. | ||
| 364 | * Then call __scc_dma_end(). | ||
| 365 | */ | ||
| 366 | |||
| 367 | static int scc_dma_end(ide_drive_t *drive) | ||
| 368 | { | ||
| 369 | ide_hwif_t *hwif = drive->hwif; | ||
| 370 | void __iomem *dma_base = (void __iomem *)hwif->dma_base; | ||
| 371 | unsigned long intsts_port = hwif->dma_base + 0x014; | ||
| 372 | u32 reg; | ||
| 373 | int dma_stat, data_loss = 0; | ||
| 374 | static int retry = 0; | ||
| 375 | |||
| 376 | /* errata A308 workaround: Step5 (check data loss) */ | ||
| 377 | /* We don't check non ide_disk because it is limited to UDMA4 */ | ||
| 378 | if (!(in_be32((void __iomem *)hwif->io_ports.ctl_addr) | ||
| 379 | & ATA_ERR) && | ||
| 380 | drive->media == ide_disk && drive->current_speed > XFER_UDMA_4) { | ||
| 381 | reg = in_be32((void __iomem *)intsts_port); | ||
| 382 | if (!(reg & INTSTS_ACTEINT)) { | ||
| 383 | printk(KERN_WARNING "%s: operation failed (transfer data loss)\n", | ||
| 384 | drive->name); | ||
| 385 | data_loss = 1; | ||
| 386 | if (retry++) { | ||
| 387 | struct request *rq = hwif->rq; | ||
| 388 | ide_drive_t *drive; | ||
| 389 | int i; | ||
| 390 | |||
| 391 | /* ERROR_RESET and drive->crc_count are needed | ||
| 392 | * to reduce DMA transfer mode in retry process. | ||
| 393 | */ | ||
| 394 | if (rq) | ||
| 395 | rq->errors |= ERROR_RESET; | ||
| 396 | |||
| 397 | ide_port_for_each_dev(i, drive, hwif) | ||
| 398 | drive->crc_count++; | ||
| 399 | } | ||
| 400 | } | ||
| 401 | } | ||
| 402 | |||
| 403 | while (1) { | ||
| 404 | reg = in_be32((void __iomem *)intsts_port); | ||
| 405 | |||
| 406 | if (reg & INTSTS_SERROR) { | ||
| 407 | printk(KERN_WARNING "%s: SERROR\n", SCC_PATA_NAME); | ||
| 408 | out_be32((void __iomem *)intsts_port, INTSTS_SERROR|INTSTS_BMSINT); | ||
| 409 | |||
| 410 | out_be32(dma_base, in_be32(dma_base) & ~QCHCD_IOS_SS); | ||
| 411 | continue; | ||
| 412 | } | ||
| 413 | |||
| 414 | if (reg & INTSTS_PRERR) { | ||
| 415 | u32 maea0, maec0; | ||
| 416 | unsigned long ctl_base = hwif->config_data; | ||
| 417 | |||
| 418 | maea0 = in_be32((void __iomem *)(ctl_base + 0xF50)); | ||
| 419 | maec0 = in_be32((void __iomem *)(ctl_base + 0xF54)); | ||
| 420 | |||
| 421 | printk(KERN_WARNING "%s: PRERR [addr:%x cmd:%x]\n", SCC_PATA_NAME, maea0, maec0); | ||
| 422 | |||
| 423 | out_be32((void __iomem *)intsts_port, INTSTS_PRERR|INTSTS_BMSINT); | ||
| 424 | |||
| 425 | out_be32(dma_base, in_be32(dma_base) & ~QCHCD_IOS_SS); | ||
| 426 | continue; | ||
| 427 | } | ||
| 428 | |||
| 429 | if (reg & INTSTS_RERR) { | ||
| 430 | printk(KERN_WARNING "%s: Response Error\n", SCC_PATA_NAME); | ||
| 431 | out_be32((void __iomem *)intsts_port, INTSTS_RERR|INTSTS_BMSINT); | ||
| 432 | |||
| 433 | out_be32(dma_base, in_be32(dma_base) & ~QCHCD_IOS_SS); | ||
| 434 | continue; | ||
| 435 | } | ||
| 436 | |||
| 437 | if (reg & INTSTS_ICERR) { | ||
| 438 | out_be32(dma_base, in_be32(dma_base) & ~QCHCD_IOS_SS); | ||
| 439 | |||
| 440 | printk(KERN_WARNING "%s: Illegal Configuration\n", SCC_PATA_NAME); | ||
| 441 | out_be32((void __iomem *)intsts_port, INTSTS_ICERR|INTSTS_BMSINT); | ||
| 442 | continue; | ||
| 443 | } | ||
| 444 | |||
| 445 | if (reg & INTSTS_BMSINT) { | ||
| 446 | printk(KERN_WARNING "%s: Internal Bus Error\n", SCC_PATA_NAME); | ||
| 447 | out_be32((void __iomem *)intsts_port, INTSTS_BMSINT); | ||
| 448 | |||
| 449 | ide_do_reset(drive); | ||
| 450 | continue; | ||
| 451 | } | ||
| 452 | |||
| 453 | if (reg & INTSTS_BMHE) { | ||
| 454 | out_be32((void __iomem *)intsts_port, INTSTS_BMHE); | ||
| 455 | continue; | ||
| 456 | } | ||
| 457 | |||
| 458 | if (reg & INTSTS_ACTEINT) { | ||
| 459 | out_be32((void __iomem *)intsts_port, INTSTS_ACTEINT); | ||
| 460 | continue; | ||
| 461 | } | ||
| 462 | |||
| 463 | if (reg & INTSTS_IOIRQS) { | ||
| 464 | out_be32((void __iomem *)intsts_port, INTSTS_IOIRQS); | ||
| 465 | continue; | ||
| 466 | } | ||
| 467 | break; | ||
| 468 | } | ||
| 469 | |||
| 470 | dma_stat = __scc_dma_end(drive); | ||
| 471 | if (data_loss) | ||
| 472 | dma_stat |= 2; /* emulate DMA error (to retry command) */ | ||
| 473 | return dma_stat; | ||
| 474 | } | ||
| 475 | |||
| 476 | /* returns 1 if dma irq issued, 0 otherwise */ | ||
| 477 | static int scc_dma_test_irq(ide_drive_t *drive) | ||
| 478 | { | ||
| 479 | ide_hwif_t *hwif = drive->hwif; | ||
| 480 | u32 int_stat = in_be32((void __iomem *)hwif->dma_base + 0x014); | ||
| 481 | |||
| 482 | /* SCC errata A252,A308 workaround: Step4 */ | ||
| 483 | if ((in_be32((void __iomem *)hwif->io_ports.ctl_addr) | ||
| 484 | & ATA_ERR) && | ||
| 485 | (int_stat & INTSTS_INTRQ)) | ||
| 486 | return 1; | ||
| 487 | |||
| 488 | /* SCC errata A308 workaround: Step5 (polling IOIRQS) */ | ||
| 489 | if (int_stat & INTSTS_IOIRQS) | ||
| 490 | return 1; | ||
| 491 | |||
| 492 | return 0; | ||
| 493 | } | ||
| 494 | |||
| 495 | static u8 scc_udma_filter(ide_drive_t *drive) | ||
| 496 | { | ||
| 497 | ide_hwif_t *hwif = drive->hwif; | ||
| 498 | u8 mask = hwif->ultra_mask; | ||
| 499 | |||
| 500 | /* errata A308 workaround: limit non ide_disk drive to UDMA4 */ | ||
| 501 | if ((drive->media != ide_disk) && (mask & 0xE0)) { | ||
| 502 | printk(KERN_INFO "%s: limit %s to UDMA4\n", | ||
| 503 | SCC_PATA_NAME, drive->name); | ||
| 504 | mask = ATA_UDMA4; | ||
| 505 | } | ||
| 506 | |||
| 507 | return mask; | ||
| 508 | } | ||
| 509 | |||
| 510 | /** | ||
| 511 | * setup_mmio_scc - map CTRL/BMID region | ||
| 512 | * @dev: PCI device we are configuring | ||
| 513 | * @name: device name | ||
| 514 | * | ||
| 515 | */ | ||
| 516 | |||
| 517 | static int setup_mmio_scc (struct pci_dev *dev, const char *name) | ||
| 518 | { | ||
| 519 | void __iomem *ctl_addr; | ||
| 520 | void __iomem *dma_addr; | ||
| 521 | int i, ret; | ||
| 522 | |||
| 523 | for (i = 0; i < MAX_HWIFS; i++) { | ||
| 524 | if (scc_ports[i].ctl == 0) | ||
| 525 | break; | ||
| 526 | } | ||
| 527 | if (i >= MAX_HWIFS) | ||
| 528 | return -ENOMEM; | ||
| 529 | |||
| 530 | ret = pci_request_selected_regions(dev, (1 << 2) - 1, name); | ||
| 531 | if (ret < 0) { | ||
| 532 | printk(KERN_ERR "%s: can't reserve resources\n", name); | ||
| 533 | return ret; | ||
| 534 | } | ||
| 535 | |||
| 536 | ctl_addr = pci_ioremap_bar(dev, 0); | ||
| 537 | if (!ctl_addr) | ||
| 538 | goto fail_0; | ||
| 539 | |||
| 540 | dma_addr = pci_ioremap_bar(dev, 1); | ||
| 541 | if (!dma_addr) | ||
| 542 | goto fail_1; | ||
| 543 | |||
| 544 | pci_set_master(dev); | ||
| 545 | scc_ports[i].ctl = (unsigned long)ctl_addr; | ||
| 546 | scc_ports[i].dma = (unsigned long)dma_addr; | ||
| 547 | pci_set_drvdata(dev, (void *) &scc_ports[i]); | ||
| 548 | |||
| 549 | return 1; | ||
| 550 | |||
| 551 | fail_1: | ||
| 552 | iounmap(ctl_addr); | ||
| 553 | fail_0: | ||
| 554 | return -ENOMEM; | ||
| 555 | } | ||
| 556 | |||
| 557 | static int scc_ide_setup_pci_device(struct pci_dev *dev, | ||
| 558 | const struct ide_port_info *d) | ||
| 559 | { | ||
| 560 | struct scc_ports *ports = pci_get_drvdata(dev); | ||
| 561 | struct ide_host *host; | ||
| 562 | struct ide_hw hw, *hws[] = { &hw }; | ||
| 563 | int i, rc; | ||
| 564 | |||
| 565 | memset(&hw, 0, sizeof(hw)); | ||
| 566 | for (i = 0; i <= 8; i++) | ||
| 567 | hw.io_ports_array[i] = ports->dma + 0x20 + i * 4; | ||
| 568 | hw.irq = dev->irq; | ||
| 569 | hw.dev = &dev->dev; | ||
| 570 | |||
| 571 | rc = ide_host_add(d, hws, 1, &host); | ||
| 572 | if (rc) | ||
| 573 | return rc; | ||
| 574 | |||
| 575 | ports->host = host; | ||
| 576 | |||
| 577 | return 0; | ||
| 578 | } | ||
| 579 | |||
| 580 | /** | ||
| 581 | * init_setup_scc - set up an SCC PATA Controller | ||
| 582 | * @dev: PCI device | ||
| 583 | * @d: IDE port info | ||
| 584 | * | ||
| 585 | * Perform the initial set up for this device. | ||
| 586 | */ | ||
| 587 | |||
| 588 | static int init_setup_scc(struct pci_dev *dev, const struct ide_port_info *d) | ||
| 589 | { | ||
| 590 | unsigned long ctl_base; | ||
| 591 | unsigned long dma_base; | ||
| 592 | unsigned long cckctrl_port; | ||
| 593 | unsigned long intmask_port; | ||
| 594 | unsigned long mode_port; | ||
| 595 | unsigned long ecmode_port; | ||
| 596 | u32 reg = 0; | ||
| 597 | struct scc_ports *ports; | ||
| 598 | int rc; | ||
| 599 | |||
| 600 | rc = pci_enable_device(dev); | ||
| 601 | if (rc) | ||
| 602 | goto end; | ||
| 603 | |||
| 604 | rc = setup_mmio_scc(dev, d->name); | ||
| 605 | if (rc < 0) | ||
| 606 | goto end; | ||
| 607 | |||
| 608 | ports = pci_get_drvdata(dev); | ||
| 609 | ctl_base = ports->ctl; | ||
| 610 | dma_base = ports->dma; | ||
| 611 | cckctrl_port = ctl_base + 0xff0; | ||
| 612 | intmask_port = dma_base + 0x010; | ||
| 613 | mode_port = ctl_base + 0x024; | ||
| 614 | ecmode_port = ctl_base + 0xf00; | ||
| 615 | |||
| 616 | /* controller initialization */ | ||
| 617 | reg = 0; | ||
| 618 | out_be32((void*)cckctrl_port, reg); | ||
| 619 | reg |= CCKCTRL_ATACLKOEN; | ||
| 620 | out_be32((void*)cckctrl_port, reg); | ||
| 621 | reg |= CCKCTRL_LCLKEN | CCKCTRL_OCLKEN; | ||
| 622 | out_be32((void*)cckctrl_port, reg); | ||
| 623 | reg |= CCKCTRL_CRST; | ||
| 624 | out_be32((void*)cckctrl_port, reg); | ||
| 625 | |||
| 626 | for (;;) { | ||
| 627 | reg = in_be32((void*)cckctrl_port); | ||
| 628 | if (reg & CCKCTRL_CRST) | ||
| 629 | break; | ||
| 630 | udelay(5000); | ||
| 631 | } | ||
| 632 | |||
| 633 | reg |= CCKCTRL_ATARESET; | ||
| 634 | out_be32((void*)cckctrl_port, reg); | ||
| 635 | |||
| 636 | out_be32((void*)ecmode_port, ECMODE_VALUE); | ||
| 637 | out_be32((void*)mode_port, MODE_JCUSFEN); | ||
| 638 | out_be32((void*)intmask_port, INTMASK_MSK); | ||
| 639 | |||
| 640 | rc = scc_ide_setup_pci_device(dev, d); | ||
| 641 | |||
| 642 | end: | ||
| 643 | return rc; | ||
| 644 | } | ||
| 645 | |||
| 646 | static void scc_tf_load(ide_drive_t *drive, struct ide_taskfile *tf, u8 valid) | ||
| 647 | { | ||
| 648 | struct ide_io_ports *io_ports = &drive->hwif->io_ports; | ||
| 649 | |||
| 650 | if (valid & IDE_VALID_FEATURE) | ||
| 651 | scc_ide_outb(tf->feature, io_ports->feature_addr); | ||
| 652 | if (valid & IDE_VALID_NSECT) | ||
| 653 | scc_ide_outb(tf->nsect, io_ports->nsect_addr); | ||
| 654 | if (valid & IDE_VALID_LBAL) | ||
| 655 | scc_ide_outb(tf->lbal, io_ports->lbal_addr); | ||
| 656 | if (valid & IDE_VALID_LBAM) | ||
| 657 | scc_ide_outb(tf->lbam, io_ports->lbam_addr); | ||
| 658 | if (valid & IDE_VALID_LBAH) | ||
| 659 | scc_ide_outb(tf->lbah, io_ports->lbah_addr); | ||
| 660 | if (valid & IDE_VALID_DEVICE) | ||
| 661 | scc_ide_outb(tf->device, io_ports->device_addr); | ||
| 662 | } | ||
| 663 | |||
| 664 | static void scc_tf_read(ide_drive_t *drive, struct ide_taskfile *tf, u8 valid) | ||
| 665 | { | ||
| 666 | struct ide_io_ports *io_ports = &drive->hwif->io_ports; | ||
| 667 | |||
| 668 | if (valid & IDE_VALID_ERROR) | ||
| 669 | tf->error = scc_ide_inb(io_ports->feature_addr); | ||
| 670 | if (valid & IDE_VALID_NSECT) | ||
| 671 | tf->nsect = scc_ide_inb(io_ports->nsect_addr); | ||
| 672 | if (valid & IDE_VALID_LBAL) | ||
| 673 | tf->lbal = scc_ide_inb(io_ports->lbal_addr); | ||
| 674 | if (valid & IDE_VALID_LBAM) | ||
| 675 | tf->lbam = scc_ide_inb(io_ports->lbam_addr); | ||
| 676 | if (valid & IDE_VALID_LBAH) | ||
| 677 | tf->lbah = scc_ide_inb(io_ports->lbah_addr); | ||
| 678 | if (valid & IDE_VALID_DEVICE) | ||
| 679 | tf->device = scc_ide_inb(io_ports->device_addr); | ||
| 680 | } | ||
| 681 | |||
| 682 | static void scc_input_data(ide_drive_t *drive, struct ide_cmd *cmd, | ||
| 683 | void *buf, unsigned int len) | ||
| 684 | { | ||
| 685 | unsigned long data_addr = drive->hwif->io_ports.data_addr; | ||
| 686 | |||
| 687 | len++; | ||
| 688 | |||
| 689 | if (drive->io_32bit) { | ||
| 690 | scc_ide_insl(data_addr, buf, len / 4); | ||
| 691 | |||
| 692 | if ((len & 3) >= 2) | ||
| 693 | scc_ide_insw(data_addr, (u8 *)buf + (len & ~3), 1); | ||
| 694 | } else | ||
| 695 | scc_ide_insw(data_addr, buf, len / 2); | ||
| 696 | } | ||
| 697 | |||
| 698 | static void scc_output_data(ide_drive_t *drive, struct ide_cmd *cmd, | ||
| 699 | void *buf, unsigned int len) | ||
| 700 | { | ||
| 701 | unsigned long data_addr = drive->hwif->io_ports.data_addr; | ||
| 702 | |||
| 703 | len++; | ||
| 704 | |||
| 705 | if (drive->io_32bit) { | ||
| 706 | scc_ide_outsl(data_addr, buf, len / 4); | ||
| 707 | |||
| 708 | if ((len & 3) >= 2) | ||
| 709 | scc_ide_outsw(data_addr, (u8 *)buf + (len & ~3), 1); | ||
| 710 | } else | ||
| 711 | scc_ide_outsw(data_addr, buf, len / 2); | ||
| 712 | } | ||
| 713 | |||
| 714 | /** | ||
| 715 | * init_mmio_iops_scc - set up the iops for MMIO | ||
| 716 | * @hwif: interface to set up | ||
| 717 | * | ||
| 718 | */ | ||
| 719 | |||
| 720 | static void init_mmio_iops_scc(ide_hwif_t *hwif) | ||
| 721 | { | ||
| 722 | struct pci_dev *dev = to_pci_dev(hwif->dev); | ||
| 723 | struct scc_ports *ports = pci_get_drvdata(dev); | ||
| 724 | unsigned long dma_base = ports->dma; | ||
| 725 | |||
| 726 | ide_set_hwifdata(hwif, ports); | ||
| 727 | |||
| 728 | hwif->dma_base = dma_base; | ||
| 729 | hwif->config_data = ports->ctl; | ||
| 730 | } | ||
| 731 | |||
| 732 | /** | ||
| 733 | * init_iops_scc - set up iops | ||
| 734 | * @hwif: interface to set up | ||
| 735 | * | ||
| 736 | * Do the basic setup for the SCC hardware interface | ||
| 737 | * and then do the MMIO setup. | ||
| 738 | */ | ||
| 739 | |||
| 740 | static void init_iops_scc(ide_hwif_t *hwif) | ||
| 741 | { | ||
| 742 | struct pci_dev *dev = to_pci_dev(hwif->dev); | ||
| 743 | |||
| 744 | hwif->hwif_data = NULL; | ||
| 745 | if (pci_get_drvdata(dev) == NULL) | ||
| 746 | return; | ||
| 747 | init_mmio_iops_scc(hwif); | ||
| 748 | } | ||
| 749 | |||
| 750 | static int scc_init_dma(ide_hwif_t *hwif, const struct ide_port_info *d) | ||
| 751 | { | ||
| 752 | return ide_allocate_dma_engine(hwif); | ||
| 753 | } | ||
| 754 | |||
| 755 | static u8 scc_cable_detect(ide_hwif_t *hwif) | ||
| 756 | { | ||
| 757 | return ATA_CBL_PATA80; | ||
| 758 | } | ||
| 759 | |||
| 760 | /** | ||
| 761 | * init_hwif_scc - set up hwif | ||
| 762 | * @hwif: interface to set up | ||
| 763 | * | ||
| 764 | * We do the basic set up of the interface structure. The SCC | ||
| 765 | * requires several custom handlers so we override the default | ||
| 766 | * ide DMA handlers appropriately. | ||
| 767 | */ | ||
| 768 | |||
| 769 | static void init_hwif_scc(ide_hwif_t *hwif) | ||
| 770 | { | ||
| 771 | /* PTERADD */ | ||
| 772 | out_be32((void __iomem *)(hwif->dma_base + 0x018), hwif->dmatable_dma); | ||
| 773 | |||
| 774 | if (in_be32((void __iomem *)(hwif->config_data + 0xff0)) & CCKCTRL_ATACLKOEN) | ||
| 775 | hwif->ultra_mask = ATA_UDMA6; /* 133MHz */ | ||
| 776 | else | ||
| 777 | hwif->ultra_mask = ATA_UDMA5; /* 100MHz */ | ||
| 778 | } | ||
| 779 | |||
| 780 | static const struct ide_tp_ops scc_tp_ops = { | ||
| 781 | .exec_command = scc_exec_command, | ||
| 782 | .read_status = scc_read_status, | ||
| 783 | .read_altstatus = scc_read_altstatus, | ||
| 784 | .write_devctl = scc_write_devctl, | ||
| 785 | |||
| 786 | .dev_select = ide_dev_select, | ||
| 787 | .tf_load = scc_tf_load, | ||
| 788 | .tf_read = scc_tf_read, | ||
| 789 | |||
| 790 | .input_data = scc_input_data, | ||
| 791 | .output_data = scc_output_data, | ||
| 792 | }; | ||
| 793 | |||
| 794 | static const struct ide_port_ops scc_port_ops = { | ||
| 795 | .set_pio_mode = scc_set_pio_mode, | ||
| 796 | .set_dma_mode = scc_set_dma_mode, | ||
| 797 | .udma_filter = scc_udma_filter, | ||
| 798 | .cable_detect = scc_cable_detect, | ||
| 799 | }; | ||
| 800 | |||
| 801 | static const struct ide_dma_ops scc_dma_ops = { | ||
| 802 | .dma_host_set = scc_dma_host_set, | ||
| 803 | .dma_setup = scc_dma_setup, | ||
| 804 | .dma_start = scc_dma_start, | ||
| 805 | .dma_end = scc_dma_end, | ||
| 806 | .dma_test_irq = scc_dma_test_irq, | ||
| 807 | .dma_lost_irq = ide_dma_lost_irq, | ||
| 808 | .dma_timer_expiry = ide_dma_sff_timer_expiry, | ||
| 809 | .dma_sff_read_status = scc_dma_sff_read_status, | ||
| 810 | }; | ||
| 811 | |||
| 812 | static const struct ide_port_info scc_chipset = { | ||
| 813 | .name = "sccIDE", | ||
| 814 | .init_iops = init_iops_scc, | ||
| 815 | .init_dma = scc_init_dma, | ||
| 816 | .init_hwif = init_hwif_scc, | ||
| 817 | .tp_ops = &scc_tp_ops, | ||
| 818 | .port_ops = &scc_port_ops, | ||
| 819 | .dma_ops = &scc_dma_ops, | ||
| 820 | .host_flags = IDE_HFLAG_SINGLE, | ||
| 821 | .irq_flags = IRQF_SHARED, | ||
| 822 | .pio_mask = ATA_PIO4, | ||
| 823 | .chipset = ide_pci, | ||
| 824 | }; | ||
| 825 | |||
| 826 | /** | ||
| 827 | * scc_init_one - pci layer discovery entry | ||
| 828 | * @dev: PCI device | ||
| 829 | * @id: ident table entry | ||
| 830 | * | ||
| 831 | * Called by the PCI code when it finds an SCC PATA controller. | ||
| 832 | * We then use the IDE PCI generic helper to do most of the work. | ||
| 833 | */ | ||
| 834 | |||
| 835 | static int scc_init_one(struct pci_dev *dev, const struct pci_device_id *id) | ||
| 836 | { | ||
| 837 | return init_setup_scc(dev, &scc_chipset); | ||
| 838 | } | ||
| 839 | |||
| 840 | /** | ||
| 841 | * scc_remove - pci layer remove entry | ||
| 842 | * @dev: PCI device | ||
| 843 | * | ||
| 844 | * Called by the PCI code when it removes an SCC PATA controller. | ||
| 845 | */ | ||
| 846 | |||
| 847 | static void scc_remove(struct pci_dev *dev) | ||
| 848 | { | ||
| 849 | struct scc_ports *ports = pci_get_drvdata(dev); | ||
| 850 | struct ide_host *host = ports->host; | ||
| 851 | |||
| 852 | ide_host_remove(host); | ||
| 853 | |||
| 854 | iounmap((void*)ports->dma); | ||
| 855 | iounmap((void*)ports->ctl); | ||
| 856 | pci_release_selected_regions(dev, (1 << 2) - 1); | ||
| 857 | memset(ports, 0, sizeof(*ports)); | ||
| 858 | } | ||
| 859 | |||
| 860 | static const struct pci_device_id scc_pci_tbl[] = { | ||
| 861 | { PCI_VDEVICE(TOSHIBA_2, PCI_DEVICE_ID_TOSHIBA_SCC_ATA), 0 }, | ||
| 862 | { 0, }, | ||
| 863 | }; | ||
| 864 | MODULE_DEVICE_TABLE(pci, scc_pci_tbl); | ||
| 865 | |||
| 866 | static struct pci_driver scc_pci_driver = { | ||
| 867 | .name = "SCC IDE", | ||
| 868 | .id_table = scc_pci_tbl, | ||
| 869 | .probe = scc_init_one, | ||
| 870 | .remove = scc_remove, | ||
| 871 | }; | ||
| 872 | |||
| 873 | static int __init scc_ide_init(void) | ||
| 874 | { | ||
| 875 | return ide_pci_register_driver(&scc_pci_driver); | ||
| 876 | } | ||
| 877 | |||
| 878 | static void __exit scc_ide_exit(void) | ||
| 879 | { | ||
| 880 | pci_unregister_driver(&scc_pci_driver); | ||
| 881 | } | ||
| 882 | |||
| 883 | module_init(scc_ide_init); | ||
| 884 | module_exit(scc_ide_exit); | ||
| 885 | |||
| 886 | MODULE_DESCRIPTION("PCI driver module for Toshiba SCC IDE"); | ||
| 887 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/iio/accel/mma9551_core.c b/drivers/iio/accel/mma9551_core.c index 7f55a6d7cd03..c6d5a3a40b60 100644 --- a/drivers/iio/accel/mma9551_core.c +++ b/drivers/iio/accel/mma9551_core.c | |||
| @@ -389,7 +389,12 @@ int mma9551_read_config_words(struct i2c_client *client, u8 app_id, | |||
| 389 | { | 389 | { |
| 390 | int ret, i; | 390 | int ret, i; |
| 391 | int len_words = len / sizeof(u16); | 391 | int len_words = len / sizeof(u16); |
| 392 | __be16 be_buf[MMA9551_MAX_MAILBOX_DATA_REGS]; | 392 | __be16 be_buf[MMA9551_MAX_MAILBOX_DATA_REGS / 2]; |
| 393 | |||
| 394 | if (len_words > ARRAY_SIZE(be_buf)) { | ||
| 395 | dev_err(&client->dev, "Invalid buffer size %d\n", len); | ||
| 396 | return -EINVAL; | ||
| 397 | } | ||
| 393 | 398 | ||
| 394 | ret = mma9551_transfer(client, app_id, MMA9551_CMD_READ_CONFIG, | 399 | ret = mma9551_transfer(client, app_id, MMA9551_CMD_READ_CONFIG, |
| 395 | reg, NULL, 0, (u8 *) be_buf, len); | 400 | reg, NULL, 0, (u8 *) be_buf, len); |
| @@ -424,7 +429,12 @@ int mma9551_read_status_words(struct i2c_client *client, u8 app_id, | |||
| 424 | { | 429 | { |
| 425 | int ret, i; | 430 | int ret, i; |
| 426 | int len_words = len / sizeof(u16); | 431 | int len_words = len / sizeof(u16); |
| 427 | __be16 be_buf[MMA9551_MAX_MAILBOX_DATA_REGS]; | 432 | __be16 be_buf[MMA9551_MAX_MAILBOX_DATA_REGS / 2]; |
| 433 | |||
| 434 | if (len_words > ARRAY_SIZE(be_buf)) { | ||
| 435 | dev_err(&client->dev, "Invalid buffer size %d\n", len); | ||
| 436 | return -EINVAL; | ||
| 437 | } | ||
| 428 | 438 | ||
| 429 | ret = mma9551_transfer(client, app_id, MMA9551_CMD_READ_STATUS, | 439 | ret = mma9551_transfer(client, app_id, MMA9551_CMD_READ_STATUS, |
| 430 | reg, NULL, 0, (u8 *) be_buf, len); | 440 | reg, NULL, 0, (u8 *) be_buf, len); |
| @@ -459,7 +469,12 @@ int mma9551_write_config_words(struct i2c_client *client, u8 app_id, | |||
| 459 | { | 469 | { |
| 460 | int i; | 470 | int i; |
| 461 | int len_words = len / sizeof(u16); | 471 | int len_words = len / sizeof(u16); |
| 462 | __be16 be_buf[MMA9551_MAX_MAILBOX_DATA_REGS]; | 472 | __be16 be_buf[(MMA9551_MAX_MAILBOX_DATA_REGS - 1) / 2]; |
| 473 | |||
| 474 | if (len_words > ARRAY_SIZE(be_buf)) { | ||
| 475 | dev_err(&client->dev, "Invalid buffer size %d\n", len); | ||
| 476 | return -EINVAL; | ||
| 477 | } | ||
| 463 | 478 | ||
| 464 | for (i = 0; i < len_words; i++) | 479 | for (i = 0; i < len_words; i++) |
| 465 | be_buf[i] = cpu_to_be16(buf[i]); | 480 | be_buf[i] = cpu_to_be16(buf[i]); |
diff --git a/drivers/iio/accel/mma9553.c b/drivers/iio/accel/mma9553.c index 2df1af7d43fc..365a109aaaef 100644 --- a/drivers/iio/accel/mma9553.c +++ b/drivers/iio/accel/mma9553.c | |||
| @@ -54,6 +54,7 @@ | |||
| 54 | #define MMA9553_MASK_CONF_STEPCOALESCE GENMASK(7, 0) | 54 | #define MMA9553_MASK_CONF_STEPCOALESCE GENMASK(7, 0) |
| 55 | 55 | ||
| 56 | #define MMA9553_REG_CONF_ACTTHD 0x0E | 56 | #define MMA9553_REG_CONF_ACTTHD 0x0E |
| 57 | #define MMA9553_MAX_ACTTHD GENMASK(15, 0) | ||
| 57 | 58 | ||
| 58 | /* Pedometer status registers (R-only) */ | 59 | /* Pedometer status registers (R-only) */ |
| 59 | #define MMA9553_REG_STATUS 0x00 | 60 | #define MMA9553_REG_STATUS 0x00 |
| @@ -316,22 +317,19 @@ static int mma9553_set_config(struct mma9553_data *data, u16 reg, | |||
| 316 | static int mma9553_read_activity_stepcnt(struct mma9553_data *data, | 317 | static int mma9553_read_activity_stepcnt(struct mma9553_data *data, |
| 317 | u8 *activity, u16 *stepcnt) | 318 | u8 *activity, u16 *stepcnt) |
| 318 | { | 319 | { |
| 319 | u32 status_stepcnt; | 320 | u16 buf[2]; |
| 320 | u16 status; | ||
| 321 | int ret; | 321 | int ret; |
| 322 | 322 | ||
| 323 | ret = mma9551_read_status_words(data->client, MMA9551_APPID_PEDOMETER, | 323 | ret = mma9551_read_status_words(data->client, MMA9551_APPID_PEDOMETER, |
| 324 | MMA9553_REG_STATUS, sizeof(u32), | 324 | MMA9553_REG_STATUS, sizeof(u32), buf); |
| 325 | (u16 *) &status_stepcnt); | ||
| 326 | if (ret < 0) { | 325 | if (ret < 0) { |
| 327 | dev_err(&data->client->dev, | 326 | dev_err(&data->client->dev, |
| 328 | "error reading status and stepcnt\n"); | 327 | "error reading status and stepcnt\n"); |
| 329 | return ret; | 328 | return ret; |
| 330 | } | 329 | } |
| 331 | 330 | ||
| 332 | status = status_stepcnt & MMA9553_MASK_CONF_WORD; | 331 | *activity = mma9553_get_bits(buf[0], MMA9553_MASK_STATUS_ACTIVITY); |
| 333 | *activity = mma9553_get_bits(status, MMA9553_MASK_STATUS_ACTIVITY); | 332 | *stepcnt = buf[1]; |
| 334 | *stepcnt = status_stepcnt >> 16; | ||
| 335 | 333 | ||
| 336 | return 0; | 334 | return 0; |
| 337 | } | 335 | } |
| @@ -872,6 +870,9 @@ static int mma9553_write_event_value(struct iio_dev *indio_dev, | |||
| 872 | case IIO_EV_INFO_PERIOD: | 870 | case IIO_EV_INFO_PERIOD: |
| 873 | switch (chan->type) { | 871 | switch (chan->type) { |
| 874 | case IIO_ACTIVITY: | 872 | case IIO_ACTIVITY: |
| 873 | if (val < 0 || val > MMA9553_ACTIVITY_THD_TO_SEC( | ||
| 874 | MMA9553_MAX_ACTTHD)) | ||
| 875 | return -EINVAL; | ||
| 875 | mutex_lock(&data->mutex); | 876 | mutex_lock(&data->mutex); |
| 876 | ret = mma9553_set_config(data, MMA9553_REG_CONF_ACTTHD, | 877 | ret = mma9553_set_config(data, MMA9553_REG_CONF_ACTTHD, |
| 877 | &data->conf.actthd, | 878 | &data->conf.actthd, |
| @@ -971,7 +972,8 @@ static const struct iio_chan_spec_ext_info mma9553_ext_info[] = { | |||
| 971 | .modified = 1, \ | 972 | .modified = 1, \ |
| 972 | .channel2 = _chan2, \ | 973 | .channel2 = _chan2, \ |
| 973 | .info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED), \ | 974 | .info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED), \ |
| 974 | .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_CALIBHEIGHT), \ | 975 | .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_CALIBHEIGHT) | \ |
| 976 | BIT(IIO_CHAN_INFO_ENABLE), \ | ||
| 975 | .event_spec = mma9553_activity_events, \ | 977 | .event_spec = mma9553_activity_events, \ |
| 976 | .num_event_specs = ARRAY_SIZE(mma9553_activity_events), \ | 978 | .num_event_specs = ARRAY_SIZE(mma9553_activity_events), \ |
| 977 | .ext_info = mma9553_ext_info, \ | 979 | .ext_info = mma9553_ext_info, \ |
diff --git a/drivers/iio/accel/st_accel_core.c b/drivers/iio/accel/st_accel_core.c index 58d1d13d552a..211b13271c61 100644 --- a/drivers/iio/accel/st_accel_core.c +++ b/drivers/iio/accel/st_accel_core.c | |||
| @@ -546,6 +546,7 @@ int st_accel_common_probe(struct iio_dev *indio_dev) | |||
| 546 | 546 | ||
| 547 | indio_dev->modes = INDIO_DIRECT_MODE; | 547 | indio_dev->modes = INDIO_DIRECT_MODE; |
| 548 | indio_dev->info = &accel_info; | 548 | indio_dev->info = &accel_info; |
| 549 | mutex_init(&adata->tb.buf_lock); | ||
| 549 | 550 | ||
| 550 | st_sensors_power_enable(indio_dev); | 551 | st_sensors_power_enable(indio_dev); |
| 551 | 552 | ||
diff --git a/drivers/iio/adc/axp288_adc.c b/drivers/iio/adc/axp288_adc.c index 08bcfb061ca5..56008a86b78f 100644 --- a/drivers/iio/adc/axp288_adc.c +++ b/drivers/iio/adc/axp288_adc.c | |||
| @@ -53,39 +53,42 @@ static const struct iio_chan_spec const axp288_adc_channels[] = { | |||
| 53 | .channel = 0, | 53 | .channel = 0, |
| 54 | .address = AXP288_TS_ADC_H, | 54 | .address = AXP288_TS_ADC_H, |
| 55 | .datasheet_name = "TS_PIN", | 55 | .datasheet_name = "TS_PIN", |
| 56 | .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), | ||
| 56 | }, { | 57 | }, { |
| 57 | .indexed = 1, | 58 | .indexed = 1, |
| 58 | .type = IIO_TEMP, | 59 | .type = IIO_TEMP, |
| 59 | .channel = 1, | 60 | .channel = 1, |
| 60 | .address = AXP288_PMIC_ADC_H, | 61 | .address = AXP288_PMIC_ADC_H, |
| 61 | .datasheet_name = "PMIC_TEMP", | 62 | .datasheet_name = "PMIC_TEMP", |
| 63 | .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), | ||
| 62 | }, { | 64 | }, { |
| 63 | .indexed = 1, | 65 | .indexed = 1, |
| 64 | .type = IIO_TEMP, | 66 | .type = IIO_TEMP, |
| 65 | .channel = 2, | 67 | .channel = 2, |
| 66 | .address = AXP288_GP_ADC_H, | 68 | .address = AXP288_GP_ADC_H, |
| 67 | .datasheet_name = "GPADC", | 69 | .datasheet_name = "GPADC", |
| 70 | .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), | ||
| 68 | }, { | 71 | }, { |
| 69 | .indexed = 1, | 72 | .indexed = 1, |
| 70 | .type = IIO_CURRENT, | 73 | .type = IIO_CURRENT, |
| 71 | .channel = 3, | 74 | .channel = 3, |
| 72 | .address = AXP20X_BATT_CHRG_I_H, | 75 | .address = AXP20X_BATT_CHRG_I_H, |
| 73 | .datasheet_name = "BATT_CHG_I", | 76 | .datasheet_name = "BATT_CHG_I", |
| 74 | .info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED), | 77 | .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), |
| 75 | }, { | 78 | }, { |
| 76 | .indexed = 1, | 79 | .indexed = 1, |
| 77 | .type = IIO_CURRENT, | 80 | .type = IIO_CURRENT, |
| 78 | .channel = 4, | 81 | .channel = 4, |
| 79 | .address = AXP20X_BATT_DISCHRG_I_H, | 82 | .address = AXP20X_BATT_DISCHRG_I_H, |
| 80 | .datasheet_name = "BATT_DISCHRG_I", | 83 | .datasheet_name = "BATT_DISCHRG_I", |
| 81 | .info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED), | 84 | .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), |
| 82 | }, { | 85 | }, { |
| 83 | .indexed = 1, | 86 | .indexed = 1, |
| 84 | .type = IIO_VOLTAGE, | 87 | .type = IIO_VOLTAGE, |
| 85 | .channel = 5, | 88 | .channel = 5, |
| 86 | .address = AXP20X_BATT_V_H, | 89 | .address = AXP20X_BATT_V_H, |
| 87 | .datasheet_name = "BATT_V", | 90 | .datasheet_name = "BATT_V", |
| 88 | .info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED), | 91 | .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), |
| 89 | }, | 92 | }, |
| 90 | }; | 93 | }; |
| 91 | 94 | ||
| @@ -151,9 +154,6 @@ static int axp288_adc_read_raw(struct iio_dev *indio_dev, | |||
| 151 | chan->address)) | 154 | chan->address)) |
| 152 | dev_err(&indio_dev->dev, "TS pin restore\n"); | 155 | dev_err(&indio_dev->dev, "TS pin restore\n"); |
| 153 | break; | 156 | break; |
| 154 | case IIO_CHAN_INFO_PROCESSED: | ||
| 155 | ret = axp288_adc_read_channel(val, chan->address, info->regmap); | ||
| 156 | break; | ||
| 157 | default: | 157 | default: |
| 158 | ret = -EINVAL; | 158 | ret = -EINVAL; |
| 159 | } | 159 | } |
diff --git a/drivers/iio/adc/cc10001_adc.c b/drivers/iio/adc/cc10001_adc.c index 51e2a83c9404..115f6e99a7fa 100644 --- a/drivers/iio/adc/cc10001_adc.c +++ b/drivers/iio/adc/cc10001_adc.c | |||
| @@ -35,8 +35,9 @@ | |||
| 35 | #define CC10001_ADC_EOC_SET BIT(0) | 35 | #define CC10001_ADC_EOC_SET BIT(0) |
| 36 | 36 | ||
| 37 | #define CC10001_ADC_CHSEL_SAMPLED 0x0c | 37 | #define CC10001_ADC_CHSEL_SAMPLED 0x0c |
| 38 | #define CC10001_ADC_POWER_UP 0x10 | 38 | #define CC10001_ADC_POWER_DOWN 0x10 |
| 39 | #define CC10001_ADC_POWER_UP_SET BIT(0) | 39 | #define CC10001_ADC_POWER_DOWN_SET BIT(0) |
| 40 | |||
| 40 | #define CC10001_ADC_DEBUG 0x14 | 41 | #define CC10001_ADC_DEBUG 0x14 |
| 41 | #define CC10001_ADC_DATA_COUNT 0x20 | 42 | #define CC10001_ADC_DATA_COUNT 0x20 |
| 42 | 43 | ||
| @@ -62,7 +63,6 @@ struct cc10001_adc_device { | |||
| 62 | u16 *buf; | 63 | u16 *buf; |
| 63 | 64 | ||
| 64 | struct mutex lock; | 65 | struct mutex lock; |
| 65 | unsigned long channel_map; | ||
| 66 | unsigned int start_delay_ns; | 66 | unsigned int start_delay_ns; |
| 67 | unsigned int eoc_delay_ns; | 67 | unsigned int eoc_delay_ns; |
| 68 | }; | 68 | }; |
| @@ -79,6 +79,18 @@ static inline u32 cc10001_adc_read_reg(struct cc10001_adc_device *adc_dev, | |||
| 79 | return readl(adc_dev->reg_base + reg); | 79 | return readl(adc_dev->reg_base + reg); |
| 80 | } | 80 | } |
| 81 | 81 | ||
| 82 | static void cc10001_adc_power_up(struct cc10001_adc_device *adc_dev) | ||
| 83 | { | ||
| 84 | cc10001_adc_write_reg(adc_dev, CC10001_ADC_POWER_DOWN, 0); | ||
| 85 | ndelay(adc_dev->start_delay_ns); | ||
| 86 | } | ||
| 87 | |||
| 88 | static void cc10001_adc_power_down(struct cc10001_adc_device *adc_dev) | ||
| 89 | { | ||
| 90 | cc10001_adc_write_reg(adc_dev, CC10001_ADC_POWER_DOWN, | ||
| 91 | CC10001_ADC_POWER_DOWN_SET); | ||
| 92 | } | ||
| 93 | |||
| 82 | static void cc10001_adc_start(struct cc10001_adc_device *adc_dev, | 94 | static void cc10001_adc_start(struct cc10001_adc_device *adc_dev, |
| 83 | unsigned int channel) | 95 | unsigned int channel) |
| 84 | { | 96 | { |
| @@ -88,6 +100,7 @@ static void cc10001_adc_start(struct cc10001_adc_device *adc_dev, | |||
| 88 | val = (channel & CC10001_ADC_CH_MASK) | CC10001_ADC_MODE_SINGLE_CONV; | 100 | val = (channel & CC10001_ADC_CH_MASK) | CC10001_ADC_MODE_SINGLE_CONV; |
| 89 | cc10001_adc_write_reg(adc_dev, CC10001_ADC_CONFIG, val); | 101 | cc10001_adc_write_reg(adc_dev, CC10001_ADC_CONFIG, val); |
| 90 | 102 | ||
| 103 | udelay(1); | ||
| 91 | val = cc10001_adc_read_reg(adc_dev, CC10001_ADC_CONFIG); | 104 | val = cc10001_adc_read_reg(adc_dev, CC10001_ADC_CONFIG); |
| 92 | val = val | CC10001_ADC_START_CONV; | 105 | val = val | CC10001_ADC_START_CONV; |
| 93 | cc10001_adc_write_reg(adc_dev, CC10001_ADC_CONFIG, val); | 106 | cc10001_adc_write_reg(adc_dev, CC10001_ADC_CONFIG, val); |
| @@ -129,6 +142,7 @@ static irqreturn_t cc10001_adc_trigger_h(int irq, void *p) | |||
| 129 | struct iio_dev *indio_dev; | 142 | struct iio_dev *indio_dev; |
| 130 | unsigned int delay_ns; | 143 | unsigned int delay_ns; |
| 131 | unsigned int channel; | 144 | unsigned int channel; |
| 145 | unsigned int scan_idx; | ||
| 132 | bool sample_invalid; | 146 | bool sample_invalid; |
| 133 | u16 *data; | 147 | u16 *data; |
| 134 | int i; | 148 | int i; |
| @@ -139,20 +153,17 @@ static irqreturn_t cc10001_adc_trigger_h(int irq, void *p) | |||
| 139 | 153 | ||
| 140 | mutex_lock(&adc_dev->lock); | 154 | mutex_lock(&adc_dev->lock); |
| 141 | 155 | ||
| 142 | cc10001_adc_write_reg(adc_dev, CC10001_ADC_POWER_UP, | 156 | cc10001_adc_power_up(adc_dev); |
| 143 | CC10001_ADC_POWER_UP_SET); | ||
| 144 | |||
| 145 | /* Wait for 8 (6+2) clock cycles before activating START */ | ||
| 146 | ndelay(adc_dev->start_delay_ns); | ||
| 147 | 157 | ||
| 148 | /* Calculate delay step for eoc and sampled data */ | 158 | /* Calculate delay step for eoc and sampled data */ |
| 149 | delay_ns = adc_dev->eoc_delay_ns / CC10001_MAX_POLL_COUNT; | 159 | delay_ns = adc_dev->eoc_delay_ns / CC10001_MAX_POLL_COUNT; |
| 150 | 160 | ||
| 151 | i = 0; | 161 | i = 0; |
| 152 | sample_invalid = false; | 162 | sample_invalid = false; |
| 153 | for_each_set_bit(channel, indio_dev->active_scan_mask, | 163 | for_each_set_bit(scan_idx, indio_dev->active_scan_mask, |
| 154 | indio_dev->masklength) { | 164 | indio_dev->masklength) { |
| 155 | 165 | ||
| 166 | channel = indio_dev->channels[scan_idx].channel; | ||
| 156 | cc10001_adc_start(adc_dev, channel); | 167 | cc10001_adc_start(adc_dev, channel); |
| 157 | 168 | ||
| 158 | data[i] = cc10001_adc_poll_done(indio_dev, channel, delay_ns); | 169 | data[i] = cc10001_adc_poll_done(indio_dev, channel, delay_ns); |
| @@ -166,7 +177,7 @@ static irqreturn_t cc10001_adc_trigger_h(int irq, void *p) | |||
| 166 | } | 177 | } |
| 167 | 178 | ||
| 168 | done: | 179 | done: |
| 169 | cc10001_adc_write_reg(adc_dev, CC10001_ADC_POWER_UP, 0); | 180 | cc10001_adc_power_down(adc_dev); |
| 170 | 181 | ||
| 171 | mutex_unlock(&adc_dev->lock); | 182 | mutex_unlock(&adc_dev->lock); |
| 172 | 183 | ||
| @@ -185,11 +196,7 @@ static u16 cc10001_adc_read_raw_voltage(struct iio_dev *indio_dev, | |||
| 185 | unsigned int delay_ns; | 196 | unsigned int delay_ns; |
| 186 | u16 val; | 197 | u16 val; |
| 187 | 198 | ||
| 188 | cc10001_adc_write_reg(adc_dev, CC10001_ADC_POWER_UP, | 199 | cc10001_adc_power_up(adc_dev); |
| 189 | CC10001_ADC_POWER_UP_SET); | ||
| 190 | |||
| 191 | /* Wait for 8 (6+2) clock cycles before activating START */ | ||
| 192 | ndelay(adc_dev->start_delay_ns); | ||
| 193 | 200 | ||
| 194 | /* Calculate delay step for eoc and sampled data */ | 201 | /* Calculate delay step for eoc and sampled data */ |
| 195 | delay_ns = adc_dev->eoc_delay_ns / CC10001_MAX_POLL_COUNT; | 202 | delay_ns = adc_dev->eoc_delay_ns / CC10001_MAX_POLL_COUNT; |
| @@ -198,7 +205,7 @@ static u16 cc10001_adc_read_raw_voltage(struct iio_dev *indio_dev, | |||
| 198 | 205 | ||
| 199 | val = cc10001_adc_poll_done(indio_dev, chan->channel, delay_ns); | 206 | val = cc10001_adc_poll_done(indio_dev, chan->channel, delay_ns); |
| 200 | 207 | ||
| 201 | cc10001_adc_write_reg(adc_dev, CC10001_ADC_POWER_UP, 0); | 208 | cc10001_adc_power_down(adc_dev); |
| 202 | 209 | ||
| 203 | return val; | 210 | return val; |
| 204 | } | 211 | } |
| @@ -224,7 +231,7 @@ static int cc10001_adc_read_raw(struct iio_dev *indio_dev, | |||
| 224 | 231 | ||
| 225 | case IIO_CHAN_INFO_SCALE: | 232 | case IIO_CHAN_INFO_SCALE: |
| 226 | ret = regulator_get_voltage(adc_dev->reg); | 233 | ret = regulator_get_voltage(adc_dev->reg); |
| 227 | if (ret) | 234 | if (ret < 0) |
| 228 | return ret; | 235 | return ret; |
| 229 | 236 | ||
| 230 | *val = ret / 1000; | 237 | *val = ret / 1000; |
| @@ -255,22 +262,22 @@ static const struct iio_info cc10001_adc_info = { | |||
| 255 | .update_scan_mode = &cc10001_update_scan_mode, | 262 | .update_scan_mode = &cc10001_update_scan_mode, |
| 256 | }; | 263 | }; |
| 257 | 264 | ||
| 258 | static int cc10001_adc_channel_init(struct iio_dev *indio_dev) | 265 | static int cc10001_adc_channel_init(struct iio_dev *indio_dev, |
| 266 | unsigned long channel_map) | ||
| 259 | { | 267 | { |
| 260 | struct cc10001_adc_device *adc_dev = iio_priv(indio_dev); | ||
| 261 | struct iio_chan_spec *chan_array, *timestamp; | 268 | struct iio_chan_spec *chan_array, *timestamp; |
| 262 | unsigned int bit, idx = 0; | 269 | unsigned int bit, idx = 0; |
| 263 | 270 | ||
| 264 | indio_dev->num_channels = bitmap_weight(&adc_dev->channel_map, | 271 | indio_dev->num_channels = bitmap_weight(&channel_map, |
| 265 | CC10001_ADC_NUM_CHANNELS); | 272 | CC10001_ADC_NUM_CHANNELS) + 1; |
| 266 | 273 | ||
| 267 | chan_array = devm_kcalloc(&indio_dev->dev, indio_dev->num_channels + 1, | 274 | chan_array = devm_kcalloc(&indio_dev->dev, indio_dev->num_channels, |
| 268 | sizeof(struct iio_chan_spec), | 275 | sizeof(struct iio_chan_spec), |
| 269 | GFP_KERNEL); | 276 | GFP_KERNEL); |
| 270 | if (!chan_array) | 277 | if (!chan_array) |
| 271 | return -ENOMEM; | 278 | return -ENOMEM; |
| 272 | 279 | ||
| 273 | for_each_set_bit(bit, &adc_dev->channel_map, CC10001_ADC_NUM_CHANNELS) { | 280 | for_each_set_bit(bit, &channel_map, CC10001_ADC_NUM_CHANNELS) { |
| 274 | struct iio_chan_spec *chan = &chan_array[idx]; | 281 | struct iio_chan_spec *chan = &chan_array[idx]; |
| 275 | 282 | ||
| 276 | chan->type = IIO_VOLTAGE; | 283 | chan->type = IIO_VOLTAGE; |
| @@ -305,6 +312,7 @@ static int cc10001_adc_probe(struct platform_device *pdev) | |||
| 305 | unsigned long adc_clk_rate; | 312 | unsigned long adc_clk_rate; |
| 306 | struct resource *res; | 313 | struct resource *res; |
| 307 | struct iio_dev *indio_dev; | 314 | struct iio_dev *indio_dev; |
| 315 | unsigned long channel_map; | ||
| 308 | int ret; | 316 | int ret; |
| 309 | 317 | ||
| 310 | indio_dev = devm_iio_device_alloc(&pdev->dev, sizeof(*adc_dev)); | 318 | indio_dev = devm_iio_device_alloc(&pdev->dev, sizeof(*adc_dev)); |
| @@ -313,9 +321,9 @@ static int cc10001_adc_probe(struct platform_device *pdev) | |||
| 313 | 321 | ||
| 314 | adc_dev = iio_priv(indio_dev); | 322 | adc_dev = iio_priv(indio_dev); |
| 315 | 323 | ||
| 316 | adc_dev->channel_map = GENMASK(CC10001_ADC_NUM_CHANNELS - 1, 0); | 324 | channel_map = GENMASK(CC10001_ADC_NUM_CHANNELS - 1, 0); |
| 317 | if (!of_property_read_u32(node, "adc-reserved-channels", &ret)) | 325 | if (!of_property_read_u32(node, "adc-reserved-channels", &ret)) |
| 318 | adc_dev->channel_map &= ~ret; | 326 | channel_map &= ~ret; |
| 319 | 327 | ||
| 320 | adc_dev->reg = devm_regulator_get(&pdev->dev, "vref"); | 328 | adc_dev->reg = devm_regulator_get(&pdev->dev, "vref"); |
| 321 | if (IS_ERR(adc_dev->reg)) | 329 | if (IS_ERR(adc_dev->reg)) |
| @@ -361,7 +369,7 @@ static int cc10001_adc_probe(struct platform_device *pdev) | |||
| 361 | adc_dev->start_delay_ns = adc_dev->eoc_delay_ns * CC10001_WAIT_CYCLES; | 369 | adc_dev->start_delay_ns = adc_dev->eoc_delay_ns * CC10001_WAIT_CYCLES; |
| 362 | 370 | ||
| 363 | /* Setup the ADC channels available on the device */ | 371 | /* Setup the ADC channels available on the device */ |
| 364 | ret = cc10001_adc_channel_init(indio_dev); | 372 | ret = cc10001_adc_channel_init(indio_dev, channel_map); |
| 365 | if (ret < 0) | 373 | if (ret < 0) |
| 366 | goto err_disable_clk; | 374 | goto err_disable_clk; |
| 367 | 375 | ||
diff --git a/drivers/iio/adc/mcp320x.c b/drivers/iio/adc/mcp320x.c index efbfd12a4bfd..8d9c9b9215dd 100644 --- a/drivers/iio/adc/mcp320x.c +++ b/drivers/iio/adc/mcp320x.c | |||
| @@ -60,12 +60,12 @@ struct mcp320x { | |||
| 60 | struct spi_message msg; | 60 | struct spi_message msg; |
| 61 | struct spi_transfer transfer[2]; | 61 | struct spi_transfer transfer[2]; |
| 62 | 62 | ||
| 63 | u8 tx_buf; | ||
| 64 | u8 rx_buf[2]; | ||
| 65 | |||
| 66 | struct regulator *reg; | 63 | struct regulator *reg; |
| 67 | struct mutex lock; | 64 | struct mutex lock; |
| 68 | const struct mcp320x_chip_info *chip_info; | 65 | const struct mcp320x_chip_info *chip_info; |
| 66 | |||
| 67 | u8 tx_buf ____cacheline_aligned; | ||
| 68 | u8 rx_buf[2]; | ||
| 69 | }; | 69 | }; |
| 70 | 70 | ||
| 71 | static int mcp320x_channel_to_tx_data(int device_index, | 71 | static int mcp320x_channel_to_tx_data(int device_index, |
diff --git a/drivers/iio/adc/qcom-spmi-vadc.c b/drivers/iio/adc/qcom-spmi-vadc.c index 3211729bcb0b..0c4618b4d515 100644 --- a/drivers/iio/adc/qcom-spmi-vadc.c +++ b/drivers/iio/adc/qcom-spmi-vadc.c | |||
| @@ -18,6 +18,7 @@ | |||
| 18 | #include <linux/iio/iio.h> | 18 | #include <linux/iio/iio.h> |
| 19 | #include <linux/interrupt.h> | 19 | #include <linux/interrupt.h> |
| 20 | #include <linux/kernel.h> | 20 | #include <linux/kernel.h> |
| 21 | #include <linux/math64.h> | ||
| 21 | #include <linux/module.h> | 22 | #include <linux/module.h> |
| 22 | #include <linux/of.h> | 23 | #include <linux/of.h> |
| 23 | #include <linux/platform_device.h> | 24 | #include <linux/platform_device.h> |
| @@ -471,11 +472,11 @@ static s32 vadc_calibrate(struct vadc_priv *vadc, | |||
| 471 | const struct vadc_channel_prop *prop, u16 adc_code) | 472 | const struct vadc_channel_prop *prop, u16 adc_code) |
| 472 | { | 473 | { |
| 473 | const struct vadc_prescale_ratio *prescale; | 474 | const struct vadc_prescale_ratio *prescale; |
| 474 | s32 voltage; | 475 | s64 voltage; |
| 475 | 476 | ||
| 476 | voltage = adc_code - vadc->graph[prop->calibration].gnd; | 477 | voltage = adc_code - vadc->graph[prop->calibration].gnd; |
| 477 | voltage *= vadc->graph[prop->calibration].dx; | 478 | voltage *= vadc->graph[prop->calibration].dx; |
| 478 | voltage = voltage / vadc->graph[prop->calibration].dy; | 479 | voltage = div64_s64(voltage, vadc->graph[prop->calibration].dy); |
| 479 | 480 | ||
| 480 | if (prop->calibration == VADC_CALIB_ABSOLUTE) | 481 | if (prop->calibration == VADC_CALIB_ABSOLUTE) |
| 481 | voltage += vadc->graph[prop->calibration].dx; | 482 | voltage += vadc->graph[prop->calibration].dx; |
| @@ -487,7 +488,7 @@ static s32 vadc_calibrate(struct vadc_priv *vadc, | |||
| 487 | 488 | ||
| 488 | voltage = voltage * prescale->den; | 489 | voltage = voltage * prescale->den; |
| 489 | 490 | ||
| 490 | return voltage / prescale->num; | 491 | return div64_s64(voltage, prescale->num); |
| 491 | } | 492 | } |
| 492 | 493 | ||
| 493 | static int vadc_decimation_from_dt(u32 value) | 494 | static int vadc_decimation_from_dt(u32 value) |
diff --git a/drivers/iio/adc/xilinx-xadc-core.c b/drivers/iio/adc/xilinx-xadc-core.c index a221f7329b79..ce93bd8e3f68 100644 --- a/drivers/iio/adc/xilinx-xadc-core.c +++ b/drivers/iio/adc/xilinx-xadc-core.c | |||
| @@ -856,6 +856,7 @@ static int xadc_read_raw(struct iio_dev *indio_dev, | |||
| 856 | switch (chan->address) { | 856 | switch (chan->address) { |
| 857 | case XADC_REG_VCCINT: | 857 | case XADC_REG_VCCINT: |
| 858 | case XADC_REG_VCCAUX: | 858 | case XADC_REG_VCCAUX: |
| 859 | case XADC_REG_VREFP: | ||
| 859 | case XADC_REG_VCCBRAM: | 860 | case XADC_REG_VCCBRAM: |
| 860 | case XADC_REG_VCCPINT: | 861 | case XADC_REG_VCCPINT: |
| 861 | case XADC_REG_VCCPAUX: | 862 | case XADC_REG_VCCPAUX: |
| @@ -996,7 +997,7 @@ static const struct iio_event_spec xadc_voltage_events[] = { | |||
| 996 | .num_event_specs = (_alarm) ? ARRAY_SIZE(xadc_voltage_events) : 0, \ | 997 | .num_event_specs = (_alarm) ? ARRAY_SIZE(xadc_voltage_events) : 0, \ |
| 997 | .scan_index = (_scan_index), \ | 998 | .scan_index = (_scan_index), \ |
| 998 | .scan_type = { \ | 999 | .scan_type = { \ |
| 999 | .sign = 'u', \ | 1000 | .sign = ((_addr) == XADC_REG_VREFN) ? 's' : 'u', \ |
| 1000 | .realbits = 12, \ | 1001 | .realbits = 12, \ |
| 1001 | .storagebits = 16, \ | 1002 | .storagebits = 16, \ |
| 1002 | .shift = 4, \ | 1003 | .shift = 4, \ |
| @@ -1008,7 +1009,7 @@ static const struct iio_event_spec xadc_voltage_events[] = { | |||
| 1008 | static const struct iio_chan_spec xadc_channels[] = { | 1009 | static const struct iio_chan_spec xadc_channels[] = { |
| 1009 | XADC_CHAN_TEMP(0, 8, XADC_REG_TEMP), | 1010 | XADC_CHAN_TEMP(0, 8, XADC_REG_TEMP), |
| 1010 | XADC_CHAN_VOLTAGE(0, 9, XADC_REG_VCCINT, "vccint", true), | 1011 | XADC_CHAN_VOLTAGE(0, 9, XADC_REG_VCCINT, "vccint", true), |
| 1011 | XADC_CHAN_VOLTAGE(1, 10, XADC_REG_VCCINT, "vccaux", true), | 1012 | XADC_CHAN_VOLTAGE(1, 10, XADC_REG_VCCAUX, "vccaux", true), |
| 1012 | XADC_CHAN_VOLTAGE(2, 14, XADC_REG_VCCBRAM, "vccbram", true), | 1013 | XADC_CHAN_VOLTAGE(2, 14, XADC_REG_VCCBRAM, "vccbram", true), |
| 1013 | XADC_CHAN_VOLTAGE(3, 5, XADC_REG_VCCPINT, "vccpint", true), | 1014 | XADC_CHAN_VOLTAGE(3, 5, XADC_REG_VCCPINT, "vccpint", true), |
| 1014 | XADC_CHAN_VOLTAGE(4, 6, XADC_REG_VCCPAUX, "vccpaux", true), | 1015 | XADC_CHAN_VOLTAGE(4, 6, XADC_REG_VCCPAUX, "vccpaux", true), |
diff --git a/drivers/iio/adc/xilinx-xadc.h b/drivers/iio/adc/xilinx-xadc.h index c7487e8d7f80..54adc5087210 100644 --- a/drivers/iio/adc/xilinx-xadc.h +++ b/drivers/iio/adc/xilinx-xadc.h | |||
| @@ -145,9 +145,9 @@ static inline int xadc_write_adc_reg(struct xadc *xadc, unsigned int reg, | |||
| 145 | #define XADC_REG_MAX_VCCPINT 0x28 | 145 | #define XADC_REG_MAX_VCCPINT 0x28 |
| 146 | #define XADC_REG_MAX_VCCPAUX 0x29 | 146 | #define XADC_REG_MAX_VCCPAUX 0x29 |
| 147 | #define XADC_REG_MAX_VCCO_DDR 0x2a | 147 | #define XADC_REG_MAX_VCCO_DDR 0x2a |
| 148 | #define XADC_REG_MIN_VCCPINT 0x2b | 148 | #define XADC_REG_MIN_VCCPINT 0x2c |
| 149 | #define XADC_REG_MIN_VCCPAUX 0x2c | 149 | #define XADC_REG_MIN_VCCPAUX 0x2d |
| 150 | #define XADC_REG_MIN_VCCO_DDR 0x2d | 150 | #define XADC_REG_MIN_VCCO_DDR 0x2e |
| 151 | 151 | ||
| 152 | #define XADC_REG_CONF0 0x40 | 152 | #define XADC_REG_CONF0 0x40 |
| 153 | #define XADC_REG_CONF1 0x41 | 153 | #define XADC_REG_CONF1 0x41 |
diff --git a/drivers/iio/common/st_sensors/st_sensors_core.c b/drivers/iio/common/st_sensors/st_sensors_core.c index edd13d2b4121..8dd0477e201c 100644 --- a/drivers/iio/common/st_sensors/st_sensors_core.c +++ b/drivers/iio/common/st_sensors/st_sensors_core.c | |||
| @@ -304,8 +304,6 @@ int st_sensors_init_sensor(struct iio_dev *indio_dev, | |||
| 304 | struct st_sensors_platform_data *of_pdata; | 304 | struct st_sensors_platform_data *of_pdata; |
| 305 | int err = 0; | 305 | int err = 0; |
| 306 | 306 | ||
| 307 | mutex_init(&sdata->tb.buf_lock); | ||
| 308 | |||
| 309 | /* If OF/DT pdata exists, it will take precedence of anything else */ | 307 | /* If OF/DT pdata exists, it will take precedence of anything else */ |
| 310 | of_pdata = st_sensors_of_probe(indio_dev->dev.parent, pdata); | 308 | of_pdata = st_sensors_of_probe(indio_dev->dev.parent, pdata); |
| 311 | if (of_pdata) | 309 | if (of_pdata) |
diff --git a/drivers/iio/gyro/st_gyro_core.c b/drivers/iio/gyro/st_gyro_core.c index 21395f26d227..ffe96642b6d0 100644 --- a/drivers/iio/gyro/st_gyro_core.c +++ b/drivers/iio/gyro/st_gyro_core.c | |||
| @@ -400,6 +400,7 @@ int st_gyro_common_probe(struct iio_dev *indio_dev) | |||
| 400 | 400 | ||
| 401 | indio_dev->modes = INDIO_DIRECT_MODE; | 401 | indio_dev->modes = INDIO_DIRECT_MODE; |
| 402 | indio_dev->info = &gyro_info; | 402 | indio_dev->info = &gyro_info; |
| 403 | mutex_init(&gdata->tb.buf_lock); | ||
| 403 | 404 | ||
| 404 | st_sensors_power_enable(indio_dev); | 405 | st_sensors_power_enable(indio_dev); |
| 405 | 406 | ||
diff --git a/drivers/iio/kfifo_buf.c b/drivers/iio/kfifo_buf.c index 847ca561afe0..55c267bbfd2f 100644 --- a/drivers/iio/kfifo_buf.c +++ b/drivers/iio/kfifo_buf.c | |||
| @@ -38,7 +38,8 @@ static int iio_request_update_kfifo(struct iio_buffer *r) | |||
| 38 | kfifo_free(&buf->kf); | 38 | kfifo_free(&buf->kf); |
| 39 | ret = __iio_allocate_kfifo(buf, buf->buffer.bytes_per_datum, | 39 | ret = __iio_allocate_kfifo(buf, buf->buffer.bytes_per_datum, |
| 40 | buf->buffer.length); | 40 | buf->buffer.length); |
| 41 | buf->update_needed = false; | 41 | if (ret >= 0) |
| 42 | buf->update_needed = false; | ||
| 42 | } else { | 43 | } else { |
| 43 | kfifo_reset_out(&buf->kf); | 44 | kfifo_reset_out(&buf->kf); |
| 44 | } | 45 | } |
diff --git a/drivers/iio/light/hid-sensor-prox.c b/drivers/iio/light/hid-sensor-prox.c index 91ecc46ffeaa..ef60bae738e3 100644 --- a/drivers/iio/light/hid-sensor-prox.c +++ b/drivers/iio/light/hid-sensor-prox.c | |||
| @@ -43,8 +43,6 @@ struct prox_state { | |||
| 43 | static const struct iio_chan_spec prox_channels[] = { | 43 | static const struct iio_chan_spec prox_channels[] = { |
| 44 | { | 44 | { |
| 45 | .type = IIO_PROXIMITY, | 45 | .type = IIO_PROXIMITY, |
| 46 | .modified = 1, | ||
| 47 | .channel2 = IIO_NO_MOD, | ||
| 48 | .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), | 46 | .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), |
| 49 | .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_OFFSET) | | 47 | .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_OFFSET) | |
| 50 | BIT(IIO_CHAN_INFO_SCALE) | | 48 | BIT(IIO_CHAN_INFO_SCALE) | |
| @@ -253,7 +251,6 @@ static int hid_prox_probe(struct platform_device *pdev) | |||
| 253 | struct iio_dev *indio_dev; | 251 | struct iio_dev *indio_dev; |
| 254 | struct prox_state *prox_state; | 252 | struct prox_state *prox_state; |
| 255 | struct hid_sensor_hub_device *hsdev = pdev->dev.platform_data; | 253 | struct hid_sensor_hub_device *hsdev = pdev->dev.platform_data; |
| 256 | struct iio_chan_spec *channels; | ||
| 257 | 254 | ||
| 258 | indio_dev = devm_iio_device_alloc(&pdev->dev, | 255 | indio_dev = devm_iio_device_alloc(&pdev->dev, |
| 259 | sizeof(struct prox_state)); | 256 | sizeof(struct prox_state)); |
| @@ -272,20 +269,21 @@ static int hid_prox_probe(struct platform_device *pdev) | |||
| 272 | return ret; | 269 | return ret; |
| 273 | } | 270 | } |
| 274 | 271 | ||
| 275 | channels = kmemdup(prox_channels, sizeof(prox_channels), GFP_KERNEL); | 272 | indio_dev->channels = kmemdup(prox_channels, sizeof(prox_channels), |
| 276 | if (!channels) { | 273 | GFP_KERNEL); |
| 274 | if (!indio_dev->channels) { | ||
| 277 | dev_err(&pdev->dev, "failed to duplicate channels\n"); | 275 | dev_err(&pdev->dev, "failed to duplicate channels\n"); |
| 278 | return -ENOMEM; | 276 | return -ENOMEM; |
| 279 | } | 277 | } |
| 280 | 278 | ||
| 281 | ret = prox_parse_report(pdev, hsdev, channels, | 279 | ret = prox_parse_report(pdev, hsdev, |
| 280 | (struct iio_chan_spec *)indio_dev->channels, | ||
| 282 | HID_USAGE_SENSOR_PROX, prox_state); | 281 | HID_USAGE_SENSOR_PROX, prox_state); |
| 283 | if (ret) { | 282 | if (ret) { |
| 284 | dev_err(&pdev->dev, "failed to setup attributes\n"); | 283 | dev_err(&pdev->dev, "failed to setup attributes\n"); |
| 285 | goto error_free_dev_mem; | 284 | goto error_free_dev_mem; |
| 286 | } | 285 | } |
| 287 | 286 | ||
| 288 | indio_dev->channels = channels; | ||
| 289 | indio_dev->num_channels = | 287 | indio_dev->num_channels = |
| 290 | ARRAY_SIZE(prox_channels); | 288 | ARRAY_SIZE(prox_channels); |
| 291 | indio_dev->dev.parent = &pdev->dev; | 289 | indio_dev->dev.parent = &pdev->dev; |
diff --git a/drivers/iio/magnetometer/st_magn_core.c b/drivers/iio/magnetometer/st_magn_core.c index 8ade473f99fe..2e56f812a644 100644 --- a/drivers/iio/magnetometer/st_magn_core.c +++ b/drivers/iio/magnetometer/st_magn_core.c | |||
| @@ -369,6 +369,7 @@ int st_magn_common_probe(struct iio_dev *indio_dev) | |||
| 369 | 369 | ||
| 370 | indio_dev->modes = INDIO_DIRECT_MODE; | 370 | indio_dev->modes = INDIO_DIRECT_MODE; |
| 371 | indio_dev->info = &magn_info; | 371 | indio_dev->info = &magn_info; |
| 372 | mutex_init(&mdata->tb.buf_lock); | ||
| 372 | 373 | ||
| 373 | st_sensors_power_enable(indio_dev); | 374 | st_sensors_power_enable(indio_dev); |
| 374 | 375 | ||
diff --git a/drivers/iio/pressure/bmp280.c b/drivers/iio/pressure/bmp280.c index 7c623e2bd633..a2602d8dd6d5 100644 --- a/drivers/iio/pressure/bmp280.c +++ b/drivers/iio/pressure/bmp280.c | |||
| @@ -172,6 +172,7 @@ static s32 bmp280_compensate_temp(struct bmp280_data *data, | |||
| 172 | var2 = (((((adc_temp >> 4) - ((s32)le16_to_cpu(buf[T1]))) * | 172 | var2 = (((((adc_temp >> 4) - ((s32)le16_to_cpu(buf[T1]))) * |
| 173 | ((adc_temp >> 4) - ((s32)le16_to_cpu(buf[T1])))) >> 12) * | 173 | ((adc_temp >> 4) - ((s32)le16_to_cpu(buf[T1])))) >> 12) * |
| 174 | ((s32)(s16)le16_to_cpu(buf[T3]))) >> 14; | 174 | ((s32)(s16)le16_to_cpu(buf[T3]))) >> 14; |
| 175 | data->t_fine = var1 + var2; | ||
| 175 | 176 | ||
| 176 | return (data->t_fine * 5 + 128) >> 8; | 177 | return (data->t_fine * 5 + 128) >> 8; |
| 177 | } | 178 | } |
diff --git a/drivers/iio/pressure/hid-sensor-press.c b/drivers/iio/pressure/hid-sensor-press.c index 7bb8d4c1f7df..3cf0bd67d24c 100644 --- a/drivers/iio/pressure/hid-sensor-press.c +++ b/drivers/iio/pressure/hid-sensor-press.c | |||
| @@ -47,8 +47,6 @@ struct press_state { | |||
| 47 | static const struct iio_chan_spec press_channels[] = { | 47 | static const struct iio_chan_spec press_channels[] = { |
| 48 | { | 48 | { |
| 49 | .type = IIO_PRESSURE, | 49 | .type = IIO_PRESSURE, |
| 50 | .modified = 1, | ||
| 51 | .channel2 = IIO_NO_MOD, | ||
| 52 | .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), | 50 | .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), |
| 53 | .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_OFFSET) | | 51 | .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_OFFSET) | |
| 54 | BIT(IIO_CHAN_INFO_SCALE) | | 52 | BIT(IIO_CHAN_INFO_SCALE) | |
diff --git a/drivers/iio/pressure/st_pressure_core.c b/drivers/iio/pressure/st_pressure_core.c index 97baf40d424b..e881fa6291e9 100644 --- a/drivers/iio/pressure/st_pressure_core.c +++ b/drivers/iio/pressure/st_pressure_core.c | |||
| @@ -417,6 +417,7 @@ int st_press_common_probe(struct iio_dev *indio_dev) | |||
| 417 | 417 | ||
| 418 | indio_dev->modes = INDIO_DIRECT_MODE; | 418 | indio_dev->modes = INDIO_DIRECT_MODE; |
| 419 | indio_dev->info = &press_info; | 419 | indio_dev->info = &press_info; |
| 420 | mutex_init(&press_data->tb.buf_lock); | ||
| 420 | 421 | ||
| 421 | st_sensors_power_enable(indio_dev); | 422 | st_sensors_power_enable(indio_dev); |
| 422 | 423 | ||
diff --git a/drivers/infiniband/core/addr.c b/drivers/infiniband/core/addr.c index f80da50d84a5..38339d220d7f 100644 --- a/drivers/infiniband/core/addr.c +++ b/drivers/infiniband/core/addr.c | |||
| @@ -472,13 +472,8 @@ int rdma_addr_find_dmac_by_grh(union ib_gid *sgid, union ib_gid *dgid, u8 *dmac, | |||
| 472 | } sgid_addr, dgid_addr; | 472 | } sgid_addr, dgid_addr; |
| 473 | 473 | ||
| 474 | 474 | ||
| 475 | ret = rdma_gid2ip(&sgid_addr._sockaddr, sgid); | 475 | rdma_gid2ip(&sgid_addr._sockaddr, sgid); |
| 476 | if (ret) | 476 | rdma_gid2ip(&dgid_addr._sockaddr, dgid); |
| 477 | return ret; | ||
| 478 | |||
| 479 | ret = rdma_gid2ip(&dgid_addr._sockaddr, dgid); | ||
| 480 | if (ret) | ||
| 481 | return ret; | ||
| 482 | 477 | ||
| 483 | memset(&dev_addr, 0, sizeof(dev_addr)); | 478 | memset(&dev_addr, 0, sizeof(dev_addr)); |
| 484 | 479 | ||
| @@ -512,10 +507,8 @@ int rdma_addr_find_smac_by_sgid(union ib_gid *sgid, u8 *smac, u16 *vlan_id) | |||
| 512 | struct sockaddr_in6 _sockaddr_in6; | 507 | struct sockaddr_in6 _sockaddr_in6; |
| 513 | } gid_addr; | 508 | } gid_addr; |
| 514 | 509 | ||
| 515 | ret = rdma_gid2ip(&gid_addr._sockaddr, sgid); | 510 | rdma_gid2ip(&gid_addr._sockaddr, sgid); |
| 516 | 511 | ||
| 517 | if (ret) | ||
| 518 | return ret; | ||
| 519 | memset(&dev_addr, 0, sizeof(dev_addr)); | 512 | memset(&dev_addr, 0, sizeof(dev_addr)); |
| 520 | ret = rdma_translate_ip(&gid_addr._sockaddr, &dev_addr, vlan_id); | 513 | ret = rdma_translate_ip(&gid_addr._sockaddr, &dev_addr, vlan_id); |
| 521 | if (ret) | 514 | if (ret) |
diff --git a/drivers/infiniband/core/cm.c b/drivers/infiniband/core/cm.c index e28a494e2a3a..0c1419105ff0 100644 --- a/drivers/infiniband/core/cm.c +++ b/drivers/infiniband/core/cm.c | |||
| @@ -437,39 +437,38 @@ static struct cm_id_private * cm_acquire_id(__be32 local_id, __be32 remote_id) | |||
| 437 | return cm_id_priv; | 437 | return cm_id_priv; |
| 438 | } | 438 | } |
| 439 | 439 | ||
| 440 | static void cm_mask_copy(u8 *dst, u8 *src, u8 *mask) | 440 | static void cm_mask_copy(u32 *dst, const u32 *src, const u32 *mask) |
| 441 | { | 441 | { |
| 442 | int i; | 442 | int i; |
| 443 | 443 | ||
| 444 | for (i = 0; i < IB_CM_COMPARE_SIZE / sizeof(unsigned long); i++) | 444 | for (i = 0; i < IB_CM_COMPARE_SIZE; i++) |
| 445 | ((unsigned long *) dst)[i] = ((unsigned long *) src)[i] & | 445 | dst[i] = src[i] & mask[i]; |
| 446 | ((unsigned long *) mask)[i]; | ||
| 447 | } | 446 | } |
| 448 | 447 | ||
| 449 | static int cm_compare_data(struct ib_cm_compare_data *src_data, | 448 | static int cm_compare_data(struct ib_cm_compare_data *src_data, |
| 450 | struct ib_cm_compare_data *dst_data) | 449 | struct ib_cm_compare_data *dst_data) |
| 451 | { | 450 | { |
| 452 | u8 src[IB_CM_COMPARE_SIZE]; | 451 | u32 src[IB_CM_COMPARE_SIZE]; |
| 453 | u8 dst[IB_CM_COMPARE_SIZE]; | 452 | u32 dst[IB_CM_COMPARE_SIZE]; |
| 454 | 453 | ||
| 455 | if (!src_data || !dst_data) | 454 | if (!src_data || !dst_data) |
| 456 | return 0; | 455 | return 0; |
| 457 | 456 | ||
| 458 | cm_mask_copy(src, src_data->data, dst_data->mask); | 457 | cm_mask_copy(src, src_data->data, dst_data->mask); |
| 459 | cm_mask_copy(dst, dst_data->data, src_data->mask); | 458 | cm_mask_copy(dst, dst_data->data, src_data->mask); |
| 460 | return memcmp(src, dst, IB_CM_COMPARE_SIZE); | 459 | return memcmp(src, dst, sizeof(src)); |
| 461 | } | 460 | } |
| 462 | 461 | ||
| 463 | static int cm_compare_private_data(u8 *private_data, | 462 | static int cm_compare_private_data(u32 *private_data, |
| 464 | struct ib_cm_compare_data *dst_data) | 463 | struct ib_cm_compare_data *dst_data) |
| 465 | { | 464 | { |
| 466 | u8 src[IB_CM_COMPARE_SIZE]; | 465 | u32 src[IB_CM_COMPARE_SIZE]; |
| 467 | 466 | ||
| 468 | if (!dst_data) | 467 | if (!dst_data) |
| 469 | return 0; | 468 | return 0; |
| 470 | 469 | ||
| 471 | cm_mask_copy(src, private_data, dst_data->mask); | 470 | cm_mask_copy(src, private_data, dst_data->mask); |
| 472 | return memcmp(src, dst_data->data, IB_CM_COMPARE_SIZE); | 471 | return memcmp(src, dst_data->data, sizeof(src)); |
| 473 | } | 472 | } |
| 474 | 473 | ||
| 475 | /* | 474 | /* |
| @@ -538,7 +537,7 @@ static struct cm_id_private * cm_insert_listen(struct cm_id_private *cm_id_priv) | |||
| 538 | 537 | ||
| 539 | static struct cm_id_private * cm_find_listen(struct ib_device *device, | 538 | static struct cm_id_private * cm_find_listen(struct ib_device *device, |
| 540 | __be64 service_id, | 539 | __be64 service_id, |
| 541 | u8 *private_data) | 540 | u32 *private_data) |
| 542 | { | 541 | { |
| 543 | struct rb_node *node = cm.listen_service_table.rb_node; | 542 | struct rb_node *node = cm.listen_service_table.rb_node; |
| 544 | struct cm_id_private *cm_id_priv; | 543 | struct cm_id_private *cm_id_priv; |
| @@ -953,7 +952,7 @@ int ib_cm_listen(struct ib_cm_id *cm_id, __be64 service_id, __be64 service_mask, | |||
| 953 | cm_mask_copy(cm_id_priv->compare_data->data, | 952 | cm_mask_copy(cm_id_priv->compare_data->data, |
| 954 | compare_data->data, compare_data->mask); | 953 | compare_data->data, compare_data->mask); |
| 955 | memcpy(cm_id_priv->compare_data->mask, compare_data->mask, | 954 | memcpy(cm_id_priv->compare_data->mask, compare_data->mask, |
| 956 | IB_CM_COMPARE_SIZE); | 955 | sizeof(compare_data->mask)); |
| 957 | } | 956 | } |
| 958 | 957 | ||
| 959 | cm_id->state = IB_CM_LISTEN; | 958 | cm_id->state = IB_CM_LISTEN; |
diff --git a/drivers/infiniband/core/cm_msgs.h b/drivers/infiniband/core/cm_msgs.h index be068f47e47e..8b76f0ef965e 100644 --- a/drivers/infiniband/core/cm_msgs.h +++ b/drivers/infiniband/core/cm_msgs.h | |||
| @@ -103,7 +103,7 @@ struct cm_req_msg { | |||
| 103 | /* local ACK timeout:5, rsvd:3 */ | 103 | /* local ACK timeout:5, rsvd:3 */ |
| 104 | u8 alt_offset139; | 104 | u8 alt_offset139; |
| 105 | 105 | ||
| 106 | u8 private_data[IB_CM_REQ_PRIVATE_DATA_SIZE]; | 106 | u32 private_data[IB_CM_REQ_PRIVATE_DATA_SIZE / sizeof(u32)]; |
| 107 | 107 | ||
| 108 | } __attribute__ ((packed)); | 108 | } __attribute__ ((packed)); |
| 109 | 109 | ||
| @@ -801,7 +801,7 @@ struct cm_sidr_req_msg { | |||
| 801 | __be16 rsvd; | 801 | __be16 rsvd; |
| 802 | __be64 service_id; | 802 | __be64 service_id; |
| 803 | 803 | ||
| 804 | u8 private_data[IB_CM_SIDR_REQ_PRIVATE_DATA_SIZE]; | 804 | u32 private_data[IB_CM_SIDR_REQ_PRIVATE_DATA_SIZE / sizeof(u32)]; |
| 805 | } __attribute__ ((packed)); | 805 | } __attribute__ ((packed)); |
| 806 | 806 | ||
| 807 | struct cm_sidr_rep_msg { | 807 | struct cm_sidr_rep_msg { |
diff --git a/drivers/infiniband/core/cma.c b/drivers/infiniband/core/cma.c index d570030d899c..06441a43c3aa 100644 --- a/drivers/infiniband/core/cma.c +++ b/drivers/infiniband/core/cma.c | |||
| @@ -859,19 +859,27 @@ static void cma_save_ib_info(struct rdma_cm_id *id, struct rdma_cm_id *listen_id | |||
| 859 | memcpy(&ib->sib_addr, &path->dgid, 16); | 859 | memcpy(&ib->sib_addr, &path->dgid, 16); |
| 860 | } | 860 | } |
| 861 | 861 | ||
| 862 | static __be16 ss_get_port(const struct sockaddr_storage *ss) | ||
| 863 | { | ||
| 864 | if (ss->ss_family == AF_INET) | ||
| 865 | return ((struct sockaddr_in *)ss)->sin_port; | ||
| 866 | else if (ss->ss_family == AF_INET6) | ||
| 867 | return ((struct sockaddr_in6 *)ss)->sin6_port; | ||
| 868 | BUG(); | ||
| 869 | } | ||
| 870 | |||
| 862 | static void cma_save_ip4_info(struct rdma_cm_id *id, struct rdma_cm_id *listen_id, | 871 | static void cma_save_ip4_info(struct rdma_cm_id *id, struct rdma_cm_id *listen_id, |
| 863 | struct cma_hdr *hdr) | 872 | struct cma_hdr *hdr) |
| 864 | { | 873 | { |
| 865 | struct sockaddr_in *listen4, *ip4; | 874 | struct sockaddr_in *ip4; |
| 866 | 875 | ||
| 867 | listen4 = (struct sockaddr_in *) &listen_id->route.addr.src_addr; | ||
| 868 | ip4 = (struct sockaddr_in *) &id->route.addr.src_addr; | 876 | ip4 = (struct sockaddr_in *) &id->route.addr.src_addr; |
| 869 | ip4->sin_family = listen4->sin_family; | 877 | ip4->sin_family = AF_INET; |
| 870 | ip4->sin_addr.s_addr = hdr->dst_addr.ip4.addr; | 878 | ip4->sin_addr.s_addr = hdr->dst_addr.ip4.addr; |
| 871 | ip4->sin_port = listen4->sin_port; | 879 | ip4->sin_port = ss_get_port(&listen_id->route.addr.src_addr); |
| 872 | 880 | ||
| 873 | ip4 = (struct sockaddr_in *) &id->route.addr.dst_addr; | 881 | ip4 = (struct sockaddr_in *) &id->route.addr.dst_addr; |
| 874 | ip4->sin_family = listen4->sin_family; | 882 | ip4->sin_family = AF_INET; |
| 875 | ip4->sin_addr.s_addr = hdr->src_addr.ip4.addr; | 883 | ip4->sin_addr.s_addr = hdr->src_addr.ip4.addr; |
| 876 | ip4->sin_port = hdr->port; | 884 | ip4->sin_port = hdr->port; |
| 877 | } | 885 | } |
| @@ -879,16 +887,15 @@ static void cma_save_ip4_info(struct rdma_cm_id *id, struct rdma_cm_id *listen_i | |||
| 879 | static void cma_save_ip6_info(struct rdma_cm_id *id, struct rdma_cm_id *listen_id, | 887 | static void cma_save_ip6_info(struct rdma_cm_id *id, struct rdma_cm_id *listen_id, |
| 880 | struct cma_hdr *hdr) | 888 | struct cma_hdr *hdr) |
| 881 | { | 889 | { |
| 882 | struct sockaddr_in6 *listen6, *ip6; | 890 | struct sockaddr_in6 *ip6; |
| 883 | 891 | ||
| 884 | listen6 = (struct sockaddr_in6 *) &listen_id->route.addr.src_addr; | ||
| 885 | ip6 = (struct sockaddr_in6 *) &id->route.addr.src_addr; | 892 | ip6 = (struct sockaddr_in6 *) &id->route.addr.src_addr; |
| 886 | ip6->sin6_family = listen6->sin6_family; | 893 | ip6->sin6_family = AF_INET6; |
| 887 | ip6->sin6_addr = hdr->dst_addr.ip6; | 894 | ip6->sin6_addr = hdr->dst_addr.ip6; |
| 888 | ip6->sin6_port = listen6->sin6_port; | 895 | ip6->sin6_port = ss_get_port(&listen_id->route.addr.src_addr); |
| 889 | 896 | ||
| 890 | ip6 = (struct sockaddr_in6 *) &id->route.addr.dst_addr; | 897 | ip6 = (struct sockaddr_in6 *) &id->route.addr.dst_addr; |
| 891 | ip6->sin6_family = listen6->sin6_family; | 898 | ip6->sin6_family = AF_INET6; |
| 892 | ip6->sin6_addr = hdr->src_addr.ip6; | 899 | ip6->sin6_addr = hdr->src_addr.ip6; |
| 893 | ip6->sin6_port = hdr->port; | 900 | ip6->sin6_port = hdr->port; |
| 894 | } | 901 | } |
diff --git a/drivers/infiniband/core/iwpm_msg.c b/drivers/infiniband/core/iwpm_msg.c index b85ddbc979e0..e6ffa2e66c1a 100644 --- a/drivers/infiniband/core/iwpm_msg.c +++ b/drivers/infiniband/core/iwpm_msg.c | |||
| @@ -33,7 +33,7 @@ | |||
| 33 | 33 | ||
| 34 | #include "iwpm_util.h" | 34 | #include "iwpm_util.h" |
| 35 | 35 | ||
| 36 | static const char iwpm_ulib_name[] = "iWarpPortMapperUser"; | 36 | static const char iwpm_ulib_name[IWPM_ULIBNAME_SIZE] = "iWarpPortMapperUser"; |
| 37 | static int iwpm_ulib_version = 3; | 37 | static int iwpm_ulib_version = 3; |
| 38 | static int iwpm_user_pid = IWPM_PID_UNDEFINED; | 38 | static int iwpm_user_pid = IWPM_PID_UNDEFINED; |
| 39 | static atomic_t echo_nlmsg_seq; | 39 | static atomic_t echo_nlmsg_seq; |
| @@ -468,7 +468,8 @@ add_mapping_response_exit: | |||
| 468 | } | 468 | } |
| 469 | EXPORT_SYMBOL(iwpm_add_mapping_cb); | 469 | EXPORT_SYMBOL(iwpm_add_mapping_cb); |
| 470 | 470 | ||
| 471 | /* netlink attribute policy for the response to add and query mapping request */ | 471 | /* netlink attribute policy for the response to add and query mapping request |
| 472 | * and response with remote address info */ | ||
| 472 | static const struct nla_policy resp_query_policy[IWPM_NLA_RQUERY_MAPPING_MAX] = { | 473 | static const struct nla_policy resp_query_policy[IWPM_NLA_RQUERY_MAPPING_MAX] = { |
| 473 | [IWPM_NLA_QUERY_MAPPING_SEQ] = { .type = NLA_U32 }, | 474 | [IWPM_NLA_QUERY_MAPPING_SEQ] = { .type = NLA_U32 }, |
| 474 | [IWPM_NLA_QUERY_LOCAL_ADDR] = { .len = sizeof(struct sockaddr_storage) }, | 475 | [IWPM_NLA_QUERY_LOCAL_ADDR] = { .len = sizeof(struct sockaddr_storage) }, |
| @@ -559,6 +560,76 @@ query_mapping_response_exit: | |||
| 559 | } | 560 | } |
| 560 | EXPORT_SYMBOL(iwpm_add_and_query_mapping_cb); | 561 | EXPORT_SYMBOL(iwpm_add_and_query_mapping_cb); |
| 561 | 562 | ||
| 563 | /* | ||
| 564 | * iwpm_remote_info_cb - Process a port mapper message, containing | ||
| 565 | * the remote connecting peer address info | ||
| 566 | */ | ||
| 567 | int iwpm_remote_info_cb(struct sk_buff *skb, struct netlink_callback *cb) | ||
| 568 | { | ||
| 569 | struct nlattr *nltb[IWPM_NLA_RQUERY_MAPPING_MAX]; | ||
| 570 | struct sockaddr_storage *local_sockaddr, *remote_sockaddr; | ||
| 571 | struct sockaddr_storage *mapped_loc_sockaddr, *mapped_rem_sockaddr; | ||
| 572 | struct iwpm_remote_info *rem_info; | ||
| 573 | const char *msg_type; | ||
| 574 | u8 nl_client; | ||
| 575 | int ret = -EINVAL; | ||
| 576 | |||
| 577 | msg_type = "Remote Mapping info"; | ||
| 578 | if (iwpm_parse_nlmsg(cb, IWPM_NLA_RQUERY_MAPPING_MAX, | ||
| 579 | resp_query_policy, nltb, msg_type)) | ||
| 580 | return ret; | ||
| 581 | |||
| 582 | nl_client = RDMA_NL_GET_CLIENT(cb->nlh->nlmsg_type); | ||
| 583 | if (!iwpm_valid_client(nl_client)) { | ||
| 584 | pr_info("%s: Invalid port mapper client = %d\n", | ||
| 585 | __func__, nl_client); | ||
| 586 | return ret; | ||
| 587 | } | ||
| 588 | atomic_set(&echo_nlmsg_seq, cb->nlh->nlmsg_seq); | ||
| 589 | |||
| 590 | local_sockaddr = (struct sockaddr_storage *) | ||
| 591 | nla_data(nltb[IWPM_NLA_QUERY_LOCAL_ADDR]); | ||
| 592 | remote_sockaddr = (struct sockaddr_storage *) | ||
| 593 | nla_data(nltb[IWPM_NLA_QUERY_REMOTE_ADDR]); | ||
| 594 | mapped_loc_sockaddr = (struct sockaddr_storage *) | ||
| 595 | nla_data(nltb[IWPM_NLA_RQUERY_MAPPED_LOC_ADDR]); | ||
| 596 | mapped_rem_sockaddr = (struct sockaddr_storage *) | ||
| 597 | nla_data(nltb[IWPM_NLA_RQUERY_MAPPED_REM_ADDR]); | ||
| 598 | |||
| 599 | if (mapped_loc_sockaddr->ss_family != local_sockaddr->ss_family || | ||
| 600 | mapped_rem_sockaddr->ss_family != remote_sockaddr->ss_family) { | ||
| 601 | pr_info("%s: Sockaddr family doesn't match the requested one\n", | ||
| 602 | __func__); | ||
| 603 | return ret; | ||
| 604 | } | ||
| 605 | rem_info = kzalloc(sizeof(struct iwpm_remote_info), GFP_ATOMIC); | ||
| 606 | if (!rem_info) { | ||
| 607 | pr_err("%s: Unable to allocate a remote info\n", __func__); | ||
| 608 | ret = -ENOMEM; | ||
| 609 | return ret; | ||
| 610 | } | ||
| 611 | memcpy(&rem_info->mapped_loc_sockaddr, mapped_loc_sockaddr, | ||
| 612 | sizeof(struct sockaddr_storage)); | ||
| 613 | memcpy(&rem_info->remote_sockaddr, remote_sockaddr, | ||
| 614 | sizeof(struct sockaddr_storage)); | ||
| 615 | memcpy(&rem_info->mapped_rem_sockaddr, mapped_rem_sockaddr, | ||
| 616 | sizeof(struct sockaddr_storage)); | ||
| 617 | rem_info->nl_client = nl_client; | ||
| 618 | |||
| 619 | iwpm_add_remote_info(rem_info); | ||
| 620 | |||
| 621 | iwpm_print_sockaddr(local_sockaddr, | ||
| 622 | "remote_info: Local sockaddr:"); | ||
| 623 | iwpm_print_sockaddr(mapped_loc_sockaddr, | ||
| 624 | "remote_info: Mapped local sockaddr:"); | ||
| 625 | iwpm_print_sockaddr(remote_sockaddr, | ||
| 626 | "remote_info: Remote sockaddr:"); | ||
| 627 | iwpm_print_sockaddr(mapped_rem_sockaddr, | ||
| 628 | "remote_info: Mapped remote sockaddr:"); | ||
| 629 | return ret; | ||
| 630 | } | ||
| 631 | EXPORT_SYMBOL(iwpm_remote_info_cb); | ||
| 632 | |||
| 562 | /* netlink attribute policy for the received request for mapping info */ | 633 | /* netlink attribute policy for the received request for mapping info */ |
| 563 | static const struct nla_policy resp_mapinfo_policy[IWPM_NLA_MAPINFO_REQ_MAX] = { | 634 | static const struct nla_policy resp_mapinfo_policy[IWPM_NLA_MAPINFO_REQ_MAX] = { |
| 564 | [IWPM_NLA_MAPINFO_ULIB_NAME] = { .type = NLA_STRING, | 635 | [IWPM_NLA_MAPINFO_ULIB_NAME] = { .type = NLA_STRING, |
diff --git a/drivers/infiniband/core/iwpm_util.c b/drivers/infiniband/core/iwpm_util.c index 69e9f84c1605..a626795bf9c7 100644 --- a/drivers/infiniband/core/iwpm_util.c +++ b/drivers/infiniband/core/iwpm_util.c | |||
| @@ -33,8 +33,10 @@ | |||
| 33 | 33 | ||
| 34 | #include "iwpm_util.h" | 34 | #include "iwpm_util.h" |
| 35 | 35 | ||
| 36 | #define IWPM_HASH_BUCKET_SIZE 512 | 36 | #define IWPM_MAPINFO_HASH_SIZE 512 |
| 37 | #define IWPM_HASH_BUCKET_MASK (IWPM_HASH_BUCKET_SIZE - 1) | 37 | #define IWPM_MAPINFO_HASH_MASK (IWPM_MAPINFO_HASH_SIZE - 1) |
| 38 | #define IWPM_REMINFO_HASH_SIZE 64 | ||
| 39 | #define IWPM_REMINFO_HASH_MASK (IWPM_REMINFO_HASH_SIZE - 1) | ||
| 38 | 40 | ||
| 39 | static LIST_HEAD(iwpm_nlmsg_req_list); | 41 | static LIST_HEAD(iwpm_nlmsg_req_list); |
| 40 | static DEFINE_SPINLOCK(iwpm_nlmsg_req_lock); | 42 | static DEFINE_SPINLOCK(iwpm_nlmsg_req_lock); |
| @@ -42,31 +44,49 @@ static DEFINE_SPINLOCK(iwpm_nlmsg_req_lock); | |||
| 42 | static struct hlist_head *iwpm_hash_bucket; | 44 | static struct hlist_head *iwpm_hash_bucket; |
| 43 | static DEFINE_SPINLOCK(iwpm_mapinfo_lock); | 45 | static DEFINE_SPINLOCK(iwpm_mapinfo_lock); |
| 44 | 46 | ||
| 47 | static struct hlist_head *iwpm_reminfo_bucket; | ||
| 48 | static DEFINE_SPINLOCK(iwpm_reminfo_lock); | ||
| 49 | |||
| 45 | static DEFINE_MUTEX(iwpm_admin_lock); | 50 | static DEFINE_MUTEX(iwpm_admin_lock); |
| 46 | static struct iwpm_admin_data iwpm_admin; | 51 | static struct iwpm_admin_data iwpm_admin; |
| 47 | 52 | ||
| 48 | int iwpm_init(u8 nl_client) | 53 | int iwpm_init(u8 nl_client) |
| 49 | { | 54 | { |
| 55 | int ret = 0; | ||
| 50 | if (iwpm_valid_client(nl_client)) | 56 | if (iwpm_valid_client(nl_client)) |
| 51 | return -EINVAL; | 57 | return -EINVAL; |
| 52 | mutex_lock(&iwpm_admin_lock); | 58 | mutex_lock(&iwpm_admin_lock); |
| 53 | if (atomic_read(&iwpm_admin.refcount) == 0) { | 59 | if (atomic_read(&iwpm_admin.refcount) == 0) { |
| 54 | iwpm_hash_bucket = kzalloc(IWPM_HASH_BUCKET_SIZE * | 60 | iwpm_hash_bucket = kzalloc(IWPM_MAPINFO_HASH_SIZE * |
| 55 | sizeof(struct hlist_head), GFP_KERNEL); | 61 | sizeof(struct hlist_head), GFP_KERNEL); |
| 56 | if (!iwpm_hash_bucket) { | 62 | if (!iwpm_hash_bucket) { |
| 57 | mutex_unlock(&iwpm_admin_lock); | 63 | ret = -ENOMEM; |
| 58 | pr_err("%s Unable to create mapinfo hash table\n", __func__); | 64 | pr_err("%s Unable to create mapinfo hash table\n", __func__); |
| 59 | return -ENOMEM; | 65 | goto init_exit; |
| 66 | } | ||
| 67 | iwpm_reminfo_bucket = kzalloc(IWPM_REMINFO_HASH_SIZE * | ||
| 68 | sizeof(struct hlist_head), GFP_KERNEL); | ||
| 69 | if (!iwpm_reminfo_bucket) { | ||
| 70 | kfree(iwpm_hash_bucket); | ||
| 71 | ret = -ENOMEM; | ||
| 72 | pr_err("%s Unable to create reminfo hash table\n", __func__); | ||
| 73 | goto init_exit; | ||
| 60 | } | 74 | } |
| 61 | } | 75 | } |
| 62 | atomic_inc(&iwpm_admin.refcount); | 76 | atomic_inc(&iwpm_admin.refcount); |
| 77 | init_exit: | ||
| 63 | mutex_unlock(&iwpm_admin_lock); | 78 | mutex_unlock(&iwpm_admin_lock); |
| 64 | iwpm_set_valid(nl_client, 1); | 79 | if (!ret) { |
| 65 | return 0; | 80 | iwpm_set_valid(nl_client, 1); |
| 81 | pr_debug("%s: Mapinfo and reminfo tables are created\n", | ||
| 82 | __func__); | ||
| 83 | } | ||
| 84 | return ret; | ||
| 66 | } | 85 | } |
| 67 | EXPORT_SYMBOL(iwpm_init); | 86 | EXPORT_SYMBOL(iwpm_init); |
| 68 | 87 | ||
| 69 | static void free_hash_bucket(void); | 88 | static void free_hash_bucket(void); |
| 89 | static void free_reminfo_bucket(void); | ||
| 70 | 90 | ||
| 71 | int iwpm_exit(u8 nl_client) | 91 | int iwpm_exit(u8 nl_client) |
| 72 | { | 92 | { |
| @@ -81,7 +101,8 @@ int iwpm_exit(u8 nl_client) | |||
| 81 | } | 101 | } |
| 82 | if (atomic_dec_and_test(&iwpm_admin.refcount)) { | 102 | if (atomic_dec_and_test(&iwpm_admin.refcount)) { |
| 83 | free_hash_bucket(); | 103 | free_hash_bucket(); |
| 84 | pr_debug("%s: Mapinfo hash table is destroyed\n", __func__); | 104 | free_reminfo_bucket(); |
| 105 | pr_debug("%s: Resources are destroyed\n", __func__); | ||
| 85 | } | 106 | } |
| 86 | mutex_unlock(&iwpm_admin_lock); | 107 | mutex_unlock(&iwpm_admin_lock); |
| 87 | iwpm_set_valid(nl_client, 0); | 108 | iwpm_set_valid(nl_client, 0); |
| @@ -89,7 +110,7 @@ int iwpm_exit(u8 nl_client) | |||
| 89 | } | 110 | } |
| 90 | EXPORT_SYMBOL(iwpm_exit); | 111 | EXPORT_SYMBOL(iwpm_exit); |
| 91 | 112 | ||
| 92 | static struct hlist_head *get_hash_bucket_head(struct sockaddr_storage *, | 113 | static struct hlist_head *get_mapinfo_hash_bucket(struct sockaddr_storage *, |
| 93 | struct sockaddr_storage *); | 114 | struct sockaddr_storage *); |
| 94 | 115 | ||
| 95 | int iwpm_create_mapinfo(struct sockaddr_storage *local_sockaddr, | 116 | int iwpm_create_mapinfo(struct sockaddr_storage *local_sockaddr, |
| @@ -99,9 +120,10 @@ int iwpm_create_mapinfo(struct sockaddr_storage *local_sockaddr, | |||
| 99 | struct hlist_head *hash_bucket_head; | 120 | struct hlist_head *hash_bucket_head; |
| 100 | struct iwpm_mapping_info *map_info; | 121 | struct iwpm_mapping_info *map_info; |
| 101 | unsigned long flags; | 122 | unsigned long flags; |
| 123 | int ret = -EINVAL; | ||
| 102 | 124 | ||
| 103 | if (!iwpm_valid_client(nl_client)) | 125 | if (!iwpm_valid_client(nl_client)) |
| 104 | return -EINVAL; | 126 | return ret; |
| 105 | map_info = kzalloc(sizeof(struct iwpm_mapping_info), GFP_KERNEL); | 127 | map_info = kzalloc(sizeof(struct iwpm_mapping_info), GFP_KERNEL); |
| 106 | if (!map_info) { | 128 | if (!map_info) { |
| 107 | pr_err("%s: Unable to allocate a mapping info\n", __func__); | 129 | pr_err("%s: Unable to allocate a mapping info\n", __func__); |
| @@ -115,13 +137,16 @@ int iwpm_create_mapinfo(struct sockaddr_storage *local_sockaddr, | |||
| 115 | 137 | ||
| 116 | spin_lock_irqsave(&iwpm_mapinfo_lock, flags); | 138 | spin_lock_irqsave(&iwpm_mapinfo_lock, flags); |
| 117 | if (iwpm_hash_bucket) { | 139 | if (iwpm_hash_bucket) { |
| 118 | hash_bucket_head = get_hash_bucket_head( | 140 | hash_bucket_head = get_mapinfo_hash_bucket( |
| 119 | &map_info->local_sockaddr, | 141 | &map_info->local_sockaddr, |
| 120 | &map_info->mapped_sockaddr); | 142 | &map_info->mapped_sockaddr); |
| 121 | hlist_add_head(&map_info->hlist_node, hash_bucket_head); | 143 | if (hash_bucket_head) { |
| 144 | hlist_add_head(&map_info->hlist_node, hash_bucket_head); | ||
| 145 | ret = 0; | ||
| 146 | } | ||
| 122 | } | 147 | } |
| 123 | spin_unlock_irqrestore(&iwpm_mapinfo_lock, flags); | 148 | spin_unlock_irqrestore(&iwpm_mapinfo_lock, flags); |
| 124 | return 0; | 149 | return ret; |
| 125 | } | 150 | } |
| 126 | EXPORT_SYMBOL(iwpm_create_mapinfo); | 151 | EXPORT_SYMBOL(iwpm_create_mapinfo); |
| 127 | 152 | ||
| @@ -136,9 +161,12 @@ int iwpm_remove_mapinfo(struct sockaddr_storage *local_sockaddr, | |||
| 136 | 161 | ||
| 137 | spin_lock_irqsave(&iwpm_mapinfo_lock, flags); | 162 | spin_lock_irqsave(&iwpm_mapinfo_lock, flags); |
| 138 | if (iwpm_hash_bucket) { | 163 | if (iwpm_hash_bucket) { |
| 139 | hash_bucket_head = get_hash_bucket_head( | 164 | hash_bucket_head = get_mapinfo_hash_bucket( |
| 140 | local_sockaddr, | 165 | local_sockaddr, |
| 141 | mapped_local_addr); | 166 | mapped_local_addr); |
| 167 | if (!hash_bucket_head) | ||
| 168 | goto remove_mapinfo_exit; | ||
| 169 | |||
| 142 | hlist_for_each_entry_safe(map_info, tmp_hlist_node, | 170 | hlist_for_each_entry_safe(map_info, tmp_hlist_node, |
| 143 | hash_bucket_head, hlist_node) { | 171 | hash_bucket_head, hlist_node) { |
| 144 | 172 | ||
| @@ -152,6 +180,7 @@ int iwpm_remove_mapinfo(struct sockaddr_storage *local_sockaddr, | |||
| 152 | } | 180 | } |
| 153 | } | 181 | } |
| 154 | } | 182 | } |
| 183 | remove_mapinfo_exit: | ||
| 155 | spin_unlock_irqrestore(&iwpm_mapinfo_lock, flags); | 184 | spin_unlock_irqrestore(&iwpm_mapinfo_lock, flags); |
| 156 | return ret; | 185 | return ret; |
| 157 | } | 186 | } |
| @@ -166,7 +195,7 @@ static void free_hash_bucket(void) | |||
| 166 | 195 | ||
| 167 | /* remove all the mapinfo data from the list */ | 196 | /* remove all the mapinfo data from the list */ |
| 168 | spin_lock_irqsave(&iwpm_mapinfo_lock, flags); | 197 | spin_lock_irqsave(&iwpm_mapinfo_lock, flags); |
| 169 | for (i = 0; i < IWPM_HASH_BUCKET_SIZE; i++) { | 198 | for (i = 0; i < IWPM_MAPINFO_HASH_SIZE; i++) { |
| 170 | hlist_for_each_entry_safe(map_info, tmp_hlist_node, | 199 | hlist_for_each_entry_safe(map_info, tmp_hlist_node, |
| 171 | &iwpm_hash_bucket[i], hlist_node) { | 200 | &iwpm_hash_bucket[i], hlist_node) { |
| 172 | 201 | ||
| @@ -180,6 +209,96 @@ static void free_hash_bucket(void) | |||
| 180 | spin_unlock_irqrestore(&iwpm_mapinfo_lock, flags); | 209 | spin_unlock_irqrestore(&iwpm_mapinfo_lock, flags); |
| 181 | } | 210 | } |
| 182 | 211 | ||
| 212 | static void free_reminfo_bucket(void) | ||
| 213 | { | ||
| 214 | struct hlist_node *tmp_hlist_node; | ||
| 215 | struct iwpm_remote_info *rem_info; | ||
| 216 | unsigned long flags; | ||
| 217 | int i; | ||
| 218 | |||
| 219 | /* remove all the remote info from the list */ | ||
| 220 | spin_lock_irqsave(&iwpm_reminfo_lock, flags); | ||
| 221 | for (i = 0; i < IWPM_REMINFO_HASH_SIZE; i++) { | ||
| 222 | hlist_for_each_entry_safe(rem_info, tmp_hlist_node, | ||
| 223 | &iwpm_reminfo_bucket[i], hlist_node) { | ||
| 224 | |||
| 225 | hlist_del_init(&rem_info->hlist_node); | ||
| 226 | kfree(rem_info); | ||
| 227 | } | ||
| 228 | } | ||
| 229 | /* free the hash list */ | ||
| 230 | kfree(iwpm_reminfo_bucket); | ||
| 231 | iwpm_reminfo_bucket = NULL; | ||
| 232 | spin_unlock_irqrestore(&iwpm_reminfo_lock, flags); | ||
| 233 | } | ||
| 234 | |||
| 235 | static struct hlist_head *get_reminfo_hash_bucket(struct sockaddr_storage *, | ||
| 236 | struct sockaddr_storage *); | ||
| 237 | |||
| 238 | void iwpm_add_remote_info(struct iwpm_remote_info *rem_info) | ||
| 239 | { | ||
| 240 | struct hlist_head *hash_bucket_head; | ||
| 241 | unsigned long flags; | ||
| 242 | |||
| 243 | spin_lock_irqsave(&iwpm_reminfo_lock, flags); | ||
| 244 | if (iwpm_reminfo_bucket) { | ||
| 245 | hash_bucket_head = get_reminfo_hash_bucket( | ||
| 246 | &rem_info->mapped_loc_sockaddr, | ||
| 247 | &rem_info->mapped_rem_sockaddr); | ||
| 248 | if (hash_bucket_head) | ||
| 249 | hlist_add_head(&rem_info->hlist_node, hash_bucket_head); | ||
| 250 | } | ||
| 251 | spin_unlock_irqrestore(&iwpm_reminfo_lock, flags); | ||
| 252 | } | ||
| 253 | |||
| 254 | int iwpm_get_remote_info(struct sockaddr_storage *mapped_loc_addr, | ||
| 255 | struct sockaddr_storage *mapped_rem_addr, | ||
| 256 | struct sockaddr_storage *remote_addr, | ||
| 257 | u8 nl_client) | ||
| 258 | { | ||
| 259 | struct hlist_node *tmp_hlist_node; | ||
| 260 | struct hlist_head *hash_bucket_head; | ||
| 261 | struct iwpm_remote_info *rem_info = NULL; | ||
| 262 | unsigned long flags; | ||
| 263 | int ret = -EINVAL; | ||
| 264 | |||
| 265 | if (!iwpm_valid_client(nl_client)) { | ||
| 266 | pr_info("%s: Invalid client = %d\n", __func__, nl_client); | ||
| 267 | return ret; | ||
| 268 | } | ||
| 269 | spin_lock_irqsave(&iwpm_reminfo_lock, flags); | ||
| 270 | if (iwpm_reminfo_bucket) { | ||
| 271 | hash_bucket_head = get_reminfo_hash_bucket( | ||
| 272 | mapped_loc_addr, | ||
| 273 | mapped_rem_addr); | ||
| 274 | if (!hash_bucket_head) | ||
| 275 | goto get_remote_info_exit; | ||
| 276 | hlist_for_each_entry_safe(rem_info, tmp_hlist_node, | ||
| 277 | hash_bucket_head, hlist_node) { | ||
| 278 | |||
| 279 | if (!iwpm_compare_sockaddr(&rem_info->mapped_loc_sockaddr, | ||
| 280 | mapped_loc_addr) && | ||
| 281 | !iwpm_compare_sockaddr(&rem_info->mapped_rem_sockaddr, | ||
| 282 | mapped_rem_addr)) { | ||
| 283 | |||
| 284 | memcpy(remote_addr, &rem_info->remote_sockaddr, | ||
| 285 | sizeof(struct sockaddr_storage)); | ||
| 286 | iwpm_print_sockaddr(remote_addr, | ||
| 287 | "get_remote_info: Remote sockaddr:"); | ||
| 288 | |||
| 289 | hlist_del_init(&rem_info->hlist_node); | ||
| 290 | kfree(rem_info); | ||
| 291 | ret = 0; | ||
| 292 | break; | ||
| 293 | } | ||
| 294 | } | ||
| 295 | } | ||
| 296 | get_remote_info_exit: | ||
| 297 | spin_unlock_irqrestore(&iwpm_reminfo_lock, flags); | ||
| 298 | return ret; | ||
| 299 | } | ||
| 300 | EXPORT_SYMBOL(iwpm_get_remote_info); | ||
| 301 | |||
| 183 | struct iwpm_nlmsg_request *iwpm_get_nlmsg_request(__u32 nlmsg_seq, | 302 | struct iwpm_nlmsg_request *iwpm_get_nlmsg_request(__u32 nlmsg_seq, |
| 184 | u8 nl_client, gfp_t gfp) | 303 | u8 nl_client, gfp_t gfp) |
| 185 | { | 304 | { |
| @@ -409,31 +528,54 @@ static u32 iwpm_ipv4_jhash(struct sockaddr_in *ipv4_sockaddr) | |||
| 409 | return hash; | 528 | return hash; |
| 410 | } | 529 | } |
| 411 | 530 | ||
| 412 | static struct hlist_head *get_hash_bucket_head(struct sockaddr_storage | 531 | static int get_hash_bucket(struct sockaddr_storage *a_sockaddr, |
| 413 | *local_sockaddr, | 532 | struct sockaddr_storage *b_sockaddr, u32 *hash) |
| 414 | struct sockaddr_storage | ||
| 415 | *mapped_sockaddr) | ||
| 416 | { | 533 | { |
| 417 | u32 local_hash, mapped_hash, hash; | 534 | u32 a_hash, b_hash; |
| 418 | 535 | ||
| 419 | if (local_sockaddr->ss_family == AF_INET) { | 536 | if (a_sockaddr->ss_family == AF_INET) { |
| 420 | local_hash = iwpm_ipv4_jhash((struct sockaddr_in *) local_sockaddr); | 537 | a_hash = iwpm_ipv4_jhash((struct sockaddr_in *) a_sockaddr); |
| 421 | mapped_hash = iwpm_ipv4_jhash((struct sockaddr_in *) mapped_sockaddr); | 538 | b_hash = iwpm_ipv4_jhash((struct sockaddr_in *) b_sockaddr); |
| 422 | 539 | ||
| 423 | } else if (local_sockaddr->ss_family == AF_INET6) { | 540 | } else if (a_sockaddr->ss_family == AF_INET6) { |
| 424 | local_hash = iwpm_ipv6_jhash((struct sockaddr_in6 *) local_sockaddr); | 541 | a_hash = iwpm_ipv6_jhash((struct sockaddr_in6 *) a_sockaddr); |
| 425 | mapped_hash = iwpm_ipv6_jhash((struct sockaddr_in6 *) mapped_sockaddr); | 542 | b_hash = iwpm_ipv6_jhash((struct sockaddr_in6 *) b_sockaddr); |
| 426 | } else { | 543 | } else { |
| 427 | pr_err("%s: Invalid sockaddr family\n", __func__); | 544 | pr_err("%s: Invalid sockaddr family\n", __func__); |
| 428 | return NULL; | 545 | return -EINVAL; |
| 429 | } | 546 | } |
| 430 | 547 | ||
| 431 | if (local_hash == mapped_hash) /* if port mapper isn't available */ | 548 | if (a_hash == b_hash) /* if port mapper isn't available */ |
| 432 | hash = local_hash; | 549 | *hash = a_hash; |
| 433 | else | 550 | else |
| 434 | hash = jhash_2words(local_hash, mapped_hash, 0); | 551 | *hash = jhash_2words(a_hash, b_hash, 0); |
| 552 | return 0; | ||
| 553 | } | ||
| 554 | |||
| 555 | static struct hlist_head *get_mapinfo_hash_bucket(struct sockaddr_storage | ||
| 556 | *local_sockaddr, struct sockaddr_storage | ||
| 557 | *mapped_sockaddr) | ||
| 558 | { | ||
| 559 | u32 hash; | ||
| 560 | int ret; | ||
| 435 | 561 | ||
| 436 | return &iwpm_hash_bucket[hash & IWPM_HASH_BUCKET_MASK]; | 562 | ret = get_hash_bucket(local_sockaddr, mapped_sockaddr, &hash); |
| 563 | if (ret) | ||
| 564 | return NULL; | ||
| 565 | return &iwpm_hash_bucket[hash & IWPM_MAPINFO_HASH_MASK]; | ||
| 566 | } | ||
| 567 | |||
| 568 | static struct hlist_head *get_reminfo_hash_bucket(struct sockaddr_storage | ||
| 569 | *mapped_loc_sockaddr, struct sockaddr_storage | ||
| 570 | *mapped_rem_sockaddr) | ||
| 571 | { | ||
| 572 | u32 hash; | ||
| 573 | int ret; | ||
| 574 | |||
| 575 | ret = get_hash_bucket(mapped_loc_sockaddr, mapped_rem_sockaddr, &hash); | ||
| 576 | if (ret) | ||
| 577 | return NULL; | ||
| 578 | return &iwpm_reminfo_bucket[hash & IWPM_REMINFO_HASH_MASK]; | ||
| 437 | } | 579 | } |
| 438 | 580 | ||
| 439 | static int send_mapinfo_num(u32 mapping_num, u8 nl_client, int iwpm_pid) | 581 | static int send_mapinfo_num(u32 mapping_num, u8 nl_client, int iwpm_pid) |
| @@ -512,7 +654,7 @@ int iwpm_send_mapinfo(u8 nl_client, int iwpm_pid) | |||
| 512 | } | 654 | } |
| 513 | skb_num++; | 655 | skb_num++; |
| 514 | spin_lock_irqsave(&iwpm_mapinfo_lock, flags); | 656 | spin_lock_irqsave(&iwpm_mapinfo_lock, flags); |
| 515 | for (i = 0; i < IWPM_HASH_BUCKET_SIZE; i++) { | 657 | for (i = 0; i < IWPM_MAPINFO_HASH_SIZE; i++) { |
| 516 | hlist_for_each_entry(map_info, &iwpm_hash_bucket[i], | 658 | hlist_for_each_entry(map_info, &iwpm_hash_bucket[i], |
| 517 | hlist_node) { | 659 | hlist_node) { |
| 518 | if (map_info->nl_client != nl_client) | 660 | if (map_info->nl_client != nl_client) |
| @@ -595,7 +737,7 @@ int iwpm_mapinfo_available(void) | |||
| 595 | 737 | ||
| 596 | spin_lock_irqsave(&iwpm_mapinfo_lock, flags); | 738 | spin_lock_irqsave(&iwpm_mapinfo_lock, flags); |
| 597 | if (iwpm_hash_bucket) { | 739 | if (iwpm_hash_bucket) { |
| 598 | for (i = 0; i < IWPM_HASH_BUCKET_SIZE; i++) { | 740 | for (i = 0; i < IWPM_MAPINFO_HASH_SIZE; i++) { |
| 599 | if (!hlist_empty(&iwpm_hash_bucket[i])) { | 741 | if (!hlist_empty(&iwpm_hash_bucket[i])) { |
| 600 | full_bucket = 1; | 742 | full_bucket = 1; |
| 601 | break; | 743 | break; |
diff --git a/drivers/infiniband/core/iwpm_util.h b/drivers/infiniband/core/iwpm_util.h index 9777c869a140..ee2d9ff095be 100644 --- a/drivers/infiniband/core/iwpm_util.h +++ b/drivers/infiniband/core/iwpm_util.h | |||
| @@ -76,6 +76,14 @@ struct iwpm_mapping_info { | |||
| 76 | u8 nl_client; | 76 | u8 nl_client; |
| 77 | }; | 77 | }; |
| 78 | 78 | ||
| 79 | struct iwpm_remote_info { | ||
| 80 | struct hlist_node hlist_node; | ||
| 81 | struct sockaddr_storage remote_sockaddr; | ||
| 82 | struct sockaddr_storage mapped_loc_sockaddr; | ||
| 83 | struct sockaddr_storage mapped_rem_sockaddr; | ||
| 84 | u8 nl_client; | ||
| 85 | }; | ||
| 86 | |||
| 79 | struct iwpm_admin_data { | 87 | struct iwpm_admin_data { |
| 80 | atomic_t refcount; | 88 | atomic_t refcount; |
| 81 | atomic_t nlmsg_seq; | 89 | atomic_t nlmsg_seq; |
| @@ -128,6 +136,13 @@ int iwpm_wait_complete_req(struct iwpm_nlmsg_request *nlmsg_request); | |||
| 128 | int iwpm_get_nlmsg_seq(void); | 136 | int iwpm_get_nlmsg_seq(void); |
| 129 | 137 | ||
| 130 | /** | 138 | /** |
| 139 | * iwpm_add_reminfo - Add remote address info of the connecting peer | ||
| 140 | * to the remote info hash table | ||
| 141 | * @reminfo: The remote info to be added | ||
| 142 | */ | ||
| 143 | void iwpm_add_remote_info(struct iwpm_remote_info *reminfo); | ||
| 144 | |||
| 145 | /** | ||
| 131 | * iwpm_valid_client - Check if the port mapper client is valid | 146 | * iwpm_valid_client - Check if the port mapper client is valid |
| 132 | * @nl_client: The index of the netlink client | 147 | * @nl_client: The index of the netlink client |
| 133 | * | 148 | * |
diff --git a/drivers/infiniband/core/umem_odp.c b/drivers/infiniband/core/umem_odp.c index 8b8cc6fa0ab0..40becdb3196e 100644 --- a/drivers/infiniband/core/umem_odp.c +++ b/drivers/infiniband/core/umem_odp.c | |||
| @@ -446,7 +446,6 @@ static int ib_umem_odp_map_dma_single_page( | |||
| 446 | int remove_existing_mapping = 0; | 446 | int remove_existing_mapping = 0; |
| 447 | int ret = 0; | 447 | int ret = 0; |
| 448 | 448 | ||
| 449 | mutex_lock(&umem->odp_data->umem_mutex); | ||
| 450 | /* | 449 | /* |
| 451 | * Note: we avoid writing if seq is different from the initial seq, to | 450 | * Note: we avoid writing if seq is different from the initial seq, to |
| 452 | * handle case of a racing notifier. This check also allows us to bail | 451 | * handle case of a racing notifier. This check also allows us to bail |
| @@ -479,8 +478,6 @@ static int ib_umem_odp_map_dma_single_page( | |||
| 479 | } | 478 | } |
| 480 | 479 | ||
| 481 | out: | 480 | out: |
| 482 | mutex_unlock(&umem->odp_data->umem_mutex); | ||
| 483 | |||
| 484 | /* On Demand Paging - avoid pinning the page */ | 481 | /* On Demand Paging - avoid pinning the page */ |
| 485 | if (umem->context->invalidate_range || !stored_page) | 482 | if (umem->context->invalidate_range || !stored_page) |
| 486 | put_page(page); | 483 | put_page(page); |
| @@ -586,6 +583,7 @@ int ib_umem_odp_map_dma_pages(struct ib_umem *umem, u64 user_virt, u64 bcnt, | |||
| 586 | 583 | ||
| 587 | bcnt -= min_t(size_t, npages << PAGE_SHIFT, bcnt); | 584 | bcnt -= min_t(size_t, npages << PAGE_SHIFT, bcnt); |
| 588 | user_virt += npages << PAGE_SHIFT; | 585 | user_virt += npages << PAGE_SHIFT; |
| 586 | mutex_lock(&umem->odp_data->umem_mutex); | ||
| 589 | for (j = 0; j < npages; ++j) { | 587 | for (j = 0; j < npages; ++j) { |
| 590 | ret = ib_umem_odp_map_dma_single_page( | 588 | ret = ib_umem_odp_map_dma_single_page( |
| 591 | umem, k, base_virt_addr, local_page_list[j], | 589 | umem, k, base_virt_addr, local_page_list[j], |
| @@ -594,6 +592,7 @@ int ib_umem_odp_map_dma_pages(struct ib_umem *umem, u64 user_virt, u64 bcnt, | |||
| 594 | break; | 592 | break; |
| 595 | k++; | 593 | k++; |
| 596 | } | 594 | } |
| 595 | mutex_unlock(&umem->odp_data->umem_mutex); | ||
| 597 | 596 | ||
| 598 | if (ret < 0) { | 597 | if (ret < 0) { |
| 599 | /* Release left over pages when handling errors. */ | 598 | /* Release left over pages when handling errors. */ |
| @@ -633,12 +632,11 @@ void ib_umem_odp_unmap_dma_pages(struct ib_umem *umem, u64 virt, | |||
| 633 | * faults from completion. We might be racing with other | 632 | * faults from completion. We might be racing with other |
| 634 | * invalidations, so we must make sure we free each page only | 633 | * invalidations, so we must make sure we free each page only |
| 635 | * once. */ | 634 | * once. */ |
| 635 | mutex_lock(&umem->odp_data->umem_mutex); | ||
| 636 | for (addr = virt; addr < bound; addr += (u64)umem->page_size) { | 636 | for (addr = virt; addr < bound; addr += (u64)umem->page_size) { |
| 637 | idx = (addr - ib_umem_start(umem)) / PAGE_SIZE; | 637 | idx = (addr - ib_umem_start(umem)) / PAGE_SIZE; |
| 638 | mutex_lock(&umem->odp_data->umem_mutex); | ||
| 639 | if (umem->odp_data->page_list[idx]) { | 638 | if (umem->odp_data->page_list[idx]) { |
| 640 | struct page *page = umem->odp_data->page_list[idx]; | 639 | struct page *page = umem->odp_data->page_list[idx]; |
| 641 | struct page *head_page = compound_head(page); | ||
| 642 | dma_addr_t dma = umem->odp_data->dma_list[idx]; | 640 | dma_addr_t dma = umem->odp_data->dma_list[idx]; |
| 643 | dma_addr_t dma_addr = dma & ODP_DMA_ADDR_MASK; | 641 | dma_addr_t dma_addr = dma & ODP_DMA_ADDR_MASK; |
| 644 | 642 | ||
| @@ -646,7 +644,8 @@ void ib_umem_odp_unmap_dma_pages(struct ib_umem *umem, u64 virt, | |||
| 646 | 644 | ||
| 647 | ib_dma_unmap_page(dev, dma_addr, PAGE_SIZE, | 645 | ib_dma_unmap_page(dev, dma_addr, PAGE_SIZE, |
| 648 | DMA_BIDIRECTIONAL); | 646 | DMA_BIDIRECTIONAL); |
| 649 | if (dma & ODP_WRITE_ALLOWED_BIT) | 647 | if (dma & ODP_WRITE_ALLOWED_BIT) { |
| 648 | struct page *head_page = compound_head(page); | ||
| 650 | /* | 649 | /* |
| 651 | * set_page_dirty prefers being called with | 650 | * set_page_dirty prefers being called with |
| 652 | * the page lock. However, MMU notifiers are | 651 | * the page lock. However, MMU notifiers are |
| @@ -657,13 +656,14 @@ void ib_umem_odp_unmap_dma_pages(struct ib_umem *umem, u64 virt, | |||
| 657 | * be removed. | 656 | * be removed. |
| 658 | */ | 657 | */ |
| 659 | set_page_dirty(head_page); | 658 | set_page_dirty(head_page); |
| 659 | } | ||
| 660 | /* on demand pinning support */ | 660 | /* on demand pinning support */ |
| 661 | if (!umem->context->invalidate_range) | 661 | if (!umem->context->invalidate_range) |
| 662 | put_page(page); | 662 | put_page(page); |
| 663 | umem->odp_data->page_list[idx] = NULL; | 663 | umem->odp_data->page_list[idx] = NULL; |
| 664 | umem->odp_data->dma_list[idx] = 0; | 664 | umem->odp_data->dma_list[idx] = 0; |
| 665 | } | 665 | } |
| 666 | mutex_unlock(&umem->odp_data->umem_mutex); | ||
| 667 | } | 666 | } |
| 667 | mutex_unlock(&umem->odp_data->umem_mutex); | ||
| 668 | } | 668 | } |
| 669 | EXPORT_SYMBOL(ib_umem_odp_unmap_dma_pages); | 669 | EXPORT_SYMBOL(ib_umem_odp_unmap_dma_pages); |
diff --git a/drivers/infiniband/hw/cxgb4/cm.c b/drivers/infiniband/hw/cxgb4/cm.c index 57176ddd4c50..3ad8dc798f52 100644 --- a/drivers/infiniband/hw/cxgb4/cm.c +++ b/drivers/infiniband/hw/cxgb4/cm.c | |||
| @@ -583,6 +583,22 @@ static void c4iw_record_pm_msg(struct c4iw_ep *ep, | |||
| 583 | sizeof(ep->com.mapped_remote_addr)); | 583 | sizeof(ep->com.mapped_remote_addr)); |
| 584 | } | 584 | } |
| 585 | 585 | ||
| 586 | static int get_remote_addr(struct c4iw_ep *parent_ep, struct c4iw_ep *child_ep) | ||
| 587 | { | ||
| 588 | int ret; | ||
| 589 | |||
| 590 | print_addr(&parent_ep->com, __func__, "get_remote_addr parent_ep "); | ||
| 591 | print_addr(&child_ep->com, __func__, "get_remote_addr child_ep "); | ||
| 592 | |||
| 593 | ret = iwpm_get_remote_info(&parent_ep->com.mapped_local_addr, | ||
| 594 | &child_ep->com.mapped_remote_addr, | ||
| 595 | &child_ep->com.remote_addr, RDMA_NL_C4IW); | ||
| 596 | if (ret) | ||
| 597 | PDBG("Unable to find remote peer addr info - err %d\n", ret); | ||
| 598 | |||
| 599 | return ret; | ||
| 600 | } | ||
| 601 | |||
| 586 | static void best_mtu(const unsigned short *mtus, unsigned short mtu, | 602 | static void best_mtu(const unsigned short *mtus, unsigned short mtu, |
| 587 | unsigned int *idx, int use_ts, int ipv6) | 603 | unsigned int *idx, int use_ts, int ipv6) |
| 588 | { | 604 | { |
| @@ -675,7 +691,7 @@ static int send_connect(struct c4iw_ep *ep) | |||
| 675 | if (is_t5(ep->com.dev->rdev.lldi.adapter_type)) { | 691 | if (is_t5(ep->com.dev->rdev.lldi.adapter_type)) { |
| 676 | opt2 |= T5_OPT_2_VALID_F; | 692 | opt2 |= T5_OPT_2_VALID_F; |
| 677 | opt2 |= CONG_CNTRL_V(CONG_ALG_TAHOE); | 693 | opt2 |= CONG_CNTRL_V(CONG_ALG_TAHOE); |
| 678 | opt2 |= CONG_CNTRL_VALID; /* OPT_2_ISS for T5 */ | 694 | opt2 |= T5_ISS_F; |
| 679 | } | 695 | } |
| 680 | t4_set_arp_err_handler(skb, ep, act_open_req_arp_failure); | 696 | t4_set_arp_err_handler(skb, ep, act_open_req_arp_failure); |
| 681 | 697 | ||
| @@ -2042,9 +2058,12 @@ static int act_open_rpl(struct c4iw_dev *dev, struct sk_buff *skb) | |||
| 2042 | status, status2errno(status)); | 2058 | status, status2errno(status)); |
| 2043 | 2059 | ||
| 2044 | if (is_neg_adv(status)) { | 2060 | if (is_neg_adv(status)) { |
| 2045 | dev_warn(&dev->rdev.lldi.pdev->dev, | 2061 | PDBG("%s Connection problems for atid %u status %u (%s)\n", |
| 2046 | "Connection problems for atid %u status %u (%s)\n", | 2062 | __func__, atid, status, neg_adv_str(status)); |
| 2047 | atid, status, neg_adv_str(status)); | 2063 | ep->stats.connect_neg_adv++; |
| 2064 | mutex_lock(&dev->rdev.stats.lock); | ||
| 2065 | dev->rdev.stats.neg_adv++; | ||
| 2066 | mutex_unlock(&dev->rdev.stats.lock); | ||
| 2048 | return 0; | 2067 | return 0; |
| 2049 | } | 2068 | } |
| 2050 | 2069 | ||
| @@ -2214,7 +2233,7 @@ static void accept_cr(struct c4iw_ep *ep, struct sk_buff *skb, | |||
| 2214 | u32 isn = (prandom_u32() & ~7UL) - 1; | 2233 | u32 isn = (prandom_u32() & ~7UL) - 1; |
| 2215 | opt2 |= T5_OPT_2_VALID_F; | 2234 | opt2 |= T5_OPT_2_VALID_F; |
| 2216 | opt2 |= CONG_CNTRL_V(CONG_ALG_TAHOE); | 2235 | opt2 |= CONG_CNTRL_V(CONG_ALG_TAHOE); |
| 2217 | opt2 |= CONG_CNTRL_VALID; /* OPT_2_ISS for T5 */ | 2236 | opt2 |= T5_ISS_F; |
| 2218 | rpl5 = (void *)rpl; | 2237 | rpl5 = (void *)rpl; |
| 2219 | memset(&rpl5->iss, 0, roundup(sizeof(*rpl5)-sizeof(*rpl), 16)); | 2238 | memset(&rpl5->iss, 0, roundup(sizeof(*rpl5)-sizeof(*rpl), 16)); |
| 2220 | if (peer2peer) | 2239 | if (peer2peer) |
| @@ -2352,27 +2371,57 @@ static int pass_accept_req(struct c4iw_dev *dev, struct sk_buff *skb) | |||
| 2352 | state_set(&child_ep->com, CONNECTING); | 2371 | state_set(&child_ep->com, CONNECTING); |
| 2353 | child_ep->com.dev = dev; | 2372 | child_ep->com.dev = dev; |
| 2354 | child_ep->com.cm_id = NULL; | 2373 | child_ep->com.cm_id = NULL; |
| 2374 | |||
| 2375 | /* | ||
| 2376 | * The mapped_local and mapped_remote addresses get setup with | ||
| 2377 | * the actual 4-tuple. The local address will be based on the | ||
| 2378 | * actual local address of the connection, but on the port number | ||
| 2379 | * of the parent listening endpoint. The remote address is | ||
| 2380 | * setup based on a query to the IWPM since we don't know what it | ||
| 2381 | * originally was before mapping. If no mapping was done, then | ||
| 2382 | * mapped_remote == remote, and mapped_local == local. | ||
| 2383 | */ | ||
| 2355 | if (iptype == 4) { | 2384 | if (iptype == 4) { |
| 2356 | struct sockaddr_in *sin = (struct sockaddr_in *) | 2385 | struct sockaddr_in *sin = (struct sockaddr_in *) |
| 2357 | &child_ep->com.local_addr; | 2386 | &child_ep->com.mapped_local_addr; |
| 2387 | |||
| 2358 | sin->sin_family = PF_INET; | 2388 | sin->sin_family = PF_INET; |
| 2359 | sin->sin_port = local_port; | 2389 | sin->sin_port = local_port; |
| 2360 | sin->sin_addr.s_addr = *(__be32 *)local_ip; | 2390 | sin->sin_addr.s_addr = *(__be32 *)local_ip; |
| 2361 | sin = (struct sockaddr_in *)&child_ep->com.remote_addr; | 2391 | |
| 2392 | sin = (struct sockaddr_in *)&child_ep->com.local_addr; | ||
| 2393 | sin->sin_family = PF_INET; | ||
| 2394 | sin->sin_port = ((struct sockaddr_in *) | ||
| 2395 | &parent_ep->com.local_addr)->sin_port; | ||
| 2396 | sin->sin_addr.s_addr = *(__be32 *)local_ip; | ||
| 2397 | |||
| 2398 | sin = (struct sockaddr_in *)&child_ep->com.mapped_remote_addr; | ||
| 2362 | sin->sin_family = PF_INET; | 2399 | sin->sin_family = PF_INET; |
| 2363 | sin->sin_port = peer_port; | 2400 | sin->sin_port = peer_port; |
| 2364 | sin->sin_addr.s_addr = *(__be32 *)peer_ip; | 2401 | sin->sin_addr.s_addr = *(__be32 *)peer_ip; |
| 2365 | } else { | 2402 | } else { |
| 2366 | struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *) | 2403 | struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *) |
| 2367 | &child_ep->com.local_addr; | 2404 | &child_ep->com.mapped_local_addr; |
| 2405 | |||
| 2368 | sin6->sin6_family = PF_INET6; | 2406 | sin6->sin6_family = PF_INET6; |
| 2369 | sin6->sin6_port = local_port; | 2407 | sin6->sin6_port = local_port; |
| 2370 | memcpy(sin6->sin6_addr.s6_addr, local_ip, 16); | 2408 | memcpy(sin6->sin6_addr.s6_addr, local_ip, 16); |
| 2371 | sin6 = (struct sockaddr_in6 *)&child_ep->com.remote_addr; | 2409 | |
| 2410 | sin6 = (struct sockaddr_in6 *)&child_ep->com.local_addr; | ||
| 2411 | sin6->sin6_family = PF_INET6; | ||
| 2412 | sin6->sin6_port = ((struct sockaddr_in6 *) | ||
| 2413 | &parent_ep->com.local_addr)->sin6_port; | ||
| 2414 | memcpy(sin6->sin6_addr.s6_addr, local_ip, 16); | ||
| 2415 | |||
| 2416 | sin6 = (struct sockaddr_in6 *)&child_ep->com.mapped_remote_addr; | ||
| 2372 | sin6->sin6_family = PF_INET6; | 2417 | sin6->sin6_family = PF_INET6; |
| 2373 | sin6->sin6_port = peer_port; | 2418 | sin6->sin6_port = peer_port; |
| 2374 | memcpy(sin6->sin6_addr.s6_addr, peer_ip, 16); | 2419 | memcpy(sin6->sin6_addr.s6_addr, peer_ip, 16); |
| 2375 | } | 2420 | } |
| 2421 | memcpy(&child_ep->com.remote_addr, &child_ep->com.mapped_remote_addr, | ||
| 2422 | sizeof(child_ep->com.remote_addr)); | ||
| 2423 | get_remote_addr(parent_ep, child_ep); | ||
| 2424 | |||
| 2376 | c4iw_get_ep(&parent_ep->com); | 2425 | c4iw_get_ep(&parent_ep->com); |
| 2377 | child_ep->parent_ep = parent_ep; | 2426 | child_ep->parent_ep = parent_ep; |
| 2378 | child_ep->tos = PASS_OPEN_TOS_G(ntohl(req->tos_stid)); | 2427 | child_ep->tos = PASS_OPEN_TOS_G(ntohl(req->tos_stid)); |
| @@ -2520,9 +2569,13 @@ static int peer_abort(struct c4iw_dev *dev, struct sk_buff *skb) | |||
| 2520 | 2569 | ||
| 2521 | ep = lookup_tid(t, tid); | 2570 | ep = lookup_tid(t, tid); |
| 2522 | if (is_neg_adv(req->status)) { | 2571 | if (is_neg_adv(req->status)) { |
| 2523 | dev_warn(&dev->rdev.lldi.pdev->dev, | 2572 | PDBG("%s Negative advice on abort- tid %u status %d (%s)\n", |
| 2524 | "Negative advice on abort - tid %u status %d (%s)\n", | 2573 | __func__, ep->hwtid, req->status, |
| 2525 | ep->hwtid, req->status, neg_adv_str(req->status)); | 2574 | neg_adv_str(req->status)); |
| 2575 | ep->stats.abort_neg_adv++; | ||
| 2576 | mutex_lock(&dev->rdev.stats.lock); | ||
| 2577 | dev->rdev.stats.neg_adv++; | ||
| 2578 | mutex_unlock(&dev->rdev.stats.lock); | ||
| 2526 | return 0; | 2579 | return 0; |
| 2527 | } | 2580 | } |
| 2528 | PDBG("%s ep %p tid %u state %u\n", __func__, ep, ep->hwtid, | 2581 | PDBG("%s ep %p tid %u state %u\n", __func__, ep, ep->hwtid, |
| @@ -3571,7 +3624,7 @@ static void send_fw_pass_open_req(struct c4iw_dev *dev, struct sk_buff *skb, | |||
| 3571 | * TP will ignore any value > 0 for MSS index. | 3624 | * TP will ignore any value > 0 for MSS index. |
| 3572 | */ | 3625 | */ |
| 3573 | req->tcb.opt0 = cpu_to_be64(MSS_IDX_V(0xF)); | 3626 | req->tcb.opt0 = cpu_to_be64(MSS_IDX_V(0xF)); |
| 3574 | req->cookie = (unsigned long)skb; | 3627 | req->cookie = (uintptr_t)skb; |
| 3575 | 3628 | ||
| 3576 | set_wr_txq(req_skb, CPL_PRIORITY_CONTROL, port_id); | 3629 | set_wr_txq(req_skb, CPL_PRIORITY_CONTROL, port_id); |
| 3577 | ret = cxgb4_ofld_send(dev->rdev.lldi.ports[0], req_skb); | 3630 | ret = cxgb4_ofld_send(dev->rdev.lldi.ports[0], req_skb); |
| @@ -3931,9 +3984,11 @@ static int peer_abort_intr(struct c4iw_dev *dev, struct sk_buff *skb) | |||
| 3931 | return 0; | 3984 | return 0; |
| 3932 | } | 3985 | } |
| 3933 | if (is_neg_adv(req->status)) { | 3986 | if (is_neg_adv(req->status)) { |
| 3934 | dev_warn(&dev->rdev.lldi.pdev->dev, | 3987 | PDBG("%s Negative advice on abort- tid %u status %d (%s)\n", |
| 3935 | "Negative advice on abort - tid %u status %d (%s)\n", | 3988 | __func__, ep->hwtid, req->status, |
| 3936 | ep->hwtid, req->status, neg_adv_str(req->status)); | 3989 | neg_adv_str(req->status)); |
| 3990 | ep->stats.abort_neg_adv++; | ||
| 3991 | dev->rdev.stats.neg_adv++; | ||
| 3937 | kfree_skb(skb); | 3992 | kfree_skb(skb); |
| 3938 | return 0; | 3993 | return 0; |
| 3939 | } | 3994 | } |
diff --git a/drivers/infiniband/hw/cxgb4/cq.c b/drivers/infiniband/hw/cxgb4/cq.c index ab7692ac2044..68ddb3710215 100644 --- a/drivers/infiniband/hw/cxgb4/cq.c +++ b/drivers/infiniband/hw/cxgb4/cq.c | |||
| @@ -55,7 +55,7 @@ static int destroy_cq(struct c4iw_rdev *rdev, struct t4_cq *cq, | |||
| 55 | FW_RI_RES_WR_NRES_V(1) | | 55 | FW_RI_RES_WR_NRES_V(1) | |
| 56 | FW_WR_COMPL_F); | 56 | FW_WR_COMPL_F); |
| 57 | res_wr->len16_pkd = cpu_to_be32(DIV_ROUND_UP(wr_len, 16)); | 57 | res_wr->len16_pkd = cpu_to_be32(DIV_ROUND_UP(wr_len, 16)); |
| 58 | res_wr->cookie = (unsigned long) &wr_wait; | 58 | res_wr->cookie = (uintptr_t)&wr_wait; |
| 59 | res = res_wr->res; | 59 | res = res_wr->res; |
| 60 | res->u.cq.restype = FW_RI_RES_TYPE_CQ; | 60 | res->u.cq.restype = FW_RI_RES_TYPE_CQ; |
| 61 | res->u.cq.op = FW_RI_RES_OP_RESET; | 61 | res->u.cq.op = FW_RI_RES_OP_RESET; |
| @@ -125,7 +125,7 @@ static int create_cq(struct c4iw_rdev *rdev, struct t4_cq *cq, | |||
| 125 | FW_RI_RES_WR_NRES_V(1) | | 125 | FW_RI_RES_WR_NRES_V(1) | |
| 126 | FW_WR_COMPL_F); | 126 | FW_WR_COMPL_F); |
| 127 | res_wr->len16_pkd = cpu_to_be32(DIV_ROUND_UP(wr_len, 16)); | 127 | res_wr->len16_pkd = cpu_to_be32(DIV_ROUND_UP(wr_len, 16)); |
| 128 | res_wr->cookie = (unsigned long) &wr_wait; | 128 | res_wr->cookie = (uintptr_t)&wr_wait; |
| 129 | res = res_wr->res; | 129 | res = res_wr->res; |
| 130 | res->u.cq.restype = FW_RI_RES_TYPE_CQ; | 130 | res->u.cq.restype = FW_RI_RES_TYPE_CQ; |
| 131 | res->u.cq.op = FW_RI_RES_OP_WRITE; | 131 | res->u.cq.op = FW_RI_RES_OP_WRITE; |
| @@ -156,12 +156,19 @@ static int create_cq(struct c4iw_rdev *rdev, struct t4_cq *cq, | |||
| 156 | goto err4; | 156 | goto err4; |
| 157 | 157 | ||
| 158 | cq->gen = 1; | 158 | cq->gen = 1; |
| 159 | cq->gts = rdev->lldi.gts_reg; | ||
| 160 | cq->rdev = rdev; | 159 | cq->rdev = rdev; |
| 161 | if (user) { | 160 | if (user) { |
| 162 | cq->ugts = (u64)pci_resource_start(rdev->lldi.pdev, 2) + | 161 | u32 off = (cq->cqid << rdev->cqshift) & PAGE_MASK; |
| 163 | (cq->cqid << rdev->cqshift); | 162 | |
| 164 | cq->ugts &= PAGE_MASK; | 163 | cq->ugts = (u64)rdev->bar2_pa + off; |
| 164 | } else if (is_t4(rdev->lldi.adapter_type)) { | ||
| 165 | cq->gts = rdev->lldi.gts_reg; | ||
| 166 | cq->qid_mask = -1U; | ||
| 167 | } else { | ||
| 168 | u32 off = ((cq->cqid << rdev->cqshift) & PAGE_MASK) + 12; | ||
| 169 | |||
| 170 | cq->gts = rdev->bar2_kva + off; | ||
| 171 | cq->qid_mask = rdev->qpmask; | ||
| 165 | } | 172 | } |
| 166 | return 0; | 173 | return 0; |
| 167 | err4: | 174 | err4: |
| @@ -970,8 +977,7 @@ struct ib_cq *c4iw_create_cq(struct ib_device *ibdev, int entries, | |||
| 970 | } | 977 | } |
| 971 | PDBG("%s cqid 0x%0x chp %p size %u memsize %zu, dma_addr 0x%0llx\n", | 978 | PDBG("%s cqid 0x%0x chp %p size %u memsize %zu, dma_addr 0x%0llx\n", |
| 972 | __func__, chp->cq.cqid, chp, chp->cq.size, | 979 | __func__, chp->cq.cqid, chp, chp->cq.size, |
| 973 | chp->cq.memsize, | 980 | chp->cq.memsize, (unsigned long long) chp->cq.dma_addr); |
| 974 | (unsigned long long) chp->cq.dma_addr); | ||
| 975 | return &chp->ibcq; | 981 | return &chp->ibcq; |
| 976 | err5: | 982 | err5: |
| 977 | kfree(mm2); | 983 | kfree(mm2); |
diff --git a/drivers/infiniband/hw/cxgb4/device.c b/drivers/infiniband/hw/cxgb4/device.c index 8fb295e4a9ab..7e895d714b19 100644 --- a/drivers/infiniband/hw/cxgb4/device.c +++ b/drivers/infiniband/hw/cxgb4/device.c | |||
| @@ -93,6 +93,7 @@ static struct ibnl_client_cbs c4iw_nl_cb_table[] = { | |||
| 93 | [RDMA_NL_IWPM_ADD_MAPPING] = {.dump = iwpm_add_mapping_cb}, | 93 | [RDMA_NL_IWPM_ADD_MAPPING] = {.dump = iwpm_add_mapping_cb}, |
| 94 | [RDMA_NL_IWPM_QUERY_MAPPING] = {.dump = iwpm_add_and_query_mapping_cb}, | 94 | [RDMA_NL_IWPM_QUERY_MAPPING] = {.dump = iwpm_add_and_query_mapping_cb}, |
| 95 | [RDMA_NL_IWPM_HANDLE_ERR] = {.dump = iwpm_mapping_error_cb}, | 95 | [RDMA_NL_IWPM_HANDLE_ERR] = {.dump = iwpm_mapping_error_cb}, |
| 96 | [RDMA_NL_IWPM_REMOTE_INFO] = {.dump = iwpm_remote_info_cb}, | ||
| 96 | [RDMA_NL_IWPM_MAPINFO] = {.dump = iwpm_mapping_info_cb}, | 97 | [RDMA_NL_IWPM_MAPINFO] = {.dump = iwpm_mapping_info_cb}, |
| 97 | [RDMA_NL_IWPM_MAPINFO_NUM] = {.dump = iwpm_ack_mapping_info_cb} | 98 | [RDMA_NL_IWPM_MAPINFO_NUM] = {.dump = iwpm_ack_mapping_info_cb} |
| 98 | }; | 99 | }; |
| @@ -151,7 +152,7 @@ static int wr_log_show(struct seq_file *seq, void *v) | |||
| 151 | int prev_ts_set = 0; | 152 | int prev_ts_set = 0; |
| 152 | int idx, end; | 153 | int idx, end; |
| 153 | 154 | ||
| 154 | #define ts2ns(ts) div64_ul((ts) * dev->rdev.lldi.cclk_ps, 1000) | 155 | #define ts2ns(ts) div64_u64((ts) * dev->rdev.lldi.cclk_ps, 1000) |
| 155 | 156 | ||
| 156 | idx = atomic_read(&dev->rdev.wr_log_idx) & | 157 | idx = atomic_read(&dev->rdev.wr_log_idx) & |
| 157 | (dev->rdev.wr_log_size - 1); | 158 | (dev->rdev.wr_log_size - 1); |
| @@ -489,6 +490,7 @@ static int stats_show(struct seq_file *seq, void *v) | |||
| 489 | dev->rdev.stats.act_ofld_conn_fails); | 490 | dev->rdev.stats.act_ofld_conn_fails); |
| 490 | seq_printf(seq, "PAS_OFLD_CONN_FAILS: %10llu\n", | 491 | seq_printf(seq, "PAS_OFLD_CONN_FAILS: %10llu\n", |
| 491 | dev->rdev.stats.pas_ofld_conn_fails); | 492 | dev->rdev.stats.pas_ofld_conn_fails); |
| 493 | seq_printf(seq, "NEG_ADV_RCVD: %10llu\n", dev->rdev.stats.neg_adv); | ||
| 492 | seq_printf(seq, "AVAILABLE IRD: %10u\n", dev->avail_ird); | 494 | seq_printf(seq, "AVAILABLE IRD: %10u\n", dev->avail_ird); |
| 493 | return 0; | 495 | return 0; |
| 494 | } | 496 | } |
| @@ -560,10 +562,13 @@ static int dump_ep(int id, void *p, void *data) | |||
| 560 | cc = snprintf(epd->buf + epd->pos, space, | 562 | cc = snprintf(epd->buf + epd->pos, space, |
| 561 | "ep %p cm_id %p qp %p state %d flags 0x%lx " | 563 | "ep %p cm_id %p qp %p state %d flags 0x%lx " |
| 562 | "history 0x%lx hwtid %d atid %d " | 564 | "history 0x%lx hwtid %d atid %d " |
| 565 | "conn_na %u abort_na %u " | ||
| 563 | "%pI4:%d/%d <-> %pI4:%d/%d\n", | 566 | "%pI4:%d/%d <-> %pI4:%d/%d\n", |
| 564 | ep, ep->com.cm_id, ep->com.qp, | 567 | ep, ep->com.cm_id, ep->com.qp, |
| 565 | (int)ep->com.state, ep->com.flags, | 568 | (int)ep->com.state, ep->com.flags, |
| 566 | ep->com.history, ep->hwtid, ep->atid, | 569 | ep->com.history, ep->hwtid, ep->atid, |
| 570 | ep->stats.connect_neg_adv, | ||
| 571 | ep->stats.abort_neg_adv, | ||
| 567 | &lsin->sin_addr, ntohs(lsin->sin_port), | 572 | &lsin->sin_addr, ntohs(lsin->sin_port), |
| 568 | ntohs(mapped_lsin->sin_port), | 573 | ntohs(mapped_lsin->sin_port), |
| 569 | &rsin->sin_addr, ntohs(rsin->sin_port), | 574 | &rsin->sin_addr, ntohs(rsin->sin_port), |
| @@ -581,10 +586,13 @@ static int dump_ep(int id, void *p, void *data) | |||
| 581 | cc = snprintf(epd->buf + epd->pos, space, | 586 | cc = snprintf(epd->buf + epd->pos, space, |
| 582 | "ep %p cm_id %p qp %p state %d flags 0x%lx " | 587 | "ep %p cm_id %p qp %p state %d flags 0x%lx " |
| 583 | "history 0x%lx hwtid %d atid %d " | 588 | "history 0x%lx hwtid %d atid %d " |
| 589 | "conn_na %u abort_na %u " | ||
| 584 | "%pI6:%d/%d <-> %pI6:%d/%d\n", | 590 | "%pI6:%d/%d <-> %pI6:%d/%d\n", |
| 585 | ep, ep->com.cm_id, ep->com.qp, | 591 | ep, ep->com.cm_id, ep->com.qp, |
| 586 | (int)ep->com.state, ep->com.flags, | 592 | (int)ep->com.state, ep->com.flags, |
| 587 | ep->com.history, ep->hwtid, ep->atid, | 593 | ep->com.history, ep->hwtid, ep->atid, |
| 594 | ep->stats.connect_neg_adv, | ||
| 595 | ep->stats.abort_neg_adv, | ||
| 588 | &lsin6->sin6_addr, ntohs(lsin6->sin6_port), | 596 | &lsin6->sin6_addr, ntohs(lsin6->sin6_port), |
| 589 | ntohs(mapped_lsin6->sin6_port), | 597 | ntohs(mapped_lsin6->sin6_port), |
| 590 | &rsin6->sin6_addr, ntohs(rsin6->sin6_port), | 598 | &rsin6->sin6_addr, ntohs(rsin6->sin6_port), |
| @@ -765,6 +773,29 @@ static int c4iw_rdev_open(struct c4iw_rdev *rdev) | |||
| 765 | c4iw_init_dev_ucontext(rdev, &rdev->uctx); | 773 | c4iw_init_dev_ucontext(rdev, &rdev->uctx); |
| 766 | 774 | ||
| 767 | /* | 775 | /* |
| 776 | * This implementation assumes udb_density == ucq_density! Eventually | ||
| 777 | * we might need to support this but for now fail the open. Also the | ||
| 778 | * cqid and qpid range must match for now. | ||
| 779 | */ | ||
| 780 | if (rdev->lldi.udb_density != rdev->lldi.ucq_density) { | ||
| 781 | pr_err(MOD "%s: unsupported udb/ucq densities %u/%u\n", | ||
| 782 | pci_name(rdev->lldi.pdev), rdev->lldi.udb_density, | ||
| 783 | rdev->lldi.ucq_density); | ||
| 784 | err = -EINVAL; | ||
| 785 | goto err1; | ||
| 786 | } | ||
| 787 | if (rdev->lldi.vr->qp.start != rdev->lldi.vr->cq.start || | ||
| 788 | rdev->lldi.vr->qp.size != rdev->lldi.vr->cq.size) { | ||
| 789 | pr_err(MOD "%s: unsupported qp and cq id ranges " | ||
| 790 | "qp start %u size %u cq start %u size %u\n", | ||
| 791 | pci_name(rdev->lldi.pdev), rdev->lldi.vr->qp.start, | ||
| 792 | rdev->lldi.vr->qp.size, rdev->lldi.vr->cq.size, | ||
| 793 | rdev->lldi.vr->cq.size); | ||
| 794 | err = -EINVAL; | ||
| 795 | goto err1; | ||
| 796 | } | ||
| 797 | |||
| 798 | /* | ||
| 768 | * qpshift is the number of bits to shift the qpid left in order | 799 | * qpshift is the number of bits to shift the qpid left in order |
| 769 | * to get the correct address of the doorbell for that qp. | 800 | * to get the correct address of the doorbell for that qp. |
| 770 | */ | 801 | */ |
| @@ -784,10 +815,10 @@ static int c4iw_rdev_open(struct c4iw_rdev *rdev) | |||
| 784 | rdev->lldi.vr->qp.size, | 815 | rdev->lldi.vr->qp.size, |
| 785 | rdev->lldi.vr->cq.start, | 816 | rdev->lldi.vr->cq.start, |
| 786 | rdev->lldi.vr->cq.size); | 817 | rdev->lldi.vr->cq.size); |
| 787 | PDBG("udb len 0x%x udb base %llx db_reg %p gts_reg %p qpshift %lu " | 818 | PDBG("udb len 0x%x udb base %p db_reg %p gts_reg %p qpshift %lu " |
| 788 | "qpmask 0x%x cqshift %lu cqmask 0x%x\n", | 819 | "qpmask 0x%x cqshift %lu cqmask 0x%x\n", |
| 789 | (unsigned)pci_resource_len(rdev->lldi.pdev, 2), | 820 | (unsigned)pci_resource_len(rdev->lldi.pdev, 2), |
| 790 | (u64)pci_resource_start(rdev->lldi.pdev, 2), | 821 | (void *)pci_resource_start(rdev->lldi.pdev, 2), |
| 791 | rdev->lldi.db_reg, | 822 | rdev->lldi.db_reg, |
| 792 | rdev->lldi.gts_reg, | 823 | rdev->lldi.gts_reg, |
| 793 | rdev->qpshift, rdev->qpmask, | 824 | rdev->qpshift, rdev->qpmask, |
| @@ -1355,7 +1386,7 @@ static void recover_lost_dbs(struct uld_ctx *ctx, struct qp_list *qp_list) | |||
| 1355 | t4_sq_host_wq_pidx(&qp->wq), | 1386 | t4_sq_host_wq_pidx(&qp->wq), |
| 1356 | t4_sq_wq_size(&qp->wq)); | 1387 | t4_sq_wq_size(&qp->wq)); |
| 1357 | if (ret) { | 1388 | if (ret) { |
| 1358 | pr_err(KERN_ERR MOD "%s: Fatal error - " | 1389 | pr_err(MOD "%s: Fatal error - " |
| 1359 | "DB overflow recovery failed - " | 1390 | "DB overflow recovery failed - " |
| 1360 | "error syncing SQ qid %u\n", | 1391 | "error syncing SQ qid %u\n", |
| 1361 | pci_name(ctx->lldi.pdev), qp->wq.sq.qid); | 1392 | pci_name(ctx->lldi.pdev), qp->wq.sq.qid); |
| @@ -1371,7 +1402,7 @@ static void recover_lost_dbs(struct uld_ctx *ctx, struct qp_list *qp_list) | |||
| 1371 | t4_rq_wq_size(&qp->wq)); | 1402 | t4_rq_wq_size(&qp->wq)); |
| 1372 | 1403 | ||
| 1373 | if (ret) { | 1404 | if (ret) { |
| 1374 | pr_err(KERN_ERR MOD "%s: Fatal error - " | 1405 | pr_err(MOD "%s: Fatal error - " |
| 1375 | "DB overflow recovery failed - " | 1406 | "DB overflow recovery failed - " |
| 1376 | "error syncing RQ qid %u\n", | 1407 | "error syncing RQ qid %u\n", |
| 1377 | pci_name(ctx->lldi.pdev), qp->wq.rq.qid); | 1408 | pci_name(ctx->lldi.pdev), qp->wq.rq.qid); |
diff --git a/drivers/infiniband/hw/cxgb4/iw_cxgb4.h b/drivers/infiniband/hw/cxgb4/iw_cxgb4.h index d87e1650f643..97bb5550a6cf 100644 --- a/drivers/infiniband/hw/cxgb4/iw_cxgb4.h +++ b/drivers/infiniband/hw/cxgb4/iw_cxgb4.h | |||
| @@ -137,6 +137,7 @@ struct c4iw_stats { | |||
| 137 | u64 tcam_full; | 137 | u64 tcam_full; |
| 138 | u64 act_ofld_conn_fails; | 138 | u64 act_ofld_conn_fails; |
| 139 | u64 pas_ofld_conn_fails; | 139 | u64 pas_ofld_conn_fails; |
| 140 | u64 neg_adv; | ||
| 140 | }; | 141 | }; |
| 141 | 142 | ||
| 142 | struct c4iw_hw_queue { | 143 | struct c4iw_hw_queue { |
| @@ -814,6 +815,11 @@ struct c4iw_listen_ep { | |||
| 814 | int backlog; | 815 | int backlog; |
| 815 | }; | 816 | }; |
| 816 | 817 | ||
| 818 | struct c4iw_ep_stats { | ||
| 819 | unsigned connect_neg_adv; | ||
| 820 | unsigned abort_neg_adv; | ||
| 821 | }; | ||
| 822 | |||
| 817 | struct c4iw_ep { | 823 | struct c4iw_ep { |
| 818 | struct c4iw_ep_common com; | 824 | struct c4iw_ep_common com; |
| 819 | struct c4iw_ep *parent_ep; | 825 | struct c4iw_ep *parent_ep; |
| @@ -846,6 +852,7 @@ struct c4iw_ep { | |||
| 846 | unsigned int retry_count; | 852 | unsigned int retry_count; |
| 847 | int snd_win; | 853 | int snd_win; |
| 848 | int rcv_win; | 854 | int rcv_win; |
| 855 | struct c4iw_ep_stats stats; | ||
| 849 | }; | 856 | }; |
| 850 | 857 | ||
| 851 | static inline void print_addr(struct c4iw_ep_common *epc, const char *func, | 858 | static inline void print_addr(struct c4iw_ep_common *epc, const char *func, |
diff --git a/drivers/infiniband/hw/cxgb4/mem.c b/drivers/infiniband/hw/cxgb4/mem.c index 3ef0cf9f5c44..cff815b91707 100644 --- a/drivers/infiniband/hw/cxgb4/mem.c +++ b/drivers/infiniband/hw/cxgb4/mem.c | |||
| @@ -144,7 +144,7 @@ static int _c4iw_write_mem_inline(struct c4iw_rdev *rdev, u32 addr, u32 len, | |||
| 144 | if (i == (num_wqe-1)) { | 144 | if (i == (num_wqe-1)) { |
| 145 | req->wr.wr_hi = cpu_to_be32(FW_WR_OP_V(FW_ULPTX_WR) | | 145 | req->wr.wr_hi = cpu_to_be32(FW_WR_OP_V(FW_ULPTX_WR) | |
| 146 | FW_WR_COMPL_F); | 146 | FW_WR_COMPL_F); |
| 147 | req->wr.wr_lo = (__force __be64)(unsigned long) &wr_wait; | 147 | req->wr.wr_lo = (__force __be64)&wr_wait; |
| 148 | } else | 148 | } else |
| 149 | req->wr.wr_hi = cpu_to_be32(FW_WR_OP_V(FW_ULPTX_WR)); | 149 | req->wr.wr_hi = cpu_to_be32(FW_WR_OP_V(FW_ULPTX_WR)); |
| 150 | req->wr.wr_mid = cpu_to_be32( | 150 | req->wr.wr_mid = cpu_to_be32( |
| @@ -676,12 +676,12 @@ struct ib_mr *c4iw_get_dma_mr(struct ib_pd *pd, int acc) | |||
| 676 | mhp->attr.zbva = 0; | 676 | mhp->attr.zbva = 0; |
| 677 | mhp->attr.va_fbo = 0; | 677 | mhp->attr.va_fbo = 0; |
| 678 | mhp->attr.page_size = 0; | 678 | mhp->attr.page_size = 0; |
| 679 | mhp->attr.len = ~0UL; | 679 | mhp->attr.len = ~0ULL; |
| 680 | mhp->attr.pbl_size = 0; | 680 | mhp->attr.pbl_size = 0; |
| 681 | 681 | ||
| 682 | ret = write_tpt_entry(&rhp->rdev, 0, &stag, 1, php->pdid, | 682 | ret = write_tpt_entry(&rhp->rdev, 0, &stag, 1, php->pdid, |
| 683 | FW_RI_STAG_NSMR, mhp->attr.perms, | 683 | FW_RI_STAG_NSMR, mhp->attr.perms, |
| 684 | mhp->attr.mw_bind_enable, 0, 0, ~0UL, 0, 0, 0); | 684 | mhp->attr.mw_bind_enable, 0, 0, ~0ULL, 0, 0, 0); |
| 685 | if (ret) | 685 | if (ret) |
| 686 | goto err1; | 686 | goto err1; |
| 687 | 687 | ||
diff --git a/drivers/infiniband/hw/cxgb4/qp.c b/drivers/infiniband/hw/cxgb4/qp.c index 15cae5a31018..389ced335bc5 100644 --- a/drivers/infiniband/hw/cxgb4/qp.c +++ b/drivers/infiniband/hw/cxgb4/qp.c | |||
| @@ -275,7 +275,7 @@ static int create_qp(struct c4iw_rdev *rdev, struct t4_wq *wq, | |||
| 275 | FW_RI_RES_WR_NRES_V(2) | | 275 | FW_RI_RES_WR_NRES_V(2) | |
| 276 | FW_WR_COMPL_F); | 276 | FW_WR_COMPL_F); |
| 277 | res_wr->len16_pkd = cpu_to_be32(DIV_ROUND_UP(wr_len, 16)); | 277 | res_wr->len16_pkd = cpu_to_be32(DIV_ROUND_UP(wr_len, 16)); |
| 278 | res_wr->cookie = (unsigned long) &wr_wait; | 278 | res_wr->cookie = (uintptr_t)&wr_wait; |
| 279 | res = res_wr->res; | 279 | res = res_wr->res; |
| 280 | res->u.sqrq.restype = FW_RI_RES_TYPE_SQ; | 280 | res->u.sqrq.restype = FW_RI_RES_TYPE_SQ; |
| 281 | res->u.sqrq.op = FW_RI_RES_OP_WRITE; | 281 | res->u.sqrq.op = FW_RI_RES_OP_WRITE; |
| @@ -1209,7 +1209,7 @@ static int rdma_fini(struct c4iw_dev *rhp, struct c4iw_qp *qhp, | |||
| 1209 | wqe->flowid_len16 = cpu_to_be32( | 1209 | wqe->flowid_len16 = cpu_to_be32( |
| 1210 | FW_WR_FLOWID_V(ep->hwtid) | | 1210 | FW_WR_FLOWID_V(ep->hwtid) | |
| 1211 | FW_WR_LEN16_V(DIV_ROUND_UP(sizeof(*wqe), 16))); | 1211 | FW_WR_LEN16_V(DIV_ROUND_UP(sizeof(*wqe), 16))); |
| 1212 | wqe->cookie = (unsigned long) &ep->com.wr_wait; | 1212 | wqe->cookie = (uintptr_t)&ep->com.wr_wait; |
| 1213 | 1213 | ||
| 1214 | wqe->u.fini.type = FW_RI_TYPE_FINI; | 1214 | wqe->u.fini.type = FW_RI_TYPE_FINI; |
| 1215 | ret = c4iw_ofld_send(&rhp->rdev, skb); | 1215 | ret = c4iw_ofld_send(&rhp->rdev, skb); |
| @@ -1279,7 +1279,7 @@ static int rdma_init(struct c4iw_dev *rhp, struct c4iw_qp *qhp) | |||
| 1279 | FW_WR_FLOWID_V(qhp->ep->hwtid) | | 1279 | FW_WR_FLOWID_V(qhp->ep->hwtid) | |
| 1280 | FW_WR_LEN16_V(DIV_ROUND_UP(sizeof(*wqe), 16))); | 1280 | FW_WR_LEN16_V(DIV_ROUND_UP(sizeof(*wqe), 16))); |
| 1281 | 1281 | ||
| 1282 | wqe->cookie = (unsigned long) &qhp->ep->com.wr_wait; | 1282 | wqe->cookie = (uintptr_t)&qhp->ep->com.wr_wait; |
| 1283 | 1283 | ||
| 1284 | wqe->u.init.type = FW_RI_TYPE_INIT; | 1284 | wqe->u.init.type = FW_RI_TYPE_INIT; |
| 1285 | wqe->u.init.mpareqbit_p2ptype = | 1285 | wqe->u.init.mpareqbit_p2ptype = |
| @@ -1766,11 +1766,11 @@ struct ib_qp *c4iw_create_qp(struct ib_pd *pd, struct ib_qp_init_attr *attrs, | |||
| 1766 | mm2->len = PAGE_ALIGN(qhp->wq.rq.memsize); | 1766 | mm2->len = PAGE_ALIGN(qhp->wq.rq.memsize); |
| 1767 | insert_mmap(ucontext, mm2); | 1767 | insert_mmap(ucontext, mm2); |
| 1768 | mm3->key = uresp.sq_db_gts_key; | 1768 | mm3->key = uresp.sq_db_gts_key; |
| 1769 | mm3->addr = (__force unsigned long) qhp->wq.sq.udb; | 1769 | mm3->addr = (__force unsigned long)qhp->wq.sq.udb; |
| 1770 | mm3->len = PAGE_SIZE; | 1770 | mm3->len = PAGE_SIZE; |
| 1771 | insert_mmap(ucontext, mm3); | 1771 | insert_mmap(ucontext, mm3); |
| 1772 | mm4->key = uresp.rq_db_gts_key; | 1772 | mm4->key = uresp.rq_db_gts_key; |
| 1773 | mm4->addr = (__force unsigned long) qhp->wq.rq.udb; | 1773 | mm4->addr = (__force unsigned long)qhp->wq.rq.udb; |
| 1774 | mm4->len = PAGE_SIZE; | 1774 | mm4->len = PAGE_SIZE; |
| 1775 | insert_mmap(ucontext, mm4); | 1775 | insert_mmap(ucontext, mm4); |
| 1776 | if (mm5) { | 1776 | if (mm5) { |
diff --git a/drivers/infiniband/hw/cxgb4/t4.h b/drivers/infiniband/hw/cxgb4/t4.h index 871cdcac7be2..7f2a6c244d25 100644 --- a/drivers/infiniband/hw/cxgb4/t4.h +++ b/drivers/infiniband/hw/cxgb4/t4.h | |||
| @@ -539,6 +539,7 @@ struct t4_cq { | |||
| 539 | size_t memsize; | 539 | size_t memsize; |
| 540 | __be64 bits_type_ts; | 540 | __be64 bits_type_ts; |
| 541 | u32 cqid; | 541 | u32 cqid; |
| 542 | u32 qid_mask; | ||
| 542 | int vector; | 543 | int vector; |
| 543 | u16 size; /* including status page */ | 544 | u16 size; /* including status page */ |
| 544 | u16 cidx; | 545 | u16 cidx; |
| @@ -563,12 +564,12 @@ static inline int t4_arm_cq(struct t4_cq *cq, int se) | |||
| 563 | set_bit(CQ_ARMED, &cq->flags); | 564 | set_bit(CQ_ARMED, &cq->flags); |
| 564 | while (cq->cidx_inc > CIDXINC_M) { | 565 | while (cq->cidx_inc > CIDXINC_M) { |
| 565 | val = SEINTARM_V(0) | CIDXINC_V(CIDXINC_M) | TIMERREG_V(7) | | 566 | val = SEINTARM_V(0) | CIDXINC_V(CIDXINC_M) | TIMERREG_V(7) | |
| 566 | INGRESSQID_V(cq->cqid); | 567 | INGRESSQID_V(cq->cqid & cq->qid_mask); |
| 567 | writel(val, cq->gts); | 568 | writel(val, cq->gts); |
| 568 | cq->cidx_inc -= CIDXINC_M; | 569 | cq->cidx_inc -= CIDXINC_M; |
| 569 | } | 570 | } |
| 570 | val = SEINTARM_V(se) | CIDXINC_V(cq->cidx_inc) | TIMERREG_V(6) | | 571 | val = SEINTARM_V(se) | CIDXINC_V(cq->cidx_inc) | TIMERREG_V(6) | |
| 571 | INGRESSQID_V(cq->cqid); | 572 | INGRESSQID_V(cq->cqid & cq->qid_mask); |
| 572 | writel(val, cq->gts); | 573 | writel(val, cq->gts); |
| 573 | cq->cidx_inc = 0; | 574 | cq->cidx_inc = 0; |
| 574 | return 0; | 575 | return 0; |
| @@ -601,7 +602,7 @@ static inline void t4_hwcq_consume(struct t4_cq *cq) | |||
| 601 | u32 val; | 602 | u32 val; |
| 602 | 603 | ||
| 603 | val = SEINTARM_V(0) | CIDXINC_V(cq->cidx_inc) | TIMERREG_V(7) | | 604 | val = SEINTARM_V(0) | CIDXINC_V(cq->cidx_inc) | TIMERREG_V(7) | |
| 604 | INGRESSQID_V(cq->cqid); | 605 | INGRESSQID_V(cq->cqid & cq->qid_mask); |
| 605 | writel(val, cq->gts); | 606 | writel(val, cq->gts); |
| 606 | cq->cidx_inc = 0; | 607 | cq->cidx_inc = 0; |
| 607 | } | 608 | } |
diff --git a/drivers/infiniband/hw/cxgb4/t4fw_ri_api.h b/drivers/infiniband/hw/cxgb4/t4fw_ri_api.h index 5e53327fc647..343e8daf2270 100644 --- a/drivers/infiniband/hw/cxgb4/t4fw_ri_api.h +++ b/drivers/infiniband/hw/cxgb4/t4fw_ri_api.h | |||
| @@ -848,6 +848,8 @@ enum { /* TCP congestion control algorithms */ | |||
| 848 | #define CONG_CNTRL_V(x) ((x) << CONG_CNTRL_S) | 848 | #define CONG_CNTRL_V(x) ((x) << CONG_CNTRL_S) |
| 849 | #define CONG_CNTRL_G(x) (((x) >> CONG_CNTRL_S) & CONG_CNTRL_M) | 849 | #define CONG_CNTRL_G(x) (((x) >> CONG_CNTRL_S) & CONG_CNTRL_M) |
| 850 | 850 | ||
| 851 | #define CONG_CNTRL_VALID (1 << 18) | 851 | #define T5_ISS_S 18 |
| 852 | #define T5_ISS_V(x) ((x) << T5_ISS_S) | ||
| 853 | #define T5_ISS_F T5_ISS_V(1U) | ||
| 852 | 854 | ||
| 853 | #endif /* _T4FW_RI_API_H_ */ | 855 | #endif /* _T4FW_RI_API_H_ */ |
diff --git a/drivers/infiniband/hw/ehca/ehca_mcast.c b/drivers/infiniband/hw/ehca/ehca_mcast.c index 120aedf9f989..cec181532924 100644 --- a/drivers/infiniband/hw/ehca/ehca_mcast.c +++ b/drivers/infiniband/hw/ehca/ehca_mcast.c | |||
| @@ -77,7 +77,7 @@ int ehca_attach_mcast(struct ib_qp *ibqp, union ib_gid *gid, u16 lid) | |||
| 77 | return -EINVAL; | 77 | return -EINVAL; |
| 78 | } | 78 | } |
| 79 | 79 | ||
| 80 | memcpy(&my_gid.raw, gid->raw, sizeof(union ib_gid)); | 80 | memcpy(&my_gid, gid->raw, sizeof(union ib_gid)); |
| 81 | 81 | ||
| 82 | subnet_prefix = be64_to_cpu(my_gid.global.subnet_prefix); | 82 | subnet_prefix = be64_to_cpu(my_gid.global.subnet_prefix); |
| 83 | interface_id = be64_to_cpu(my_gid.global.interface_id); | 83 | interface_id = be64_to_cpu(my_gid.global.interface_id); |
| @@ -114,7 +114,7 @@ int ehca_detach_mcast(struct ib_qp *ibqp, union ib_gid *gid, u16 lid) | |||
| 114 | return -EINVAL; | 114 | return -EINVAL; |
| 115 | } | 115 | } |
| 116 | 116 | ||
| 117 | memcpy(&my_gid.raw, gid->raw, sizeof(union ib_gid)); | 117 | memcpy(&my_gid, gid->raw, sizeof(union ib_gid)); |
| 118 | 118 | ||
| 119 | subnet_prefix = be64_to_cpu(my_gid.global.subnet_prefix); | 119 | subnet_prefix = be64_to_cpu(my_gid.global.subnet_prefix); |
| 120 | interface_id = be64_to_cpu(my_gid.global.interface_id); | 120 | interface_id = be64_to_cpu(my_gid.global.interface_id); |
diff --git a/drivers/infiniband/hw/mlx4/main.c b/drivers/infiniband/hw/mlx4/main.c index 57070c529dfb..cc64400d41ac 100644 --- a/drivers/infiniband/hw/mlx4/main.c +++ b/drivers/infiniband/hw/mlx4/main.c | |||
| @@ -1569,8 +1569,7 @@ static void reset_gids_task(struct work_struct *work) | |||
| 1569 | MLX4_CMD_TIME_CLASS_B, | 1569 | MLX4_CMD_TIME_CLASS_B, |
| 1570 | MLX4_CMD_WRAPPED); | 1570 | MLX4_CMD_WRAPPED); |
| 1571 | if (err) | 1571 | if (err) |
| 1572 | pr_warn(KERN_WARNING | 1572 | pr_warn("set port %d command failed\n", gw->port); |
| 1573 | "set port %d command failed\n", gw->port); | ||
| 1574 | } | 1573 | } |
| 1575 | 1574 | ||
| 1576 | mlx4_free_cmd_mailbox(dev, mailbox); | 1575 | mlx4_free_cmd_mailbox(dev, mailbox); |
diff --git a/drivers/infiniband/hw/mlx5/qp.c b/drivers/infiniband/hw/mlx5/qp.c index 4d7024b899cb..d35f62d4f4c5 100644 --- a/drivers/infiniband/hw/mlx5/qp.c +++ b/drivers/infiniband/hw/mlx5/qp.c | |||
| @@ -1392,7 +1392,7 @@ static int mlx5_set_path(struct mlx5_ib_dev *dev, const struct ib_ah_attr *ah, | |||
| 1392 | 1392 | ||
| 1393 | if (ah->ah_flags & IB_AH_GRH) { | 1393 | if (ah->ah_flags & IB_AH_GRH) { |
| 1394 | if (ah->grh.sgid_index >= gen->port[port - 1].gid_table_len) { | 1394 | if (ah->grh.sgid_index >= gen->port[port - 1].gid_table_len) { |
| 1395 | pr_err(KERN_ERR "sgid_index (%u) too large. max is %d\n", | 1395 | pr_err("sgid_index (%u) too large. max is %d\n", |
| 1396 | ah->grh.sgid_index, gen->port[port - 1].gid_table_len); | 1396 | ah->grh.sgid_index, gen->port[port - 1].gid_table_len); |
| 1397 | return -EINVAL; | 1397 | return -EINVAL; |
| 1398 | } | 1398 | } |
diff --git a/drivers/infiniband/hw/nes/nes.c b/drivers/infiniband/hw/nes/nes.c index 3b2a6dc8ea99..9f9d5c563a61 100644 --- a/drivers/infiniband/hw/nes/nes.c +++ b/drivers/infiniband/hw/nes/nes.c | |||
| @@ -116,6 +116,7 @@ static struct ibnl_client_cbs nes_nl_cb_table[] = { | |||
| 116 | [RDMA_NL_IWPM_REG_PID] = {.dump = iwpm_register_pid_cb}, | 116 | [RDMA_NL_IWPM_REG_PID] = {.dump = iwpm_register_pid_cb}, |
| 117 | [RDMA_NL_IWPM_ADD_MAPPING] = {.dump = iwpm_add_mapping_cb}, | 117 | [RDMA_NL_IWPM_ADD_MAPPING] = {.dump = iwpm_add_mapping_cb}, |
| 118 | [RDMA_NL_IWPM_QUERY_MAPPING] = {.dump = iwpm_add_and_query_mapping_cb}, | 118 | [RDMA_NL_IWPM_QUERY_MAPPING] = {.dump = iwpm_add_and_query_mapping_cb}, |
| 119 | [RDMA_NL_IWPM_REMOTE_INFO] = {.dump = iwpm_remote_info_cb}, | ||
| 119 | [RDMA_NL_IWPM_HANDLE_ERR] = {.dump = iwpm_mapping_error_cb}, | 120 | [RDMA_NL_IWPM_HANDLE_ERR] = {.dump = iwpm_mapping_error_cb}, |
| 120 | [RDMA_NL_IWPM_MAPINFO] = {.dump = iwpm_mapping_info_cb}, | 121 | [RDMA_NL_IWPM_MAPINFO] = {.dump = iwpm_mapping_info_cb}, |
| 121 | [RDMA_NL_IWPM_MAPINFO_NUM] = {.dump = iwpm_ack_mapping_info_cb} | 122 | [RDMA_NL_IWPM_MAPINFO_NUM] = {.dump = iwpm_ack_mapping_info_cb} |
diff --git a/drivers/infiniband/hw/nes/nes_cm.c b/drivers/infiniband/hw/nes/nes_cm.c index 6f09a72e78d7..72b43417cbe3 100644 --- a/drivers/infiniband/hw/nes/nes_cm.c +++ b/drivers/infiniband/hw/nes/nes_cm.c | |||
| @@ -596,27 +596,52 @@ static void nes_form_reg_msg(struct nes_vnic *nesvnic, | |||
| 596 | memcpy(pm_msg->if_name, nesvnic->netdev->name, IWPM_IFNAME_SIZE); | 596 | memcpy(pm_msg->if_name, nesvnic->netdev->name, IWPM_IFNAME_SIZE); |
| 597 | } | 597 | } |
| 598 | 598 | ||
| 599 | static void record_sockaddr_info(struct sockaddr_storage *addr_info, | ||
| 600 | nes_addr_t *ip_addr, u16 *port_num) | ||
| 601 | { | ||
| 602 | struct sockaddr_in *in_addr = (struct sockaddr_in *)addr_info; | ||
| 603 | |||
| 604 | if (in_addr->sin_family == AF_INET) { | ||
| 605 | *ip_addr = ntohl(in_addr->sin_addr.s_addr); | ||
| 606 | *port_num = ntohs(in_addr->sin_port); | ||
| 607 | } | ||
| 608 | } | ||
| 609 | |||
| 599 | /* | 610 | /* |
| 600 | * nes_record_pm_msg - Save the received mapping info | 611 | * nes_record_pm_msg - Save the received mapping info |
| 601 | */ | 612 | */ |
| 602 | static void nes_record_pm_msg(struct nes_cm_info *cm_info, | 613 | static void nes_record_pm_msg(struct nes_cm_info *cm_info, |
| 603 | struct iwpm_sa_data *pm_msg) | 614 | struct iwpm_sa_data *pm_msg) |
| 604 | { | 615 | { |
| 605 | struct sockaddr_in *mapped_loc_addr = | 616 | record_sockaddr_info(&pm_msg->mapped_loc_addr, |
| 606 | (struct sockaddr_in *)&pm_msg->mapped_loc_addr; | 617 | &cm_info->mapped_loc_addr, &cm_info->mapped_loc_port); |
| 607 | struct sockaddr_in *mapped_rem_addr = | 618 | |
| 608 | (struct sockaddr_in *)&pm_msg->mapped_rem_addr; | 619 | record_sockaddr_info(&pm_msg->mapped_rem_addr, |
| 609 | 620 | &cm_info->mapped_rem_addr, &cm_info->mapped_rem_port); | |
| 610 | if (mapped_loc_addr->sin_family == AF_INET) { | 621 | } |
| 611 | cm_info->mapped_loc_addr = | 622 | |
| 612 | ntohl(mapped_loc_addr->sin_addr.s_addr); | 623 | /* |
| 613 | cm_info->mapped_loc_port = ntohs(mapped_loc_addr->sin_port); | 624 | * nes_get_reminfo - Get the address info of the remote connecting peer |
| 614 | } | 625 | */ |
| 615 | if (mapped_rem_addr->sin_family == AF_INET) { | 626 | static int nes_get_remote_addr(struct nes_cm_node *cm_node) |
| 616 | cm_info->mapped_rem_addr = | 627 | { |
| 617 | ntohl(mapped_rem_addr->sin_addr.s_addr); | 628 | struct sockaddr_storage mapped_loc_addr, mapped_rem_addr; |
| 618 | cm_info->mapped_rem_port = ntohs(mapped_rem_addr->sin_port); | 629 | struct sockaddr_storage remote_addr; |
| 619 | } | 630 | int ret; |
| 631 | |||
| 632 | nes_create_sockaddr(htonl(cm_node->mapped_loc_addr), | ||
| 633 | htons(cm_node->mapped_loc_port), &mapped_loc_addr); | ||
| 634 | nes_create_sockaddr(htonl(cm_node->mapped_rem_addr), | ||
| 635 | htons(cm_node->mapped_rem_port), &mapped_rem_addr); | ||
| 636 | |||
| 637 | ret = iwpm_get_remote_info(&mapped_loc_addr, &mapped_rem_addr, | ||
| 638 | &remote_addr, RDMA_NL_NES); | ||
| 639 | if (ret) | ||
| 640 | nes_debug(NES_DBG_CM, "Unable to find remote peer address info\n"); | ||
| 641 | else | ||
| 642 | record_sockaddr_info(&remote_addr, &cm_node->rem_addr, | ||
| 643 | &cm_node->rem_port); | ||
| 644 | return ret; | ||
| 620 | } | 645 | } |
| 621 | 646 | ||
| 622 | /** | 647 | /** |
| @@ -1566,9 +1591,14 @@ static struct nes_cm_node *make_cm_node(struct nes_cm_core *cm_core, | |||
| 1566 | return NULL; | 1591 | return NULL; |
| 1567 | 1592 | ||
| 1568 | /* set our node specific transport info */ | 1593 | /* set our node specific transport info */ |
| 1569 | cm_node->loc_addr = cm_info->loc_addr; | 1594 | if (listener) { |
| 1595 | cm_node->loc_addr = listener->loc_addr; | ||
| 1596 | cm_node->loc_port = listener->loc_port; | ||
| 1597 | } else { | ||
| 1598 | cm_node->loc_addr = cm_info->loc_addr; | ||
| 1599 | cm_node->loc_port = cm_info->loc_port; | ||
| 1600 | } | ||
| 1570 | cm_node->rem_addr = cm_info->rem_addr; | 1601 | cm_node->rem_addr = cm_info->rem_addr; |
| 1571 | cm_node->loc_port = cm_info->loc_port; | ||
| 1572 | cm_node->rem_port = cm_info->rem_port; | 1602 | cm_node->rem_port = cm_info->rem_port; |
| 1573 | 1603 | ||
| 1574 | cm_node->mapped_loc_addr = cm_info->mapped_loc_addr; | 1604 | cm_node->mapped_loc_addr = cm_info->mapped_loc_addr; |
| @@ -2151,6 +2181,7 @@ static int handle_ack_pkt(struct nes_cm_node *cm_node, struct sk_buff *skb, | |||
| 2151 | cm_node->state = NES_CM_STATE_ESTABLISHED; | 2181 | cm_node->state = NES_CM_STATE_ESTABLISHED; |
| 2152 | if (datasize) { | 2182 | if (datasize) { |
| 2153 | cm_node->tcp_cntxt.rcv_nxt = inc_sequence + datasize; | 2183 | cm_node->tcp_cntxt.rcv_nxt = inc_sequence + datasize; |
| 2184 | nes_get_remote_addr(cm_node); | ||
| 2154 | handle_rcv_mpa(cm_node, skb); | 2185 | handle_rcv_mpa(cm_node, skb); |
| 2155 | } else { /* rcvd ACK only */ | 2186 | } else { /* rcvd ACK only */ |
| 2156 | dev_kfree_skb_any(skb); | 2187 | dev_kfree_skb_any(skb); |
diff --git a/drivers/infiniband/hw/qib/qib.h b/drivers/infiniband/hw/qib/qib.h index ffd48bfc4923..7df16f74bb45 100644 --- a/drivers/infiniband/hw/qib/qib.h +++ b/drivers/infiniband/hw/qib/qib.h | |||
| @@ -903,7 +903,7 @@ struct qib_devdata { | |||
| 903 | /* PCI Device ID (here for NodeInfo) */ | 903 | /* PCI Device ID (here for NodeInfo) */ |
| 904 | u16 deviceid; | 904 | u16 deviceid; |
| 905 | /* for write combining settings */ | 905 | /* for write combining settings */ |
| 906 | unsigned long wc_cookie; | 906 | int wc_cookie; |
| 907 | unsigned long wc_base; | 907 | unsigned long wc_base; |
| 908 | unsigned long wc_len; | 908 | unsigned long wc_len; |
| 909 | 909 | ||
| @@ -1136,7 +1136,6 @@ extern struct qib_devdata *qib_lookup(int unit); | |||
| 1136 | extern u32 qib_cpulist_count; | 1136 | extern u32 qib_cpulist_count; |
| 1137 | extern unsigned long *qib_cpulist; | 1137 | extern unsigned long *qib_cpulist; |
| 1138 | 1138 | ||
| 1139 | extern unsigned qib_wc_pat; | ||
| 1140 | extern unsigned qib_cc_table_size; | 1139 | extern unsigned qib_cc_table_size; |
| 1141 | int qib_init(struct qib_devdata *, int); | 1140 | int qib_init(struct qib_devdata *, int); |
| 1142 | int init_chip_wc_pat(struct qib_devdata *dd, u32); | 1141 | int init_chip_wc_pat(struct qib_devdata *dd, u32); |
diff --git a/drivers/infiniband/hw/qib/qib_file_ops.c b/drivers/infiniband/hw/qib/qib_file_ops.c index 9ea6c440a00c..725881890c4a 100644 --- a/drivers/infiniband/hw/qib/qib_file_ops.c +++ b/drivers/infiniband/hw/qib/qib_file_ops.c | |||
| @@ -835,7 +835,8 @@ static int mmap_piobufs(struct vm_area_struct *vma, | |||
| 835 | vma->vm_flags &= ~VM_MAYREAD; | 835 | vma->vm_flags &= ~VM_MAYREAD; |
| 836 | vma->vm_flags |= VM_DONTCOPY | VM_DONTEXPAND; | 836 | vma->vm_flags |= VM_DONTCOPY | VM_DONTEXPAND; |
| 837 | 837 | ||
| 838 | if (qib_wc_pat) | 838 | /* We used PAT if wc_cookie == 0 */ |
| 839 | if (!dd->wc_cookie) | ||
| 839 | vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot); | 840 | vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot); |
| 840 | 841 | ||
| 841 | ret = io_remap_pfn_range(vma, vma->vm_start, phys >> PAGE_SHIFT, | 842 | ret = io_remap_pfn_range(vma, vma->vm_start, phys >> PAGE_SHIFT, |
diff --git a/drivers/infiniband/hw/qib/qib_iba6120.c b/drivers/infiniband/hw/qib/qib_iba6120.c index 0d2ba59af30a..4b927809d1a1 100644 --- a/drivers/infiniband/hw/qib/qib_iba6120.c +++ b/drivers/infiniband/hw/qib/qib_iba6120.c | |||
| @@ -3315,11 +3315,9 @@ static int init_6120_variables(struct qib_devdata *dd) | |||
| 3315 | qib_6120_config_ctxts(dd); | 3315 | qib_6120_config_ctxts(dd); |
| 3316 | qib_set_ctxtcnt(dd); | 3316 | qib_set_ctxtcnt(dd); |
| 3317 | 3317 | ||
| 3318 | if (qib_wc_pat) { | 3318 | ret = init_chip_wc_pat(dd, 0); |
| 3319 | ret = init_chip_wc_pat(dd, 0); | 3319 | if (ret) |
| 3320 | if (ret) | 3320 | goto bail; |
| 3321 | goto bail; | ||
| 3322 | } | ||
| 3323 | set_6120_baseaddrs(dd); /* set chip access pointers now */ | 3321 | set_6120_baseaddrs(dd); /* set chip access pointers now */ |
| 3324 | 3322 | ||
| 3325 | ret = 0; | 3323 | ret = 0; |
diff --git a/drivers/infiniband/hw/qib/qib_iba7220.c b/drivers/infiniband/hw/qib/qib_iba7220.c index 22affda8af88..00b2af211157 100644 --- a/drivers/infiniband/hw/qib/qib_iba7220.c +++ b/drivers/infiniband/hw/qib/qib_iba7220.c | |||
| @@ -4126,11 +4126,9 @@ static int qib_init_7220_variables(struct qib_devdata *dd) | |||
| 4126 | qib_7220_config_ctxts(dd); | 4126 | qib_7220_config_ctxts(dd); |
| 4127 | qib_set_ctxtcnt(dd); /* needed for PAT setup */ | 4127 | qib_set_ctxtcnt(dd); /* needed for PAT setup */ |
| 4128 | 4128 | ||
| 4129 | if (qib_wc_pat) { | 4129 | ret = init_chip_wc_pat(dd, 0); |
| 4130 | ret = init_chip_wc_pat(dd, 0); | 4130 | if (ret) |
| 4131 | if (ret) | 4131 | goto bail; |
| 4132 | goto bail; | ||
| 4133 | } | ||
| 4134 | set_7220_baseaddrs(dd); /* set chip access pointers now */ | 4132 | set_7220_baseaddrs(dd); /* set chip access pointers now */ |
| 4135 | 4133 | ||
| 4136 | ret = 0; | 4134 | ret = 0; |
diff --git a/drivers/infiniband/hw/qib/qib_iba7322.c b/drivers/infiniband/hw/qib/qib_iba7322.c index ef97b71c8f7d..f32b4628e991 100644 --- a/drivers/infiniband/hw/qib/qib_iba7322.c +++ b/drivers/infiniband/hw/qib/qib_iba7322.c | |||
| @@ -6429,6 +6429,7 @@ static int qib_init_7322_variables(struct qib_devdata *dd) | |||
| 6429 | unsigned features, pidx, sbufcnt; | 6429 | unsigned features, pidx, sbufcnt; |
| 6430 | int ret, mtu; | 6430 | int ret, mtu; |
| 6431 | u32 sbufs, updthresh; | 6431 | u32 sbufs, updthresh; |
| 6432 | resource_size_t vl15off; | ||
| 6432 | 6433 | ||
| 6433 | /* pport structs are contiguous, allocated after devdata */ | 6434 | /* pport structs are contiguous, allocated after devdata */ |
| 6434 | ppd = (struct qib_pportdata *)(dd + 1); | 6435 | ppd = (struct qib_pportdata *)(dd + 1); |
| @@ -6677,29 +6678,27 @@ static int qib_init_7322_variables(struct qib_devdata *dd) | |||
| 6677 | qib_7322_config_ctxts(dd); | 6678 | qib_7322_config_ctxts(dd); |
| 6678 | qib_set_ctxtcnt(dd); | 6679 | qib_set_ctxtcnt(dd); |
| 6679 | 6680 | ||
| 6680 | if (qib_wc_pat) { | 6681 | /* |
| 6681 | resource_size_t vl15off; | 6682 | * We do not set WC on the VL15 buffers to avoid |
| 6682 | /* | 6683 | * a rare problem with unaligned writes from |
| 6683 | * We do not set WC on the VL15 buffers to avoid | 6684 | * interrupt-flushed store buffers, so we need |
| 6684 | * a rare problem with unaligned writes from | 6685 | * to map those separately here. We can't solve |
| 6685 | * interrupt-flushed store buffers, so we need | 6686 | * this for the rarely used mtrr case. |
| 6686 | * to map those separately here. We can't solve | 6687 | */ |
| 6687 | * this for the rarely used mtrr case. | 6688 | ret = init_chip_wc_pat(dd, 0); |
| 6688 | */ | 6689 | if (ret) |
| 6689 | ret = init_chip_wc_pat(dd, 0); | 6690 | goto bail; |
| 6690 | if (ret) | ||
| 6691 | goto bail; | ||
| 6692 | 6691 | ||
| 6693 | /* vl15 buffers start just after the 4k buffers */ | 6692 | /* vl15 buffers start just after the 4k buffers */ |
| 6694 | vl15off = dd->physaddr + (dd->piobufbase >> 32) + | 6693 | vl15off = dd->physaddr + (dd->piobufbase >> 32) + |
| 6695 | dd->piobcnt4k * dd->align4k; | 6694 | dd->piobcnt4k * dd->align4k; |
| 6696 | dd->piovl15base = ioremap_nocache(vl15off, | 6695 | dd->piovl15base = ioremap_nocache(vl15off, |
| 6697 | NUM_VL15_BUFS * dd->align4k); | 6696 | NUM_VL15_BUFS * dd->align4k); |
| 6698 | if (!dd->piovl15base) { | 6697 | if (!dd->piovl15base) { |
| 6699 | ret = -ENOMEM; | 6698 | ret = -ENOMEM; |
| 6700 | goto bail; | 6699 | goto bail; |
| 6701 | } | ||
| 6702 | } | 6700 | } |
| 6701 | |||
| 6703 | qib_7322_set_baseaddrs(dd); /* set chip access pointers now */ | 6702 | qib_7322_set_baseaddrs(dd); /* set chip access pointers now */ |
| 6704 | 6703 | ||
| 6705 | ret = 0; | 6704 | ret = 0; |
diff --git a/drivers/infiniband/hw/qib/qib_init.c b/drivers/infiniband/hw/qib/qib_init.c index 2ee36953e234..7e00470adc30 100644 --- a/drivers/infiniband/hw/qib/qib_init.c +++ b/drivers/infiniband/hw/qib/qib_init.c | |||
| @@ -91,15 +91,6 @@ MODULE_PARM_DESC(krcvqs, "number of kernel receive queues per IB port"); | |||
| 91 | unsigned qib_cc_table_size; | 91 | unsigned qib_cc_table_size; |
| 92 | module_param_named(cc_table_size, qib_cc_table_size, uint, S_IRUGO); | 92 | module_param_named(cc_table_size, qib_cc_table_size, uint, S_IRUGO); |
| 93 | MODULE_PARM_DESC(cc_table_size, "Congestion control table entries 0 (CCA disabled - default), min = 128, max = 1984"); | 93 | MODULE_PARM_DESC(cc_table_size, "Congestion control table entries 0 (CCA disabled - default), min = 128, max = 1984"); |
| 94 | /* | ||
| 95 | * qib_wc_pat parameter: | ||
| 96 | * 0 is WC via MTRR | ||
| 97 | * 1 is WC via PAT | ||
| 98 | * If PAT initialization fails, code reverts back to MTRR | ||
| 99 | */ | ||
| 100 | unsigned qib_wc_pat = 1; /* default (1) is to use PAT, not MTRR */ | ||
| 101 | module_param_named(wc_pat, qib_wc_pat, uint, S_IRUGO); | ||
| 102 | MODULE_PARM_DESC(wc_pat, "enable write-combining via PAT mechanism"); | ||
| 103 | 94 | ||
| 104 | static void verify_interrupt(unsigned long); | 95 | static void verify_interrupt(unsigned long); |
| 105 | 96 | ||
| @@ -1377,8 +1368,7 @@ static void cleanup_device_data(struct qib_devdata *dd) | |||
| 1377 | spin_unlock(&dd->pport[pidx].cc_shadow_lock); | 1368 | spin_unlock(&dd->pport[pidx].cc_shadow_lock); |
| 1378 | } | 1369 | } |
| 1379 | 1370 | ||
| 1380 | if (!qib_wc_pat) | 1371 | qib_disable_wc(dd); |
| 1381 | qib_disable_wc(dd); | ||
| 1382 | 1372 | ||
| 1383 | if (dd->pioavailregs_dma) { | 1373 | if (dd->pioavailregs_dma) { |
| 1384 | dma_free_coherent(&dd->pcidev->dev, PAGE_SIZE, | 1374 | dma_free_coherent(&dd->pcidev->dev, PAGE_SIZE, |
| @@ -1547,14 +1537,12 @@ static int qib_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
| 1547 | goto bail; | 1537 | goto bail; |
| 1548 | } | 1538 | } |
| 1549 | 1539 | ||
| 1550 | if (!qib_wc_pat) { | 1540 | ret = qib_enable_wc(dd); |
| 1551 | ret = qib_enable_wc(dd); | 1541 | if (ret) { |
| 1552 | if (ret) { | 1542 | qib_dev_err(dd, |
| 1553 | qib_dev_err(dd, | 1543 | "Write combining not enabled (err %d): performance may be poor\n", |
| 1554 | "Write combining not enabled (err %d): performance may be poor\n", | 1544 | -ret); |
| 1555 | -ret); | 1545 | ret = 0; |
| 1556 | ret = 0; | ||
| 1557 | } | ||
| 1558 | } | 1546 | } |
| 1559 | 1547 | ||
| 1560 | qib_verify_pioperf(dd); | 1548 | qib_verify_pioperf(dd); |
diff --git a/drivers/infiniband/hw/qib/qib_wc_x86_64.c b/drivers/infiniband/hw/qib/qib_wc_x86_64.c index 81b225f2300a..edd0ddbd4481 100644 --- a/drivers/infiniband/hw/qib/qib_wc_x86_64.c +++ b/drivers/infiniband/hw/qib/qib_wc_x86_64.c | |||
| @@ -116,21 +116,10 @@ int qib_enable_wc(struct qib_devdata *dd) | |||
| 116 | } | 116 | } |
| 117 | 117 | ||
| 118 | if (!ret) { | 118 | if (!ret) { |
| 119 | int cookie; | 119 | dd->wc_cookie = arch_phys_wc_add(pioaddr, piolen); |
| 120 | 120 | if (dd->wc_cookie < 0) | |
| 121 | cookie = mtrr_add(pioaddr, piolen, MTRR_TYPE_WRCOMB, 0); | 121 | /* use error from routine */ |
| 122 | if (cookie < 0) { | 122 | ret = dd->wc_cookie; |
| 123 | { | ||
| 124 | qib_devinfo(dd->pcidev, | ||
| 125 | "mtrr_add() WC for PIO bufs failed (%d)\n", | ||
| 126 | cookie); | ||
| 127 | ret = -EINVAL; | ||
| 128 | } | ||
| 129 | } else { | ||
| 130 | dd->wc_cookie = cookie; | ||
| 131 | dd->wc_base = (unsigned long) pioaddr; | ||
| 132 | dd->wc_len = (unsigned long) piolen; | ||
| 133 | } | ||
| 134 | } | 123 | } |
| 135 | 124 | ||
| 136 | return ret; | 125 | return ret; |
| @@ -142,18 +131,7 @@ int qib_enable_wc(struct qib_devdata *dd) | |||
| 142 | */ | 131 | */ |
| 143 | void qib_disable_wc(struct qib_devdata *dd) | 132 | void qib_disable_wc(struct qib_devdata *dd) |
| 144 | { | 133 | { |
| 145 | if (dd->wc_cookie) { | 134 | arch_phys_wc_del(dd->wc_cookie); |
| 146 | int r; | ||
| 147 | |||
| 148 | r = mtrr_del(dd->wc_cookie, dd->wc_base, | ||
| 149 | dd->wc_len); | ||
| 150 | if (r < 0) | ||
| 151 | qib_devinfo(dd->pcidev, | ||
| 152 | "mtrr_del(%lx, %lx, %lx) failed: %d\n", | ||
| 153 | dd->wc_cookie, dd->wc_base, | ||
| 154 | dd->wc_len, r); | ||
| 155 | dd->wc_cookie = 0; /* even on failure */ | ||
| 156 | } | ||
| 157 | } | 135 | } |
| 158 | 136 | ||
| 159 | /** | 137 | /** |
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_cm.c b/drivers/infiniband/ulp/ipoib/ipoib_cm.c index 56959adb6c7d..cf32a778e7d0 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_cm.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_cm.c | |||
| @@ -386,8 +386,8 @@ static int ipoib_cm_nonsrq_init_rx(struct net_device *dev, struct ib_cm_id *cm_i | |||
| 386 | rx->rx_ring[i].mapping, | 386 | rx->rx_ring[i].mapping, |
| 387 | GFP_KERNEL)) { | 387 | GFP_KERNEL)) { |
| 388 | ipoib_warn(priv, "failed to allocate receive buffer %d\n", i); | 388 | ipoib_warn(priv, "failed to allocate receive buffer %d\n", i); |
| 389 | ret = -ENOMEM; | 389 | ret = -ENOMEM; |
| 390 | goto err_count; | 390 | goto err_count; |
| 391 | } | 391 | } |
| 392 | ret = ipoib_cm_post_receive_nonsrq(dev, rx, &t->wr, t->sge, i); | 392 | ret = ipoib_cm_post_receive_nonsrq(dev, rx, &t->wr, t->sge, i); |
| 393 | if (ret) { | 393 | if (ret) { |
diff --git a/drivers/iommu/amd_iommu_v2.c b/drivers/iommu/amd_iommu_v2.c index a1cbba9056fd..3465faf1809e 100644 --- a/drivers/iommu/amd_iommu_v2.c +++ b/drivers/iommu/amd_iommu_v2.c | |||
| @@ -266,6 +266,7 @@ static void put_pasid_state(struct pasid_state *pasid_state) | |||
| 266 | 266 | ||
| 267 | static void put_pasid_state_wait(struct pasid_state *pasid_state) | 267 | static void put_pasid_state_wait(struct pasid_state *pasid_state) |
| 268 | { | 268 | { |
| 269 | atomic_dec(&pasid_state->count); | ||
| 269 | wait_event(pasid_state->wq, !atomic_read(&pasid_state->count)); | 270 | wait_event(pasid_state->wq, !atomic_read(&pasid_state->count)); |
| 270 | free_pasid_state(pasid_state); | 271 | free_pasid_state(pasid_state); |
| 271 | } | 272 | } |
diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c index 9f7e1d34a32b..66a803b9dd3a 100644 --- a/drivers/iommu/arm-smmu.c +++ b/drivers/iommu/arm-smmu.c | |||
| @@ -224,14 +224,7 @@ | |||
| 224 | #define RESUME_TERMINATE (1 << 0) | 224 | #define RESUME_TERMINATE (1 << 0) |
| 225 | 225 | ||
| 226 | #define TTBCR2_SEP_SHIFT 15 | 226 | #define TTBCR2_SEP_SHIFT 15 |
| 227 | #define TTBCR2_SEP_MASK 0x7 | 227 | #define TTBCR2_SEP_UPSTREAM (0x7 << TTBCR2_SEP_SHIFT) |
| 228 | |||
| 229 | #define TTBCR2_ADDR_32 0 | ||
| 230 | #define TTBCR2_ADDR_36 1 | ||
| 231 | #define TTBCR2_ADDR_40 2 | ||
| 232 | #define TTBCR2_ADDR_42 3 | ||
| 233 | #define TTBCR2_ADDR_44 4 | ||
| 234 | #define TTBCR2_ADDR_48 5 | ||
| 235 | 228 | ||
| 236 | #define TTBRn_HI_ASID_SHIFT 16 | 229 | #define TTBRn_HI_ASID_SHIFT 16 |
| 237 | 230 | ||
| @@ -793,26 +786,7 @@ static void arm_smmu_init_context_bank(struct arm_smmu_domain *smmu_domain, | |||
| 793 | writel_relaxed(reg, cb_base + ARM_SMMU_CB_TTBCR); | 786 | writel_relaxed(reg, cb_base + ARM_SMMU_CB_TTBCR); |
| 794 | if (smmu->version > ARM_SMMU_V1) { | 787 | if (smmu->version > ARM_SMMU_V1) { |
| 795 | reg = pgtbl_cfg->arm_lpae_s1_cfg.tcr >> 32; | 788 | reg = pgtbl_cfg->arm_lpae_s1_cfg.tcr >> 32; |
| 796 | switch (smmu->va_size) { | 789 | reg |= TTBCR2_SEP_UPSTREAM; |
| 797 | case 32: | ||
| 798 | reg |= (TTBCR2_ADDR_32 << TTBCR2_SEP_SHIFT); | ||
| 799 | break; | ||
| 800 | case 36: | ||
| 801 | reg |= (TTBCR2_ADDR_36 << TTBCR2_SEP_SHIFT); | ||
| 802 | break; | ||
| 803 | case 40: | ||
| 804 | reg |= (TTBCR2_ADDR_40 << TTBCR2_SEP_SHIFT); | ||
| 805 | break; | ||
| 806 | case 42: | ||
| 807 | reg |= (TTBCR2_ADDR_42 << TTBCR2_SEP_SHIFT); | ||
| 808 | break; | ||
| 809 | case 44: | ||
| 810 | reg |= (TTBCR2_ADDR_44 << TTBCR2_SEP_SHIFT); | ||
| 811 | break; | ||
| 812 | case 48: | ||
| 813 | reg |= (TTBCR2_ADDR_48 << TTBCR2_SEP_SHIFT); | ||
| 814 | break; | ||
| 815 | } | ||
| 816 | writel_relaxed(reg, cb_base + ARM_SMMU_CB_TTBCR2); | 790 | writel_relaxed(reg, cb_base + ARM_SMMU_CB_TTBCR2); |
| 817 | } | 791 | } |
| 818 | } else { | 792 | } else { |
diff --git a/drivers/iommu/rockchip-iommu.c b/drivers/iommu/rockchip-iommu.c index 4015560bf486..cab214544237 100644 --- a/drivers/iommu/rockchip-iommu.c +++ b/drivers/iommu/rockchip-iommu.c | |||
| @@ -1004,20 +1004,18 @@ static int rk_iommu_remove(struct platform_device *pdev) | |||
| 1004 | return 0; | 1004 | return 0; |
| 1005 | } | 1005 | } |
| 1006 | 1006 | ||
| 1007 | #ifdef CONFIG_OF | ||
| 1008 | static const struct of_device_id rk_iommu_dt_ids[] = { | 1007 | static const struct of_device_id rk_iommu_dt_ids[] = { |
| 1009 | { .compatible = "rockchip,iommu" }, | 1008 | { .compatible = "rockchip,iommu" }, |
| 1010 | { /* sentinel */ } | 1009 | { /* sentinel */ } |
| 1011 | }; | 1010 | }; |
| 1012 | MODULE_DEVICE_TABLE(of, rk_iommu_dt_ids); | 1011 | MODULE_DEVICE_TABLE(of, rk_iommu_dt_ids); |
| 1013 | #endif | ||
| 1014 | 1012 | ||
| 1015 | static struct platform_driver rk_iommu_driver = { | 1013 | static struct platform_driver rk_iommu_driver = { |
| 1016 | .probe = rk_iommu_probe, | 1014 | .probe = rk_iommu_probe, |
| 1017 | .remove = rk_iommu_remove, | 1015 | .remove = rk_iommu_remove, |
| 1018 | .driver = { | 1016 | .driver = { |
| 1019 | .name = "rk_iommu", | 1017 | .name = "rk_iommu", |
| 1020 | .of_match_table = of_match_ptr(rk_iommu_dt_ids), | 1018 | .of_match_table = rk_iommu_dt_ids, |
| 1021 | }, | 1019 | }, |
| 1022 | }; | 1020 | }; |
| 1023 | 1021 | ||
diff --git a/drivers/irqchip/irq-gic.c b/drivers/irqchip/irq-gic.c index 7b315e385ba3..01999d74bd3a 100644 --- a/drivers/irqchip/irq-gic.c +++ b/drivers/irqchip/irq-gic.c | |||
| @@ -82,19 +82,6 @@ static DEFINE_RAW_SPINLOCK(irq_controller_lock); | |||
| 82 | #define NR_GIC_CPU_IF 8 | 82 | #define NR_GIC_CPU_IF 8 |
| 83 | static u8 gic_cpu_map[NR_GIC_CPU_IF] __read_mostly; | 83 | static u8 gic_cpu_map[NR_GIC_CPU_IF] __read_mostly; |
| 84 | 84 | ||
| 85 | /* | ||
| 86 | * Supported arch specific GIC irq extension. | ||
| 87 | * Default make them NULL. | ||
| 88 | */ | ||
| 89 | struct irq_chip gic_arch_extn = { | ||
| 90 | .irq_eoi = NULL, | ||
| 91 | .irq_mask = NULL, | ||
| 92 | .irq_unmask = NULL, | ||
| 93 | .irq_retrigger = NULL, | ||
| 94 | .irq_set_type = NULL, | ||
| 95 | .irq_set_wake = NULL, | ||
| 96 | }; | ||
| 97 | |||
| 98 | #ifndef MAX_GIC_NR | 85 | #ifndef MAX_GIC_NR |
| 99 | #define MAX_GIC_NR 1 | 86 | #define MAX_GIC_NR 1 |
| 100 | #endif | 87 | #endif |
| @@ -167,34 +154,16 @@ static int gic_peek_irq(struct irq_data *d, u32 offset) | |||
| 167 | 154 | ||
| 168 | static void gic_mask_irq(struct irq_data *d) | 155 | static void gic_mask_irq(struct irq_data *d) |
| 169 | { | 156 | { |
| 170 | unsigned long flags; | ||
| 171 | |||
| 172 | raw_spin_lock_irqsave(&irq_controller_lock, flags); | ||
| 173 | gic_poke_irq(d, GIC_DIST_ENABLE_CLEAR); | 157 | gic_poke_irq(d, GIC_DIST_ENABLE_CLEAR); |
| 174 | if (gic_arch_extn.irq_mask) | ||
| 175 | gic_arch_extn.irq_mask(d); | ||
| 176 | raw_spin_unlock_irqrestore(&irq_controller_lock, flags); | ||
| 177 | } | 158 | } |
| 178 | 159 | ||
| 179 | static void gic_unmask_irq(struct irq_data *d) | 160 | static void gic_unmask_irq(struct irq_data *d) |
| 180 | { | 161 | { |
| 181 | unsigned long flags; | ||
| 182 | |||
| 183 | raw_spin_lock_irqsave(&irq_controller_lock, flags); | ||
| 184 | if (gic_arch_extn.irq_unmask) | ||
| 185 | gic_arch_extn.irq_unmask(d); | ||
| 186 | gic_poke_irq(d, GIC_DIST_ENABLE_SET); | 162 | gic_poke_irq(d, GIC_DIST_ENABLE_SET); |
| 187 | raw_spin_unlock_irqrestore(&irq_controller_lock, flags); | ||
| 188 | } | 163 | } |
| 189 | 164 | ||
| 190 | static void gic_eoi_irq(struct irq_data *d) | 165 | static void gic_eoi_irq(struct irq_data *d) |
| 191 | { | 166 | { |
| 192 | if (gic_arch_extn.irq_eoi) { | ||
| 193 | raw_spin_lock(&irq_controller_lock); | ||
| 194 | gic_arch_extn.irq_eoi(d); | ||
| 195 | raw_spin_unlock(&irq_controller_lock); | ||
| 196 | } | ||
| 197 | |||
| 198 | writel_relaxed(gic_irq(d), gic_cpu_base(d) + GIC_CPU_EOI); | 167 | writel_relaxed(gic_irq(d), gic_cpu_base(d) + GIC_CPU_EOI); |
| 199 | } | 168 | } |
| 200 | 169 | ||
| @@ -251,8 +220,6 @@ static int gic_set_type(struct irq_data *d, unsigned int type) | |||
| 251 | { | 220 | { |
| 252 | void __iomem *base = gic_dist_base(d); | 221 | void __iomem *base = gic_dist_base(d); |
| 253 | unsigned int gicirq = gic_irq(d); | 222 | unsigned int gicirq = gic_irq(d); |
| 254 | unsigned long flags; | ||
| 255 | int ret; | ||
| 256 | 223 | ||
| 257 | /* Interrupt configuration for SGIs can't be changed */ | 224 | /* Interrupt configuration for SGIs can't be changed */ |
| 258 | if (gicirq < 16) | 225 | if (gicirq < 16) |
| @@ -263,25 +230,7 @@ static int gic_set_type(struct irq_data *d, unsigned int type) | |||
| 263 | type != IRQ_TYPE_EDGE_RISING) | 230 | type != IRQ_TYPE_EDGE_RISING) |
| 264 | return -EINVAL; | 231 | return -EINVAL; |
| 265 | 232 | ||
| 266 | raw_spin_lock_irqsave(&irq_controller_lock, flags); | 233 | return gic_configure_irq(gicirq, type, base, NULL); |
| 267 | |||
| 268 | if (gic_arch_extn.irq_set_type) | ||
| 269 | gic_arch_extn.irq_set_type(d, type); | ||
| 270 | |||
| 271 | ret = gic_configure_irq(gicirq, type, base, NULL); | ||
| 272 | |||
| 273 | raw_spin_unlock_irqrestore(&irq_controller_lock, flags); | ||
| 274 | |||
| 275 | return ret; | ||
| 276 | } | ||
| 277 | |||
| 278 | static int gic_retrigger(struct irq_data *d) | ||
| 279 | { | ||
| 280 | if (gic_arch_extn.irq_retrigger) | ||
| 281 | return gic_arch_extn.irq_retrigger(d); | ||
| 282 | |||
| 283 | /* the genirq layer expects 0 if we can't retrigger in hardware */ | ||
| 284 | return 0; | ||
| 285 | } | 234 | } |
| 286 | 235 | ||
| 287 | #ifdef CONFIG_SMP | 236 | #ifdef CONFIG_SMP |
| @@ -312,21 +261,6 @@ static int gic_set_affinity(struct irq_data *d, const struct cpumask *mask_val, | |||
| 312 | } | 261 | } |
| 313 | #endif | 262 | #endif |
| 314 | 263 | ||
| 315 | #ifdef CONFIG_PM | ||
| 316 | static int gic_set_wake(struct irq_data *d, unsigned int on) | ||
| 317 | { | ||
| 318 | int ret = -ENXIO; | ||
| 319 | |||
| 320 | if (gic_arch_extn.irq_set_wake) | ||
| 321 | ret = gic_arch_extn.irq_set_wake(d, on); | ||
| 322 | |||
| 323 | return ret; | ||
| 324 | } | ||
| 325 | |||
| 326 | #else | ||
| 327 | #define gic_set_wake NULL | ||
| 328 | #endif | ||
| 329 | |||
| 330 | static void __exception_irq_entry gic_handle_irq(struct pt_regs *regs) | 264 | static void __exception_irq_entry gic_handle_irq(struct pt_regs *regs) |
| 331 | { | 265 | { |
| 332 | u32 irqstat, irqnr; | 266 | u32 irqstat, irqnr; |
| @@ -385,11 +319,9 @@ static struct irq_chip gic_chip = { | |||
| 385 | .irq_unmask = gic_unmask_irq, | 319 | .irq_unmask = gic_unmask_irq, |
| 386 | .irq_eoi = gic_eoi_irq, | 320 | .irq_eoi = gic_eoi_irq, |
| 387 | .irq_set_type = gic_set_type, | 321 | .irq_set_type = gic_set_type, |
| 388 | .irq_retrigger = gic_retrigger, | ||
| 389 | #ifdef CONFIG_SMP | 322 | #ifdef CONFIG_SMP |
| 390 | .irq_set_affinity = gic_set_affinity, | 323 | .irq_set_affinity = gic_set_affinity, |
| 391 | #endif | 324 | #endif |
| 392 | .irq_set_wake = gic_set_wake, | ||
| 393 | .irq_get_irqchip_state = gic_irq_get_irqchip_state, | 325 | .irq_get_irqchip_state = gic_irq_get_irqchip_state, |
| 394 | .irq_set_irqchip_state = gic_irq_set_irqchip_state, | 326 | .irq_set_irqchip_state = gic_irq_set_irqchip_state, |
| 395 | }; | 327 | }; |
| @@ -1055,7 +987,6 @@ void __init gic_init_bases(unsigned int gic_nr, int irq_start, | |||
| 1055 | set_handle_irq(gic_handle_irq); | 987 | set_handle_irq(gic_handle_irq); |
| 1056 | } | 988 | } |
| 1057 | 989 | ||
| 1058 | gic_chip.flags |= gic_arch_extn.flags; | ||
| 1059 | gic_dist_init(gic); | 990 | gic_dist_init(gic); |
| 1060 | gic_cpu_init(gic); | 991 | gic_cpu_init(gic); |
| 1061 | gic_pm_init(gic); | 992 | gic_pm_init(gic); |
diff --git a/drivers/irqchip/irq-tegra.c b/drivers/irqchip/irq-tegra.c index 51c485d9a877..f67bbd80433e 100644 --- a/drivers/irqchip/irq-tegra.c +++ b/drivers/irqchip/irq-tegra.c | |||
| @@ -264,7 +264,7 @@ static int tegra_ictlr_domain_alloc(struct irq_domain *domain, | |||
| 264 | 264 | ||
| 265 | irq_domain_set_hwirq_and_chip(domain, virq + i, hwirq + i, | 265 | irq_domain_set_hwirq_and_chip(domain, virq + i, hwirq + i, |
| 266 | &tegra_ictlr_chip, | 266 | &tegra_ictlr_chip, |
| 267 | &info->base[ictlr]); | 267 | info->base[ictlr]); |
| 268 | } | 268 | } |
| 269 | 269 | ||
| 270 | parent_args = *args; | 270 | parent_args = *args; |
diff --git a/drivers/md/dm-crypt.c b/drivers/md/dm-crypt.c index 9eeea196328a..5503e43e5f28 100644 --- a/drivers/md/dm-crypt.c +++ b/drivers/md/dm-crypt.c | |||
| @@ -925,10 +925,11 @@ static int crypt_convert(struct crypt_config *cc, | |||
| 925 | 925 | ||
| 926 | switch (r) { | 926 | switch (r) { |
| 927 | /* async */ | 927 | /* async */ |
| 928 | case -EINPROGRESS: | ||
| 929 | case -EBUSY: | 928 | case -EBUSY: |
| 930 | wait_for_completion(&ctx->restart); | 929 | wait_for_completion(&ctx->restart); |
| 931 | reinit_completion(&ctx->restart); | 930 | reinit_completion(&ctx->restart); |
| 931 | /* fall through*/ | ||
| 932 | case -EINPROGRESS: | ||
| 932 | ctx->req = NULL; | 933 | ctx->req = NULL; |
| 933 | ctx->cc_sector++; | 934 | ctx->cc_sector++; |
| 934 | continue; | 935 | continue; |
| @@ -1345,8 +1346,10 @@ static void kcryptd_async_done(struct crypto_async_request *async_req, | |||
| 1345 | struct dm_crypt_io *io = container_of(ctx, struct dm_crypt_io, ctx); | 1346 | struct dm_crypt_io *io = container_of(ctx, struct dm_crypt_io, ctx); |
| 1346 | struct crypt_config *cc = io->cc; | 1347 | struct crypt_config *cc = io->cc; |
| 1347 | 1348 | ||
| 1348 | if (error == -EINPROGRESS) | 1349 | if (error == -EINPROGRESS) { |
| 1350 | complete(&ctx->restart); | ||
| 1349 | return; | 1351 | return; |
| 1352 | } | ||
| 1350 | 1353 | ||
| 1351 | if (!error && cc->iv_gen_ops && cc->iv_gen_ops->post) | 1354 | if (!error && cc->iv_gen_ops && cc->iv_gen_ops->post) |
| 1352 | error = cc->iv_gen_ops->post(cc, iv_of_dmreq(cc, dmreq), dmreq); | 1355 | error = cc->iv_gen_ops->post(cc, iv_of_dmreq(cc, dmreq), dmreq); |
| @@ -1357,15 +1360,12 @@ static void kcryptd_async_done(struct crypto_async_request *async_req, | |||
| 1357 | crypt_free_req(cc, req_of_dmreq(cc, dmreq), io->base_bio); | 1360 | crypt_free_req(cc, req_of_dmreq(cc, dmreq), io->base_bio); |
| 1358 | 1361 | ||
| 1359 | if (!atomic_dec_and_test(&ctx->cc_pending)) | 1362 | if (!atomic_dec_and_test(&ctx->cc_pending)) |
| 1360 | goto done; | 1363 | return; |
| 1361 | 1364 | ||
| 1362 | if (bio_data_dir(io->base_bio) == READ) | 1365 | if (bio_data_dir(io->base_bio) == READ) |
| 1363 | kcryptd_crypt_read_done(io); | 1366 | kcryptd_crypt_read_done(io); |
| 1364 | else | 1367 | else |
| 1365 | kcryptd_crypt_write_io_submit(io, 1); | 1368 | kcryptd_crypt_write_io_submit(io, 1); |
| 1366 | done: | ||
| 1367 | if (!completion_done(&ctx->restart)) | ||
| 1368 | complete(&ctx->restart); | ||
| 1369 | } | 1369 | } |
| 1370 | 1370 | ||
| 1371 | static void kcryptd_crypt(struct work_struct *work) | 1371 | static void kcryptd_crypt(struct work_struct *work) |
diff --git a/drivers/md/md.c b/drivers/md/md.c index d4f31e195e26..593a02476c78 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c | |||
| @@ -4818,12 +4818,12 @@ static void md_free(struct kobject *ko) | |||
| 4818 | if (mddev->sysfs_state) | 4818 | if (mddev->sysfs_state) |
| 4819 | sysfs_put(mddev->sysfs_state); | 4819 | sysfs_put(mddev->sysfs_state); |
| 4820 | 4820 | ||
| 4821 | if (mddev->queue) | ||
| 4822 | blk_cleanup_queue(mddev->queue); | ||
| 4821 | if (mddev->gendisk) { | 4823 | if (mddev->gendisk) { |
| 4822 | del_gendisk(mddev->gendisk); | 4824 | del_gendisk(mddev->gendisk); |
| 4823 | put_disk(mddev->gendisk); | 4825 | put_disk(mddev->gendisk); |
| 4824 | } | 4826 | } |
| 4825 | if (mddev->queue) | ||
| 4826 | blk_cleanup_queue(mddev->queue); | ||
| 4827 | 4827 | ||
| 4828 | kfree(mddev); | 4828 | kfree(mddev); |
| 4829 | } | 4829 | } |
diff --git a/drivers/md/raid0.c b/drivers/md/raid0.c index 2cb59a641cd2..6a68ef5246d4 100644 --- a/drivers/md/raid0.c +++ b/drivers/md/raid0.c | |||
| @@ -188,8 +188,9 @@ static int create_strip_zones(struct mddev *mddev, struct r0conf **private_conf) | |||
| 188 | } | 188 | } |
| 189 | dev[j] = rdev1; | 189 | dev[j] = rdev1; |
| 190 | 190 | ||
| 191 | disk_stack_limits(mddev->gendisk, rdev1->bdev, | 191 | if (mddev->queue) |
| 192 | rdev1->data_offset << 9); | 192 | disk_stack_limits(mddev->gendisk, rdev1->bdev, |
| 193 | rdev1->data_offset << 9); | ||
| 193 | 194 | ||
| 194 | if (rdev1->bdev->bd_disk->queue->merge_bvec_fn) | 195 | if (rdev1->bdev->bd_disk->queue->merge_bvec_fn) |
| 195 | conf->has_merge_bvec = 1; | 196 | conf->has_merge_bvec = 1; |
diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c index 77dfd720aaa0..1ba97fdc6df1 100644 --- a/drivers/md/raid5.c +++ b/drivers/md/raid5.c | |||
| @@ -1078,9 +1078,6 @@ again: | |||
| 1078 | pr_debug("skip op %ld on disc %d for sector %llu\n", | 1078 | pr_debug("skip op %ld on disc %d for sector %llu\n", |
| 1079 | bi->bi_rw, i, (unsigned long long)sh->sector); | 1079 | bi->bi_rw, i, (unsigned long long)sh->sector); |
| 1080 | clear_bit(R5_LOCKED, &sh->dev[i].flags); | 1080 | clear_bit(R5_LOCKED, &sh->dev[i].flags); |
| 1081 | if (sh->batch_head) | ||
| 1082 | set_bit(STRIPE_BATCH_ERR, | ||
| 1083 | &sh->batch_head->state); | ||
| 1084 | set_bit(STRIPE_HANDLE, &sh->state); | 1081 | set_bit(STRIPE_HANDLE, &sh->state); |
| 1085 | } | 1082 | } |
| 1086 | 1083 | ||
| @@ -1971,17 +1968,30 @@ static void raid_run_ops(struct stripe_head *sh, unsigned long ops_request) | |||
| 1971 | put_cpu(); | 1968 | put_cpu(); |
| 1972 | } | 1969 | } |
| 1973 | 1970 | ||
| 1971 | static struct stripe_head *alloc_stripe(struct kmem_cache *sc, gfp_t gfp) | ||
| 1972 | { | ||
| 1973 | struct stripe_head *sh; | ||
| 1974 | |||
| 1975 | sh = kmem_cache_zalloc(sc, gfp); | ||
| 1976 | if (sh) { | ||
| 1977 | spin_lock_init(&sh->stripe_lock); | ||
| 1978 | spin_lock_init(&sh->batch_lock); | ||
| 1979 | INIT_LIST_HEAD(&sh->batch_list); | ||
| 1980 | INIT_LIST_HEAD(&sh->lru); | ||
| 1981 | atomic_set(&sh->count, 1); | ||
| 1982 | } | ||
| 1983 | return sh; | ||
| 1984 | } | ||
| 1974 | static int grow_one_stripe(struct r5conf *conf, gfp_t gfp) | 1985 | static int grow_one_stripe(struct r5conf *conf, gfp_t gfp) |
| 1975 | { | 1986 | { |
| 1976 | struct stripe_head *sh; | 1987 | struct stripe_head *sh; |
| 1977 | sh = kmem_cache_zalloc(conf->slab_cache, gfp); | 1988 | |
| 1989 | sh = alloc_stripe(conf->slab_cache, gfp); | ||
| 1978 | if (!sh) | 1990 | if (!sh) |
| 1979 | return 0; | 1991 | return 0; |
| 1980 | 1992 | ||
| 1981 | sh->raid_conf = conf; | 1993 | sh->raid_conf = conf; |
| 1982 | 1994 | ||
| 1983 | spin_lock_init(&sh->stripe_lock); | ||
| 1984 | |||
| 1985 | if (grow_buffers(sh, gfp)) { | 1995 | if (grow_buffers(sh, gfp)) { |
| 1986 | shrink_buffers(sh); | 1996 | shrink_buffers(sh); |
| 1987 | kmem_cache_free(conf->slab_cache, sh); | 1997 | kmem_cache_free(conf->slab_cache, sh); |
| @@ -1990,13 +2000,8 @@ static int grow_one_stripe(struct r5conf *conf, gfp_t gfp) | |||
| 1990 | sh->hash_lock_index = | 2000 | sh->hash_lock_index = |
| 1991 | conf->max_nr_stripes % NR_STRIPE_HASH_LOCKS; | 2001 | conf->max_nr_stripes % NR_STRIPE_HASH_LOCKS; |
| 1992 | /* we just created an active stripe so... */ | 2002 | /* we just created an active stripe so... */ |
| 1993 | atomic_set(&sh->count, 1); | ||
| 1994 | atomic_inc(&conf->active_stripes); | 2003 | atomic_inc(&conf->active_stripes); |
| 1995 | INIT_LIST_HEAD(&sh->lru); | ||
| 1996 | 2004 | ||
| 1997 | spin_lock_init(&sh->batch_lock); | ||
| 1998 | INIT_LIST_HEAD(&sh->batch_list); | ||
| 1999 | sh->batch_head = NULL; | ||
| 2000 | release_stripe(sh); | 2005 | release_stripe(sh); |
| 2001 | conf->max_nr_stripes++; | 2006 | conf->max_nr_stripes++; |
| 2002 | return 1; | 2007 | return 1; |
| @@ -2060,6 +2065,35 @@ static struct flex_array *scribble_alloc(int num, int cnt, gfp_t flags) | |||
| 2060 | return ret; | 2065 | return ret; |
| 2061 | } | 2066 | } |
| 2062 | 2067 | ||
| 2068 | static int resize_chunks(struct r5conf *conf, int new_disks, int new_sectors) | ||
| 2069 | { | ||
| 2070 | unsigned long cpu; | ||
| 2071 | int err = 0; | ||
| 2072 | |||
| 2073 | mddev_suspend(conf->mddev); | ||
| 2074 | get_online_cpus(); | ||
| 2075 | for_each_present_cpu(cpu) { | ||
| 2076 | struct raid5_percpu *percpu; | ||
| 2077 | struct flex_array *scribble; | ||
| 2078 | |||
| 2079 | percpu = per_cpu_ptr(conf->percpu, cpu); | ||
| 2080 | scribble = scribble_alloc(new_disks, | ||
| 2081 | new_sectors / STRIPE_SECTORS, | ||
| 2082 | GFP_NOIO); | ||
| 2083 | |||
| 2084 | if (scribble) { | ||
| 2085 | flex_array_free(percpu->scribble); | ||
| 2086 | percpu->scribble = scribble; | ||
| 2087 | } else { | ||
| 2088 | err = -ENOMEM; | ||
| 2089 | break; | ||
| 2090 | } | ||
| 2091 | } | ||
| 2092 | put_online_cpus(); | ||
| 2093 | mddev_resume(conf->mddev); | ||
| 2094 | return err; | ||
| 2095 | } | ||
| 2096 | |||
| 2063 | static int resize_stripes(struct r5conf *conf, int newsize) | 2097 | static int resize_stripes(struct r5conf *conf, int newsize) |
| 2064 | { | 2098 | { |
| 2065 | /* Make all the stripes able to hold 'newsize' devices. | 2099 | /* Make all the stripes able to hold 'newsize' devices. |
| @@ -2088,7 +2122,6 @@ static int resize_stripes(struct r5conf *conf, int newsize) | |||
| 2088 | struct stripe_head *osh, *nsh; | 2122 | struct stripe_head *osh, *nsh; |
| 2089 | LIST_HEAD(newstripes); | 2123 | LIST_HEAD(newstripes); |
| 2090 | struct disk_info *ndisks; | 2124 | struct disk_info *ndisks; |
| 2091 | unsigned long cpu; | ||
| 2092 | int err; | 2125 | int err; |
| 2093 | struct kmem_cache *sc; | 2126 | struct kmem_cache *sc; |
| 2094 | int i; | 2127 | int i; |
| @@ -2109,13 +2142,11 @@ static int resize_stripes(struct r5conf *conf, int newsize) | |||
| 2109 | return -ENOMEM; | 2142 | return -ENOMEM; |
| 2110 | 2143 | ||
| 2111 | for (i = conf->max_nr_stripes; i; i--) { | 2144 | for (i = conf->max_nr_stripes; i; i--) { |
| 2112 | nsh = kmem_cache_zalloc(sc, GFP_KERNEL); | 2145 | nsh = alloc_stripe(sc, GFP_KERNEL); |
| 2113 | if (!nsh) | 2146 | if (!nsh) |
| 2114 | break; | 2147 | break; |
| 2115 | 2148 | ||
| 2116 | nsh->raid_conf = conf; | 2149 | nsh->raid_conf = conf; |
| 2117 | spin_lock_init(&nsh->stripe_lock); | ||
| 2118 | |||
| 2119 | list_add(&nsh->lru, &newstripes); | 2150 | list_add(&nsh->lru, &newstripes); |
| 2120 | } | 2151 | } |
| 2121 | if (i) { | 2152 | if (i) { |
| @@ -2142,13 +2173,11 @@ static int resize_stripes(struct r5conf *conf, int newsize) | |||
| 2142 | lock_device_hash_lock(conf, hash)); | 2173 | lock_device_hash_lock(conf, hash)); |
| 2143 | osh = get_free_stripe(conf, hash); | 2174 | osh = get_free_stripe(conf, hash); |
| 2144 | unlock_device_hash_lock(conf, hash); | 2175 | unlock_device_hash_lock(conf, hash); |
| 2145 | atomic_set(&nsh->count, 1); | 2176 | |
| 2146 | for(i=0; i<conf->pool_size; i++) { | 2177 | for(i=0; i<conf->pool_size; i++) { |
| 2147 | nsh->dev[i].page = osh->dev[i].page; | 2178 | nsh->dev[i].page = osh->dev[i].page; |
| 2148 | nsh->dev[i].orig_page = osh->dev[i].page; | 2179 | nsh->dev[i].orig_page = osh->dev[i].page; |
| 2149 | } | 2180 | } |
| 2150 | for( ; i<newsize; i++) | ||
| 2151 | nsh->dev[i].page = NULL; | ||
| 2152 | nsh->hash_lock_index = hash; | 2181 | nsh->hash_lock_index = hash; |
| 2153 | kmem_cache_free(conf->slab_cache, osh); | 2182 | kmem_cache_free(conf->slab_cache, osh); |
| 2154 | cnt++; | 2183 | cnt++; |
| @@ -2174,25 +2203,6 @@ static int resize_stripes(struct r5conf *conf, int newsize) | |||
| 2174 | } else | 2203 | } else |
| 2175 | err = -ENOMEM; | 2204 | err = -ENOMEM; |
| 2176 | 2205 | ||
| 2177 | get_online_cpus(); | ||
| 2178 | for_each_present_cpu(cpu) { | ||
| 2179 | struct raid5_percpu *percpu; | ||
| 2180 | struct flex_array *scribble; | ||
| 2181 | |||
| 2182 | percpu = per_cpu_ptr(conf->percpu, cpu); | ||
| 2183 | scribble = scribble_alloc(newsize, conf->chunk_sectors / | ||
| 2184 | STRIPE_SECTORS, GFP_NOIO); | ||
| 2185 | |||
| 2186 | if (scribble) { | ||
| 2187 | flex_array_free(percpu->scribble); | ||
| 2188 | percpu->scribble = scribble; | ||
| 2189 | } else { | ||
| 2190 | err = -ENOMEM; | ||
| 2191 | break; | ||
| 2192 | } | ||
| 2193 | } | ||
| 2194 | put_online_cpus(); | ||
| 2195 | |||
| 2196 | /* Step 4, return new stripes to service */ | 2206 | /* Step 4, return new stripes to service */ |
| 2197 | while(!list_empty(&newstripes)) { | 2207 | while(!list_empty(&newstripes)) { |
| 2198 | nsh = list_entry(newstripes.next, struct stripe_head, lru); | 2208 | nsh = list_entry(newstripes.next, struct stripe_head, lru); |
| @@ -2212,7 +2222,8 @@ static int resize_stripes(struct r5conf *conf, int newsize) | |||
| 2212 | 2222 | ||
| 2213 | conf->slab_cache = sc; | 2223 | conf->slab_cache = sc; |
| 2214 | conf->active_name = 1-conf->active_name; | 2224 | conf->active_name = 1-conf->active_name; |
| 2215 | conf->pool_size = newsize; | 2225 | if (!err) |
| 2226 | conf->pool_size = newsize; | ||
| 2216 | return err; | 2227 | return err; |
| 2217 | } | 2228 | } |
| 2218 | 2229 | ||
| @@ -2434,7 +2445,7 @@ static void raid5_end_write_request(struct bio *bi, int error) | |||
| 2434 | } | 2445 | } |
| 2435 | rdev_dec_pending(rdev, conf->mddev); | 2446 | rdev_dec_pending(rdev, conf->mddev); |
| 2436 | 2447 | ||
| 2437 | if (sh->batch_head && !uptodate) | 2448 | if (sh->batch_head && !uptodate && !replacement) |
| 2438 | set_bit(STRIPE_BATCH_ERR, &sh->batch_head->state); | 2449 | set_bit(STRIPE_BATCH_ERR, &sh->batch_head->state); |
| 2439 | 2450 | ||
| 2440 | if (!test_and_clear_bit(R5_DOUBLE_LOCKED, &sh->dev[i].flags)) | 2451 | if (!test_and_clear_bit(R5_DOUBLE_LOCKED, &sh->dev[i].flags)) |
| @@ -3278,7 +3289,9 @@ static int need_this_block(struct stripe_head *sh, struct stripe_head_state *s, | |||
| 3278 | /* reconstruct-write isn't being forced */ | 3289 | /* reconstruct-write isn't being forced */ |
| 3279 | return 0; | 3290 | return 0; |
| 3280 | for (i = 0; i < s->failed; i++) { | 3291 | for (i = 0; i < s->failed; i++) { |
| 3281 | if (!test_bit(R5_UPTODATE, &fdev[i]->flags) && | 3292 | if (s->failed_num[i] != sh->pd_idx && |
| 3293 | s->failed_num[i] != sh->qd_idx && | ||
| 3294 | !test_bit(R5_UPTODATE, &fdev[i]->flags) && | ||
| 3282 | !test_bit(R5_OVERWRITE, &fdev[i]->flags)) | 3295 | !test_bit(R5_OVERWRITE, &fdev[i]->flags)) |
| 3283 | return 1; | 3296 | return 1; |
| 3284 | } | 3297 | } |
| @@ -3298,6 +3311,7 @@ static int fetch_block(struct stripe_head *sh, struct stripe_head_state *s, | |||
| 3298 | */ | 3311 | */ |
| 3299 | BUG_ON(test_bit(R5_Wantcompute, &dev->flags)); | 3312 | BUG_ON(test_bit(R5_Wantcompute, &dev->flags)); |
| 3300 | BUG_ON(test_bit(R5_Wantread, &dev->flags)); | 3313 | BUG_ON(test_bit(R5_Wantread, &dev->flags)); |
| 3314 | BUG_ON(sh->batch_head); | ||
| 3301 | if ((s->uptodate == disks - 1) && | 3315 | if ((s->uptodate == disks - 1) && |
| 3302 | (s->failed && (disk_idx == s->failed_num[0] || | 3316 | (s->failed && (disk_idx == s->failed_num[0] || |
| 3303 | disk_idx == s->failed_num[1]))) { | 3317 | disk_idx == s->failed_num[1]))) { |
| @@ -3366,7 +3380,6 @@ static void handle_stripe_fill(struct stripe_head *sh, | |||
| 3366 | { | 3380 | { |
| 3367 | int i; | 3381 | int i; |
| 3368 | 3382 | ||
| 3369 | BUG_ON(sh->batch_head); | ||
| 3370 | /* look for blocks to read/compute, skip this if a compute | 3383 | /* look for blocks to read/compute, skip this if a compute |
| 3371 | * is already in flight, or if the stripe contents are in the | 3384 | * is already in flight, or if the stripe contents are in the |
| 3372 | * midst of changing due to a write | 3385 | * midst of changing due to a write |
| @@ -4198,15 +4211,9 @@ static void check_break_stripe_batch_list(struct stripe_head *sh) | |||
| 4198 | return; | 4211 | return; |
| 4199 | 4212 | ||
| 4200 | head_sh = sh; | 4213 | head_sh = sh; |
| 4201 | do { | ||
| 4202 | sh = list_first_entry(&sh->batch_list, | ||
| 4203 | struct stripe_head, batch_list); | ||
| 4204 | BUG_ON(sh == head_sh); | ||
| 4205 | } while (!test_bit(STRIPE_DEGRADED, &sh->state)); | ||
| 4206 | 4214 | ||
| 4207 | while (sh != head_sh) { | 4215 | list_for_each_entry_safe(sh, next, &head_sh->batch_list, batch_list) { |
| 4208 | next = list_first_entry(&sh->batch_list, | 4216 | |
| 4209 | struct stripe_head, batch_list); | ||
| 4210 | list_del_init(&sh->batch_list); | 4217 | list_del_init(&sh->batch_list); |
| 4211 | 4218 | ||
| 4212 | set_mask_bits(&sh->state, ~STRIPE_EXPAND_SYNC_FLAG, | 4219 | set_mask_bits(&sh->state, ~STRIPE_EXPAND_SYNC_FLAG, |
| @@ -4226,8 +4233,6 @@ static void check_break_stripe_batch_list(struct stripe_head *sh) | |||
| 4226 | 4233 | ||
| 4227 | set_bit(STRIPE_HANDLE, &sh->state); | 4234 | set_bit(STRIPE_HANDLE, &sh->state); |
| 4228 | release_stripe(sh); | 4235 | release_stripe(sh); |
| 4229 | |||
| 4230 | sh = next; | ||
| 4231 | } | 4236 | } |
| 4232 | } | 4237 | } |
| 4233 | 4238 | ||
| @@ -6221,8 +6226,11 @@ static int alloc_scratch_buffer(struct r5conf *conf, struct raid5_percpu *percpu | |||
| 6221 | percpu->spare_page = alloc_page(GFP_KERNEL); | 6226 | percpu->spare_page = alloc_page(GFP_KERNEL); |
| 6222 | if (!percpu->scribble) | 6227 | if (!percpu->scribble) |
| 6223 | percpu->scribble = scribble_alloc(max(conf->raid_disks, | 6228 | percpu->scribble = scribble_alloc(max(conf->raid_disks, |
| 6224 | conf->previous_raid_disks), conf->chunk_sectors / | 6229 | conf->previous_raid_disks), |
| 6225 | STRIPE_SECTORS, GFP_KERNEL); | 6230 | max(conf->chunk_sectors, |
| 6231 | conf->prev_chunk_sectors) | ||
| 6232 | / STRIPE_SECTORS, | ||
| 6233 | GFP_KERNEL); | ||
| 6226 | 6234 | ||
| 6227 | if (!percpu->scribble || (conf->level == 6 && !percpu->spare_page)) { | 6235 | if (!percpu->scribble || (conf->level == 6 && !percpu->spare_page)) { |
| 6228 | free_scratch_buffer(conf, percpu); | 6236 | free_scratch_buffer(conf, percpu); |
| @@ -7198,6 +7206,15 @@ static int check_reshape(struct mddev *mddev) | |||
| 7198 | if (!check_stripe_cache(mddev)) | 7206 | if (!check_stripe_cache(mddev)) |
| 7199 | return -ENOSPC; | 7207 | return -ENOSPC; |
| 7200 | 7208 | ||
| 7209 | if (mddev->new_chunk_sectors > mddev->chunk_sectors || | ||
| 7210 | mddev->delta_disks > 0) | ||
| 7211 | if (resize_chunks(conf, | ||
| 7212 | conf->previous_raid_disks | ||
| 7213 | + max(0, mddev->delta_disks), | ||
| 7214 | max(mddev->new_chunk_sectors, | ||
| 7215 | mddev->chunk_sectors) | ||
| 7216 | ) < 0) | ||
| 7217 | return -ENOMEM; | ||
| 7201 | return resize_stripes(conf, (conf->previous_raid_disks | 7218 | return resize_stripes(conf, (conf->previous_raid_disks |
| 7202 | + mddev->delta_disks)); | 7219 | + mddev->delta_disks)); |
| 7203 | } | 7220 | } |
diff --git a/drivers/media/platform/marvell-ccic/mcam-core.c b/drivers/media/platform/marvell-ccic/mcam-core.c index 9c64b5d01c6a..110fd70c7326 100644 --- a/drivers/media/platform/marvell-ccic/mcam-core.c +++ b/drivers/media/platform/marvell-ccic/mcam-core.c | |||
| @@ -116,8 +116,8 @@ static struct mcam_format_struct { | |||
| 116 | .planar = false, | 116 | .planar = false, |
| 117 | }, | 117 | }, |
| 118 | { | 118 | { |
| 119 | .desc = "UYVY 4:2:2", | 119 | .desc = "YVYU 4:2:2", |
| 120 | .pixelformat = V4L2_PIX_FMT_UYVY, | 120 | .pixelformat = V4L2_PIX_FMT_YVYU, |
| 121 | .mbus_code = MEDIA_BUS_FMT_YUYV8_2X8, | 121 | .mbus_code = MEDIA_BUS_FMT_YUYV8_2X8, |
| 122 | .bpp = 2, | 122 | .bpp = 2, |
| 123 | .planar = false, | 123 | .planar = false, |
| @@ -748,7 +748,7 @@ static void mcam_ctlr_image(struct mcam_camera *cam) | |||
| 748 | 748 | ||
| 749 | switch (fmt->pixelformat) { | 749 | switch (fmt->pixelformat) { |
| 750 | case V4L2_PIX_FMT_YUYV: | 750 | case V4L2_PIX_FMT_YUYV: |
| 751 | case V4L2_PIX_FMT_UYVY: | 751 | case V4L2_PIX_FMT_YVYU: |
| 752 | widthy = fmt->width * 2; | 752 | widthy = fmt->width * 2; |
| 753 | widthuv = 0; | 753 | widthuv = 0; |
| 754 | break; | 754 | break; |
| @@ -784,15 +784,15 @@ static void mcam_ctlr_image(struct mcam_camera *cam) | |||
| 784 | case V4L2_PIX_FMT_YUV420: | 784 | case V4L2_PIX_FMT_YUV420: |
| 785 | case V4L2_PIX_FMT_YVU420: | 785 | case V4L2_PIX_FMT_YVU420: |
| 786 | mcam_reg_write_mask(cam, REG_CTRL0, | 786 | mcam_reg_write_mask(cam, REG_CTRL0, |
| 787 | C0_DF_YUV | C0_YUV_420PL | C0_YUVE_YVYU, C0_DF_MASK); | 787 | C0_DF_YUV | C0_YUV_420PL | C0_YUVE_VYUY, C0_DF_MASK); |
| 788 | break; | 788 | break; |
| 789 | case V4L2_PIX_FMT_YUYV: | 789 | case V4L2_PIX_FMT_YUYV: |
| 790 | mcam_reg_write_mask(cam, REG_CTRL0, | 790 | mcam_reg_write_mask(cam, REG_CTRL0, |
| 791 | C0_DF_YUV | C0_YUV_PACKED | C0_YUVE_UYVY, C0_DF_MASK); | 791 | C0_DF_YUV | C0_YUV_PACKED | C0_YUVE_NOSWAP, C0_DF_MASK); |
| 792 | break; | 792 | break; |
| 793 | case V4L2_PIX_FMT_UYVY: | 793 | case V4L2_PIX_FMT_YVYU: |
| 794 | mcam_reg_write_mask(cam, REG_CTRL0, | 794 | mcam_reg_write_mask(cam, REG_CTRL0, |
| 795 | C0_DF_YUV | C0_YUV_PACKED | C0_YUVE_YUYV, C0_DF_MASK); | 795 | C0_DF_YUV | C0_YUV_PACKED | C0_YUVE_SWAP24, C0_DF_MASK); |
| 796 | break; | 796 | break; |
| 797 | case V4L2_PIX_FMT_JPEG: | 797 | case V4L2_PIX_FMT_JPEG: |
| 798 | mcam_reg_write_mask(cam, REG_CTRL0, | 798 | mcam_reg_write_mask(cam, REG_CTRL0, |
diff --git a/drivers/media/platform/marvell-ccic/mcam-core.h b/drivers/media/platform/marvell-ccic/mcam-core.h index aa0c6eac254a..7ffdf4dbaf8c 100644 --- a/drivers/media/platform/marvell-ccic/mcam-core.h +++ b/drivers/media/platform/marvell-ccic/mcam-core.h | |||
| @@ -330,10 +330,10 @@ int mccic_resume(struct mcam_camera *cam); | |||
| 330 | #define C0_YUVE_YVYU 0x00010000 /* Y1CrY0Cb */ | 330 | #define C0_YUVE_YVYU 0x00010000 /* Y1CrY0Cb */ |
| 331 | #define C0_YUVE_VYUY 0x00020000 /* CrY1CbY0 */ | 331 | #define C0_YUVE_VYUY 0x00020000 /* CrY1CbY0 */ |
| 332 | #define C0_YUVE_UYVY 0x00030000 /* CbY1CrY0 */ | 332 | #define C0_YUVE_UYVY 0x00030000 /* CbY1CrY0 */ |
| 333 | #define C0_YUVE_XYUV 0x00000000 /* 420: .YUV */ | 333 | #define C0_YUVE_NOSWAP 0x00000000 /* no bytes swapping */ |
| 334 | #define C0_YUVE_XYVU 0x00010000 /* 420: .YVU */ | 334 | #define C0_YUVE_SWAP13 0x00010000 /* swap byte 1 and 3 */ |
| 335 | #define C0_YUVE_XUVY 0x00020000 /* 420: .UVY */ | 335 | #define C0_YUVE_SWAP24 0x00020000 /* swap byte 2 and 4 */ |
| 336 | #define C0_YUVE_XVUY 0x00030000 /* 420: .VUY */ | 336 | #define C0_YUVE_SWAP1324 0x00030000 /* swap bytes 1&3 and 2&4 */ |
| 337 | /* Bayer bits 18,19 if needed */ | 337 | /* Bayer bits 18,19 if needed */ |
| 338 | #define C0_EOF_VSYNC 0x00400000 /* Generate EOF by VSYNC */ | 338 | #define C0_EOF_VSYNC 0x00400000 /* Generate EOF by VSYNC */ |
| 339 | #define C0_VEDGE_CTRL 0x00800000 /* Detect falling edge of VSYNC */ | 339 | #define C0_VEDGE_CTRL 0x00800000 /* Detect falling edge of VSYNC */ |
diff --git a/drivers/media/platform/soc_camera/rcar_vin.c b/drivers/media/platform/soc_camera/rcar_vin.c index 9351f64dee7b..6460f8e1b07f 100644 --- a/drivers/media/platform/soc_camera/rcar_vin.c +++ b/drivers/media/platform/soc_camera/rcar_vin.c | |||
| @@ -135,6 +135,8 @@ | |||
| 135 | #define VIN_MAX_WIDTH 2048 | 135 | #define VIN_MAX_WIDTH 2048 |
| 136 | #define VIN_MAX_HEIGHT 2048 | 136 | #define VIN_MAX_HEIGHT 2048 |
| 137 | 137 | ||
| 138 | #define TIMEOUT_MS 100 | ||
| 139 | |||
| 138 | enum chip_id { | 140 | enum chip_id { |
| 139 | RCAR_GEN2, | 141 | RCAR_GEN2, |
| 140 | RCAR_H1, | 142 | RCAR_H1, |
| @@ -820,7 +822,10 @@ static void rcar_vin_wait_stop_streaming(struct rcar_vin_priv *priv) | |||
| 820 | if (priv->state == STOPPING) { | 822 | if (priv->state == STOPPING) { |
| 821 | priv->request_to_stop = true; | 823 | priv->request_to_stop = true; |
| 822 | spin_unlock_irq(&priv->lock); | 824 | spin_unlock_irq(&priv->lock); |
| 823 | wait_for_completion(&priv->capture_stop); | 825 | if (!wait_for_completion_timeout( |
| 826 | &priv->capture_stop, | ||
| 827 | msecs_to_jiffies(TIMEOUT_MS))) | ||
| 828 | priv->state = STOPPED; | ||
| 824 | spin_lock_irq(&priv->lock); | 829 | spin_lock_irq(&priv->lock); |
| 825 | } | 830 | } |
| 826 | } | 831 | } |
diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c index 2c25271f8c41..60f7141a6b02 100644 --- a/drivers/mmc/card/block.c +++ b/drivers/mmc/card/block.c | |||
| @@ -1029,6 +1029,18 @@ static inline void mmc_blk_reset_success(struct mmc_blk_data *md, int type) | |||
| 1029 | md->reset_done &= ~type; | 1029 | md->reset_done &= ~type; |
| 1030 | } | 1030 | } |
| 1031 | 1031 | ||
| 1032 | int mmc_access_rpmb(struct mmc_queue *mq) | ||
| 1033 | { | ||
| 1034 | struct mmc_blk_data *md = mq->data; | ||
| 1035 | /* | ||
| 1036 | * If this is a RPMB partition access, return ture | ||
| 1037 | */ | ||
| 1038 | if (md && md->part_type == EXT_CSD_PART_CONFIG_ACC_RPMB) | ||
| 1039 | return true; | ||
| 1040 | |||
| 1041 | return false; | ||
| 1042 | } | ||
| 1043 | |||
| 1032 | static int mmc_blk_issue_discard_rq(struct mmc_queue *mq, struct request *req) | 1044 | static int mmc_blk_issue_discard_rq(struct mmc_queue *mq, struct request *req) |
| 1033 | { | 1045 | { |
| 1034 | struct mmc_blk_data *md = mq->data; | 1046 | struct mmc_blk_data *md = mq->data; |
diff --git a/drivers/mmc/card/queue.c b/drivers/mmc/card/queue.c index 236d194c2883..8efa3684aef8 100644 --- a/drivers/mmc/card/queue.c +++ b/drivers/mmc/card/queue.c | |||
| @@ -38,7 +38,7 @@ static int mmc_prep_request(struct request_queue *q, struct request *req) | |||
| 38 | return BLKPREP_KILL; | 38 | return BLKPREP_KILL; |
| 39 | } | 39 | } |
| 40 | 40 | ||
| 41 | if (mq && mmc_card_removed(mq->card)) | 41 | if (mq && (mmc_card_removed(mq->card) || mmc_access_rpmb(mq))) |
| 42 | return BLKPREP_KILL; | 42 | return BLKPREP_KILL; |
| 43 | 43 | ||
| 44 | req->cmd_flags |= REQ_DONTPREP; | 44 | req->cmd_flags |= REQ_DONTPREP; |
diff --git a/drivers/mmc/card/queue.h b/drivers/mmc/card/queue.h index 5752d50049a3..99e6521e6169 100644 --- a/drivers/mmc/card/queue.h +++ b/drivers/mmc/card/queue.h | |||
| @@ -73,4 +73,6 @@ extern void mmc_queue_bounce_post(struct mmc_queue_req *); | |||
| 73 | extern int mmc_packed_init(struct mmc_queue *, struct mmc_card *); | 73 | extern int mmc_packed_init(struct mmc_queue *, struct mmc_card *); |
| 74 | extern void mmc_packed_clean(struct mmc_queue *); | 74 | extern void mmc_packed_clean(struct mmc_queue *); |
| 75 | 75 | ||
| 76 | extern int mmc_access_rpmb(struct mmc_queue *); | ||
| 77 | |||
| 76 | #endif | 78 | #endif |
diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c index c296bc098fe2..92e7671426eb 100644 --- a/drivers/mmc/core/core.c +++ b/drivers/mmc/core/core.c | |||
| @@ -2651,6 +2651,7 @@ int mmc_pm_notify(struct notifier_block *notify_block, | |||
| 2651 | switch (mode) { | 2651 | switch (mode) { |
| 2652 | case PM_HIBERNATION_PREPARE: | 2652 | case PM_HIBERNATION_PREPARE: |
| 2653 | case PM_SUSPEND_PREPARE: | 2653 | case PM_SUSPEND_PREPARE: |
| 2654 | case PM_RESTORE_PREPARE: | ||
| 2654 | spin_lock_irqsave(&host->lock, flags); | 2655 | spin_lock_irqsave(&host->lock, flags); |
| 2655 | host->rescan_disable = 1; | 2656 | host->rescan_disable = 1; |
| 2656 | spin_unlock_irqrestore(&host->lock, flags); | 2657 | spin_unlock_irqrestore(&host->lock, flags); |
diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c index 38b29265cc7c..5f5adafb253a 100644 --- a/drivers/mmc/host/dw_mmc.c +++ b/drivers/mmc/host/dw_mmc.c | |||
| @@ -589,9 +589,11 @@ static int dw_mci_idmac_init(struct dw_mci *host) | |||
| 589 | host->ring_size = PAGE_SIZE / sizeof(struct idmac_desc); | 589 | host->ring_size = PAGE_SIZE / sizeof(struct idmac_desc); |
| 590 | 590 | ||
| 591 | /* Forward link the descriptor list */ | 591 | /* Forward link the descriptor list */ |
| 592 | for (i = 0, p = host->sg_cpu; i < host->ring_size - 1; i++, p++) | 592 | for (i = 0, p = host->sg_cpu; i < host->ring_size - 1; i++, p++) { |
| 593 | p->des3 = cpu_to_le32(host->sg_dma + | 593 | p->des3 = cpu_to_le32(host->sg_dma + |
| 594 | (sizeof(struct idmac_desc) * (i + 1))); | 594 | (sizeof(struct idmac_desc) * (i + 1))); |
| 595 | p->des1 = 0; | ||
| 596 | } | ||
| 595 | 597 | ||
| 596 | /* Set the last descriptor as the end-of-ring descriptor */ | 598 | /* Set the last descriptor as the end-of-ring descriptor */ |
| 597 | p->des3 = cpu_to_le32(host->sg_dma); | 599 | p->des3 = cpu_to_le32(host->sg_dma); |
| @@ -1300,7 +1302,8 @@ static int dw_mci_get_cd(struct mmc_host *mmc) | |||
| 1300 | int gpio_cd = mmc_gpio_get_cd(mmc); | 1302 | int gpio_cd = mmc_gpio_get_cd(mmc); |
| 1301 | 1303 | ||
| 1302 | /* Use platform get_cd function, else try onboard card detect */ | 1304 | /* Use platform get_cd function, else try onboard card detect */ |
| 1303 | if (brd->quirks & DW_MCI_QUIRK_BROKEN_CARD_DETECTION) | 1305 | if ((brd->quirks & DW_MCI_QUIRK_BROKEN_CARD_DETECTION) || |
| 1306 | (mmc->caps & MMC_CAP_NONREMOVABLE)) | ||
| 1304 | present = 1; | 1307 | present = 1; |
| 1305 | else if (!IS_ERR_VALUE(gpio_cd)) | 1308 | else if (!IS_ERR_VALUE(gpio_cd)) |
| 1306 | present = gpio_cd; | 1309 | present = gpio_cd; |
diff --git a/drivers/mmc/host/sh_mmcif.c b/drivers/mmc/host/sh_mmcif.c index 2b6ef6bd5d5f..7eff087cf515 100644 --- a/drivers/mmc/host/sh_mmcif.c +++ b/drivers/mmc/host/sh_mmcif.c | |||
| @@ -1408,7 +1408,7 @@ static int sh_mmcif_probe(struct platform_device *pdev) | |||
| 1408 | host = mmc_priv(mmc); | 1408 | host = mmc_priv(mmc); |
| 1409 | host->mmc = mmc; | 1409 | host->mmc = mmc; |
| 1410 | host->addr = reg; | 1410 | host->addr = reg; |
| 1411 | host->timeout = msecs_to_jiffies(1000); | 1411 | host->timeout = msecs_to_jiffies(10000); |
| 1412 | host->ccs_enable = !pd || !pd->ccs_unsupported; | 1412 | host->ccs_enable = !pd || !pd->ccs_unsupported; |
| 1413 | host->clk_ctrl2_enable = pd && pd->clk_ctrl2_present; | 1413 | host->clk_ctrl2_enable = pd && pd->clk_ctrl2_present; |
| 1414 | 1414 | ||
diff --git a/drivers/mtd/ubi/block.c b/drivers/mtd/ubi/block.c index db2c05b6fe7f..c9eb78f10a0d 100644 --- a/drivers/mtd/ubi/block.c +++ b/drivers/mtd/ubi/block.c | |||
| @@ -310,6 +310,8 @@ static void ubiblock_do_work(struct work_struct *work) | |||
| 310 | blk_rq_map_sg(req->q, req, pdu->usgl.sg); | 310 | blk_rq_map_sg(req->q, req, pdu->usgl.sg); |
| 311 | 311 | ||
| 312 | ret = ubiblock_read(pdu); | 312 | ret = ubiblock_read(pdu); |
| 313 | rq_flush_dcache_pages(req); | ||
| 314 | |||
| 313 | blk_mq_end_request(req, ret); | 315 | blk_mq_end_request(req, ret); |
| 314 | } | 316 | } |
| 315 | 317 | ||
diff --git a/drivers/net/can/xilinx_can.c b/drivers/net/can/xilinx_can.c index 6bddfe062b51..fc55e8e0351d 100644 --- a/drivers/net/can/xilinx_can.c +++ b/drivers/net/can/xilinx_can.c | |||
| @@ -509,10 +509,11 @@ static int xcan_rx(struct net_device *ndev) | |||
| 509 | cf->can_id |= CAN_RTR_FLAG; | 509 | cf->can_id |= CAN_RTR_FLAG; |
| 510 | } | 510 | } |
| 511 | 511 | ||
| 512 | if (!(id_xcan & XCAN_IDR_SRR_MASK)) { | 512 | /* DW1/DW2 must always be read to remove message from RXFIFO */ |
| 513 | data[0] = priv->read_reg(priv, XCAN_RXFIFO_DW1_OFFSET); | 513 | data[0] = priv->read_reg(priv, XCAN_RXFIFO_DW1_OFFSET); |
| 514 | data[1] = priv->read_reg(priv, XCAN_RXFIFO_DW2_OFFSET); | 514 | data[1] = priv->read_reg(priv, XCAN_RXFIFO_DW2_OFFSET); |
| 515 | 515 | ||
| 516 | if (!(cf->can_id & CAN_RTR_FLAG)) { | ||
| 516 | /* Change Xilinx CAN data format to socketCAN data format */ | 517 | /* Change Xilinx CAN data format to socketCAN data format */ |
| 517 | if (cf->can_dlc > 0) | 518 | if (cf->can_dlc > 0) |
| 518 | *(__be32 *)(cf->data) = cpu_to_be32(data[0]); | 519 | *(__be32 *)(cf->data) = cpu_to_be32(data[0]); |
diff --git a/drivers/net/dsa/mv88e6xxx.c b/drivers/net/dsa/mv88e6xxx.c index af639ab4c55b..cf309aa92802 100644 --- a/drivers/net/dsa/mv88e6xxx.c +++ b/drivers/net/dsa/mv88e6xxx.c | |||
| @@ -1469,6 +1469,9 @@ static void __exit mv88e6xxx_cleanup(void) | |||
| 1469 | #if IS_ENABLED(CONFIG_NET_DSA_MV88E6171) | 1469 | #if IS_ENABLED(CONFIG_NET_DSA_MV88E6171) |
| 1470 | unregister_switch_driver(&mv88e6171_switch_driver); | 1470 | unregister_switch_driver(&mv88e6171_switch_driver); |
| 1471 | #endif | 1471 | #endif |
| 1472 | #if IS_ENABLED(CONFIG_NET_DSA_MV88E6352) | ||
| 1473 | unregister_switch_driver(&mv88e6352_switch_driver); | ||
| 1474 | #endif | ||
| 1472 | #if IS_ENABLED(CONFIG_NET_DSA_MV88E6123_61_65) | 1475 | #if IS_ENABLED(CONFIG_NET_DSA_MV88E6123_61_65) |
| 1473 | unregister_switch_driver(&mv88e6123_61_65_switch_driver); | 1476 | unregister_switch_driver(&mv88e6123_61_65_switch_driver); |
| 1474 | #endif | 1477 | #endif |
diff --git a/drivers/net/ethernet/amd/Kconfig b/drivers/net/ethernet/amd/Kconfig index 089c269637b7..426916036151 100644 --- a/drivers/net/ethernet/amd/Kconfig +++ b/drivers/net/ethernet/amd/Kconfig | |||
| @@ -180,6 +180,7 @@ config SUNLANCE | |||
| 180 | config AMD_XGBE | 180 | config AMD_XGBE |
| 181 | tristate "AMD 10GbE Ethernet driver" | 181 | tristate "AMD 10GbE Ethernet driver" |
| 182 | depends on (OF_NET || ACPI) && HAS_IOMEM && HAS_DMA | 182 | depends on (OF_NET || ACPI) && HAS_IOMEM && HAS_DMA |
| 183 | depends on ARM64 || COMPILE_TEST | ||
| 183 | select PHYLIB | 184 | select PHYLIB |
| 184 | select AMD_XGBE_PHY | 185 | select AMD_XGBE_PHY |
| 185 | select BITREVERSE | 186 | select BITREVERSE |
diff --git a/drivers/net/ethernet/apm/xgene/Kconfig b/drivers/net/ethernet/apm/xgene/Kconfig index f4054d242f3c..19e38afbc5ee 100644 --- a/drivers/net/ethernet/apm/xgene/Kconfig +++ b/drivers/net/ethernet/apm/xgene/Kconfig | |||
| @@ -1,6 +1,7 @@ | |||
| 1 | config NET_XGENE | 1 | config NET_XGENE |
| 2 | tristate "APM X-Gene SoC Ethernet Driver" | 2 | tristate "APM X-Gene SoC Ethernet Driver" |
| 3 | depends on HAS_DMA | 3 | depends on HAS_DMA |
| 4 | depends on ARCH_XGENE || COMPILE_TEST | ||
| 4 | select PHYLIB | 5 | select PHYLIB |
| 5 | help | 6 | help |
| 6 | This is the Ethernet driver for the on-chip ethernet interface on the | 7 | This is the Ethernet driver for the on-chip ethernet interface on the |
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c index a8bb8f664d3d..ec56a9b65dc3 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c | |||
| @@ -4786,6 +4786,11 @@ int bnx2x_change_mtu(struct net_device *dev, int new_mtu) | |||
| 4786 | { | 4786 | { |
| 4787 | struct bnx2x *bp = netdev_priv(dev); | 4787 | struct bnx2x *bp = netdev_priv(dev); |
| 4788 | 4788 | ||
| 4789 | if (pci_num_vf(bp->pdev)) { | ||
| 4790 | DP(BNX2X_MSG_IOV, "VFs are enabled, can not change MTU\n"); | ||
| 4791 | return -EPERM; | ||
| 4792 | } | ||
| 4793 | |||
| 4789 | if (bp->recovery_state != BNX2X_RECOVERY_DONE) { | 4794 | if (bp->recovery_state != BNX2X_RECOVERY_DONE) { |
| 4790 | BNX2X_ERR("Can't perform change MTU during parity recovery\n"); | 4795 | BNX2X_ERR("Can't perform change MTU during parity recovery\n"); |
| 4791 | return -EAGAIN; | 4796 | return -EAGAIN; |
| @@ -4938,11 +4943,6 @@ int bnx2x_resume(struct pci_dev *pdev) | |||
| 4938 | } | 4943 | } |
| 4939 | bp = netdev_priv(dev); | 4944 | bp = netdev_priv(dev); |
| 4940 | 4945 | ||
| 4941 | if (pci_num_vf(bp->pdev)) { | ||
| 4942 | DP(BNX2X_MSG_IOV, "VFs are enabled, can not change MTU\n"); | ||
| 4943 | return -EPERM; | ||
| 4944 | } | ||
| 4945 | |||
| 4946 | if (bp->recovery_state != BNX2X_RECOVERY_DONE) { | 4946 | if (bp->recovery_state != BNX2X_RECOVERY_DONE) { |
| 4947 | BNX2X_ERR("Handling parity error recovery. Try again later\n"); | 4947 | BNX2X_ERR("Handling parity error recovery. Try again later\n"); |
| 4948 | return -EAGAIN; | 4948 | return -EAGAIN; |
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c index 556dcc162a62..fd52ce95127e 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c | |||
| @@ -13371,8 +13371,13 @@ static int bnx2x_init_one(struct pci_dev *pdev, | |||
| 13371 | /* Management FW 'remembers' living interfaces. Allow it some time | 13371 | /* Management FW 'remembers' living interfaces. Allow it some time |
| 13372 | * to forget previously living interfaces, allowing a proper re-load. | 13372 | * to forget previously living interfaces, allowing a proper re-load. |
| 13373 | */ | 13373 | */ |
| 13374 | if (is_kdump_kernel()) | 13374 | if (is_kdump_kernel()) { |
| 13375 | msleep(5000); | 13375 | ktime_t now = ktime_get_boottime(); |
| 13376 | ktime_t fw_ready_time = ktime_set(5, 0); | ||
| 13377 | |||
| 13378 | if (ktime_before(now, fw_ready_time)) | ||
| 13379 | msleep(ktime_ms_delta(fw_ready_time, now)); | ||
| 13380 | } | ||
| 13376 | 13381 | ||
| 13377 | /* An estimated maximum supported CoS number according to the chip | 13382 | /* An estimated maximum supported CoS number according to the chip |
| 13378 | * version. | 13383 | * version. |
diff --git a/drivers/net/ethernet/cadence/macb.c b/drivers/net/ethernet/cadence/macb.c index 4104d49f005d..61aa570aad9a 100644 --- a/drivers/net/ethernet/cadence/macb.c +++ b/drivers/net/ethernet/cadence/macb.c | |||
| @@ -981,7 +981,7 @@ static irqreturn_t macb_interrupt(int irq, void *dev_id) | |||
| 981 | struct macb_queue *queue = dev_id; | 981 | struct macb_queue *queue = dev_id; |
| 982 | struct macb *bp = queue->bp; | 982 | struct macb *bp = queue->bp; |
| 983 | struct net_device *dev = bp->dev; | 983 | struct net_device *dev = bp->dev; |
| 984 | u32 status; | 984 | u32 status, ctrl; |
| 985 | 985 | ||
| 986 | status = queue_readl(queue, ISR); | 986 | status = queue_readl(queue, ISR); |
| 987 | 987 | ||
| @@ -1037,6 +1037,15 @@ static irqreturn_t macb_interrupt(int irq, void *dev_id) | |||
| 1037 | * add that if/when we get our hands on a full-blown MII PHY. | 1037 | * add that if/when we get our hands on a full-blown MII PHY. |
| 1038 | */ | 1038 | */ |
| 1039 | 1039 | ||
| 1040 | if (status & MACB_BIT(RXUBR)) { | ||
| 1041 | ctrl = macb_readl(bp, NCR); | ||
| 1042 | macb_writel(bp, NCR, ctrl & ~MACB_BIT(RE)); | ||
| 1043 | macb_writel(bp, NCR, ctrl | MACB_BIT(RE)); | ||
| 1044 | |||
| 1045 | if (bp->caps & MACB_CAPS_ISR_CLEAR_ON_WRITE) | ||
| 1046 | macb_writel(bp, ISR, MACB_BIT(RXUBR)); | ||
| 1047 | } | ||
| 1048 | |||
| 1040 | if (status & MACB_BIT(ISR_ROVR)) { | 1049 | if (status & MACB_BIT(ISR_ROVR)) { |
| 1041 | /* We missed at least one packet */ | 1050 | /* We missed at least one packet */ |
| 1042 | if (macb_is_gem(bp)) | 1051 | if (macb_is_gem(bp)) |
diff --git a/drivers/net/ethernet/intel/e1000e/e1000.h b/drivers/net/ethernet/intel/e1000e/e1000.h index 5d9ceb17b4cb..0abc942c966e 100644 --- a/drivers/net/ethernet/intel/e1000e/e1000.h +++ b/drivers/net/ethernet/intel/e1000e/e1000.h | |||
| @@ -40,6 +40,7 @@ | |||
| 40 | #include <linux/ptp_classify.h> | 40 | #include <linux/ptp_classify.h> |
| 41 | #include <linux/mii.h> | 41 | #include <linux/mii.h> |
| 42 | #include <linux/mdio.h> | 42 | #include <linux/mdio.h> |
| 43 | #include <linux/pm_qos.h> | ||
| 43 | #include "hw.h" | 44 | #include "hw.h" |
| 44 | 45 | ||
| 45 | struct e1000_info; | 46 | struct e1000_info; |
diff --git a/drivers/net/ethernet/intel/fm10k/fm10k_main.c b/drivers/net/ethernet/intel/fm10k/fm10k_main.c index 1b0661e3573b..c754b2027281 100644 --- a/drivers/net/ethernet/intel/fm10k/fm10k_main.c +++ b/drivers/net/ethernet/intel/fm10k/fm10k_main.c | |||
| @@ -610,7 +610,7 @@ static bool fm10k_clean_rx_irq(struct fm10k_q_vector *q_vector, | |||
| 610 | unsigned int total_bytes = 0, total_packets = 0; | 610 | unsigned int total_bytes = 0, total_packets = 0; |
| 611 | u16 cleaned_count = fm10k_desc_unused(rx_ring); | 611 | u16 cleaned_count = fm10k_desc_unused(rx_ring); |
| 612 | 612 | ||
| 613 | do { | 613 | while (likely(total_packets < budget)) { |
| 614 | union fm10k_rx_desc *rx_desc; | 614 | union fm10k_rx_desc *rx_desc; |
| 615 | 615 | ||
| 616 | /* return some buffers to hardware, one at a time is too slow */ | 616 | /* return some buffers to hardware, one at a time is too slow */ |
| @@ -659,7 +659,7 @@ static bool fm10k_clean_rx_irq(struct fm10k_q_vector *q_vector, | |||
| 659 | 659 | ||
| 660 | /* update budget accounting */ | 660 | /* update budget accounting */ |
| 661 | total_packets++; | 661 | total_packets++; |
| 662 | } while (likely(total_packets < budget)); | 662 | } |
| 663 | 663 | ||
| 664 | /* place incomplete frames back on ring for completion */ | 664 | /* place incomplete frames back on ring for completion */ |
| 665 | rx_ring->skb = skb; | 665 | rx_ring->skb = skb; |
diff --git a/drivers/net/ethernet/intel/igb/igb_main.c b/drivers/net/ethernet/intel/igb/igb_main.c index 8457d0306e3a..a0a9b1fcb5e8 100644 --- a/drivers/net/ethernet/intel/igb/igb_main.c +++ b/drivers/net/ethernet/intel/igb/igb_main.c | |||
| @@ -1036,7 +1036,7 @@ static void igb_reset_q_vector(struct igb_adapter *adapter, int v_idx) | |||
| 1036 | adapter->tx_ring[q_vector->tx.ring->queue_index] = NULL; | 1036 | adapter->tx_ring[q_vector->tx.ring->queue_index] = NULL; |
| 1037 | 1037 | ||
| 1038 | if (q_vector->rx.ring) | 1038 | if (q_vector->rx.ring) |
| 1039 | adapter->tx_ring[q_vector->rx.ring->queue_index] = NULL; | 1039 | adapter->rx_ring[q_vector->rx.ring->queue_index] = NULL; |
| 1040 | 1040 | ||
| 1041 | netif_napi_del(&q_vector->napi); | 1041 | netif_napi_del(&q_vector->napi); |
| 1042 | 1042 | ||
| @@ -1207,6 +1207,8 @@ static int igb_alloc_q_vector(struct igb_adapter *adapter, | |||
| 1207 | q_vector = adapter->q_vector[v_idx]; | 1207 | q_vector = adapter->q_vector[v_idx]; |
| 1208 | if (!q_vector) | 1208 | if (!q_vector) |
| 1209 | q_vector = kzalloc(size, GFP_KERNEL); | 1209 | q_vector = kzalloc(size, GFP_KERNEL); |
| 1210 | else | ||
| 1211 | memset(q_vector, 0, size); | ||
| 1210 | if (!q_vector) | 1212 | if (!q_vector) |
| 1211 | return -ENOMEM; | 1213 | return -ENOMEM; |
| 1212 | 1214 | ||
diff --git a/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c b/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c index a16d267fbce4..e71cdde9cb01 100644 --- a/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c +++ b/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c | |||
| @@ -3612,7 +3612,7 @@ static int ixgbevf_xmit_frame(struct sk_buff *skb, struct net_device *netdev) | |||
| 3612 | u8 *dst_mac = skb_header_pointer(skb, 0, 0, NULL); | 3612 | u8 *dst_mac = skb_header_pointer(skb, 0, 0, NULL); |
| 3613 | 3613 | ||
| 3614 | if (!dst_mac || is_link_local_ether_addr(dst_mac)) { | 3614 | if (!dst_mac || is_link_local_ether_addr(dst_mac)) { |
| 3615 | dev_kfree_skb(skb); | 3615 | dev_kfree_skb_any(skb); |
| 3616 | return NETDEV_TX_OK; | 3616 | return NETDEV_TX_OK; |
| 3617 | } | 3617 | } |
| 3618 | 3618 | ||
diff --git a/drivers/net/ethernet/mellanox/mlx4/en_port.c b/drivers/net/ethernet/mellanox/mlx4/en_port.c index 54f0e5ab2e55..0a56f010c846 100644 --- a/drivers/net/ethernet/mellanox/mlx4/en_port.c +++ b/drivers/net/ethernet/mellanox/mlx4/en_port.c | |||
| @@ -139,7 +139,7 @@ static unsigned long en_stats_adder(__be64 *start, __be64 *next, int num) | |||
| 139 | int i; | 139 | int i; |
| 140 | int offset = next - start; | 140 | int offset = next - start; |
| 141 | 141 | ||
| 142 | for (i = 0; i <= num; i++) { | 142 | for (i = 0; i < num; i++) { |
| 143 | ret += be64_to_cpu(*curr); | 143 | ret += be64_to_cpu(*curr); |
| 144 | curr += offset; | 144 | curr += offset; |
| 145 | } | 145 | } |
diff --git a/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c b/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c index c7f28bf4b8e2..92fce1b98558 100644 --- a/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c +++ b/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c | |||
| @@ -2845,7 +2845,7 @@ int mlx4_SW2HW_EQ_wrapper(struct mlx4_dev *dev, int slave, | |||
| 2845 | { | 2845 | { |
| 2846 | int err; | 2846 | int err; |
| 2847 | int eqn = vhcr->in_modifier; | 2847 | int eqn = vhcr->in_modifier; |
| 2848 | int res_id = (slave << 8) | eqn; | 2848 | int res_id = (slave << 10) | eqn; |
| 2849 | struct mlx4_eq_context *eqc = inbox->buf; | 2849 | struct mlx4_eq_context *eqc = inbox->buf; |
| 2850 | int mtt_base = eq_get_mtt_addr(eqc) / dev->caps.mtt_entry_sz; | 2850 | int mtt_base = eq_get_mtt_addr(eqc) / dev->caps.mtt_entry_sz; |
| 2851 | int mtt_size = eq_get_mtt_size(eqc); | 2851 | int mtt_size = eq_get_mtt_size(eqc); |
| @@ -3051,7 +3051,7 @@ int mlx4_HW2SW_EQ_wrapper(struct mlx4_dev *dev, int slave, | |||
| 3051 | struct mlx4_cmd_info *cmd) | 3051 | struct mlx4_cmd_info *cmd) |
| 3052 | { | 3052 | { |
| 3053 | int eqn = vhcr->in_modifier; | 3053 | int eqn = vhcr->in_modifier; |
| 3054 | int res_id = eqn | (slave << 8); | 3054 | int res_id = eqn | (slave << 10); |
| 3055 | struct res_eq *eq; | 3055 | struct res_eq *eq; |
| 3056 | int err; | 3056 | int err; |
| 3057 | 3057 | ||
| @@ -3108,7 +3108,7 @@ int mlx4_GEN_EQE(struct mlx4_dev *dev, int slave, struct mlx4_eqe *eqe) | |||
| 3108 | return 0; | 3108 | return 0; |
| 3109 | 3109 | ||
| 3110 | mutex_lock(&priv->mfunc.master.gen_eqe_mutex[slave]); | 3110 | mutex_lock(&priv->mfunc.master.gen_eqe_mutex[slave]); |
| 3111 | res_id = (slave << 8) | event_eq->eqn; | 3111 | res_id = (slave << 10) | event_eq->eqn; |
| 3112 | err = get_res(dev, slave, res_id, RES_EQ, &req); | 3112 | err = get_res(dev, slave, res_id, RES_EQ, &req); |
| 3113 | if (err) | 3113 | if (err) |
| 3114 | goto unlock; | 3114 | goto unlock; |
| @@ -3131,7 +3131,7 @@ int mlx4_GEN_EQE(struct mlx4_dev *dev, int slave, struct mlx4_eqe *eqe) | |||
| 3131 | 3131 | ||
| 3132 | memcpy(mailbox->buf, (u8 *) eqe, 28); | 3132 | memcpy(mailbox->buf, (u8 *) eqe, 28); |
| 3133 | 3133 | ||
| 3134 | in_modifier = (slave & 0xff) | ((event_eq->eqn & 0xff) << 16); | 3134 | in_modifier = (slave & 0xff) | ((event_eq->eqn & 0x3ff) << 16); |
| 3135 | 3135 | ||
| 3136 | err = mlx4_cmd(dev, mailbox->dma, in_modifier, 0, | 3136 | err = mlx4_cmd(dev, mailbox->dma, in_modifier, 0, |
| 3137 | MLX4_CMD_GEN_EQE, MLX4_CMD_TIME_CLASS_B, | 3137 | MLX4_CMD_GEN_EQE, MLX4_CMD_TIME_CLASS_B, |
| @@ -3157,7 +3157,7 @@ int mlx4_QUERY_EQ_wrapper(struct mlx4_dev *dev, int slave, | |||
| 3157 | struct mlx4_cmd_info *cmd) | 3157 | struct mlx4_cmd_info *cmd) |
| 3158 | { | 3158 | { |
| 3159 | int eqn = vhcr->in_modifier; | 3159 | int eqn = vhcr->in_modifier; |
| 3160 | int res_id = eqn | (slave << 8); | 3160 | int res_id = eqn | (slave << 10); |
| 3161 | struct res_eq *eq; | 3161 | struct res_eq *eq; |
| 3162 | int err; | 3162 | int err; |
| 3163 | 3163 | ||
| @@ -4714,13 +4714,13 @@ static void rem_slave_eqs(struct mlx4_dev *dev, int slave) | |||
| 4714 | break; | 4714 | break; |
| 4715 | 4715 | ||
| 4716 | case RES_EQ_HW: | 4716 | case RES_EQ_HW: |
| 4717 | err = mlx4_cmd(dev, slave, eqn & 0xff, | 4717 | err = mlx4_cmd(dev, slave, eqn & 0x3ff, |
| 4718 | 1, MLX4_CMD_HW2SW_EQ, | 4718 | 1, MLX4_CMD_HW2SW_EQ, |
| 4719 | MLX4_CMD_TIME_CLASS_A, | 4719 | MLX4_CMD_TIME_CLASS_A, |
| 4720 | MLX4_CMD_NATIVE); | 4720 | MLX4_CMD_NATIVE); |
| 4721 | if (err) | 4721 | if (err) |
| 4722 | mlx4_dbg(dev, "rem_slave_eqs: failed to move slave %d eqs %d to SW ownership\n", | 4722 | mlx4_dbg(dev, "rem_slave_eqs: failed to move slave %d eqs %d to SW ownership\n", |
| 4723 | slave, eqn); | 4723 | slave, eqn & 0x3ff); |
| 4724 | atomic_dec(&eq->mtt->ref_count); | 4724 | atomic_dec(&eq->mtt->ref_count); |
| 4725 | state = RES_EQ_RESERVED; | 4725 | state = RES_EQ_RESERVED; |
| 4726 | break; | 4726 | break; |
diff --git a/drivers/net/ethernet/qlogic/netxen/netxen_nic_init.c b/drivers/net/ethernet/qlogic/netxen/netxen_nic_init.c index 8da7c3faf817..7b43a3b4abdc 100644 --- a/drivers/net/ethernet/qlogic/netxen/netxen_nic_init.c +++ b/drivers/net/ethernet/qlogic/netxen/netxen_nic_init.c | |||
| @@ -1764,7 +1764,7 @@ int netxen_process_cmd_ring(struct netxen_adapter *adapter) | |||
| 1764 | int done = 0; | 1764 | int done = 0; |
| 1765 | struct nx_host_tx_ring *tx_ring = adapter->tx_ring; | 1765 | struct nx_host_tx_ring *tx_ring = adapter->tx_ring; |
| 1766 | 1766 | ||
| 1767 | if (!spin_trylock(&adapter->tx_clean_lock)) | 1767 | if (!spin_trylock_bh(&adapter->tx_clean_lock)) |
| 1768 | return 1; | 1768 | return 1; |
| 1769 | 1769 | ||
| 1770 | sw_consumer = tx_ring->sw_consumer; | 1770 | sw_consumer = tx_ring->sw_consumer; |
| @@ -1819,7 +1819,7 @@ int netxen_process_cmd_ring(struct netxen_adapter *adapter) | |||
| 1819 | */ | 1819 | */ |
| 1820 | hw_consumer = le32_to_cpu(*(tx_ring->hw_consumer)); | 1820 | hw_consumer = le32_to_cpu(*(tx_ring->hw_consumer)); |
| 1821 | done = (sw_consumer == hw_consumer); | 1821 | done = (sw_consumer == hw_consumer); |
| 1822 | spin_unlock(&adapter->tx_clean_lock); | 1822 | spin_unlock_bh(&adapter->tx_clean_lock); |
| 1823 | 1823 | ||
| 1824 | return done; | 1824 | return done; |
| 1825 | } | 1825 | } |
diff --git a/drivers/net/ethernet/qualcomm/qca_spi.c b/drivers/net/ethernet/qualcomm/qca_spi.c index f66641d961e3..6af028d5f9bc 100644 --- a/drivers/net/ethernet/qualcomm/qca_spi.c +++ b/drivers/net/ethernet/qualcomm/qca_spi.c | |||
| @@ -912,6 +912,8 @@ qca_spi_probe(struct spi_device *spi_device) | |||
| 912 | qca->spi_dev = spi_device; | 912 | qca->spi_dev = spi_device; |
| 913 | qca->legacy_mode = legacy_mode; | 913 | qca->legacy_mode = legacy_mode; |
| 914 | 914 | ||
| 915 | spi_set_drvdata(spi_device, qcaspi_devs); | ||
| 916 | |||
| 915 | mac = of_get_mac_address(spi_device->dev.of_node); | 917 | mac = of_get_mac_address(spi_device->dev.of_node); |
| 916 | 918 | ||
| 917 | if (mac) | 919 | if (mac) |
| @@ -944,8 +946,6 @@ qca_spi_probe(struct spi_device *spi_device) | |||
| 944 | return -EFAULT; | 946 | return -EFAULT; |
| 945 | } | 947 | } |
| 946 | 948 | ||
| 947 | spi_set_drvdata(spi_device, qcaspi_devs); | ||
| 948 | |||
| 949 | qcaspi_init_device_debugfs(qca); | 949 | qcaspi_init_device_debugfs(qca); |
| 950 | 950 | ||
| 951 | return 0; | 951 | return 0; |
diff --git a/drivers/net/ethernet/realtek/r8169.c b/drivers/net/ethernet/realtek/r8169.c index c70ab40d8698..3df51faf18ae 100644 --- a/drivers/net/ethernet/realtek/r8169.c +++ b/drivers/net/ethernet/realtek/r8169.c | |||
| @@ -6884,7 +6884,7 @@ static void r8169_csum_workaround(struct rtl8169_private *tp, | |||
| 6884 | rtl8169_start_xmit(nskb, tp->dev); | 6884 | rtl8169_start_xmit(nskb, tp->dev); |
| 6885 | } while (segs); | 6885 | } while (segs); |
| 6886 | 6886 | ||
| 6887 | dev_kfree_skb(skb); | 6887 | dev_consume_skb_any(skb); |
| 6888 | } else if (skb->ip_summed == CHECKSUM_PARTIAL) { | 6888 | } else if (skb->ip_summed == CHECKSUM_PARTIAL) { |
| 6889 | if (skb_checksum_help(skb) < 0) | 6889 | if (skb_checksum_help(skb) < 0) |
| 6890 | goto drop; | 6890 | goto drop; |
| @@ -6896,7 +6896,7 @@ static void r8169_csum_workaround(struct rtl8169_private *tp, | |||
| 6896 | drop: | 6896 | drop: |
| 6897 | stats = &tp->dev->stats; | 6897 | stats = &tp->dev->stats; |
| 6898 | stats->tx_dropped++; | 6898 | stats->tx_dropped++; |
| 6899 | dev_kfree_skb(skb); | 6899 | dev_kfree_skb_any(skb); |
| 6900 | } | 6900 | } |
| 6901 | } | 6901 | } |
| 6902 | 6902 | ||
diff --git a/drivers/net/ethernet/smsc/smc91x.c b/drivers/net/ethernet/smsc/smc91x.c index 14b363a25c02..630f0b7800e4 100644 --- a/drivers/net/ethernet/smsc/smc91x.c +++ b/drivers/net/ethernet/smsc/smc91x.c | |||
| @@ -2238,9 +2238,10 @@ static int smc_drv_probe(struct platform_device *pdev) | |||
| 2238 | const struct of_device_id *match = NULL; | 2238 | const struct of_device_id *match = NULL; |
| 2239 | struct smc_local *lp; | 2239 | struct smc_local *lp; |
| 2240 | struct net_device *ndev; | 2240 | struct net_device *ndev; |
| 2241 | struct resource *res, *ires; | 2241 | struct resource *res; |
| 2242 | unsigned int __iomem *addr; | 2242 | unsigned int __iomem *addr; |
| 2243 | unsigned long irq_flags = SMC_IRQ_FLAGS; | 2243 | unsigned long irq_flags = SMC_IRQ_FLAGS; |
| 2244 | unsigned long irq_resflags; | ||
| 2244 | int ret; | 2245 | int ret; |
| 2245 | 2246 | ||
| 2246 | ndev = alloc_etherdev(sizeof(struct smc_local)); | 2247 | ndev = alloc_etherdev(sizeof(struct smc_local)); |
| @@ -2332,16 +2333,19 @@ static int smc_drv_probe(struct platform_device *pdev) | |||
| 2332 | goto out_free_netdev; | 2333 | goto out_free_netdev; |
| 2333 | } | 2334 | } |
| 2334 | 2335 | ||
| 2335 | ires = platform_get_resource(pdev, IORESOURCE_IRQ, 0); | 2336 | ndev->irq = platform_get_irq(pdev, 0); |
| 2336 | if (!ires) { | 2337 | if (ndev->irq <= 0) { |
| 2337 | ret = -ENODEV; | 2338 | ret = -ENODEV; |
| 2338 | goto out_release_io; | 2339 | goto out_release_io; |
| 2339 | } | 2340 | } |
| 2340 | 2341 | /* | |
| 2341 | ndev->irq = ires->start; | 2342 | * If this platform does not specify any special irqflags, or if |
| 2342 | 2343 | * the resource supplies a trigger, override the irqflags with | |
| 2343 | if (irq_flags == -1 || ires->flags & IRQF_TRIGGER_MASK) | 2344 | * the trigger flags from the resource. |
| 2344 | irq_flags = ires->flags & IRQF_TRIGGER_MASK; | 2345 | */ |
| 2346 | irq_resflags = irqd_get_trigger_type(irq_get_irq_data(ndev->irq)); | ||
| 2347 | if (irq_flags == -1 || irq_resflags & IRQF_TRIGGER_MASK) | ||
| 2348 | irq_flags = irq_resflags & IRQF_TRIGGER_MASK; | ||
| 2345 | 2349 | ||
| 2346 | ret = smc_request_attrib(pdev, ndev); | 2350 | ret = smc_request_attrib(pdev, ndev); |
| 2347 | if (ret) | 2351 | if (ret) |
diff --git a/drivers/net/ethernet/smsc/smsc911x.c b/drivers/net/ethernet/smsc/smsc911x.c index 41047c9143d0..959aeeade0c9 100644 --- a/drivers/net/ethernet/smsc/smsc911x.c +++ b/drivers/net/ethernet/smsc/smsc911x.c | |||
| @@ -2418,9 +2418,9 @@ static int smsc911x_drv_probe(struct platform_device *pdev) | |||
| 2418 | struct net_device *dev; | 2418 | struct net_device *dev; |
| 2419 | struct smsc911x_data *pdata; | 2419 | struct smsc911x_data *pdata; |
| 2420 | struct smsc911x_platform_config *config = dev_get_platdata(&pdev->dev); | 2420 | struct smsc911x_platform_config *config = dev_get_platdata(&pdev->dev); |
| 2421 | struct resource *res, *irq_res; | 2421 | struct resource *res; |
| 2422 | unsigned int intcfg = 0; | 2422 | unsigned int intcfg = 0; |
| 2423 | int res_size, irq_flags; | 2423 | int res_size, irq, irq_flags; |
| 2424 | int retval; | 2424 | int retval; |
| 2425 | 2425 | ||
| 2426 | res = platform_get_resource_byname(pdev, IORESOURCE_MEM, | 2426 | res = platform_get_resource_byname(pdev, IORESOURCE_MEM, |
| @@ -2434,8 +2434,8 @@ static int smsc911x_drv_probe(struct platform_device *pdev) | |||
| 2434 | } | 2434 | } |
| 2435 | res_size = resource_size(res); | 2435 | res_size = resource_size(res); |
| 2436 | 2436 | ||
| 2437 | irq_res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); | 2437 | irq = platform_get_irq(pdev, 0); |
| 2438 | if (!irq_res) { | 2438 | if (irq <= 0) { |
| 2439 | pr_warn("Could not allocate irq resource\n"); | 2439 | pr_warn("Could not allocate irq resource\n"); |
| 2440 | retval = -ENODEV; | 2440 | retval = -ENODEV; |
| 2441 | goto out_0; | 2441 | goto out_0; |
| @@ -2455,8 +2455,8 @@ static int smsc911x_drv_probe(struct platform_device *pdev) | |||
| 2455 | SET_NETDEV_DEV(dev, &pdev->dev); | 2455 | SET_NETDEV_DEV(dev, &pdev->dev); |
| 2456 | 2456 | ||
| 2457 | pdata = netdev_priv(dev); | 2457 | pdata = netdev_priv(dev); |
| 2458 | dev->irq = irq_res->start; | 2458 | dev->irq = irq; |
| 2459 | irq_flags = irq_res->flags & IRQF_TRIGGER_MASK; | 2459 | irq_flags = irq_get_trigger_type(irq); |
| 2460 | pdata->ioaddr = ioremap_nocache(res->start, res_size); | 2460 | pdata->ioaddr = ioremap_nocache(res->start, res_size); |
| 2461 | 2461 | ||
| 2462 | pdata->dev = dev; | 2462 | pdata->dev = dev; |
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c index 705bbdf93940..68aec5c460db 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c | |||
| @@ -23,6 +23,7 @@ | |||
| 23 | *******************************************************************************/ | 23 | *******************************************************************************/ |
| 24 | 24 | ||
| 25 | #include <linux/platform_device.h> | 25 | #include <linux/platform_device.h> |
| 26 | #include <linux/module.h> | ||
| 26 | #include <linux/io.h> | 27 | #include <linux/io.h> |
| 27 | #include <linux/of.h> | 28 | #include <linux/of.h> |
| 28 | #include <linux/of_net.h> | 29 | #include <linux/of_net.h> |
diff --git a/drivers/net/ethernet/xilinx/ll_temac_main.c b/drivers/net/ethernet/xilinx/ll_temac_main.c index 690a4c36b316..af2694dc6f90 100644 --- a/drivers/net/ethernet/xilinx/ll_temac_main.c +++ b/drivers/net/ethernet/xilinx/ll_temac_main.c | |||
| @@ -707,8 +707,8 @@ static int temac_start_xmit(struct sk_buff *skb, struct net_device *ndev) | |||
| 707 | 707 | ||
| 708 | cur_p->app0 |= STS_CTRL_APP0_SOP; | 708 | cur_p->app0 |= STS_CTRL_APP0_SOP; |
| 709 | cur_p->len = skb_headlen(skb); | 709 | cur_p->len = skb_headlen(skb); |
| 710 | cur_p->phys = dma_map_single(ndev->dev.parent, skb->data, skb->len, | 710 | cur_p->phys = dma_map_single(ndev->dev.parent, skb->data, |
| 711 | DMA_TO_DEVICE); | 711 | skb_headlen(skb), DMA_TO_DEVICE); |
| 712 | cur_p->app4 = (unsigned long)skb; | 712 | cur_p->app4 = (unsigned long)skb; |
| 713 | 713 | ||
| 714 | for (ii = 0; ii < num_frag; ii++) { | 714 | for (ii = 0; ii < num_frag; ii++) { |
diff --git a/drivers/net/hyperv/netvsc.c b/drivers/net/hyperv/netvsc.c index 2d9ef533cc48..ea091bc5ff09 100644 --- a/drivers/net/hyperv/netvsc.c +++ b/drivers/net/hyperv/netvsc.c | |||
| @@ -826,7 +826,6 @@ int netvsc_send(struct hv_device *device, | |||
| 826 | u16 q_idx = packet->q_idx; | 826 | u16 q_idx = packet->q_idx; |
| 827 | u32 pktlen = packet->total_data_buflen, msd_len = 0; | 827 | u32 pktlen = packet->total_data_buflen, msd_len = 0; |
| 828 | unsigned int section_index = NETVSC_INVALID_INDEX; | 828 | unsigned int section_index = NETVSC_INVALID_INDEX; |
| 829 | struct sk_buff *skb = NULL; | ||
| 830 | unsigned long flag; | 829 | unsigned long flag; |
| 831 | struct multi_send_data *msdp; | 830 | struct multi_send_data *msdp; |
| 832 | struct hv_netvsc_packet *msd_send = NULL, *cur_send = NULL; | 831 | struct hv_netvsc_packet *msd_send = NULL, *cur_send = NULL; |
| @@ -924,12 +923,8 @@ int netvsc_send(struct hv_device *device, | |||
| 924 | if (cur_send) | 923 | if (cur_send) |
| 925 | ret = netvsc_send_pkt(cur_send, net_device); | 924 | ret = netvsc_send_pkt(cur_send, net_device); |
| 926 | 925 | ||
| 927 | if (ret != 0) { | 926 | if (ret != 0 && section_index != NETVSC_INVALID_INDEX) |
| 928 | if (section_index != NETVSC_INVALID_INDEX) | 927 | netvsc_free_send_slot(net_device, section_index); |
| 929 | netvsc_free_send_slot(net_device, section_index); | ||
| 930 | } else if (skb) { | ||
| 931 | dev_kfree_skb_any(skb); | ||
| 932 | } | ||
| 933 | 928 | ||
| 934 | return ret; | 929 | return ret; |
| 935 | } | 930 | } |
diff --git a/drivers/net/ieee802154/at86rf230.c b/drivers/net/ieee802154/at86rf230.c index 38026650c038..67d00fbc2e0e 100644 --- a/drivers/net/ieee802154/at86rf230.c +++ b/drivers/net/ieee802154/at86rf230.c | |||
| @@ -85,6 +85,7 @@ struct at86rf230_local { | |||
| 85 | struct ieee802154_hw *hw; | 85 | struct ieee802154_hw *hw; |
| 86 | struct at86rf2xx_chip_data *data; | 86 | struct at86rf2xx_chip_data *data; |
| 87 | struct regmap *regmap; | 87 | struct regmap *regmap; |
| 88 | int slp_tr; | ||
| 88 | 89 | ||
| 89 | struct completion state_complete; | 90 | struct completion state_complete; |
| 90 | struct at86rf230_state_change state; | 91 | struct at86rf230_state_change state; |
| @@ -95,163 +96,164 @@ struct at86rf230_local { | |||
| 95 | unsigned long cal_timeout; | 96 | unsigned long cal_timeout; |
| 96 | s8 max_frame_retries; | 97 | s8 max_frame_retries; |
| 97 | bool is_tx; | 98 | bool is_tx; |
| 99 | bool is_tx_from_off; | ||
| 98 | u8 tx_retry; | 100 | u8 tx_retry; |
| 99 | struct sk_buff *tx_skb; | 101 | struct sk_buff *tx_skb; |
| 100 | struct at86rf230_state_change tx; | 102 | struct at86rf230_state_change tx; |
| 101 | }; | 103 | }; |
| 102 | 104 | ||
| 103 | #define RG_TRX_STATUS (0x01) | 105 | #define RG_TRX_STATUS (0x01) |
| 104 | #define SR_TRX_STATUS 0x01, 0x1f, 0 | 106 | #define SR_TRX_STATUS 0x01, 0x1f, 0 |
| 105 | #define SR_RESERVED_01_3 0x01, 0x20, 5 | 107 | #define SR_RESERVED_01_3 0x01, 0x20, 5 |
| 106 | #define SR_CCA_STATUS 0x01, 0x40, 6 | 108 | #define SR_CCA_STATUS 0x01, 0x40, 6 |
| 107 | #define SR_CCA_DONE 0x01, 0x80, 7 | 109 | #define SR_CCA_DONE 0x01, 0x80, 7 |
| 108 | #define RG_TRX_STATE (0x02) | 110 | #define RG_TRX_STATE (0x02) |
| 109 | #define SR_TRX_CMD 0x02, 0x1f, 0 | 111 | #define SR_TRX_CMD 0x02, 0x1f, 0 |
| 110 | #define SR_TRAC_STATUS 0x02, 0xe0, 5 | 112 | #define SR_TRAC_STATUS 0x02, 0xe0, 5 |
| 111 | #define RG_TRX_CTRL_0 (0x03) | 113 | #define RG_TRX_CTRL_0 (0x03) |
| 112 | #define SR_CLKM_CTRL 0x03, 0x07, 0 | 114 | #define SR_CLKM_CTRL 0x03, 0x07, 0 |
| 113 | #define SR_CLKM_SHA_SEL 0x03, 0x08, 3 | 115 | #define SR_CLKM_SHA_SEL 0x03, 0x08, 3 |
| 114 | #define SR_PAD_IO_CLKM 0x03, 0x30, 4 | 116 | #define SR_PAD_IO_CLKM 0x03, 0x30, 4 |
| 115 | #define SR_PAD_IO 0x03, 0xc0, 6 | 117 | #define SR_PAD_IO 0x03, 0xc0, 6 |
| 116 | #define RG_TRX_CTRL_1 (0x04) | 118 | #define RG_TRX_CTRL_1 (0x04) |
| 117 | #define SR_IRQ_POLARITY 0x04, 0x01, 0 | 119 | #define SR_IRQ_POLARITY 0x04, 0x01, 0 |
| 118 | #define SR_IRQ_MASK_MODE 0x04, 0x02, 1 | 120 | #define SR_IRQ_MASK_MODE 0x04, 0x02, 1 |
| 119 | #define SR_SPI_CMD_MODE 0x04, 0x0c, 2 | 121 | #define SR_SPI_CMD_MODE 0x04, 0x0c, 2 |
| 120 | #define SR_RX_BL_CTRL 0x04, 0x10, 4 | 122 | #define SR_RX_BL_CTRL 0x04, 0x10, 4 |
| 121 | #define SR_TX_AUTO_CRC_ON 0x04, 0x20, 5 | 123 | #define SR_TX_AUTO_CRC_ON 0x04, 0x20, 5 |
| 122 | #define SR_IRQ_2_EXT_EN 0x04, 0x40, 6 | 124 | #define SR_IRQ_2_EXT_EN 0x04, 0x40, 6 |
| 123 | #define SR_PA_EXT_EN 0x04, 0x80, 7 | 125 | #define SR_PA_EXT_EN 0x04, 0x80, 7 |
| 124 | #define RG_PHY_TX_PWR (0x05) | 126 | #define RG_PHY_TX_PWR (0x05) |
| 125 | #define SR_TX_PWR 0x05, 0x0f, 0 | 127 | #define SR_TX_PWR 0x05, 0x0f, 0 |
| 126 | #define SR_PA_LT 0x05, 0x30, 4 | 128 | #define SR_PA_LT 0x05, 0x30, 4 |
| 127 | #define SR_PA_BUF_LT 0x05, 0xc0, 6 | 129 | #define SR_PA_BUF_LT 0x05, 0xc0, 6 |
| 128 | #define RG_PHY_RSSI (0x06) | 130 | #define RG_PHY_RSSI (0x06) |
| 129 | #define SR_RSSI 0x06, 0x1f, 0 | 131 | #define SR_RSSI 0x06, 0x1f, 0 |
| 130 | #define SR_RND_VALUE 0x06, 0x60, 5 | 132 | #define SR_RND_VALUE 0x06, 0x60, 5 |
| 131 | #define SR_RX_CRC_VALID 0x06, 0x80, 7 | 133 | #define SR_RX_CRC_VALID 0x06, 0x80, 7 |
| 132 | #define RG_PHY_ED_LEVEL (0x07) | 134 | #define RG_PHY_ED_LEVEL (0x07) |
| 133 | #define SR_ED_LEVEL 0x07, 0xff, 0 | 135 | #define SR_ED_LEVEL 0x07, 0xff, 0 |
| 134 | #define RG_PHY_CC_CCA (0x08) | 136 | #define RG_PHY_CC_CCA (0x08) |
| 135 | #define SR_CHANNEL 0x08, 0x1f, 0 | 137 | #define SR_CHANNEL 0x08, 0x1f, 0 |
| 136 | #define SR_CCA_MODE 0x08, 0x60, 5 | 138 | #define SR_CCA_MODE 0x08, 0x60, 5 |
| 137 | #define SR_CCA_REQUEST 0x08, 0x80, 7 | 139 | #define SR_CCA_REQUEST 0x08, 0x80, 7 |
| 138 | #define RG_CCA_THRES (0x09) | 140 | #define RG_CCA_THRES (0x09) |
| 139 | #define SR_CCA_ED_THRES 0x09, 0x0f, 0 | 141 | #define SR_CCA_ED_THRES 0x09, 0x0f, 0 |
| 140 | #define SR_RESERVED_09_1 0x09, 0xf0, 4 | 142 | #define SR_RESERVED_09_1 0x09, 0xf0, 4 |
| 141 | #define RG_RX_CTRL (0x0a) | 143 | #define RG_RX_CTRL (0x0a) |
| 142 | #define SR_PDT_THRES 0x0a, 0x0f, 0 | 144 | #define SR_PDT_THRES 0x0a, 0x0f, 0 |
| 143 | #define SR_RESERVED_0a_1 0x0a, 0xf0, 4 | 145 | #define SR_RESERVED_0a_1 0x0a, 0xf0, 4 |
| 144 | #define RG_SFD_VALUE (0x0b) | 146 | #define RG_SFD_VALUE (0x0b) |
| 145 | #define SR_SFD_VALUE 0x0b, 0xff, 0 | 147 | #define SR_SFD_VALUE 0x0b, 0xff, 0 |
| 146 | #define RG_TRX_CTRL_2 (0x0c) | 148 | #define RG_TRX_CTRL_2 (0x0c) |
| 147 | #define SR_OQPSK_DATA_RATE 0x0c, 0x03, 0 | 149 | #define SR_OQPSK_DATA_RATE 0x0c, 0x03, 0 |
| 148 | #define SR_SUB_MODE 0x0c, 0x04, 2 | 150 | #define SR_SUB_MODE 0x0c, 0x04, 2 |
| 149 | #define SR_BPSK_QPSK 0x0c, 0x08, 3 | 151 | #define SR_BPSK_QPSK 0x0c, 0x08, 3 |
| 150 | #define SR_OQPSK_SUB1_RC_EN 0x0c, 0x10, 4 | 152 | #define SR_OQPSK_SUB1_RC_EN 0x0c, 0x10, 4 |
| 151 | #define SR_RESERVED_0c_5 0x0c, 0x60, 5 | 153 | #define SR_RESERVED_0c_5 0x0c, 0x60, 5 |
| 152 | #define SR_RX_SAFE_MODE 0x0c, 0x80, 7 | 154 | #define SR_RX_SAFE_MODE 0x0c, 0x80, 7 |
| 153 | #define RG_ANT_DIV (0x0d) | 155 | #define RG_ANT_DIV (0x0d) |
| 154 | #define SR_ANT_CTRL 0x0d, 0x03, 0 | 156 | #define SR_ANT_CTRL 0x0d, 0x03, 0 |
| 155 | #define SR_ANT_EXT_SW_EN 0x0d, 0x04, 2 | 157 | #define SR_ANT_EXT_SW_EN 0x0d, 0x04, 2 |
| 156 | #define SR_ANT_DIV_EN 0x0d, 0x08, 3 | 158 | #define SR_ANT_DIV_EN 0x0d, 0x08, 3 |
| 157 | #define SR_RESERVED_0d_2 0x0d, 0x70, 4 | 159 | #define SR_RESERVED_0d_2 0x0d, 0x70, 4 |
| 158 | #define SR_ANT_SEL 0x0d, 0x80, 7 | 160 | #define SR_ANT_SEL 0x0d, 0x80, 7 |
| 159 | #define RG_IRQ_MASK (0x0e) | 161 | #define RG_IRQ_MASK (0x0e) |
| 160 | #define SR_IRQ_MASK 0x0e, 0xff, 0 | 162 | #define SR_IRQ_MASK 0x0e, 0xff, 0 |
| 161 | #define RG_IRQ_STATUS (0x0f) | 163 | #define RG_IRQ_STATUS (0x0f) |
| 162 | #define SR_IRQ_0_PLL_LOCK 0x0f, 0x01, 0 | 164 | #define SR_IRQ_0_PLL_LOCK 0x0f, 0x01, 0 |
| 163 | #define SR_IRQ_1_PLL_UNLOCK 0x0f, 0x02, 1 | 165 | #define SR_IRQ_1_PLL_UNLOCK 0x0f, 0x02, 1 |
| 164 | #define SR_IRQ_2_RX_START 0x0f, 0x04, 2 | 166 | #define SR_IRQ_2_RX_START 0x0f, 0x04, 2 |
| 165 | #define SR_IRQ_3_TRX_END 0x0f, 0x08, 3 | 167 | #define SR_IRQ_3_TRX_END 0x0f, 0x08, 3 |
| 166 | #define SR_IRQ_4_CCA_ED_DONE 0x0f, 0x10, 4 | 168 | #define SR_IRQ_4_CCA_ED_DONE 0x0f, 0x10, 4 |
| 167 | #define SR_IRQ_5_AMI 0x0f, 0x20, 5 | 169 | #define SR_IRQ_5_AMI 0x0f, 0x20, 5 |
| 168 | #define SR_IRQ_6_TRX_UR 0x0f, 0x40, 6 | 170 | #define SR_IRQ_6_TRX_UR 0x0f, 0x40, 6 |
| 169 | #define SR_IRQ_7_BAT_LOW 0x0f, 0x80, 7 | 171 | #define SR_IRQ_7_BAT_LOW 0x0f, 0x80, 7 |
| 170 | #define RG_VREG_CTRL (0x10) | 172 | #define RG_VREG_CTRL (0x10) |
| 171 | #define SR_RESERVED_10_6 0x10, 0x03, 0 | 173 | #define SR_RESERVED_10_6 0x10, 0x03, 0 |
| 172 | #define SR_DVDD_OK 0x10, 0x04, 2 | 174 | #define SR_DVDD_OK 0x10, 0x04, 2 |
| 173 | #define SR_DVREG_EXT 0x10, 0x08, 3 | 175 | #define SR_DVREG_EXT 0x10, 0x08, 3 |
| 174 | #define SR_RESERVED_10_3 0x10, 0x30, 4 | 176 | #define SR_RESERVED_10_3 0x10, 0x30, 4 |
| 175 | #define SR_AVDD_OK 0x10, 0x40, 6 | 177 | #define SR_AVDD_OK 0x10, 0x40, 6 |
| 176 | #define SR_AVREG_EXT 0x10, 0x80, 7 | 178 | #define SR_AVREG_EXT 0x10, 0x80, 7 |
| 177 | #define RG_BATMON (0x11) | 179 | #define RG_BATMON (0x11) |
| 178 | #define SR_BATMON_VTH 0x11, 0x0f, 0 | 180 | #define SR_BATMON_VTH 0x11, 0x0f, 0 |
| 179 | #define SR_BATMON_HR 0x11, 0x10, 4 | 181 | #define SR_BATMON_HR 0x11, 0x10, 4 |
| 180 | #define SR_BATMON_OK 0x11, 0x20, 5 | 182 | #define SR_BATMON_OK 0x11, 0x20, 5 |
| 181 | #define SR_RESERVED_11_1 0x11, 0xc0, 6 | 183 | #define SR_RESERVED_11_1 0x11, 0xc0, 6 |
| 182 | #define RG_XOSC_CTRL (0x12) | 184 | #define RG_XOSC_CTRL (0x12) |
| 183 | #define SR_XTAL_TRIM 0x12, 0x0f, 0 | 185 | #define SR_XTAL_TRIM 0x12, 0x0f, 0 |
| 184 | #define SR_XTAL_MODE 0x12, 0xf0, 4 | 186 | #define SR_XTAL_MODE 0x12, 0xf0, 4 |
| 185 | #define RG_RX_SYN (0x15) | 187 | #define RG_RX_SYN (0x15) |
| 186 | #define SR_RX_PDT_LEVEL 0x15, 0x0f, 0 | 188 | #define SR_RX_PDT_LEVEL 0x15, 0x0f, 0 |
| 187 | #define SR_RESERVED_15_2 0x15, 0x70, 4 | 189 | #define SR_RESERVED_15_2 0x15, 0x70, 4 |
| 188 | #define SR_RX_PDT_DIS 0x15, 0x80, 7 | 190 | #define SR_RX_PDT_DIS 0x15, 0x80, 7 |
| 189 | #define RG_XAH_CTRL_1 (0x17) | 191 | #define RG_XAH_CTRL_1 (0x17) |
| 190 | #define SR_RESERVED_17_8 0x17, 0x01, 0 | 192 | #define SR_RESERVED_17_8 0x17, 0x01, 0 |
| 191 | #define SR_AACK_PROM_MODE 0x17, 0x02, 1 | 193 | #define SR_AACK_PROM_MODE 0x17, 0x02, 1 |
| 192 | #define SR_AACK_ACK_TIME 0x17, 0x04, 2 | 194 | #define SR_AACK_ACK_TIME 0x17, 0x04, 2 |
| 193 | #define SR_RESERVED_17_5 0x17, 0x08, 3 | 195 | #define SR_RESERVED_17_5 0x17, 0x08, 3 |
| 194 | #define SR_AACK_UPLD_RES_FT 0x17, 0x10, 4 | 196 | #define SR_AACK_UPLD_RES_FT 0x17, 0x10, 4 |
| 195 | #define SR_AACK_FLTR_RES_FT 0x17, 0x20, 5 | 197 | #define SR_AACK_FLTR_RES_FT 0x17, 0x20, 5 |
| 196 | #define SR_CSMA_LBT_MODE 0x17, 0x40, 6 | 198 | #define SR_CSMA_LBT_MODE 0x17, 0x40, 6 |
| 197 | #define SR_RESERVED_17_1 0x17, 0x80, 7 | 199 | #define SR_RESERVED_17_1 0x17, 0x80, 7 |
| 198 | #define RG_FTN_CTRL (0x18) | 200 | #define RG_FTN_CTRL (0x18) |
| 199 | #define SR_RESERVED_18_2 0x18, 0x7f, 0 | 201 | #define SR_RESERVED_18_2 0x18, 0x7f, 0 |
| 200 | #define SR_FTN_START 0x18, 0x80, 7 | 202 | #define SR_FTN_START 0x18, 0x80, 7 |
| 201 | #define RG_PLL_CF (0x1a) | 203 | #define RG_PLL_CF (0x1a) |
| 202 | #define SR_RESERVED_1a_2 0x1a, 0x7f, 0 | 204 | #define SR_RESERVED_1a_2 0x1a, 0x7f, 0 |
| 203 | #define SR_PLL_CF_START 0x1a, 0x80, 7 | 205 | #define SR_PLL_CF_START 0x1a, 0x80, 7 |
| 204 | #define RG_PLL_DCU (0x1b) | 206 | #define RG_PLL_DCU (0x1b) |
| 205 | #define SR_RESERVED_1b_3 0x1b, 0x3f, 0 | 207 | #define SR_RESERVED_1b_3 0x1b, 0x3f, 0 |
| 206 | #define SR_RESERVED_1b_2 0x1b, 0x40, 6 | 208 | #define SR_RESERVED_1b_2 0x1b, 0x40, 6 |
| 207 | #define SR_PLL_DCU_START 0x1b, 0x80, 7 | 209 | #define SR_PLL_DCU_START 0x1b, 0x80, 7 |
| 208 | #define RG_PART_NUM (0x1c) | 210 | #define RG_PART_NUM (0x1c) |
| 209 | #define SR_PART_NUM 0x1c, 0xff, 0 | 211 | #define SR_PART_NUM 0x1c, 0xff, 0 |
| 210 | #define RG_VERSION_NUM (0x1d) | 212 | #define RG_VERSION_NUM (0x1d) |
| 211 | #define SR_VERSION_NUM 0x1d, 0xff, 0 | 213 | #define SR_VERSION_NUM 0x1d, 0xff, 0 |
| 212 | #define RG_MAN_ID_0 (0x1e) | 214 | #define RG_MAN_ID_0 (0x1e) |
| 213 | #define SR_MAN_ID_0 0x1e, 0xff, 0 | 215 | #define SR_MAN_ID_0 0x1e, 0xff, 0 |
| 214 | #define RG_MAN_ID_1 (0x1f) | 216 | #define RG_MAN_ID_1 (0x1f) |
| 215 | #define SR_MAN_ID_1 0x1f, 0xff, 0 | 217 | #define SR_MAN_ID_1 0x1f, 0xff, 0 |
| 216 | #define RG_SHORT_ADDR_0 (0x20) | 218 | #define RG_SHORT_ADDR_0 (0x20) |
| 217 | #define SR_SHORT_ADDR_0 0x20, 0xff, 0 | 219 | #define SR_SHORT_ADDR_0 0x20, 0xff, 0 |
| 218 | #define RG_SHORT_ADDR_1 (0x21) | 220 | #define RG_SHORT_ADDR_1 (0x21) |
| 219 | #define SR_SHORT_ADDR_1 0x21, 0xff, 0 | 221 | #define SR_SHORT_ADDR_1 0x21, 0xff, 0 |
| 220 | #define RG_PAN_ID_0 (0x22) | 222 | #define RG_PAN_ID_0 (0x22) |
| 221 | #define SR_PAN_ID_0 0x22, 0xff, 0 | 223 | #define SR_PAN_ID_0 0x22, 0xff, 0 |
| 222 | #define RG_PAN_ID_1 (0x23) | 224 | #define RG_PAN_ID_1 (0x23) |
| 223 | #define SR_PAN_ID_1 0x23, 0xff, 0 | 225 | #define SR_PAN_ID_1 0x23, 0xff, 0 |
| 224 | #define RG_IEEE_ADDR_0 (0x24) | 226 | #define RG_IEEE_ADDR_0 (0x24) |
| 225 | #define SR_IEEE_ADDR_0 0x24, 0xff, 0 | 227 | #define SR_IEEE_ADDR_0 0x24, 0xff, 0 |
| 226 | #define RG_IEEE_ADDR_1 (0x25) | 228 | #define RG_IEEE_ADDR_1 (0x25) |
| 227 | #define SR_IEEE_ADDR_1 0x25, 0xff, 0 | 229 | #define SR_IEEE_ADDR_1 0x25, 0xff, 0 |
| 228 | #define RG_IEEE_ADDR_2 (0x26) | 230 | #define RG_IEEE_ADDR_2 (0x26) |
| 229 | #define SR_IEEE_ADDR_2 0x26, 0xff, 0 | 231 | #define SR_IEEE_ADDR_2 0x26, 0xff, 0 |
| 230 | #define RG_IEEE_ADDR_3 (0x27) | 232 | #define RG_IEEE_ADDR_3 (0x27) |
| 231 | #define SR_IEEE_ADDR_3 0x27, 0xff, 0 | 233 | #define SR_IEEE_ADDR_3 0x27, 0xff, 0 |
| 232 | #define RG_IEEE_ADDR_4 (0x28) | 234 | #define RG_IEEE_ADDR_4 (0x28) |
| 233 | #define SR_IEEE_ADDR_4 0x28, 0xff, 0 | 235 | #define SR_IEEE_ADDR_4 0x28, 0xff, 0 |
| 234 | #define RG_IEEE_ADDR_5 (0x29) | 236 | #define RG_IEEE_ADDR_5 (0x29) |
| 235 | #define SR_IEEE_ADDR_5 0x29, 0xff, 0 | 237 | #define SR_IEEE_ADDR_5 0x29, 0xff, 0 |
| 236 | #define RG_IEEE_ADDR_6 (0x2a) | 238 | #define RG_IEEE_ADDR_6 (0x2a) |
| 237 | #define SR_IEEE_ADDR_6 0x2a, 0xff, 0 | 239 | #define SR_IEEE_ADDR_6 0x2a, 0xff, 0 |
| 238 | #define RG_IEEE_ADDR_7 (0x2b) | 240 | #define RG_IEEE_ADDR_7 (0x2b) |
| 239 | #define SR_IEEE_ADDR_7 0x2b, 0xff, 0 | 241 | #define SR_IEEE_ADDR_7 0x2b, 0xff, 0 |
| 240 | #define RG_XAH_CTRL_0 (0x2c) | 242 | #define RG_XAH_CTRL_0 (0x2c) |
| 241 | #define SR_SLOTTED_OPERATION 0x2c, 0x01, 0 | 243 | #define SR_SLOTTED_OPERATION 0x2c, 0x01, 0 |
| 242 | #define SR_MAX_CSMA_RETRIES 0x2c, 0x0e, 1 | 244 | #define SR_MAX_CSMA_RETRIES 0x2c, 0x0e, 1 |
| 243 | #define SR_MAX_FRAME_RETRIES 0x2c, 0xf0, 4 | 245 | #define SR_MAX_FRAME_RETRIES 0x2c, 0xf0, 4 |
| 244 | #define RG_CSMA_SEED_0 (0x2d) | 246 | #define RG_CSMA_SEED_0 (0x2d) |
| 245 | #define SR_CSMA_SEED_0 0x2d, 0xff, 0 | 247 | #define SR_CSMA_SEED_0 0x2d, 0xff, 0 |
| 246 | #define RG_CSMA_SEED_1 (0x2e) | 248 | #define RG_CSMA_SEED_1 (0x2e) |
| 247 | #define SR_CSMA_SEED_1 0x2e, 0x07, 0 | 249 | #define SR_CSMA_SEED_1 0x2e, 0x07, 0 |
| 248 | #define SR_AACK_I_AM_COORD 0x2e, 0x08, 3 | 250 | #define SR_AACK_I_AM_COORD 0x2e, 0x08, 3 |
| 249 | #define SR_AACK_DIS_ACK 0x2e, 0x10, 4 | 251 | #define SR_AACK_DIS_ACK 0x2e, 0x10, 4 |
| 250 | #define SR_AACK_SET_PD 0x2e, 0x20, 5 | 252 | #define SR_AACK_SET_PD 0x2e, 0x20, 5 |
| 251 | #define SR_AACK_FVN_MODE 0x2e, 0xc0, 6 | 253 | #define SR_AACK_FVN_MODE 0x2e, 0xc0, 6 |
| 252 | #define RG_CSMA_BE (0x2f) | 254 | #define RG_CSMA_BE (0x2f) |
| 253 | #define SR_MIN_BE 0x2f, 0x0f, 0 | 255 | #define SR_MIN_BE 0x2f, 0x0f, 0 |
| 254 | #define SR_MAX_BE 0x2f, 0xf0, 4 | 256 | #define SR_MAX_BE 0x2f, 0xf0, 4 |
| 255 | 257 | ||
| 256 | #define CMD_REG 0x80 | 258 | #define CMD_REG 0x80 |
| 257 | #define CMD_REG_MASK 0x3f | 259 | #define CMD_REG_MASK 0x3f |
| @@ -292,6 +294,8 @@ struct at86rf230_local { | |||
| 292 | #define STATE_BUSY_RX_AACK_NOCLK 0x1E | 294 | #define STATE_BUSY_RX_AACK_NOCLK 0x1E |
| 293 | #define STATE_TRANSITION_IN_PROGRESS 0x1F | 295 | #define STATE_TRANSITION_IN_PROGRESS 0x1F |
| 294 | 296 | ||
| 297 | #define TRX_STATE_MASK (0x1F) | ||
| 298 | |||
| 295 | #define AT86RF2XX_NUMREGS 0x3F | 299 | #define AT86RF2XX_NUMREGS 0x3F |
| 296 | 300 | ||
| 297 | static void | 301 | static void |
| @@ -336,6 +340,14 @@ at86rf230_write_subreg(struct at86rf230_local *lp, | |||
| 336 | return regmap_update_bits(lp->regmap, addr, mask, data << shift); | 340 | return regmap_update_bits(lp->regmap, addr, mask, data << shift); |
| 337 | } | 341 | } |
| 338 | 342 | ||
| 343 | static inline void | ||
| 344 | at86rf230_slp_tr_rising_edge(struct at86rf230_local *lp) | ||
| 345 | { | ||
| 346 | gpio_set_value(lp->slp_tr, 1); | ||
| 347 | udelay(1); | ||
| 348 | gpio_set_value(lp->slp_tr, 0); | ||
| 349 | } | ||
| 350 | |||
| 339 | static bool | 351 | static bool |
| 340 | at86rf230_reg_writeable(struct device *dev, unsigned int reg) | 352 | at86rf230_reg_writeable(struct device *dev, unsigned int reg) |
| 341 | { | 353 | { |
| @@ -509,7 +521,7 @@ at86rf230_async_state_assert(void *context) | |||
| 509 | struct at86rf230_state_change *ctx = context; | 521 | struct at86rf230_state_change *ctx = context; |
| 510 | struct at86rf230_local *lp = ctx->lp; | 522 | struct at86rf230_local *lp = ctx->lp; |
| 511 | const u8 *buf = ctx->buf; | 523 | const u8 *buf = ctx->buf; |
| 512 | const u8 trx_state = buf[1] & 0x1f; | 524 | const u8 trx_state = buf[1] & TRX_STATE_MASK; |
| 513 | 525 | ||
| 514 | /* Assert state change */ | 526 | /* Assert state change */ |
| 515 | if (trx_state != ctx->to_state) { | 527 | if (trx_state != ctx->to_state) { |
| @@ -609,11 +621,17 @@ at86rf230_async_state_delay(void *context) | |||
| 609 | switch (ctx->to_state) { | 621 | switch (ctx->to_state) { |
| 610 | case STATE_RX_AACK_ON: | 622 | case STATE_RX_AACK_ON: |
| 611 | tim = ktime_set(0, c->t_off_to_aack * NSEC_PER_USEC); | 623 | tim = ktime_set(0, c->t_off_to_aack * NSEC_PER_USEC); |
| 624 | /* state change from TRX_OFF to RX_AACK_ON to do a | ||
| 625 | * calibration, we need to reset the timeout for the | ||
| 626 | * next one. | ||
| 627 | */ | ||
| 628 | lp->cal_timeout = jiffies + AT86RF2XX_CAL_LOOP_TIMEOUT; | ||
| 612 | goto change; | 629 | goto change; |
| 630 | case STATE_TX_ARET_ON: | ||
| 613 | case STATE_TX_ON: | 631 | case STATE_TX_ON: |
| 614 | tim = ktime_set(0, c->t_off_to_tx_on * NSEC_PER_USEC); | 632 | tim = ktime_set(0, c->t_off_to_tx_on * NSEC_PER_USEC); |
| 615 | /* state change from TRX_OFF to TX_ON to do a | 633 | /* state change from TRX_OFF to TX_ON or ARET_ON to do |
| 616 | * calibration, we need to reset the timeout for the | 634 | * a calibration, we need to reset the timeout for the |
| 617 | * next one. | 635 | * next one. |
| 618 | */ | 636 | */ |
| 619 | lp->cal_timeout = jiffies + AT86RF2XX_CAL_LOOP_TIMEOUT; | 637 | lp->cal_timeout = jiffies + AT86RF2XX_CAL_LOOP_TIMEOUT; |
| @@ -667,7 +685,7 @@ at86rf230_async_state_change_start(void *context) | |||
| 667 | struct at86rf230_state_change *ctx = context; | 685 | struct at86rf230_state_change *ctx = context; |
| 668 | struct at86rf230_local *lp = ctx->lp; | 686 | struct at86rf230_local *lp = ctx->lp; |
| 669 | u8 *buf = ctx->buf; | 687 | u8 *buf = ctx->buf; |
| 670 | const u8 trx_state = buf[1] & 0x1f; | 688 | const u8 trx_state = buf[1] & TRX_STATE_MASK; |
| 671 | int rc; | 689 | int rc; |
| 672 | 690 | ||
| 673 | /* Check for "possible" STATE_TRANSITION_IN_PROGRESS */ | 691 | /* Check for "possible" STATE_TRANSITION_IN_PROGRESS */ |
| @@ -773,16 +791,6 @@ at86rf230_tx_on(void *context) | |||
| 773 | } | 791 | } |
| 774 | 792 | ||
| 775 | static void | 793 | static void |
| 776 | at86rf230_tx_trac_error(void *context) | ||
| 777 | { | ||
| 778 | struct at86rf230_state_change *ctx = context; | ||
| 779 | struct at86rf230_local *lp = ctx->lp; | ||
| 780 | |||
| 781 | at86rf230_async_state_change(lp, ctx, STATE_TX_ON, | ||
| 782 | at86rf230_tx_on, true); | ||
| 783 | } | ||
| 784 | |||
| 785 | static void | ||
| 786 | at86rf230_tx_trac_check(void *context) | 794 | at86rf230_tx_trac_check(void *context) |
| 787 | { | 795 | { |
| 788 | struct at86rf230_state_change *ctx = context; | 796 | struct at86rf230_state_change *ctx = context; |
| @@ -791,12 +799,12 @@ at86rf230_tx_trac_check(void *context) | |||
| 791 | const u8 trac = (buf[1] & 0xe0) >> 5; | 799 | const u8 trac = (buf[1] & 0xe0) >> 5; |
| 792 | 800 | ||
| 793 | /* If trac status is different than zero we need to do a state change | 801 | /* If trac status is different than zero we need to do a state change |
| 794 | * to STATE_FORCE_TRX_OFF then STATE_TX_ON to recover the transceiver | 802 | * to STATE_FORCE_TRX_OFF then STATE_RX_AACK_ON to recover the |
| 795 | * state to TX_ON. | 803 | * transceiver. |
| 796 | */ | 804 | */ |
| 797 | if (trac) | 805 | if (trac) |
| 798 | at86rf230_async_state_change(lp, ctx, STATE_FORCE_TRX_OFF, | 806 | at86rf230_async_state_change(lp, ctx, STATE_FORCE_TRX_OFF, |
| 799 | at86rf230_tx_trac_error, true); | 807 | at86rf230_tx_on, true); |
| 800 | else | 808 | else |
| 801 | at86rf230_tx_on(context); | 809 | at86rf230_tx_on(context); |
| 802 | } | 810 | } |
| @@ -941,13 +949,18 @@ at86rf230_write_frame_complete(void *context) | |||
| 941 | u8 *buf = ctx->buf; | 949 | u8 *buf = ctx->buf; |
| 942 | int rc; | 950 | int rc; |
| 943 | 951 | ||
| 944 | buf[0] = (RG_TRX_STATE & CMD_REG_MASK) | CMD_REG | CMD_WRITE; | ||
| 945 | buf[1] = STATE_BUSY_TX; | ||
| 946 | ctx->trx.len = 2; | 952 | ctx->trx.len = 2; |
| 947 | ctx->msg.complete = NULL; | 953 | |
| 948 | rc = spi_async(lp->spi, &ctx->msg); | 954 | if (gpio_is_valid(lp->slp_tr)) { |
| 949 | if (rc) | 955 | at86rf230_slp_tr_rising_edge(lp); |
| 950 | at86rf230_async_error(lp, ctx, rc); | 956 | } else { |
| 957 | buf[0] = (RG_TRX_STATE & CMD_REG_MASK) | CMD_REG | CMD_WRITE; | ||
| 958 | buf[1] = STATE_BUSY_TX; | ||
| 959 | ctx->msg.complete = NULL; | ||
| 960 | rc = spi_async(lp->spi, &ctx->msg); | ||
| 961 | if (rc) | ||
| 962 | at86rf230_async_error(lp, ctx, rc); | ||
| 963 | } | ||
| 951 | } | 964 | } |
| 952 | 965 | ||
| 953 | static void | 966 | static void |
| @@ -993,12 +1006,21 @@ at86rf230_xmit_start(void *context) | |||
| 993 | * are in STATE_TX_ON. The pfad differs here, so we change | 1006 | * are in STATE_TX_ON. The pfad differs here, so we change |
| 994 | * the complete handler. | 1007 | * the complete handler. |
| 995 | */ | 1008 | */ |
| 996 | if (lp->tx_aret) | 1009 | if (lp->tx_aret) { |
| 997 | at86rf230_async_state_change(lp, ctx, STATE_TX_ON, | 1010 | if (lp->is_tx_from_off) { |
| 998 | at86rf230_xmit_tx_on, false); | 1011 | lp->is_tx_from_off = false; |
| 999 | else | 1012 | at86rf230_async_state_change(lp, ctx, STATE_TX_ARET_ON, |
| 1013 | at86rf230_xmit_tx_on, | ||
| 1014 | false); | ||
| 1015 | } else { | ||
| 1016 | at86rf230_async_state_change(lp, ctx, STATE_TX_ON, | ||
| 1017 | at86rf230_xmit_tx_on, | ||
| 1018 | false); | ||
| 1019 | } | ||
| 1020 | } else { | ||
| 1000 | at86rf230_async_state_change(lp, ctx, STATE_TX_ON, | 1021 | at86rf230_async_state_change(lp, ctx, STATE_TX_ON, |
| 1001 | at86rf230_write_frame, false); | 1022 | at86rf230_write_frame, false); |
| 1023 | } | ||
| 1002 | } | 1024 | } |
| 1003 | 1025 | ||
| 1004 | static int | 1026 | static int |
| @@ -1017,11 +1039,13 @@ at86rf230_xmit(struct ieee802154_hw *hw, struct sk_buff *skb) | |||
| 1017 | * to TX_ON, the lp->cal_timeout should be reinit by state_delay | 1039 | * to TX_ON, the lp->cal_timeout should be reinit by state_delay |
| 1018 | * function then to start in the next 5 minutes. | 1040 | * function then to start in the next 5 minutes. |
| 1019 | */ | 1041 | */ |
| 1020 | if (time_is_before_jiffies(lp->cal_timeout)) | 1042 | if (time_is_before_jiffies(lp->cal_timeout)) { |
| 1043 | lp->is_tx_from_off = true; | ||
| 1021 | at86rf230_async_state_change(lp, ctx, STATE_TRX_OFF, | 1044 | at86rf230_async_state_change(lp, ctx, STATE_TRX_OFF, |
| 1022 | at86rf230_xmit_start, false); | 1045 | at86rf230_xmit_start, false); |
| 1023 | else | 1046 | } else { |
| 1024 | at86rf230_xmit_start(ctx); | 1047 | at86rf230_xmit_start(ctx); |
| 1048 | } | ||
| 1025 | 1049 | ||
| 1026 | return 0; | 1050 | return 0; |
| 1027 | } | 1051 | } |
| @@ -1037,9 +1061,6 @@ at86rf230_ed(struct ieee802154_hw *hw, u8 *level) | |||
| 1037 | static int | 1061 | static int |
| 1038 | at86rf230_start(struct ieee802154_hw *hw) | 1062 | at86rf230_start(struct ieee802154_hw *hw) |
| 1039 | { | 1063 | { |
| 1040 | struct at86rf230_local *lp = hw->priv; | ||
| 1041 | |||
| 1042 | lp->cal_timeout = jiffies + AT86RF2XX_CAL_LOOP_TIMEOUT; | ||
| 1043 | return at86rf230_sync_state_change(hw->priv, STATE_RX_AACK_ON); | 1064 | return at86rf230_sync_state_change(hw->priv, STATE_RX_AACK_ON); |
| 1044 | } | 1065 | } |
| 1045 | 1066 | ||
| @@ -1673,6 +1694,7 @@ static int at86rf230_probe(struct spi_device *spi) | |||
| 1673 | lp = hw->priv; | 1694 | lp = hw->priv; |
| 1674 | lp->hw = hw; | 1695 | lp->hw = hw; |
| 1675 | lp->spi = spi; | 1696 | lp->spi = spi; |
| 1697 | lp->slp_tr = slp_tr; | ||
| 1676 | hw->parent = &spi->dev; | 1698 | hw->parent = &spi->dev; |
| 1677 | hw->vif_data_size = sizeof(*lp); | 1699 | hw->vif_data_size = sizeof(*lp); |
| 1678 | ieee802154_random_extended_addr(&hw->phy->perm_extended_addr); | 1700 | ieee802154_random_extended_addr(&hw->phy->perm_extended_addr); |
diff --git a/drivers/net/macvlan.c b/drivers/net/macvlan.c index b227a13f6473..9f59f17dc317 100644 --- a/drivers/net/macvlan.c +++ b/drivers/net/macvlan.c | |||
| @@ -599,10 +599,18 @@ static int macvlan_open(struct net_device *dev) | |||
| 599 | goto del_unicast; | 599 | goto del_unicast; |
| 600 | } | 600 | } |
| 601 | 601 | ||
| 602 | if (dev->flags & IFF_PROMISC) { | ||
| 603 | err = dev_set_promiscuity(lowerdev, 1); | ||
| 604 | if (err < 0) | ||
| 605 | goto clear_multi; | ||
| 606 | } | ||
| 607 | |||
| 602 | hash_add: | 608 | hash_add: |
| 603 | macvlan_hash_add(vlan); | 609 | macvlan_hash_add(vlan); |
| 604 | return 0; | 610 | return 0; |
| 605 | 611 | ||
| 612 | clear_multi: | ||
| 613 | dev_set_allmulti(lowerdev, -1); | ||
| 606 | del_unicast: | 614 | del_unicast: |
| 607 | dev_uc_del(lowerdev, dev->dev_addr); | 615 | dev_uc_del(lowerdev, dev->dev_addr); |
| 608 | out: | 616 | out: |
| @@ -638,6 +646,9 @@ static int macvlan_stop(struct net_device *dev) | |||
| 638 | if (dev->flags & IFF_ALLMULTI) | 646 | if (dev->flags & IFF_ALLMULTI) |
| 639 | dev_set_allmulti(lowerdev, -1); | 647 | dev_set_allmulti(lowerdev, -1); |
| 640 | 648 | ||
| 649 | if (dev->flags & IFF_PROMISC) | ||
| 650 | dev_set_promiscuity(lowerdev, -1); | ||
| 651 | |||
| 641 | dev_uc_del(lowerdev, dev->dev_addr); | 652 | dev_uc_del(lowerdev, dev->dev_addr); |
| 642 | 653 | ||
| 643 | hash_del: | 654 | hash_del: |
| @@ -696,6 +707,10 @@ static void macvlan_change_rx_flags(struct net_device *dev, int change) | |||
| 696 | if (dev->flags & IFF_UP) { | 707 | if (dev->flags & IFF_UP) { |
| 697 | if (change & IFF_ALLMULTI) | 708 | if (change & IFF_ALLMULTI) |
| 698 | dev_set_allmulti(lowerdev, dev->flags & IFF_ALLMULTI ? 1 : -1); | 709 | dev_set_allmulti(lowerdev, dev->flags & IFF_ALLMULTI ? 1 : -1); |
| 710 | if (change & IFF_PROMISC) | ||
| 711 | dev_set_promiscuity(lowerdev, | ||
| 712 | dev->flags & IFF_PROMISC ? 1 : -1); | ||
| 713 | |||
| 699 | } | 714 | } |
| 700 | } | 715 | } |
| 701 | 716 | ||
diff --git a/drivers/net/phy/Kconfig b/drivers/net/phy/Kconfig index 8fadaa14b9f0..70641d2c0429 100644 --- a/drivers/net/phy/Kconfig +++ b/drivers/net/phy/Kconfig | |||
| @@ -27,6 +27,7 @@ config AMD_PHY | |||
| 27 | config AMD_XGBE_PHY | 27 | config AMD_XGBE_PHY |
| 28 | tristate "Driver for the AMD 10GbE (amd-xgbe) PHYs" | 28 | tristate "Driver for the AMD 10GbE (amd-xgbe) PHYs" |
| 29 | depends on (OF || ACPI) && HAS_IOMEM | 29 | depends on (OF || ACPI) && HAS_IOMEM |
| 30 | depends on ARM64 || COMPILE_TEST | ||
| 30 | ---help--- | 31 | ---help--- |
| 31 | Currently supports the AMD 10GbE PHY | 32 | Currently supports the AMD 10GbE PHY |
| 32 | 33 | ||
diff --git a/drivers/net/phy/mdio-gpio.c b/drivers/net/phy/mdio-gpio.c index c9cb486c753d..53d18150f4e2 100644 --- a/drivers/net/phy/mdio-gpio.c +++ b/drivers/net/phy/mdio-gpio.c | |||
| @@ -168,7 +168,10 @@ static struct mii_bus *mdio_gpio_bus_init(struct device *dev, | |||
| 168 | if (!new_bus->irq[i]) | 168 | if (!new_bus->irq[i]) |
| 169 | new_bus->irq[i] = PHY_POLL; | 169 | new_bus->irq[i] = PHY_POLL; |
| 170 | 170 | ||
| 171 | snprintf(new_bus->id, MII_BUS_ID_SIZE, "gpio-%x", bus_id); | 171 | if (bus_id != -1) |
| 172 | snprintf(new_bus->id, MII_BUS_ID_SIZE, "gpio-%x", bus_id); | ||
| 173 | else | ||
| 174 | strncpy(new_bus->id, "gpio", MII_BUS_ID_SIZE); | ||
| 172 | 175 | ||
| 173 | if (devm_gpio_request(dev, bitbang->mdc, "mdc")) | 176 | if (devm_gpio_request(dev, bitbang->mdc, "mdc")) |
| 174 | goto out_free_bus; | 177 | goto out_free_bus; |
diff --git a/drivers/net/phy/micrel.c b/drivers/net/phy/micrel.c index 1190fd8f0088..ebdc357c5131 100644 --- a/drivers/net/phy/micrel.c +++ b/drivers/net/phy/micrel.c | |||
| @@ -548,7 +548,8 @@ static int kszphy_probe(struct phy_device *phydev) | |||
| 548 | } | 548 | } |
| 549 | 549 | ||
| 550 | clk = devm_clk_get(&phydev->dev, "rmii-ref"); | 550 | clk = devm_clk_get(&phydev->dev, "rmii-ref"); |
| 551 | if (!IS_ERR(clk)) { | 551 | /* NOTE: clk may be NULL if building without CONFIG_HAVE_CLK */ |
| 552 | if (!IS_ERR_OR_NULL(clk)) { | ||
| 552 | unsigned long rate = clk_get_rate(clk); | 553 | unsigned long rate = clk_get_rate(clk); |
| 553 | bool rmii_ref_clk_sel_25_mhz; | 554 | bool rmii_ref_clk_sel_25_mhz; |
| 554 | 555 | ||
diff --git a/drivers/net/ppp/pppoe.c b/drivers/net/ppp/pppoe.c index aa1dd926623a..b62a5e3a1c65 100644 --- a/drivers/net/ppp/pppoe.c +++ b/drivers/net/ppp/pppoe.c | |||
| @@ -465,6 +465,10 @@ static void pppoe_unbind_sock_work(struct work_struct *work) | |||
| 465 | struct sock *sk = sk_pppox(po); | 465 | struct sock *sk = sk_pppox(po); |
| 466 | 466 | ||
| 467 | lock_sock(sk); | 467 | lock_sock(sk); |
| 468 | if (po->pppoe_dev) { | ||
| 469 | dev_put(po->pppoe_dev); | ||
| 470 | po->pppoe_dev = NULL; | ||
| 471 | } | ||
| 468 | pppox_unbind_sock(sk); | 472 | pppox_unbind_sock(sk); |
| 469 | release_sock(sk); | 473 | release_sock(sk); |
| 470 | sock_put(sk); | 474 | sock_put(sk); |
diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c index ac4d03b328b1..aafa1a1898e4 100644 --- a/drivers/net/usb/r8152.c +++ b/drivers/net/usb/r8152.c | |||
| @@ -4116,6 +4116,7 @@ static struct usb_device_id rtl8152_table[] = { | |||
| 4116 | {REALTEK_USB_DEVICE(VENDOR_ID_REALTEK, 0x8153)}, | 4116 | {REALTEK_USB_DEVICE(VENDOR_ID_REALTEK, 0x8153)}, |
| 4117 | {REALTEK_USB_DEVICE(VENDOR_ID_SAMSUNG, 0xa101)}, | 4117 | {REALTEK_USB_DEVICE(VENDOR_ID_SAMSUNG, 0xa101)}, |
| 4118 | {REALTEK_USB_DEVICE(VENDOR_ID_LENOVO, 0x7205)}, | 4118 | {REALTEK_USB_DEVICE(VENDOR_ID_LENOVO, 0x7205)}, |
| 4119 | {REALTEK_USB_DEVICE(VENDOR_ID_LENOVO, 0x304f)}, | ||
| 4119 | {} | 4120 | {} |
| 4120 | }; | 4121 | }; |
| 4121 | 4122 | ||
diff --git a/drivers/net/usb/usbnet.c b/drivers/net/usb/usbnet.c index 733f4feb2ef3..3c86b107275a 100644 --- a/drivers/net/usb/usbnet.c +++ b/drivers/net/usb/usbnet.c | |||
| @@ -1285,7 +1285,7 @@ netdev_tx_t usbnet_start_xmit (struct sk_buff *skb, | |||
| 1285 | struct net_device *net) | 1285 | struct net_device *net) |
| 1286 | { | 1286 | { |
| 1287 | struct usbnet *dev = netdev_priv(net); | 1287 | struct usbnet *dev = netdev_priv(net); |
| 1288 | int length; | 1288 | unsigned int length; |
| 1289 | struct urb *urb = NULL; | 1289 | struct urb *urb = NULL; |
| 1290 | struct skb_data *entry; | 1290 | struct skb_data *entry; |
| 1291 | struct driver_info *info = dev->driver_info; | 1291 | struct driver_info *info = dev->driver_info; |
| @@ -1413,7 +1413,7 @@ not_drop: | |||
| 1413 | } | 1413 | } |
| 1414 | } else | 1414 | } else |
| 1415 | netif_dbg(dev, tx_queued, dev->net, | 1415 | netif_dbg(dev, tx_queued, dev->net, |
| 1416 | "> tx, len %d, type 0x%x\n", length, skb->protocol); | 1416 | "> tx, len %u, type 0x%x\n", length, skb->protocol); |
| 1417 | #ifdef CONFIG_PM | 1417 | #ifdef CONFIG_PM |
| 1418 | deferred: | 1418 | deferred: |
| 1419 | #endif | 1419 | #endif |
diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c index 0acd079ba96b..3ad79bb4f2c2 100644 --- a/drivers/net/wireless/ath/ath9k/xmit.c +++ b/drivers/net/wireless/ath/ath9k/xmit.c | |||
| @@ -1103,28 +1103,14 @@ static u8 ath_get_rate_txpower(struct ath_softc *sc, struct ath_buf *bf, | |||
| 1103 | struct sk_buff *skb; | 1103 | struct sk_buff *skb; |
| 1104 | struct ath_frame_info *fi; | 1104 | struct ath_frame_info *fi; |
| 1105 | struct ieee80211_tx_info *info; | 1105 | struct ieee80211_tx_info *info; |
| 1106 | struct ieee80211_vif *vif; | ||
| 1107 | struct ath_hw *ah = sc->sc_ah; | 1106 | struct ath_hw *ah = sc->sc_ah; |
| 1108 | 1107 | ||
| 1109 | if (sc->tx99_state || !ah->tpc_enabled) | 1108 | if (sc->tx99_state || !ah->tpc_enabled) |
| 1110 | return MAX_RATE_POWER; | 1109 | return MAX_RATE_POWER; |
| 1111 | 1110 | ||
| 1112 | skb = bf->bf_mpdu; | 1111 | skb = bf->bf_mpdu; |
| 1113 | info = IEEE80211_SKB_CB(skb); | ||
| 1114 | vif = info->control.vif; | ||
| 1115 | |||
| 1116 | if (!vif) { | ||
| 1117 | max_power = sc->cur_chan->cur_txpower; | ||
| 1118 | goto out; | ||
| 1119 | } | ||
| 1120 | |||
| 1121 | if (vif->bss_conf.txpower_type != NL80211_TX_POWER_LIMITED) { | ||
| 1122 | max_power = min_t(u8, sc->cur_chan->cur_txpower, | ||
| 1123 | 2 * vif->bss_conf.txpower); | ||
| 1124 | goto out; | ||
| 1125 | } | ||
| 1126 | |||
| 1127 | fi = get_frame_info(skb); | 1112 | fi = get_frame_info(skb); |
| 1113 | info = IEEE80211_SKB_CB(skb); | ||
| 1128 | 1114 | ||
| 1129 | if (!AR_SREV_9300_20_OR_LATER(ah)) { | 1115 | if (!AR_SREV_9300_20_OR_LATER(ah)) { |
| 1130 | int txpower = fi->tx_power; | 1116 | int txpower = fi->tx_power; |
| @@ -1161,25 +1147,26 @@ static u8 ath_get_rate_txpower(struct ath_softc *sc, struct ath_buf *bf, | |||
| 1161 | txpower -= 2; | 1147 | txpower -= 2; |
| 1162 | 1148 | ||
| 1163 | txpower = max(txpower, 0); | 1149 | txpower = max(txpower, 0); |
| 1164 | max_power = min_t(u8, ah->tx_power[rateidx], | 1150 | max_power = min_t(u8, ah->tx_power[rateidx], txpower); |
| 1165 | 2 * vif->bss_conf.txpower); | 1151 | |
| 1166 | max_power = min_t(u8, max_power, txpower); | 1152 | /* XXX: clamp minimum TX power at 1 for AR9160 since if |
| 1153 | * max_power is set to 0, frames are transmitted at max | ||
| 1154 | * TX power | ||
| 1155 | */ | ||
| 1156 | if (!max_power && !AR_SREV_9280_20_OR_LATER(ah)) | ||
| 1157 | max_power = 1; | ||
| 1167 | } else if (!bf->bf_state.bfs_paprd) { | 1158 | } else if (!bf->bf_state.bfs_paprd) { |
| 1168 | if (rateidx < 8 && (info->flags & IEEE80211_TX_CTL_STBC)) | 1159 | if (rateidx < 8 && (info->flags & IEEE80211_TX_CTL_STBC)) |
| 1169 | max_power = min_t(u8, ah->tx_power_stbc[rateidx], | 1160 | max_power = min_t(u8, ah->tx_power_stbc[rateidx], |
| 1170 | 2 * vif->bss_conf.txpower); | 1161 | fi->tx_power); |
| 1171 | else | 1162 | else |
| 1172 | max_power = min_t(u8, ah->tx_power[rateidx], | 1163 | max_power = min_t(u8, ah->tx_power[rateidx], |
| 1173 | 2 * vif->bss_conf.txpower); | 1164 | fi->tx_power); |
| 1174 | max_power = min(max_power, fi->tx_power); | ||
| 1175 | } else { | 1165 | } else { |
| 1176 | max_power = ah->paprd_training_power; | 1166 | max_power = ah->paprd_training_power; |
| 1177 | } | 1167 | } |
| 1178 | out: | 1168 | |
| 1179 | /* XXX: clamp minimum TX power at 1 for AR9160 since if max_power | 1169 | return max_power; |
| 1180 | * is set to 0, frames are transmitted at max TX power | ||
| 1181 | */ | ||
| 1182 | return (!max_power && !AR_SREV_9280_20_OR_LATER(ah)) ? 1 : max_power; | ||
| 1183 | } | 1170 | } |
| 1184 | 1171 | ||
| 1185 | static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf, | 1172 | static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf, |
| @@ -2129,6 +2116,7 @@ static void setup_frame_info(struct ieee80211_hw *hw, | |||
| 2129 | struct ath_node *an = NULL; | 2116 | struct ath_node *an = NULL; |
| 2130 | enum ath9k_key_type keytype; | 2117 | enum ath9k_key_type keytype; |
| 2131 | bool short_preamble = false; | 2118 | bool short_preamble = false; |
| 2119 | u8 txpower; | ||
| 2132 | 2120 | ||
| 2133 | /* | 2121 | /* |
| 2134 | * We check if Short Preamble is needed for the CTS rate by | 2122 | * We check if Short Preamble is needed for the CTS rate by |
| @@ -2145,6 +2133,16 @@ static void setup_frame_info(struct ieee80211_hw *hw, | |||
| 2145 | if (sta) | 2133 | if (sta) |
| 2146 | an = (struct ath_node *) sta->drv_priv; | 2134 | an = (struct ath_node *) sta->drv_priv; |
| 2147 | 2135 | ||
| 2136 | if (tx_info->control.vif) { | ||
| 2137 | struct ieee80211_vif *vif = tx_info->control.vif; | ||
| 2138 | |||
| 2139 | txpower = 2 * vif->bss_conf.txpower; | ||
| 2140 | } else { | ||
| 2141 | struct ath_softc *sc = hw->priv; | ||
| 2142 | |||
| 2143 | txpower = sc->cur_chan->cur_txpower; | ||
| 2144 | } | ||
| 2145 | |||
| 2148 | memset(fi, 0, sizeof(*fi)); | 2146 | memset(fi, 0, sizeof(*fi)); |
| 2149 | fi->txq = -1; | 2147 | fi->txq = -1; |
| 2150 | if (hw_key) | 2148 | if (hw_key) |
| @@ -2155,7 +2153,7 @@ static void setup_frame_info(struct ieee80211_hw *hw, | |||
| 2155 | fi->keyix = ATH9K_TXKEYIX_INVALID; | 2153 | fi->keyix = ATH9K_TXKEYIX_INVALID; |
| 2156 | fi->keytype = keytype; | 2154 | fi->keytype = keytype; |
| 2157 | fi->framelen = framelen; | 2155 | fi->framelen = framelen; |
| 2158 | fi->tx_power = MAX_RATE_POWER; | 2156 | fi->tx_power = txpower; |
| 2159 | 2157 | ||
| 2160 | if (!rate) | 2158 | if (!rate) |
| 2161 | return; | 2159 | return; |
diff --git a/drivers/net/wireless/iwlwifi/iwl-fw-file.h b/drivers/net/wireless/iwlwifi/iwl-fw-file.h index bfdf3faa6c47..62db2e5e45eb 100644 --- a/drivers/net/wireless/iwlwifi/iwl-fw-file.h +++ b/drivers/net/wireless/iwlwifi/iwl-fw-file.h | |||
| @@ -244,6 +244,7 @@ enum iwl_ucode_tlv_flag { | |||
| 244 | * longer than the passive one, which is essential for fragmented scan. | 244 | * longer than the passive one, which is essential for fragmented scan. |
| 245 | * @IWL_UCODE_TLV_API_WIFI_MCC_UPDATE: ucode supports MCC updates with source. | 245 | * @IWL_UCODE_TLV_API_WIFI_MCC_UPDATE: ucode supports MCC updates with source. |
| 246 | * IWL_UCODE_TLV_API_HDC_PHASE_0: ucode supports finer configuration of LTR | 246 | * IWL_UCODE_TLV_API_HDC_PHASE_0: ucode supports finer configuration of LTR |
| 247 | * @IWL_UCODE_TLV_API_TX_POWER_DEV: new API for tx power. | ||
| 247 | * @IWL_UCODE_TLV_API_BASIC_DWELL: use only basic dwell time in scan command, | 248 | * @IWL_UCODE_TLV_API_BASIC_DWELL: use only basic dwell time in scan command, |
| 248 | * regardless of the band or the number of the probes. FW will calculate | 249 | * regardless of the band or the number of the probes. FW will calculate |
| 249 | * the actual dwell time. | 250 | * the actual dwell time. |
| @@ -260,6 +261,7 @@ enum iwl_ucode_tlv_api { | |||
| 260 | IWL_UCODE_TLV_API_FRAGMENTED_SCAN = BIT(8), | 261 | IWL_UCODE_TLV_API_FRAGMENTED_SCAN = BIT(8), |
| 261 | IWL_UCODE_TLV_API_WIFI_MCC_UPDATE = BIT(9), | 262 | IWL_UCODE_TLV_API_WIFI_MCC_UPDATE = BIT(9), |
| 262 | IWL_UCODE_TLV_API_HDC_PHASE_0 = BIT(10), | 263 | IWL_UCODE_TLV_API_HDC_PHASE_0 = BIT(10), |
| 264 | IWL_UCODE_TLV_API_TX_POWER_DEV = BIT(11), | ||
| 263 | IWL_UCODE_TLV_API_BASIC_DWELL = BIT(13), | 265 | IWL_UCODE_TLV_API_BASIC_DWELL = BIT(13), |
| 264 | IWL_UCODE_TLV_API_SCD_CFG = BIT(15), | 266 | IWL_UCODE_TLV_API_SCD_CFG = BIT(15), |
| 265 | IWL_UCODE_TLV_API_SINGLE_SCAN_EBS = BIT(16), | 267 | IWL_UCODE_TLV_API_SINGLE_SCAN_EBS = BIT(16), |
diff --git a/drivers/net/wireless/iwlwifi/iwl-trans.h b/drivers/net/wireless/iwlwifi/iwl-trans.h index 6dfed1259260..56254a837214 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans.h +++ b/drivers/net/wireless/iwlwifi/iwl-trans.h | |||
| @@ -6,7 +6,7 @@ | |||
| 6 | * GPL LICENSE SUMMARY | 6 | * GPL LICENSE SUMMARY |
| 7 | * | 7 | * |
| 8 | * Copyright(c) 2007 - 2014 Intel Corporation. All rights reserved. | 8 | * Copyright(c) 2007 - 2014 Intel Corporation. All rights reserved. |
| 9 | * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH | 9 | * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH |
| 10 | * | 10 | * |
| 11 | * This program is free software; you can redistribute it and/or modify | 11 | * This program is free software; you can redistribute it and/or modify |
| 12 | * it under the terms of version 2 of the GNU General Public License as | 12 | * it under the terms of version 2 of the GNU General Public License as |
| @@ -32,7 +32,7 @@ | |||
| 32 | * BSD LICENSE | 32 | * BSD LICENSE |
| 33 | * | 33 | * |
| 34 | * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved. | 34 | * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved. |
| 35 | * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH | 35 | * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH |
| 36 | * All rights reserved. | 36 | * All rights reserved. |
| 37 | * | 37 | * |
| 38 | * Redistribution and use in source and binary forms, with or without | 38 | * Redistribution and use in source and binary forms, with or without |
| @@ -421,8 +421,9 @@ struct iwl_trans_txq_scd_cfg { | |||
| 421 | * | 421 | * |
| 422 | * All the handlers MUST be implemented | 422 | * All the handlers MUST be implemented |
| 423 | * | 423 | * |
| 424 | * @start_hw: starts the HW- from that point on, the HW can send interrupts | 424 | * @start_hw: starts the HW. If low_power is true, the NIC needs to be taken |
| 425 | * May sleep | 425 | * out of a low power state. From that point on, the HW can send |
| 426 | * interrupts. May sleep. | ||
| 426 | * @op_mode_leave: Turn off the HW RF kill indication if on | 427 | * @op_mode_leave: Turn off the HW RF kill indication if on |
| 427 | * May sleep | 428 | * May sleep |
| 428 | * @start_fw: allocates and inits all the resources for the transport | 429 | * @start_fw: allocates and inits all the resources for the transport |
| @@ -432,10 +433,11 @@ struct iwl_trans_txq_scd_cfg { | |||
| 432 | * the SCD base address in SRAM, then provide it here, or 0 otherwise. | 433 | * the SCD base address in SRAM, then provide it here, or 0 otherwise. |
| 433 | * May sleep | 434 | * May sleep |
| 434 | * @stop_device: stops the whole device (embedded CPU put to reset) and stops | 435 | * @stop_device: stops the whole device (embedded CPU put to reset) and stops |
| 435 | * the HW. From that point on, the HW will be in low power but will still | 436 | * the HW. If low_power is true, the NIC will be put in low power state. |
| 436 | * issue interrupt if the HW RF kill is triggered. This callback must do | 437 | * From that point on, the HW will be stopped but will still issue an |
| 437 | * the right thing and not crash even if start_hw() was called but not | 438 | * interrupt if the HW RF kill switch is triggered. |
| 438 | * start_fw(). May sleep | 439 | * This callback must do the right thing and not crash even if %start_hw() |
| 440 | * was called but not &start_fw(). May sleep. | ||
| 439 | * @d3_suspend: put the device into the correct mode for WoWLAN during | 441 | * @d3_suspend: put the device into the correct mode for WoWLAN during |
| 440 | * suspend. This is optional, if not implemented WoWLAN will not be | 442 | * suspend. This is optional, if not implemented WoWLAN will not be |
| 441 | * supported. This callback may sleep. | 443 | * supported. This callback may sleep. |
| @@ -491,14 +493,14 @@ struct iwl_trans_txq_scd_cfg { | |||
| 491 | */ | 493 | */ |
| 492 | struct iwl_trans_ops { | 494 | struct iwl_trans_ops { |
| 493 | 495 | ||
| 494 | int (*start_hw)(struct iwl_trans *iwl_trans); | 496 | int (*start_hw)(struct iwl_trans *iwl_trans, bool low_power); |
| 495 | void (*op_mode_leave)(struct iwl_trans *iwl_trans); | 497 | void (*op_mode_leave)(struct iwl_trans *iwl_trans); |
| 496 | int (*start_fw)(struct iwl_trans *trans, const struct fw_img *fw, | 498 | int (*start_fw)(struct iwl_trans *trans, const struct fw_img *fw, |
| 497 | bool run_in_rfkill); | 499 | bool run_in_rfkill); |
| 498 | int (*update_sf)(struct iwl_trans *trans, | 500 | int (*update_sf)(struct iwl_trans *trans, |
| 499 | struct iwl_sf_region *st_fwrd_space); | 501 | struct iwl_sf_region *st_fwrd_space); |
| 500 | void (*fw_alive)(struct iwl_trans *trans, u32 scd_addr); | 502 | void (*fw_alive)(struct iwl_trans *trans, u32 scd_addr); |
| 501 | void (*stop_device)(struct iwl_trans *trans); | 503 | void (*stop_device)(struct iwl_trans *trans, bool low_power); |
| 502 | 504 | ||
| 503 | void (*d3_suspend)(struct iwl_trans *trans, bool test); | 505 | void (*d3_suspend)(struct iwl_trans *trans, bool test); |
| 504 | int (*d3_resume)(struct iwl_trans *trans, enum iwl_d3_status *status, | 506 | int (*d3_resume)(struct iwl_trans *trans, enum iwl_d3_status *status, |
| @@ -652,11 +654,16 @@ static inline void iwl_trans_configure(struct iwl_trans *trans, | |||
| 652 | trans->ops->configure(trans, trans_cfg); | 654 | trans->ops->configure(trans, trans_cfg); |
| 653 | } | 655 | } |
| 654 | 656 | ||
| 655 | static inline int iwl_trans_start_hw(struct iwl_trans *trans) | 657 | static inline int _iwl_trans_start_hw(struct iwl_trans *trans, bool low_power) |
| 656 | { | 658 | { |
| 657 | might_sleep(); | 659 | might_sleep(); |
| 658 | 660 | ||
| 659 | return trans->ops->start_hw(trans); | 661 | return trans->ops->start_hw(trans, low_power); |
| 662 | } | ||
| 663 | |||
| 664 | static inline int iwl_trans_start_hw(struct iwl_trans *trans) | ||
| 665 | { | ||
| 666 | return trans->ops->start_hw(trans, true); | ||
| 660 | } | 667 | } |
| 661 | 668 | ||
| 662 | static inline void iwl_trans_op_mode_leave(struct iwl_trans *trans) | 669 | static inline void iwl_trans_op_mode_leave(struct iwl_trans *trans) |
| @@ -703,15 +710,21 @@ static inline int iwl_trans_update_sf(struct iwl_trans *trans, | |||
| 703 | return 0; | 710 | return 0; |
| 704 | } | 711 | } |
| 705 | 712 | ||
| 706 | static inline void iwl_trans_stop_device(struct iwl_trans *trans) | 713 | static inline void _iwl_trans_stop_device(struct iwl_trans *trans, |
| 714 | bool low_power) | ||
| 707 | { | 715 | { |
| 708 | might_sleep(); | 716 | might_sleep(); |
| 709 | 717 | ||
| 710 | trans->ops->stop_device(trans); | 718 | trans->ops->stop_device(trans, low_power); |
| 711 | 719 | ||
| 712 | trans->state = IWL_TRANS_NO_FW; | 720 | trans->state = IWL_TRANS_NO_FW; |
| 713 | } | 721 | } |
| 714 | 722 | ||
| 723 | static inline void iwl_trans_stop_device(struct iwl_trans *trans) | ||
| 724 | { | ||
| 725 | _iwl_trans_stop_device(trans, true); | ||
| 726 | } | ||
| 727 | |||
| 715 | static inline void iwl_trans_d3_suspend(struct iwl_trans *trans, bool test) | 728 | static inline void iwl_trans_d3_suspend(struct iwl_trans *trans, bool test) |
| 716 | { | 729 | { |
| 717 | might_sleep(); | 730 | might_sleep(); |
diff --git a/drivers/net/wireless/iwlwifi/mvm/d3.c b/drivers/net/wireless/iwlwifi/mvm/d3.c index a6c48c7b1e16..1b1b2bf26819 100644 --- a/drivers/net/wireless/iwlwifi/mvm/d3.c +++ b/drivers/net/wireless/iwlwifi/mvm/d3.c | |||
| @@ -1726,7 +1726,7 @@ iwl_mvm_netdetect_query_results(struct iwl_mvm *mvm, | |||
| 1726 | results->matched_profiles = le32_to_cpu(query->matched_profiles); | 1726 | results->matched_profiles = le32_to_cpu(query->matched_profiles); |
| 1727 | memcpy(results->matches, query->matches, sizeof(results->matches)); | 1727 | memcpy(results->matches, query->matches, sizeof(results->matches)); |
| 1728 | 1728 | ||
| 1729 | #ifdef CPTCFG_IWLWIFI_DEBUGFS | 1729 | #ifdef CONFIG_IWLWIFI_DEBUGFS |
| 1730 | mvm->last_netdetect_scans = le32_to_cpu(query->n_scans_done); | 1730 | mvm->last_netdetect_scans = le32_to_cpu(query->n_scans_done); |
| 1731 | #endif | 1731 | #endif |
| 1732 | 1732 | ||
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api-power.h b/drivers/net/wireless/iwlwifi/mvm/fw-api-power.h index 4fc0938b3fb6..b1baa33cc19b 100644 --- a/drivers/net/wireless/iwlwifi/mvm/fw-api-power.h +++ b/drivers/net/wireless/iwlwifi/mvm/fw-api-power.h | |||
| @@ -298,6 +298,40 @@ struct iwl_uapsd_misbehaving_ap_notif { | |||
| 298 | } __packed; | 298 | } __packed; |
| 299 | 299 | ||
| 300 | /** | 300 | /** |
| 301 | * struct iwl_reduce_tx_power_cmd - TX power reduction command | ||
| 302 | * REDUCE_TX_POWER_CMD = 0x9f | ||
| 303 | * @flags: (reserved for future implementation) | ||
| 304 | * @mac_context_id: id of the mac ctx for which we are reducing TX power. | ||
| 305 | * @pwr_restriction: TX power restriction in dBms. | ||
| 306 | */ | ||
| 307 | struct iwl_reduce_tx_power_cmd { | ||
| 308 | u8 flags; | ||
| 309 | u8 mac_context_id; | ||
| 310 | __le16 pwr_restriction; | ||
| 311 | } __packed; /* TX_REDUCED_POWER_API_S_VER_1 */ | ||
| 312 | |||
| 313 | /** | ||
| 314 | * struct iwl_dev_tx_power_cmd - TX power reduction command | ||
| 315 | * REDUCE_TX_POWER_CMD = 0x9f | ||
| 316 | * @set_mode: 0 - MAC tx power, 1 - device tx power | ||
| 317 | * @mac_context_id: id of the mac ctx for which we are reducing TX power. | ||
| 318 | * @pwr_restriction: TX power restriction in 1/8 dBms. | ||
| 319 | * @dev_24: device TX power restriction in 1/8 dBms | ||
| 320 | * @dev_52_low: device TX power restriction upper band - low | ||
| 321 | * @dev_52_high: device TX power restriction upper band - high | ||
| 322 | */ | ||
| 323 | struct iwl_dev_tx_power_cmd { | ||
| 324 | __le32 set_mode; | ||
| 325 | __le32 mac_context_id; | ||
| 326 | __le16 pwr_restriction; | ||
| 327 | __le16 dev_24; | ||
| 328 | __le16 dev_52_low; | ||
| 329 | __le16 dev_52_high; | ||
| 330 | } __packed; /* TX_REDUCED_POWER_API_S_VER_2 */ | ||
| 331 | |||
| 332 | #define IWL_DEV_MAX_TX_POWER 0x7FFF | ||
| 333 | |||
| 334 | /** | ||
| 301 | * struct iwl_beacon_filter_cmd | 335 | * struct iwl_beacon_filter_cmd |
| 302 | * REPLY_BEACON_FILTERING_CMD = 0xd2 (command) | 336 | * REPLY_BEACON_FILTERING_CMD = 0xd2 (command) |
| 303 | * @id_and_color: MAC contex identifier | 337 | * @id_and_color: MAC contex identifier |
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api-scan.h b/drivers/net/wireless/iwlwifi/mvm/fw-api-scan.h index 4f81dcf57a73..d6cced47d561 100644 --- a/drivers/net/wireless/iwlwifi/mvm/fw-api-scan.h +++ b/drivers/net/wireless/iwlwifi/mvm/fw-api-scan.h | |||
| @@ -122,46 +122,6 @@ enum iwl_scan_complete_status { | |||
| 122 | SCAN_COMP_STATUS_ERR_ALLOC_TE = 0x0C, | 122 | SCAN_COMP_STATUS_ERR_ALLOC_TE = 0x0C, |
| 123 | }; | 123 | }; |
| 124 | 124 | ||
| 125 | /** | ||
| 126 | * struct iwl_scan_results_notif - scan results for one channel | ||
| 127 | * ( SCAN_RESULTS_NOTIFICATION = 0x83 ) | ||
| 128 | * @channel: which channel the results are from | ||
| 129 | * @band: 0 for 5.2 GHz, 1 for 2.4 GHz | ||
| 130 | * @probe_status: SCAN_PROBE_STATUS_*, indicates success of probe request | ||
| 131 | * @num_probe_not_sent: # of request that weren't sent due to not enough time | ||
| 132 | * @duration: duration spent in channel, in usecs | ||
| 133 | * @statistics: statistics gathered for this channel | ||
| 134 | */ | ||
| 135 | struct iwl_scan_results_notif { | ||
| 136 | u8 channel; | ||
| 137 | u8 band; | ||
| 138 | u8 probe_status; | ||
| 139 | u8 num_probe_not_sent; | ||
| 140 | __le32 duration; | ||
| 141 | __le32 statistics[SCAN_RESULTS_STATISTICS]; | ||
| 142 | } __packed; /* SCAN_RESULT_NTF_API_S_VER_2 */ | ||
| 143 | |||
| 144 | /** | ||
| 145 | * struct iwl_scan_complete_notif - notifies end of scanning (all channels) | ||
| 146 | * ( SCAN_COMPLETE_NOTIFICATION = 0x84 ) | ||
| 147 | * @scanned_channels: number of channels scanned (and number of valid results) | ||
| 148 | * @status: one of SCAN_COMP_STATUS_* | ||
| 149 | * @bt_status: BT on/off status | ||
| 150 | * @last_channel: last channel that was scanned | ||
| 151 | * @tsf_low: TSF timer (lower half) in usecs | ||
| 152 | * @tsf_high: TSF timer (higher half) in usecs | ||
| 153 | * @results: array of scan results, only "scanned_channels" of them are valid | ||
| 154 | */ | ||
| 155 | struct iwl_scan_complete_notif { | ||
| 156 | u8 scanned_channels; | ||
| 157 | u8 status; | ||
| 158 | u8 bt_status; | ||
| 159 | u8 last_channel; | ||
| 160 | __le32 tsf_low; | ||
| 161 | __le32 tsf_high; | ||
| 162 | struct iwl_scan_results_notif results[]; | ||
| 163 | } __packed; /* SCAN_COMPLETE_NTF_API_S_VER_2 */ | ||
| 164 | |||
| 165 | /* scan offload */ | 125 | /* scan offload */ |
| 166 | #define IWL_SCAN_MAX_BLACKLIST_LEN 64 | 126 | #define IWL_SCAN_MAX_BLACKLIST_LEN 64 |
| 167 | #define IWL_SCAN_SHORT_BLACKLIST_LEN 16 | 127 | #define IWL_SCAN_SHORT_BLACKLIST_LEN 16 |
| @@ -554,7 +514,7 @@ struct iwl_scan_req_unified_lmac { | |||
| 554 | } __packed; | 514 | } __packed; |
| 555 | 515 | ||
| 556 | /** | 516 | /** |
| 557 | * struct iwl_lmac_scan_results_notif - scan results for one channel - | 517 | * struct iwl_scan_results_notif - scan results for one channel - |
| 558 | * SCAN_RESULT_NTF_API_S_VER_3 | 518 | * SCAN_RESULT_NTF_API_S_VER_3 |
| 559 | * @channel: which channel the results are from | 519 | * @channel: which channel the results are from |
| 560 | * @band: 0 for 5.2 GHz, 1 for 2.4 GHz | 520 | * @band: 0 for 5.2 GHz, 1 for 2.4 GHz |
| @@ -562,7 +522,7 @@ struct iwl_scan_req_unified_lmac { | |||
| 562 | * @num_probe_not_sent: # of request that weren't sent due to not enough time | 522 | * @num_probe_not_sent: # of request that weren't sent due to not enough time |
| 563 | * @duration: duration spent in channel, in usecs | 523 | * @duration: duration spent in channel, in usecs |
| 564 | */ | 524 | */ |
| 565 | struct iwl_lmac_scan_results_notif { | 525 | struct iwl_scan_results_notif { |
| 566 | u8 channel; | 526 | u8 channel; |
| 567 | u8 band; | 527 | u8 band; |
| 568 | u8 probe_status; | 528 | u8 probe_status; |
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api.h b/drivers/net/wireless/iwlwifi/mvm/fw-api.h index aab68cbae754..01b1da6ad359 100644 --- a/drivers/net/wireless/iwlwifi/mvm/fw-api.h +++ b/drivers/net/wireless/iwlwifi/mvm/fw-api.h | |||
| @@ -281,19 +281,6 @@ struct iwl_tx_ant_cfg_cmd { | |||
| 281 | __le32 valid; | 281 | __le32 valid; |
| 282 | } __packed; | 282 | } __packed; |
| 283 | 283 | ||
| 284 | /** | ||
| 285 | * struct iwl_reduce_tx_power_cmd - TX power reduction command | ||
| 286 | * REDUCE_TX_POWER_CMD = 0x9f | ||
| 287 | * @flags: (reserved for future implementation) | ||
| 288 | * @mac_context_id: id of the mac ctx for which we are reducing TX power. | ||
| 289 | * @pwr_restriction: TX power restriction in dBms. | ||
| 290 | */ | ||
| 291 | struct iwl_reduce_tx_power_cmd { | ||
| 292 | u8 flags; | ||
| 293 | u8 mac_context_id; | ||
| 294 | __le16 pwr_restriction; | ||
| 295 | } __packed; /* TX_REDUCED_POWER_API_S_VER_1 */ | ||
| 296 | |||
| 297 | /* | 284 | /* |
| 298 | * Calibration control struct. | 285 | * Calibration control struct. |
| 299 | * Sent as part of the phy configuration command. | 286 | * Sent as part of the phy configuration command. |
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw.c b/drivers/net/wireless/iwlwifi/mvm/fw.c index bc5eac4960e1..df869633f4dd 100644 --- a/drivers/net/wireless/iwlwifi/mvm/fw.c +++ b/drivers/net/wireless/iwlwifi/mvm/fw.c | |||
| @@ -6,7 +6,7 @@ | |||
| 6 | * GPL LICENSE SUMMARY | 6 | * GPL LICENSE SUMMARY |
| 7 | * | 7 | * |
| 8 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. | 8 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. |
| 9 | * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH | 9 | * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH |
| 10 | * | 10 | * |
| 11 | * This program is free software; you can redistribute it and/or modify | 11 | * This program is free software; you can redistribute it and/or modify |
| 12 | * it under the terms of version 2 of the GNU General Public License as | 12 | * it under the terms of version 2 of the GNU General Public License as |
| @@ -32,7 +32,7 @@ | |||
| 32 | * BSD LICENSE | 32 | * BSD LICENSE |
| 33 | * | 33 | * |
| 34 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. | 34 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. |
| 35 | * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH | 35 | * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH |
| 36 | * All rights reserved. | 36 | * All rights reserved. |
| 37 | * | 37 | * |
| 38 | * Redistribution and use in source and binary forms, with or without | 38 | * Redistribution and use in source and binary forms, with or without |
| @@ -322,7 +322,7 @@ int iwl_run_init_mvm_ucode(struct iwl_mvm *mvm, bool read_nvm) | |||
| 322 | 322 | ||
| 323 | lockdep_assert_held(&mvm->mutex); | 323 | lockdep_assert_held(&mvm->mutex); |
| 324 | 324 | ||
| 325 | if (WARN_ON_ONCE(mvm->init_ucode_complete || mvm->calibrating)) | 325 | if (WARN_ON_ONCE(mvm->calibrating)) |
| 326 | return 0; | 326 | return 0; |
| 327 | 327 | ||
| 328 | iwl_init_notification_wait(&mvm->notif_wait, | 328 | iwl_init_notification_wait(&mvm->notif_wait, |
| @@ -396,8 +396,6 @@ int iwl_run_init_mvm_ucode(struct iwl_mvm *mvm, bool read_nvm) | |||
| 396 | */ | 396 | */ |
| 397 | ret = iwl_wait_notification(&mvm->notif_wait, &calib_wait, | 397 | ret = iwl_wait_notification(&mvm->notif_wait, &calib_wait, |
| 398 | MVM_UCODE_CALIB_TIMEOUT); | 398 | MVM_UCODE_CALIB_TIMEOUT); |
| 399 | if (!ret) | ||
| 400 | mvm->init_ucode_complete = true; | ||
| 401 | 399 | ||
| 402 | if (ret && iwl_mvm_is_radio_killed(mvm)) { | 400 | if (ret && iwl_mvm_is_radio_killed(mvm)) { |
| 403 | IWL_DEBUG_RF_KILL(mvm, "RFKILL while calibrating.\n"); | 401 | IWL_DEBUG_RF_KILL(mvm, "RFKILL while calibrating.\n"); |
| @@ -494,15 +492,6 @@ int iwl_mvm_fw_dbg_collect_desc(struct iwl_mvm *mvm, | |||
| 494 | 492 | ||
| 495 | mvm->fw_dump_desc = desc; | 493 | mvm->fw_dump_desc = desc; |
| 496 | 494 | ||
| 497 | /* stop recording */ | ||
| 498 | if (mvm->cfg->device_family == IWL_DEVICE_FAMILY_7000) { | ||
| 499 | iwl_set_bits_prph(mvm->trans, MON_BUFF_SAMPLE_CTL, 0x100); | ||
| 500 | } else { | ||
| 501 | iwl_write_prph(mvm->trans, DBGC_IN_SAMPLE, 0); | ||
| 502 | /* wait before we collect the data till the DBGC stop */ | ||
| 503 | udelay(100); | ||
| 504 | } | ||
| 505 | |||
| 506 | queue_delayed_work(system_wq, &mvm->fw_dump_wk, delay); | 495 | queue_delayed_work(system_wq, &mvm->fw_dump_wk, delay); |
| 507 | 496 | ||
| 508 | return 0; | 497 | return 0; |
| @@ -658,25 +647,24 @@ int iwl_mvm_up(struct iwl_mvm *mvm) | |||
| 658 | * module loading, load init ucode now | 647 | * module loading, load init ucode now |
| 659 | * (for example, if we were in RFKILL) | 648 | * (for example, if we were in RFKILL) |
| 660 | */ | 649 | */ |
| 661 | if (!mvm->init_ucode_complete) { | 650 | ret = iwl_run_init_mvm_ucode(mvm, false); |
| 662 | ret = iwl_run_init_mvm_ucode(mvm, false); | 651 | if (ret && !iwlmvm_mod_params.init_dbg) { |
| 663 | if (ret && !iwlmvm_mod_params.init_dbg) { | 652 | IWL_ERR(mvm, "Failed to run INIT ucode: %d\n", ret); |
| 664 | IWL_ERR(mvm, "Failed to run INIT ucode: %d\n", ret); | 653 | /* this can't happen */ |
| 665 | /* this can't happen */ | 654 | if (WARN_ON(ret > 0)) |
| 666 | if (WARN_ON(ret > 0)) | 655 | ret = -ERFKILL; |
| 667 | ret = -ERFKILL; | 656 | goto error; |
| 668 | goto error; | 657 | } |
| 669 | } | 658 | if (!iwlmvm_mod_params.init_dbg) { |
| 670 | if (!iwlmvm_mod_params.init_dbg) { | 659 | /* |
| 671 | /* | 660 | * Stop and start the transport without entering low power |
| 672 | * should stop and start HW since that INIT | 661 | * mode. This will save the state of other components on the |
| 673 | * image just loaded | 662 | * device that are triggered by the INIT firwmare (MFUART). |
| 674 | */ | 663 | */ |
| 675 | iwl_trans_stop_device(mvm->trans); | 664 | _iwl_trans_stop_device(mvm->trans, false); |
| 676 | ret = iwl_trans_start_hw(mvm->trans); | 665 | _iwl_trans_start_hw(mvm->trans, false); |
| 677 | if (ret) | 666 | if (ret) |
| 678 | return ret; | 667 | return ret; |
| 679 | } | ||
| 680 | } | 668 | } |
| 681 | 669 | ||
| 682 | if (iwlmvm_mod_params.init_dbg) | 670 | if (iwlmvm_mod_params.init_dbg) |
diff --git a/drivers/net/wireless/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/iwlwifi/mvm/mac80211.c index 84555170b6f7..40265b9c66ae 100644 --- a/drivers/net/wireless/iwlwifi/mvm/mac80211.c +++ b/drivers/net/wireless/iwlwifi/mvm/mac80211.c | |||
| @@ -1322,7 +1322,7 @@ static void iwl_mvm_restart_complete(struct iwl_mvm *mvm) | |||
| 1322 | 1322 | ||
| 1323 | clear_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status); | 1323 | clear_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status); |
| 1324 | iwl_mvm_d0i3_enable_tx(mvm, NULL); | 1324 | iwl_mvm_d0i3_enable_tx(mvm, NULL); |
| 1325 | ret = iwl_mvm_update_quotas(mvm, false, NULL); | 1325 | ret = iwl_mvm_update_quotas(mvm, true, NULL); |
| 1326 | if (ret) | 1326 | if (ret) |
| 1327 | IWL_ERR(mvm, "Failed to update quotas after restart (%d)\n", | 1327 | IWL_ERR(mvm, "Failed to update quotas after restart (%d)\n", |
| 1328 | ret); | 1328 | ret); |
| @@ -1471,8 +1471,8 @@ static struct iwl_mvm_phy_ctxt *iwl_mvm_get_free_phy_ctxt(struct iwl_mvm *mvm) | |||
| 1471 | return NULL; | 1471 | return NULL; |
| 1472 | } | 1472 | } |
| 1473 | 1473 | ||
| 1474 | static int iwl_mvm_set_tx_power(struct iwl_mvm *mvm, struct ieee80211_vif *vif, | 1474 | static int iwl_mvm_set_tx_power_old(struct iwl_mvm *mvm, |
| 1475 | s8 tx_power) | 1475 | struct ieee80211_vif *vif, s8 tx_power) |
| 1476 | { | 1476 | { |
| 1477 | /* FW is in charge of regulatory enforcement */ | 1477 | /* FW is in charge of regulatory enforcement */ |
| 1478 | struct iwl_reduce_tx_power_cmd reduce_txpwr_cmd = { | 1478 | struct iwl_reduce_tx_power_cmd reduce_txpwr_cmd = { |
| @@ -1485,6 +1485,26 @@ static int iwl_mvm_set_tx_power(struct iwl_mvm *mvm, struct ieee80211_vif *vif, | |||
| 1485 | &reduce_txpwr_cmd); | 1485 | &reduce_txpwr_cmd); |
| 1486 | } | 1486 | } |
| 1487 | 1487 | ||
| 1488 | static int iwl_mvm_set_tx_power(struct iwl_mvm *mvm, struct ieee80211_vif *vif, | ||
| 1489 | s16 tx_power) | ||
| 1490 | { | ||
| 1491 | struct iwl_dev_tx_power_cmd cmd = { | ||
| 1492 | .set_mode = 0, | ||
| 1493 | .mac_context_id = | ||
| 1494 | cpu_to_le32(iwl_mvm_vif_from_mac80211(vif)->id), | ||
| 1495 | .pwr_restriction = cpu_to_le16(8 * tx_power), | ||
| 1496 | }; | ||
| 1497 | |||
| 1498 | if (!(mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_API_TX_POWER_DEV)) | ||
| 1499 | return iwl_mvm_set_tx_power_old(mvm, vif, tx_power); | ||
| 1500 | |||
| 1501 | if (tx_power == IWL_DEFAULT_MAX_TX_POWER) | ||
| 1502 | cmd.pwr_restriction = cpu_to_le16(IWL_DEV_MAX_TX_POWER); | ||
| 1503 | |||
| 1504 | return iwl_mvm_send_cmd_pdu(mvm, REDUCE_TX_POWER_CMD, 0, | ||
| 1505 | sizeof(cmd), &cmd); | ||
| 1506 | } | ||
| 1507 | |||
| 1488 | static int iwl_mvm_mac_add_interface(struct ieee80211_hw *hw, | 1508 | static int iwl_mvm_mac_add_interface(struct ieee80211_hw *hw, |
| 1489 | struct ieee80211_vif *vif) | 1509 | struct ieee80211_vif *vif) |
| 1490 | { | 1510 | { |
diff --git a/drivers/net/wireless/iwlwifi/mvm/mvm.h b/drivers/net/wireless/iwlwifi/mvm/mvm.h index d5522a161242..cf70f681d1ac 100644 --- a/drivers/net/wireless/iwlwifi/mvm/mvm.h +++ b/drivers/net/wireless/iwlwifi/mvm/mvm.h | |||
| @@ -603,7 +603,6 @@ struct iwl_mvm { | |||
| 603 | 603 | ||
| 604 | enum iwl_ucode_type cur_ucode; | 604 | enum iwl_ucode_type cur_ucode; |
| 605 | bool ucode_loaded; | 605 | bool ucode_loaded; |
| 606 | bool init_ucode_complete; | ||
| 607 | bool calibrating; | 606 | bool calibrating; |
| 608 | u32 error_event_table; | 607 | u32 error_event_table; |
| 609 | u32 log_event_table; | 608 | u32 log_event_table; |
diff --git a/drivers/net/wireless/iwlwifi/mvm/ops.c b/drivers/net/wireless/iwlwifi/mvm/ops.c index a08b03d58d4b..1c66297d82c0 100644 --- a/drivers/net/wireless/iwlwifi/mvm/ops.c +++ b/drivers/net/wireless/iwlwifi/mvm/ops.c | |||
| @@ -865,6 +865,16 @@ static void iwl_mvm_fw_error_dump_wk(struct work_struct *work) | |||
| 865 | return; | 865 | return; |
| 866 | 866 | ||
| 867 | mutex_lock(&mvm->mutex); | 867 | mutex_lock(&mvm->mutex); |
| 868 | |||
| 869 | /* stop recording */ | ||
| 870 | if (mvm->cfg->device_family == IWL_DEVICE_FAMILY_7000) { | ||
| 871 | iwl_set_bits_prph(mvm->trans, MON_BUFF_SAMPLE_CTL, 0x100); | ||
| 872 | } else { | ||
| 873 | iwl_write_prph(mvm->trans, DBGC_IN_SAMPLE, 0); | ||
| 874 | /* wait before we collect the data till the DBGC stop */ | ||
| 875 | udelay(100); | ||
| 876 | } | ||
| 877 | |||
| 868 | iwl_mvm_fw_error_dump(mvm); | 878 | iwl_mvm_fw_error_dump(mvm); |
| 869 | 879 | ||
| 870 | /* start recording again if the firmware is not crashed */ | 880 | /* start recording again if the firmware is not crashed */ |
diff --git a/drivers/net/wireless/iwlwifi/mvm/rx.c b/drivers/net/wireless/iwlwifi/mvm/rx.c index 78ec7db64ba5..d6314ddf57b5 100644 --- a/drivers/net/wireless/iwlwifi/mvm/rx.c +++ b/drivers/net/wireless/iwlwifi/mvm/rx.c | |||
| @@ -478,6 +478,11 @@ static void iwl_mvm_stat_iterator(void *_data, u8 *mac, | |||
| 478 | if (vif->type != NL80211_IFTYPE_STATION) | 478 | if (vif->type != NL80211_IFTYPE_STATION) |
| 479 | return; | 479 | return; |
| 480 | 480 | ||
| 481 | if (sig == 0) { | ||
| 482 | IWL_DEBUG_RX(mvm, "RSSI is 0 - skip signal based decision\n"); | ||
| 483 | return; | ||
| 484 | } | ||
| 485 | |||
| 481 | mvmvif->bf_data.ave_beacon_signal = sig; | 486 | mvmvif->bf_data.ave_beacon_signal = sig; |
| 482 | 487 | ||
| 483 | /* BT Coex */ | 488 | /* BT Coex */ |
diff --git a/drivers/net/wireless/iwlwifi/mvm/scan.c b/drivers/net/wireless/iwlwifi/mvm/scan.c index 74e1c86289dc..1075a213bd6a 100644 --- a/drivers/net/wireless/iwlwifi/mvm/scan.c +++ b/drivers/net/wireless/iwlwifi/mvm/scan.c | |||
| @@ -319,7 +319,7 @@ int iwl_mvm_rx_scan_offload_iter_complete_notif(struct iwl_mvm *mvm, | |||
| 319 | struct iwl_device_cmd *cmd) | 319 | struct iwl_device_cmd *cmd) |
| 320 | { | 320 | { |
| 321 | struct iwl_rx_packet *pkt = rxb_addr(rxb); | 321 | struct iwl_rx_packet *pkt = rxb_addr(rxb); |
| 322 | struct iwl_scan_complete_notif *notif = (void *)pkt->data; | 322 | struct iwl_lmac_scan_complete_notif *notif = (void *)pkt->data; |
| 323 | 323 | ||
| 324 | IWL_DEBUG_SCAN(mvm, | 324 | IWL_DEBUG_SCAN(mvm, |
| 325 | "Scan offload iteration complete: status=0x%x scanned channels=%d\n", | 325 | "Scan offload iteration complete: status=0x%x scanned channels=%d\n", |
diff --git a/drivers/net/wireless/iwlwifi/pcie/trans.c b/drivers/net/wireless/iwlwifi/pcie/trans.c index 2de8fbfe4edf..47bbf573fdc8 100644 --- a/drivers/net/wireless/iwlwifi/pcie/trans.c +++ b/drivers/net/wireless/iwlwifi/pcie/trans.c | |||
| @@ -5,8 +5,8 @@ | |||
| 5 | * | 5 | * |
| 6 | * GPL LICENSE SUMMARY | 6 | * GPL LICENSE SUMMARY |
| 7 | * | 7 | * |
| 8 | * Copyright(c) 2007 - 2014 Intel Corporation. All rights reserved. | 8 | * Copyright(c) 2007 - 2015 Intel Corporation. All rights reserved. |
| 9 | * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH | 9 | * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH |
| 10 | * | 10 | * |
| 11 | * This program is free software; you can redistribute it and/or modify | 11 | * This program is free software; you can redistribute it and/or modify |
| 12 | * it under the terms of version 2 of the GNU General Public License as | 12 | * it under the terms of version 2 of the GNU General Public License as |
| @@ -31,8 +31,8 @@ | |||
| 31 | * | 31 | * |
| 32 | * BSD LICENSE | 32 | * BSD LICENSE |
| 33 | * | 33 | * |
| 34 | * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved. | 34 | * Copyright(c) 2005 - 2015 Intel Corporation. All rights reserved. |
| 35 | * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH | 35 | * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH |
| 36 | * All rights reserved. | 36 | * All rights reserved. |
| 37 | * | 37 | * |
| 38 | * Redistribution and use in source and binary forms, with or without | 38 | * Redistribution and use in source and binary forms, with or without |
| @@ -104,7 +104,7 @@ static void iwl_pcie_free_fw_monitor(struct iwl_trans *trans) | |||
| 104 | static void iwl_pcie_alloc_fw_monitor(struct iwl_trans *trans) | 104 | static void iwl_pcie_alloc_fw_monitor(struct iwl_trans *trans) |
| 105 | { | 105 | { |
| 106 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); | 106 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); |
| 107 | struct page *page; | 107 | struct page *page = NULL; |
| 108 | dma_addr_t phys; | 108 | dma_addr_t phys; |
| 109 | u32 size; | 109 | u32 size; |
| 110 | u8 power; | 110 | u8 power; |
| @@ -131,6 +131,7 @@ static void iwl_pcie_alloc_fw_monitor(struct iwl_trans *trans) | |||
| 131 | DMA_FROM_DEVICE); | 131 | DMA_FROM_DEVICE); |
| 132 | if (dma_mapping_error(trans->dev, phys)) { | 132 | if (dma_mapping_error(trans->dev, phys)) { |
| 133 | __free_pages(page, order); | 133 | __free_pages(page, order); |
| 134 | page = NULL; | ||
| 134 | continue; | 135 | continue; |
| 135 | } | 136 | } |
| 136 | IWL_INFO(trans, | 137 | IWL_INFO(trans, |
| @@ -1020,7 +1021,7 @@ static void iwl_trans_pcie_fw_alive(struct iwl_trans *trans, u32 scd_addr) | |||
| 1020 | iwl_pcie_tx_start(trans, scd_addr); | 1021 | iwl_pcie_tx_start(trans, scd_addr); |
| 1021 | } | 1022 | } |
| 1022 | 1023 | ||
| 1023 | static void iwl_trans_pcie_stop_device(struct iwl_trans *trans) | 1024 | static void iwl_trans_pcie_stop_device(struct iwl_trans *trans, bool low_power) |
| 1024 | { | 1025 | { |
| 1025 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); | 1026 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); |
| 1026 | bool hw_rfkill, was_hw_rfkill; | 1027 | bool hw_rfkill, was_hw_rfkill; |
| @@ -1115,7 +1116,7 @@ static void iwl_trans_pcie_stop_device(struct iwl_trans *trans) | |||
| 1115 | void iwl_trans_pcie_rf_kill(struct iwl_trans *trans, bool state) | 1116 | void iwl_trans_pcie_rf_kill(struct iwl_trans *trans, bool state) |
| 1116 | { | 1117 | { |
| 1117 | if (iwl_op_mode_hw_rf_kill(trans->op_mode, state)) | 1118 | if (iwl_op_mode_hw_rf_kill(trans->op_mode, state)) |
| 1118 | iwl_trans_pcie_stop_device(trans); | 1119 | iwl_trans_pcie_stop_device(trans, true); |
| 1119 | } | 1120 | } |
| 1120 | 1121 | ||
| 1121 | static void iwl_trans_pcie_d3_suspend(struct iwl_trans *trans, bool test) | 1122 | static void iwl_trans_pcie_d3_suspend(struct iwl_trans *trans, bool test) |
| @@ -1200,7 +1201,7 @@ static int iwl_trans_pcie_d3_resume(struct iwl_trans *trans, | |||
| 1200 | return 0; | 1201 | return 0; |
| 1201 | } | 1202 | } |
| 1202 | 1203 | ||
| 1203 | static int iwl_trans_pcie_start_hw(struct iwl_trans *trans) | 1204 | static int iwl_trans_pcie_start_hw(struct iwl_trans *trans, bool low_power) |
| 1204 | { | 1205 | { |
| 1205 | bool hw_rfkill; | 1206 | bool hw_rfkill; |
| 1206 | int err; | 1207 | int err; |
diff --git a/drivers/net/wireless/rtlwifi/usb.c b/drivers/net/wireless/rtlwifi/usb.c index f0188c83c79f..2721cf89fb16 100644 --- a/drivers/net/wireless/rtlwifi/usb.c +++ b/drivers/net/wireless/rtlwifi/usb.c | |||
| @@ -126,7 +126,7 @@ static int _usbctrl_vendorreq_sync_read(struct usb_device *udev, u8 request, | |||
| 126 | 126 | ||
| 127 | do { | 127 | do { |
| 128 | status = usb_control_msg(udev, pipe, request, reqtype, value, | 128 | status = usb_control_msg(udev, pipe, request, reqtype, value, |
| 129 | index, pdata, len, 0); /*max. timeout*/ | 129 | index, pdata, len, 1000); |
| 130 | if (status < 0) { | 130 | if (status < 0) { |
| 131 | /* firmware download is checksumed, don't retry */ | 131 | /* firmware download is checksumed, don't retry */ |
| 132 | if ((value >= FW_8192C_START_ADDRESS && | 132 | if ((value >= FW_8192C_START_ADDRESS && |
diff --git a/drivers/parisc/superio.c b/drivers/parisc/superio.c index 8be2096c8423..deeaed544222 100644 --- a/drivers/parisc/superio.c +++ b/drivers/parisc/superio.c | |||
| @@ -348,7 +348,7 @@ int superio_fixup_irq(struct pci_dev *pcidev) | |||
| 348 | BUG(); | 348 | BUG(); |
| 349 | return -1; | 349 | return -1; |
| 350 | } | 350 | } |
| 351 | printk("superio_fixup_irq(%s) ven 0x%x dev 0x%x from %pf\n", | 351 | printk(KERN_DEBUG "superio_fixup_irq(%s) ven 0x%x dev 0x%x from %ps\n", |
| 352 | pci_name(pcidev), | 352 | pci_name(pcidev), |
| 353 | pcidev->vendor, pcidev->device, | 353 | pcidev->vendor, pcidev->device, |
| 354 | __builtin_return_address(0)); | 354 | __builtin_return_address(0)); |
diff --git a/drivers/pinctrl/core.c b/drivers/pinctrl/core.c index 89dca77ca038..18ee2089df4a 100644 --- a/drivers/pinctrl/core.c +++ b/drivers/pinctrl/core.c | |||
| @@ -1110,7 +1110,7 @@ void devm_pinctrl_put(struct pinctrl *p) | |||
| 1110 | EXPORT_SYMBOL_GPL(devm_pinctrl_put); | 1110 | EXPORT_SYMBOL_GPL(devm_pinctrl_put); |
| 1111 | 1111 | ||
| 1112 | int pinctrl_register_map(struct pinctrl_map const *maps, unsigned num_maps, | 1112 | int pinctrl_register_map(struct pinctrl_map const *maps, unsigned num_maps, |
| 1113 | bool dup, bool locked) | 1113 | bool dup) |
| 1114 | { | 1114 | { |
| 1115 | int i, ret; | 1115 | int i, ret; |
| 1116 | struct pinctrl_maps *maps_node; | 1116 | struct pinctrl_maps *maps_node; |
| @@ -1178,11 +1178,9 @@ int pinctrl_register_map(struct pinctrl_map const *maps, unsigned num_maps, | |||
| 1178 | maps_node->maps = maps; | 1178 | maps_node->maps = maps; |
| 1179 | } | 1179 | } |
| 1180 | 1180 | ||
| 1181 | if (!locked) | 1181 | mutex_lock(&pinctrl_maps_mutex); |
| 1182 | mutex_lock(&pinctrl_maps_mutex); | ||
| 1183 | list_add_tail(&maps_node->node, &pinctrl_maps); | 1182 | list_add_tail(&maps_node->node, &pinctrl_maps); |
| 1184 | if (!locked) | 1183 | mutex_unlock(&pinctrl_maps_mutex); |
| 1185 | mutex_unlock(&pinctrl_maps_mutex); | ||
| 1186 | 1184 | ||
| 1187 | return 0; | 1185 | return 0; |
| 1188 | } | 1186 | } |
| @@ -1197,7 +1195,7 @@ int pinctrl_register_map(struct pinctrl_map const *maps, unsigned num_maps, | |||
| 1197 | int pinctrl_register_mappings(struct pinctrl_map const *maps, | 1195 | int pinctrl_register_mappings(struct pinctrl_map const *maps, |
| 1198 | unsigned num_maps) | 1196 | unsigned num_maps) |
| 1199 | { | 1197 | { |
| 1200 | return pinctrl_register_map(maps, num_maps, true, false); | 1198 | return pinctrl_register_map(maps, num_maps, true); |
| 1201 | } | 1199 | } |
| 1202 | 1200 | ||
| 1203 | void pinctrl_unregister_map(struct pinctrl_map const *map) | 1201 | void pinctrl_unregister_map(struct pinctrl_map const *map) |
diff --git a/drivers/pinctrl/core.h b/drivers/pinctrl/core.h index 75476b3d87da..b24ea846c867 100644 --- a/drivers/pinctrl/core.h +++ b/drivers/pinctrl/core.h | |||
| @@ -183,7 +183,7 @@ static inline struct pin_desc *pin_desc_get(struct pinctrl_dev *pctldev, | |||
| 183 | } | 183 | } |
| 184 | 184 | ||
| 185 | int pinctrl_register_map(struct pinctrl_map const *maps, unsigned num_maps, | 185 | int pinctrl_register_map(struct pinctrl_map const *maps, unsigned num_maps, |
| 186 | bool dup, bool locked); | 186 | bool dup); |
| 187 | void pinctrl_unregister_map(struct pinctrl_map const *map); | 187 | void pinctrl_unregister_map(struct pinctrl_map const *map); |
| 188 | 188 | ||
| 189 | extern int pinctrl_force_sleep(struct pinctrl_dev *pctldev); | 189 | extern int pinctrl_force_sleep(struct pinctrl_dev *pctldev); |
diff --git a/drivers/pinctrl/devicetree.c b/drivers/pinctrl/devicetree.c index eda13de2e7c0..0bbf7d71b281 100644 --- a/drivers/pinctrl/devicetree.c +++ b/drivers/pinctrl/devicetree.c | |||
| @@ -92,7 +92,7 @@ static int dt_remember_or_free_map(struct pinctrl *p, const char *statename, | |||
| 92 | dt_map->num_maps = num_maps; | 92 | dt_map->num_maps = num_maps; |
| 93 | list_add_tail(&dt_map->node, &p->dt_maps); | 93 | list_add_tail(&dt_map->node, &p->dt_maps); |
| 94 | 94 | ||
| 95 | return pinctrl_register_map(map, num_maps, false, true); | 95 | return pinctrl_register_map(map, num_maps, false); |
| 96 | } | 96 | } |
| 97 | 97 | ||
| 98 | struct pinctrl_dev *of_pinctrl_get(struct device_node *np) | 98 | struct pinctrl_dev *of_pinctrl_get(struct device_node *np) |
diff --git a/drivers/pinctrl/mediatek/pinctrl-mtk-common.c b/drivers/pinctrl/mediatek/pinctrl-mtk-common.c index 493294c0ebe6..474812e2b0cb 100644 --- a/drivers/pinctrl/mediatek/pinctrl-mtk-common.c +++ b/drivers/pinctrl/mediatek/pinctrl-mtk-common.c | |||
| @@ -881,6 +881,8 @@ static int mtk_gpio_set_debounce(struct gpio_chip *chip, unsigned offset, | |||
| 881 | if (!mtk_eint_get_mask(pctl, eint_num)) { | 881 | if (!mtk_eint_get_mask(pctl, eint_num)) { |
| 882 | mtk_eint_mask(d); | 882 | mtk_eint_mask(d); |
| 883 | unmask = 1; | 883 | unmask = 1; |
| 884 | } else { | ||
| 885 | unmask = 0; | ||
| 884 | } | 886 | } |
| 885 | 887 | ||
| 886 | clr_bit = 0xff << eint_offset; | 888 | clr_bit = 0xff << eint_offset; |
diff --git a/drivers/pinctrl/mvebu/pinctrl-armada-370.c b/drivers/pinctrl/mvebu/pinctrl-armada-370.c index 42f930f70de3..03aa58c4cb85 100644 --- a/drivers/pinctrl/mvebu/pinctrl-armada-370.c +++ b/drivers/pinctrl/mvebu/pinctrl-armada-370.c | |||
| @@ -364,7 +364,7 @@ static struct mvebu_mpp_mode mv88f6710_mpp_modes[] = { | |||
| 364 | MPP_FUNCTION(0x5, "audio", "mclk"), | 364 | MPP_FUNCTION(0x5, "audio", "mclk"), |
| 365 | MPP_FUNCTION(0x6, "uart0", "cts")), | 365 | MPP_FUNCTION(0x6, "uart0", "cts")), |
| 366 | MPP_MODE(63, | 366 | MPP_MODE(63, |
| 367 | MPP_FUNCTION(0x0, "gpo", NULL), | 367 | MPP_FUNCTION(0x0, "gpio", NULL), |
| 368 | MPP_FUNCTION(0x1, "spi0", "sck"), | 368 | MPP_FUNCTION(0x1, "spi0", "sck"), |
| 369 | MPP_FUNCTION(0x2, "tclk", NULL)), | 369 | MPP_FUNCTION(0x2, "tclk", NULL)), |
| 370 | MPP_MODE(64, | 370 | MPP_MODE(64, |
diff --git a/drivers/pinctrl/qcom/pinctrl-spmi-gpio.c b/drivers/pinctrl/qcom/pinctrl-spmi-gpio.c index b2d22218a258..ae4115e4b4ef 100644 --- a/drivers/pinctrl/qcom/pinctrl-spmi-gpio.c +++ b/drivers/pinctrl/qcom/pinctrl-spmi-gpio.c | |||
| @@ -260,6 +260,7 @@ static int pmic_gpio_set_mux(struct pinctrl_dev *pctldev, unsigned function, | |||
| 260 | val = 1; | 260 | val = 1; |
| 261 | } | 261 | } |
| 262 | 262 | ||
| 263 | val = val << PMIC_GPIO_REG_MODE_DIR_SHIFT; | ||
| 263 | val |= pad->function << PMIC_GPIO_REG_MODE_FUNCTION_SHIFT; | 264 | val |= pad->function << PMIC_GPIO_REG_MODE_FUNCTION_SHIFT; |
| 264 | val |= pad->out_value & PMIC_GPIO_REG_MODE_VALUE_SHIFT; | 265 | val |= pad->out_value & PMIC_GPIO_REG_MODE_VALUE_SHIFT; |
| 265 | 266 | ||
| @@ -417,7 +418,7 @@ static int pmic_gpio_config_set(struct pinctrl_dev *pctldev, unsigned int pin, | |||
| 417 | return ret; | 418 | return ret; |
| 418 | 419 | ||
| 419 | val = pad->buffer_type << PMIC_GPIO_REG_OUT_TYPE_SHIFT; | 420 | val = pad->buffer_type << PMIC_GPIO_REG_OUT_TYPE_SHIFT; |
| 420 | val = pad->strength << PMIC_GPIO_REG_OUT_STRENGTH_SHIFT; | 421 | val |= pad->strength << PMIC_GPIO_REG_OUT_STRENGTH_SHIFT; |
| 421 | 422 | ||
| 422 | ret = pmic_gpio_write(state, pad, PMIC_GPIO_REG_DIG_OUT_CTL, val); | 423 | ret = pmic_gpio_write(state, pad, PMIC_GPIO_REG_DIG_OUT_CTL, val); |
| 423 | if (ret < 0) | 424 | if (ret < 0) |
| @@ -466,12 +467,13 @@ static void pmic_gpio_config_dbg_show(struct pinctrl_dev *pctldev, | |||
| 466 | seq_puts(s, " ---"); | 467 | seq_puts(s, " ---"); |
| 467 | } else { | 468 | } else { |
| 468 | 469 | ||
| 469 | if (!pad->input_enabled) { | 470 | if (pad->input_enabled) { |
| 470 | ret = pmic_gpio_read(state, pad, PMIC_MPP_REG_RT_STS); | 471 | ret = pmic_gpio_read(state, pad, PMIC_MPP_REG_RT_STS); |
| 471 | if (!ret) { | 472 | if (ret < 0) |
| 472 | ret &= PMIC_MPP_REG_RT_STS_VAL_MASK; | 473 | return; |
| 473 | pad->out_value = ret; | 474 | |
| 474 | } | 475 | ret &= PMIC_MPP_REG_RT_STS_VAL_MASK; |
| 476 | pad->out_value = ret; | ||
| 475 | } | 477 | } |
| 476 | 478 | ||
| 477 | seq_printf(s, " %-4s", pad->output_enabled ? "out" : "in"); | 479 | seq_printf(s, " %-4s", pad->output_enabled ? "out" : "in"); |
diff --git a/drivers/pinctrl/qcom/pinctrl-spmi-mpp.c b/drivers/pinctrl/qcom/pinctrl-spmi-mpp.c index 8f36c5f91949..211b942ad6d5 100644 --- a/drivers/pinctrl/qcom/pinctrl-spmi-mpp.c +++ b/drivers/pinctrl/qcom/pinctrl-spmi-mpp.c | |||
| @@ -370,6 +370,7 @@ static int pmic_mpp_set_mux(struct pinctrl_dev *pctldev, unsigned function, | |||
| 370 | } | 370 | } |
| 371 | } | 371 | } |
| 372 | 372 | ||
| 373 | val = val << PMIC_MPP_REG_MODE_DIR_SHIFT; | ||
| 373 | val |= pad->function << PMIC_MPP_REG_MODE_FUNCTION_SHIFT; | 374 | val |= pad->function << PMIC_MPP_REG_MODE_FUNCTION_SHIFT; |
| 374 | val |= pad->out_value & PMIC_MPP_REG_MODE_VALUE_MASK; | 375 | val |= pad->out_value & PMIC_MPP_REG_MODE_VALUE_MASK; |
| 375 | 376 | ||
| @@ -576,10 +577,11 @@ static void pmic_mpp_config_dbg_show(struct pinctrl_dev *pctldev, | |||
| 576 | 577 | ||
| 577 | if (pad->input_enabled) { | 578 | if (pad->input_enabled) { |
| 578 | ret = pmic_mpp_read(state, pad, PMIC_MPP_REG_RT_STS); | 579 | ret = pmic_mpp_read(state, pad, PMIC_MPP_REG_RT_STS); |
| 579 | if (!ret) { | 580 | if (ret < 0) |
| 580 | ret &= PMIC_MPP_REG_RT_STS_VAL_MASK; | 581 | return; |
| 581 | pad->out_value = ret; | 582 | |
| 582 | } | 583 | ret &= PMIC_MPP_REG_RT_STS_VAL_MASK; |
| 584 | pad->out_value = ret; | ||
| 583 | } | 585 | } |
| 584 | 586 | ||
| 585 | seq_printf(s, " %-4s", pad->output_enabled ? "out" : "in"); | 587 | seq_printf(s, " %-4s", pad->output_enabled ? "out" : "in"); |
diff --git a/drivers/platform/x86/ideapad-laptop.c b/drivers/platform/x86/ideapad-laptop.c index b3d419a84723..b496db87bc05 100644 --- a/drivers/platform/x86/ideapad-laptop.c +++ b/drivers/platform/x86/ideapad-laptop.c | |||
| @@ -830,6 +830,13 @@ static void ideapad_acpi_notify(acpi_handle handle, u32 event, void *data) | |||
| 830 | */ | 830 | */ |
| 831 | static const struct dmi_system_id no_hw_rfkill_list[] = { | 831 | static const struct dmi_system_id no_hw_rfkill_list[] = { |
| 832 | { | 832 | { |
| 833 | .ident = "Lenovo G40-30", | ||
| 834 | .matches = { | ||
| 835 | DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), | ||
| 836 | DMI_MATCH(DMI_PRODUCT_VERSION, "Lenovo G40-30"), | ||
| 837 | }, | ||
| 838 | }, | ||
| 839 | { | ||
| 833 | .ident = "Lenovo Yoga 2 11 / 13 / Pro", | 840 | .ident = "Lenovo Yoga 2 11 / 13 / Pro", |
| 834 | .matches = { | 841 | .matches = { |
| 835 | DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), | 842 | DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), |
diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c index 7769575345d8..9bb9ad6d4a1b 100644 --- a/drivers/platform/x86/thinkpad_acpi.c +++ b/drivers/platform/x86/thinkpad_acpi.c | |||
| @@ -2115,7 +2115,7 @@ static int hotkey_mask_get(void) | |||
| 2115 | return 0; | 2115 | return 0; |
| 2116 | } | 2116 | } |
| 2117 | 2117 | ||
| 2118 | void static hotkey_mask_warn_incomplete_mask(void) | 2118 | static void hotkey_mask_warn_incomplete_mask(void) |
| 2119 | { | 2119 | { |
| 2120 | /* log only what the user can fix... */ | 2120 | /* log only what the user can fix... */ |
| 2121 | const u32 wantedmask = hotkey_driver_mask & | 2121 | const u32 wantedmask = hotkey_driver_mask & |
diff --git a/drivers/power/axp288_fuel_gauge.c b/drivers/power/axp288_fuel_gauge.c index ca1cc5a47eb1..bd1dbfee2515 100644 --- a/drivers/power/axp288_fuel_gauge.c +++ b/drivers/power/axp288_fuel_gauge.c | |||
| @@ -1149,6 +1149,7 @@ static struct platform_driver axp288_fuel_gauge_driver = { | |||
| 1149 | 1149 | ||
| 1150 | module_platform_driver(axp288_fuel_gauge_driver); | 1150 | module_platform_driver(axp288_fuel_gauge_driver); |
| 1151 | 1151 | ||
| 1152 | MODULE_AUTHOR("Ramakrishna Pallala <ramakrishna.pallala@intel.com>"); | ||
| 1152 | MODULE_AUTHOR("Todd Brandt <todd.e.brandt@linux.intel.com>"); | 1153 | MODULE_AUTHOR("Todd Brandt <todd.e.brandt@linux.intel.com>"); |
| 1153 | MODULE_DESCRIPTION("Xpower AXP288 Fuel Gauge Driver"); | 1154 | MODULE_DESCRIPTION("Xpower AXP288 Fuel Gauge Driver"); |
| 1154 | MODULE_LICENSE("GPL"); | 1155 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/power/bq27x00_battery.c b/drivers/power/bq27x00_battery.c index a57433de5c24..b6b98378faa3 100644 --- a/drivers/power/bq27x00_battery.c +++ b/drivers/power/bq27x00_battery.c | |||
| @@ -1109,6 +1109,14 @@ static void __exit bq27x00_battery_exit(void) | |||
| 1109 | } | 1109 | } |
| 1110 | module_exit(bq27x00_battery_exit); | 1110 | module_exit(bq27x00_battery_exit); |
| 1111 | 1111 | ||
| 1112 | #ifdef CONFIG_BATTERY_BQ27X00_PLATFORM | ||
| 1113 | MODULE_ALIAS("platform:bq27000-battery"); | ||
| 1114 | #endif | ||
| 1115 | |||
| 1116 | #ifdef CONFIG_BATTERY_BQ27X00_I2C | ||
| 1117 | MODULE_ALIAS("i2c:bq27000-battery"); | ||
| 1118 | #endif | ||
| 1119 | |||
| 1112 | MODULE_AUTHOR("Rodolfo Giometti <giometti@linux.it>"); | 1120 | MODULE_AUTHOR("Rodolfo Giometti <giometti@linux.it>"); |
| 1113 | MODULE_DESCRIPTION("BQ27x00 battery monitor driver"); | 1121 | MODULE_DESCRIPTION("BQ27x00 battery monitor driver"); |
| 1114 | MODULE_LICENSE("GPL"); | 1122 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/power/collie_battery.c b/drivers/power/collie_battery.c index 2da9ed8ccbb5..8a971b3dbe58 100644 --- a/drivers/power/collie_battery.c +++ b/drivers/power/collie_battery.c | |||
| @@ -347,7 +347,7 @@ static int collie_bat_probe(struct ucb1x00_dev *dev) | |||
| 347 | goto err_psy_reg_main; | 347 | goto err_psy_reg_main; |
| 348 | } | 348 | } |
| 349 | 349 | ||
| 350 | psy_main_cfg.drv_data = &collie_bat_bu; | 350 | psy_bu_cfg.drv_data = &collie_bat_bu; |
| 351 | collie_bat_bu.psy = power_supply_register(&dev->ucb->dev, | 351 | collie_bat_bu.psy = power_supply_register(&dev->ucb->dev, |
| 352 | &collie_bat_bu_desc, | 352 | &collie_bat_bu_desc, |
| 353 | &psy_bu_cfg); | 353 | &psy_bu_cfg); |
diff --git a/drivers/power/reset/Kconfig b/drivers/power/reset/Kconfig index aad9c3318c02..17d93a73c513 100644 --- a/drivers/power/reset/Kconfig +++ b/drivers/power/reset/Kconfig | |||
| @@ -41,6 +41,7 @@ config POWER_RESET_AXXIA | |||
| 41 | config POWER_RESET_BRCMSTB | 41 | config POWER_RESET_BRCMSTB |
| 42 | bool "Broadcom STB reset driver" | 42 | bool "Broadcom STB reset driver" |
| 43 | depends on ARM || MIPS || COMPILE_TEST | 43 | depends on ARM || MIPS || COMPILE_TEST |
| 44 | depends on MFD_SYSCON | ||
| 44 | default ARCH_BRCMSTB | 45 | default ARCH_BRCMSTB |
| 45 | help | 46 | help |
| 46 | This driver provides restart support for Broadcom STB boards. | 47 | This driver provides restart support for Broadcom STB boards. |
diff --git a/drivers/power/reset/at91-reset.c b/drivers/power/reset/at91-reset.c index 01c7055c4200..ca461ebc7ae8 100644 --- a/drivers/power/reset/at91-reset.c +++ b/drivers/power/reset/at91-reset.c | |||
| @@ -212,9 +212,9 @@ static int at91_reset_platform_probe(struct platform_device *pdev) | |||
| 212 | res = platform_get_resource(pdev, IORESOURCE_MEM, idx + 1 ); | 212 | res = platform_get_resource(pdev, IORESOURCE_MEM, idx + 1 ); |
| 213 | at91_ramc_base[idx] = devm_ioremap(&pdev->dev, res->start, | 213 | at91_ramc_base[idx] = devm_ioremap(&pdev->dev, res->start, |
| 214 | resource_size(res)); | 214 | resource_size(res)); |
| 215 | if (IS_ERR(at91_ramc_base[idx])) { | 215 | if (!at91_ramc_base[idx]) { |
| 216 | dev_err(&pdev->dev, "Could not map ram controller address\n"); | 216 | dev_err(&pdev->dev, "Could not map ram controller address\n"); |
| 217 | return PTR_ERR(at91_ramc_base[idx]); | 217 | return -ENOMEM; |
| 218 | } | 218 | } |
| 219 | } | 219 | } |
| 220 | 220 | ||
diff --git a/drivers/power/reset/ltc2952-poweroff.c b/drivers/power/reset/ltc2952-poweroff.c index 7ef193b6f7fe..1e08195551fe 100644 --- a/drivers/power/reset/ltc2952-poweroff.c +++ b/drivers/power/reset/ltc2952-poweroff.c | |||
| @@ -120,18 +120,7 @@ static enum hrtimer_restart ltc2952_poweroff_timer_wde(struct hrtimer *timer) | |||
| 120 | 120 | ||
| 121 | static void ltc2952_poweroff_start_wde(struct ltc2952_poweroff *data) | 121 | static void ltc2952_poweroff_start_wde(struct ltc2952_poweroff *data) |
| 122 | { | 122 | { |
| 123 | if (hrtimer_start(&data->timer_wde, data->wde_interval, | 123 | hrtimer_start(&data->timer_wde, data->wde_interval, HRTIMER_MODE_REL); |
| 124 | HRTIMER_MODE_REL)) { | ||
| 125 | /* | ||
| 126 | * The device will not toggle the watchdog reset, | ||
| 127 | * thus shut down is only safe if the PowerPath controller | ||
| 128 | * has a long enough time-off before triggering a hardware | ||
| 129 | * power-off. | ||
| 130 | * | ||
| 131 | * Only sending a warning as the system will power-off anyway | ||
| 132 | */ | ||
| 133 | dev_err(data->dev, "unable to start the timer\n"); | ||
| 134 | } | ||
| 135 | } | 124 | } |
| 136 | 125 | ||
| 137 | static enum hrtimer_restart | 126 | static enum hrtimer_restart |
| @@ -165,9 +154,8 @@ static irqreturn_t ltc2952_poweroff_handler(int irq, void *dev_id) | |||
| 165 | } | 154 | } |
| 166 | 155 | ||
| 167 | if (gpiod_get_value(data->gpio_trigger)) { | 156 | if (gpiod_get_value(data->gpio_trigger)) { |
| 168 | if (hrtimer_start(&data->timer_trigger, data->trigger_delay, | 157 | hrtimer_start(&data->timer_trigger, data->trigger_delay, |
| 169 | HRTIMER_MODE_REL)) | 158 | HRTIMER_MODE_REL); |
| 170 | dev_err(data->dev, "unable to start the wait timer\n"); | ||
| 171 | } else { | 159 | } else { |
| 172 | hrtimer_cancel(&data->timer_trigger); | 160 | hrtimer_cancel(&data->timer_trigger); |
| 173 | /* omitting return value check, timer should have been valid */ | 161 | /* omitting return value check, timer should have been valid */ |
diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig index 6149ae01e11f..0fe4ad8826b2 100644 --- a/drivers/rtc/Kconfig +++ b/drivers/rtc/Kconfig | |||
| @@ -164,6 +164,16 @@ config RTC_DRV_ABB5ZES3 | |||
| 164 | This driver can also be built as a module. If so, the module | 164 | This driver can also be built as a module. If so, the module |
| 165 | will be called rtc-ab-b5ze-s3. | 165 | will be called rtc-ab-b5ze-s3. |
| 166 | 166 | ||
| 167 | config RTC_DRV_ABX80X | ||
| 168 | tristate "Abracon ABx80x" | ||
| 169 | help | ||
| 170 | If you say yes here you get support for Abracon AB080X and AB180X | ||
| 171 | families of ultra-low-power battery- and capacitor-backed real-time | ||
| 172 | clock chips. | ||
| 173 | |||
| 174 | This driver can also be built as a module. If so, the module | ||
| 175 | will be called rtc-abx80x. | ||
| 176 | |||
| 167 | config RTC_DRV_AS3722 | 177 | config RTC_DRV_AS3722 |
| 168 | tristate "ams AS3722 RTC driver" | 178 | tristate "ams AS3722 RTC driver" |
| 169 | depends on MFD_AS3722 | 179 | depends on MFD_AS3722 |
diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile index c31731c29762..2b82e2b0311b 100644 --- a/drivers/rtc/Makefile +++ b/drivers/rtc/Makefile | |||
| @@ -25,6 +25,7 @@ obj-$(CONFIG_RTC_DRV_88PM80X) += rtc-88pm80x.o | |||
| 25 | obj-$(CONFIG_RTC_DRV_AB3100) += rtc-ab3100.o | 25 | obj-$(CONFIG_RTC_DRV_AB3100) += rtc-ab3100.o |
| 26 | obj-$(CONFIG_RTC_DRV_AB8500) += rtc-ab8500.o | 26 | obj-$(CONFIG_RTC_DRV_AB8500) += rtc-ab8500.o |
| 27 | obj-$(CONFIG_RTC_DRV_ABB5ZES3) += rtc-ab-b5ze-s3.o | 27 | obj-$(CONFIG_RTC_DRV_ABB5ZES3) += rtc-ab-b5ze-s3.o |
| 28 | obj-$(CONFIG_RTC_DRV_ABX80X) += rtc-abx80x.o | ||
| 28 | obj-$(CONFIG_RTC_DRV_ARMADA38X) += rtc-armada38x.o | 29 | obj-$(CONFIG_RTC_DRV_ARMADA38X) += rtc-armada38x.o |
| 29 | obj-$(CONFIG_RTC_DRV_AS3722) += rtc-as3722.o | 30 | obj-$(CONFIG_RTC_DRV_AS3722) += rtc-as3722.o |
| 30 | obj-$(CONFIG_RTC_DRV_AT32AP700X)+= rtc-at32ap700x.o | 31 | obj-$(CONFIG_RTC_DRV_AT32AP700X)+= rtc-at32ap700x.o |
diff --git a/drivers/rtc/rtc-abx80x.c b/drivers/rtc/rtc-abx80x.c new file mode 100644 index 000000000000..4337c3bc6ace --- /dev/null +++ b/drivers/rtc/rtc-abx80x.c | |||
| @@ -0,0 +1,307 @@ | |||
| 1 | /* | ||
| 2 | * A driver for the I2C members of the Abracon AB x8xx RTC family, | ||
| 3 | * and compatible: AB 1805 and AB 0805 | ||
| 4 | * | ||
| 5 | * Copyright 2014-2015 Macq S.A. | ||
| 6 | * | ||
| 7 | * Author: Philippe De Muyter <phdm@macqel.be> | ||
| 8 | * Author: Alexandre Belloni <alexandre.belloni@free-electrons.com> | ||
| 9 | * | ||
| 10 | * This program is free software; you can redistribute it and/or modify | ||
| 11 | * it under the terms of the GNU General Public License version 2 as | ||
| 12 | * published by the Free Software Foundation. | ||
| 13 | * | ||
| 14 | */ | ||
| 15 | |||
| 16 | #include <linux/bcd.h> | ||
| 17 | #include <linux/i2c.h> | ||
| 18 | #include <linux/module.h> | ||
| 19 | #include <linux/rtc.h> | ||
| 20 | |||
| 21 | #define ABX8XX_REG_HTH 0x00 | ||
| 22 | #define ABX8XX_REG_SC 0x01 | ||
| 23 | #define ABX8XX_REG_MN 0x02 | ||
| 24 | #define ABX8XX_REG_HR 0x03 | ||
| 25 | #define ABX8XX_REG_DA 0x04 | ||
| 26 | #define ABX8XX_REG_MO 0x05 | ||
| 27 | #define ABX8XX_REG_YR 0x06 | ||
| 28 | #define ABX8XX_REG_WD 0x07 | ||
| 29 | |||
| 30 | #define ABX8XX_REG_CTRL1 0x10 | ||
| 31 | #define ABX8XX_CTRL_WRITE BIT(1) | ||
| 32 | #define ABX8XX_CTRL_12_24 BIT(6) | ||
| 33 | |||
| 34 | #define ABX8XX_REG_CFG_KEY 0x1f | ||
| 35 | #define ABX8XX_CFG_KEY_MISC 0x9d | ||
| 36 | |||
| 37 | #define ABX8XX_REG_ID0 0x28 | ||
| 38 | |||
| 39 | #define ABX8XX_REG_TRICKLE 0x20 | ||
| 40 | #define ABX8XX_TRICKLE_CHARGE_ENABLE 0xa0 | ||
| 41 | #define ABX8XX_TRICKLE_STANDARD_DIODE 0x8 | ||
| 42 | #define ABX8XX_TRICKLE_SCHOTTKY_DIODE 0x4 | ||
| 43 | |||
| 44 | static u8 trickle_resistors[] = {0, 3, 6, 11}; | ||
| 45 | |||
| 46 | enum abx80x_chip {AB0801, AB0803, AB0804, AB0805, | ||
| 47 | AB1801, AB1803, AB1804, AB1805, ABX80X}; | ||
| 48 | |||
| 49 | struct abx80x_cap { | ||
| 50 | u16 pn; | ||
| 51 | bool has_tc; | ||
| 52 | }; | ||
| 53 | |||
| 54 | static struct abx80x_cap abx80x_caps[] = { | ||
| 55 | [AB0801] = {.pn = 0x0801}, | ||
| 56 | [AB0803] = {.pn = 0x0803}, | ||
| 57 | [AB0804] = {.pn = 0x0804, .has_tc = true}, | ||
| 58 | [AB0805] = {.pn = 0x0805, .has_tc = true}, | ||
| 59 | [AB1801] = {.pn = 0x1801}, | ||
| 60 | [AB1803] = {.pn = 0x1803}, | ||
| 61 | [AB1804] = {.pn = 0x1804, .has_tc = true}, | ||
| 62 | [AB1805] = {.pn = 0x1805, .has_tc = true}, | ||
| 63 | [ABX80X] = {.pn = 0} | ||
| 64 | }; | ||
| 65 | |||
| 66 | static struct i2c_driver abx80x_driver; | ||
| 67 | |||
| 68 | static int abx80x_enable_trickle_charger(struct i2c_client *client, | ||
| 69 | u8 trickle_cfg) | ||
| 70 | { | ||
| 71 | int err; | ||
| 72 | |||
| 73 | /* | ||
| 74 | * Write the configuration key register to enable access to the Trickle | ||
| 75 | * register | ||
| 76 | */ | ||
| 77 | err = i2c_smbus_write_byte_data(client, ABX8XX_REG_CFG_KEY, | ||
| 78 | ABX8XX_CFG_KEY_MISC); | ||
| 79 | if (err < 0) { | ||
| 80 | dev_err(&client->dev, "Unable to write configuration key\n"); | ||
| 81 | return -EIO; | ||
| 82 | } | ||
| 83 | |||
| 84 | err = i2c_smbus_write_byte_data(client, ABX8XX_REG_TRICKLE, | ||
| 85 | ABX8XX_TRICKLE_CHARGE_ENABLE | | ||
| 86 | trickle_cfg); | ||
| 87 | if (err < 0) { | ||
| 88 | dev_err(&client->dev, "Unable to write trickle register\n"); | ||
| 89 | return -EIO; | ||
| 90 | } | ||
| 91 | |||
| 92 | return 0; | ||
| 93 | } | ||
| 94 | |||
| 95 | static int abx80x_rtc_read_time(struct device *dev, struct rtc_time *tm) | ||
| 96 | { | ||
| 97 | struct i2c_client *client = to_i2c_client(dev); | ||
| 98 | unsigned char buf[8]; | ||
| 99 | int err; | ||
| 100 | |||
| 101 | err = i2c_smbus_read_i2c_block_data(client, ABX8XX_REG_HTH, | ||
| 102 | sizeof(buf), buf); | ||
| 103 | if (err < 0) { | ||
| 104 | dev_err(&client->dev, "Unable to read date\n"); | ||
| 105 | return -EIO; | ||
| 106 | } | ||
| 107 | |||
| 108 | tm->tm_sec = bcd2bin(buf[ABX8XX_REG_SC] & 0x7F); | ||
| 109 | tm->tm_min = bcd2bin(buf[ABX8XX_REG_MN] & 0x7F); | ||
| 110 | tm->tm_hour = bcd2bin(buf[ABX8XX_REG_HR] & 0x3F); | ||
| 111 | tm->tm_wday = buf[ABX8XX_REG_WD] & 0x7; | ||
| 112 | tm->tm_mday = bcd2bin(buf[ABX8XX_REG_DA] & 0x3F); | ||
| 113 | tm->tm_mon = bcd2bin(buf[ABX8XX_REG_MO] & 0x1F) - 1; | ||
| 114 | tm->tm_year = bcd2bin(buf[ABX8XX_REG_YR]) + 100; | ||
| 115 | |||
| 116 | err = rtc_valid_tm(tm); | ||
| 117 | if (err < 0) | ||
| 118 | dev_err(&client->dev, "retrieved date/time is not valid.\n"); | ||
| 119 | |||
| 120 | return err; | ||
| 121 | } | ||
| 122 | |||
| 123 | static int abx80x_rtc_set_time(struct device *dev, struct rtc_time *tm) | ||
| 124 | { | ||
| 125 | struct i2c_client *client = to_i2c_client(dev); | ||
| 126 | unsigned char buf[8]; | ||
| 127 | int err; | ||
| 128 | |||
| 129 | if (tm->tm_year < 100) | ||
| 130 | return -EINVAL; | ||
| 131 | |||
| 132 | buf[ABX8XX_REG_HTH] = 0; | ||
| 133 | buf[ABX8XX_REG_SC] = bin2bcd(tm->tm_sec); | ||
| 134 | buf[ABX8XX_REG_MN] = bin2bcd(tm->tm_min); | ||
| 135 | buf[ABX8XX_REG_HR] = bin2bcd(tm->tm_hour); | ||
| 136 | buf[ABX8XX_REG_DA] = bin2bcd(tm->tm_mday); | ||
| 137 | buf[ABX8XX_REG_MO] = bin2bcd(tm->tm_mon + 1); | ||
| 138 | buf[ABX8XX_REG_YR] = bin2bcd(tm->tm_year - 100); | ||
| 139 | buf[ABX8XX_REG_WD] = tm->tm_wday; | ||
| 140 | |||
| 141 | err = i2c_smbus_write_i2c_block_data(client, ABX8XX_REG_HTH, | ||
| 142 | sizeof(buf), buf); | ||
| 143 | if (err < 0) { | ||
| 144 | dev_err(&client->dev, "Unable to write to date registers\n"); | ||
| 145 | return -EIO; | ||
| 146 | } | ||
| 147 | |||
| 148 | return 0; | ||
| 149 | } | ||
| 150 | |||
| 151 | static const struct rtc_class_ops abx80x_rtc_ops = { | ||
| 152 | .read_time = abx80x_rtc_read_time, | ||
| 153 | .set_time = abx80x_rtc_set_time, | ||
| 154 | }; | ||
| 155 | |||
| 156 | static int abx80x_dt_trickle_cfg(struct device_node *np) | ||
| 157 | { | ||
| 158 | const char *diode; | ||
| 159 | int trickle_cfg = 0; | ||
| 160 | int i, ret; | ||
| 161 | u32 tmp; | ||
| 162 | |||
| 163 | ret = of_property_read_string(np, "abracon,tc-diode", &diode); | ||
| 164 | if (ret) | ||
| 165 | return ret; | ||
| 166 | |||
| 167 | if (!strcmp(diode, "standard")) | ||
| 168 | trickle_cfg |= ABX8XX_TRICKLE_STANDARD_DIODE; | ||
| 169 | else if (!strcmp(diode, "schottky")) | ||
| 170 | trickle_cfg |= ABX8XX_TRICKLE_SCHOTTKY_DIODE; | ||
| 171 | else | ||
| 172 | return -EINVAL; | ||
| 173 | |||
| 174 | ret = of_property_read_u32(np, "abracon,tc-resistor", &tmp); | ||
| 175 | if (ret) | ||
| 176 | return ret; | ||
| 177 | |||
| 178 | for (i = 0; i < sizeof(trickle_resistors); i++) | ||
| 179 | if (trickle_resistors[i] == tmp) | ||
| 180 | break; | ||
| 181 | |||
| 182 | if (i == sizeof(trickle_resistors)) | ||
| 183 | return -EINVAL; | ||
| 184 | |||
| 185 | return (trickle_cfg | i); | ||
| 186 | } | ||
| 187 | |||
| 188 | static int abx80x_probe(struct i2c_client *client, | ||
| 189 | const struct i2c_device_id *id) | ||
| 190 | { | ||
| 191 | struct device_node *np = client->dev.of_node; | ||
| 192 | struct rtc_device *rtc; | ||
| 193 | int i, data, err, trickle_cfg = -EINVAL; | ||
| 194 | char buf[7]; | ||
| 195 | unsigned int part = id->driver_data; | ||
| 196 | unsigned int partnumber; | ||
| 197 | unsigned int majrev, minrev; | ||
| 198 | unsigned int lot; | ||
| 199 | unsigned int wafer; | ||
| 200 | unsigned int uid; | ||
| 201 | |||
| 202 | if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) | ||
| 203 | return -ENODEV; | ||
| 204 | |||
| 205 | err = i2c_smbus_read_i2c_block_data(client, ABX8XX_REG_ID0, | ||
| 206 | sizeof(buf), buf); | ||
| 207 | if (err < 0) { | ||
| 208 | dev_err(&client->dev, "Unable to read partnumber\n"); | ||
| 209 | return -EIO; | ||
| 210 | } | ||
| 211 | |||
| 212 | partnumber = (buf[0] << 8) | buf[1]; | ||
| 213 | majrev = buf[2] >> 3; | ||
| 214 | minrev = buf[2] & 0x7; | ||
| 215 | lot = ((buf[4] & 0x80) << 2) | ((buf[6] & 0x80) << 1) | buf[3]; | ||
| 216 | uid = ((buf[4] & 0x7f) << 8) | buf[5]; | ||
| 217 | wafer = (buf[6] & 0x7c) >> 2; | ||
| 218 | dev_info(&client->dev, "model %04x, revision %u.%u, lot %x, wafer %x, uid %x\n", | ||
| 219 | partnumber, majrev, minrev, lot, wafer, uid); | ||
| 220 | |||
| 221 | data = i2c_smbus_read_byte_data(client, ABX8XX_REG_CTRL1); | ||
| 222 | if (data < 0) { | ||
| 223 | dev_err(&client->dev, "Unable to read control register\n"); | ||
| 224 | return -EIO; | ||
| 225 | } | ||
| 226 | |||
| 227 | err = i2c_smbus_write_byte_data(client, ABX8XX_REG_CTRL1, | ||
| 228 | ((data & ~ABX8XX_CTRL_12_24) | | ||
| 229 | ABX8XX_CTRL_WRITE)); | ||
| 230 | if (err < 0) { | ||
| 231 | dev_err(&client->dev, "Unable to write control register\n"); | ||
| 232 | return -EIO; | ||
| 233 | } | ||
| 234 | |||
| 235 | /* part autodetection */ | ||
| 236 | if (part == ABX80X) { | ||
| 237 | for (i = 0; abx80x_caps[i].pn; i++) | ||
| 238 | if (partnumber == abx80x_caps[i].pn) | ||
| 239 | break; | ||
| 240 | if (abx80x_caps[i].pn == 0) { | ||
| 241 | dev_err(&client->dev, "Unknown part: %04x\n", | ||
| 242 | partnumber); | ||
| 243 | return -EINVAL; | ||
| 244 | } | ||
| 245 | part = i; | ||
| 246 | } | ||
| 247 | |||
| 248 | if (partnumber != abx80x_caps[part].pn) { | ||
| 249 | dev_err(&client->dev, "partnumber mismatch %04x != %04x\n", | ||
| 250 | partnumber, abx80x_caps[part].pn); | ||
| 251 | return -EINVAL; | ||
| 252 | } | ||
| 253 | |||
| 254 | if (np && abx80x_caps[part].has_tc) | ||
| 255 | trickle_cfg = abx80x_dt_trickle_cfg(np); | ||
| 256 | |||
| 257 | if (trickle_cfg > 0) { | ||
| 258 | dev_info(&client->dev, "Enabling trickle charger: %02x\n", | ||
| 259 | trickle_cfg); | ||
| 260 | abx80x_enable_trickle_charger(client, trickle_cfg); | ||
| 261 | } | ||
| 262 | |||
| 263 | rtc = devm_rtc_device_register(&client->dev, abx80x_driver.driver.name, | ||
| 264 | &abx80x_rtc_ops, THIS_MODULE); | ||
| 265 | |||
| 266 | if (IS_ERR(rtc)) | ||
| 267 | return PTR_ERR(rtc); | ||
| 268 | |||
| 269 | i2c_set_clientdata(client, rtc); | ||
| 270 | |||
| 271 | return 0; | ||
| 272 | } | ||
| 273 | |||
| 274 | static int abx80x_remove(struct i2c_client *client) | ||
| 275 | { | ||
| 276 | return 0; | ||
| 277 | } | ||
| 278 | |||
| 279 | static const struct i2c_device_id abx80x_id[] = { | ||
| 280 | { "abx80x", ABX80X }, | ||
| 281 | { "ab0801", AB0801 }, | ||
| 282 | { "ab0803", AB0803 }, | ||
| 283 | { "ab0804", AB0804 }, | ||
| 284 | { "ab0805", AB0805 }, | ||
| 285 | { "ab1801", AB1801 }, | ||
| 286 | { "ab1803", AB1803 }, | ||
| 287 | { "ab1804", AB1804 }, | ||
| 288 | { "ab1805", AB1805 }, | ||
| 289 | { } | ||
| 290 | }; | ||
| 291 | MODULE_DEVICE_TABLE(i2c, abx80x_id); | ||
| 292 | |||
| 293 | static struct i2c_driver abx80x_driver = { | ||
| 294 | .driver = { | ||
| 295 | .name = "rtc-abx80x", | ||
| 296 | }, | ||
| 297 | .probe = abx80x_probe, | ||
| 298 | .remove = abx80x_remove, | ||
| 299 | .id_table = abx80x_id, | ||
| 300 | }; | ||
| 301 | |||
| 302 | module_i2c_driver(abx80x_driver); | ||
| 303 | |||
| 304 | MODULE_AUTHOR("Philippe De Muyter <phdm@macqel.be>"); | ||
| 305 | MODULE_AUTHOR("Alexandre Belloni <alexandre.belloni@free-electrons.com>"); | ||
| 306 | MODULE_DESCRIPTION("Abracon ABX80X RTC driver"); | ||
| 307 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/rtc/rtc-armada38x.c b/drivers/rtc/rtc-armada38x.c index 43e04af39e09..4b62d1a875e4 100644 --- a/drivers/rtc/rtc-armada38x.c +++ b/drivers/rtc/rtc-armada38x.c | |||
| @@ -40,6 +40,13 @@ struct armada38x_rtc { | |||
| 40 | void __iomem *regs; | 40 | void __iomem *regs; |
| 41 | void __iomem *regs_soc; | 41 | void __iomem *regs_soc; |
| 42 | spinlock_t lock; | 42 | spinlock_t lock; |
| 43 | /* | ||
| 44 | * While setting the time, the RTC TIME register should not be | ||
| 45 | * accessed. Setting the RTC time involves sleeping during | ||
| 46 | * 100ms, so a mutex instead of a spinlock is used to protect | ||
| 47 | * it | ||
| 48 | */ | ||
| 49 | struct mutex mutex_time; | ||
| 43 | int irq; | 50 | int irq; |
| 44 | }; | 51 | }; |
| 45 | 52 | ||
| @@ -57,10 +64,9 @@ static void rtc_delayed_write(u32 val, struct armada38x_rtc *rtc, int offset) | |||
| 57 | static int armada38x_rtc_read_time(struct device *dev, struct rtc_time *tm) | 64 | static int armada38x_rtc_read_time(struct device *dev, struct rtc_time *tm) |
| 58 | { | 65 | { |
| 59 | struct armada38x_rtc *rtc = dev_get_drvdata(dev); | 66 | struct armada38x_rtc *rtc = dev_get_drvdata(dev); |
| 60 | unsigned long time, time_check, flags; | 67 | unsigned long time, time_check; |
| 61 | |||
| 62 | spin_lock_irqsave(&rtc->lock, flags); | ||
| 63 | 68 | ||
| 69 | mutex_lock(&rtc->mutex_time); | ||
| 64 | time = readl(rtc->regs + RTC_TIME); | 70 | time = readl(rtc->regs + RTC_TIME); |
| 65 | /* | 71 | /* |
| 66 | * WA for failing time set attempts. As stated in HW ERRATA if | 72 | * WA for failing time set attempts. As stated in HW ERRATA if |
| @@ -71,7 +77,7 @@ static int armada38x_rtc_read_time(struct device *dev, struct rtc_time *tm) | |||
| 71 | if ((time_check - time) > 1) | 77 | if ((time_check - time) > 1) |
| 72 | time_check = readl(rtc->regs + RTC_TIME); | 78 | time_check = readl(rtc->regs + RTC_TIME); |
| 73 | 79 | ||
| 74 | spin_unlock_irqrestore(&rtc->lock, flags); | 80 | mutex_unlock(&rtc->mutex_time); |
| 75 | 81 | ||
| 76 | rtc_time_to_tm(time_check, tm); | 82 | rtc_time_to_tm(time_check, tm); |
| 77 | 83 | ||
| @@ -94,19 +100,12 @@ static int armada38x_rtc_set_time(struct device *dev, struct rtc_time *tm) | |||
| 94 | * then wait for 100ms before writing to the time register to be | 100 | * then wait for 100ms before writing to the time register to be |
| 95 | * sure that the data will be taken into account. | 101 | * sure that the data will be taken into account. |
| 96 | */ | 102 | */ |
| 97 | spin_lock_irqsave(&rtc->lock, flags); | 103 | mutex_lock(&rtc->mutex_time); |
| 98 | |||
| 99 | rtc_delayed_write(0, rtc, RTC_STATUS); | 104 | rtc_delayed_write(0, rtc, RTC_STATUS); |
| 100 | |||
| 101 | spin_unlock_irqrestore(&rtc->lock, flags); | ||
| 102 | |||
| 103 | msleep(100); | 105 | msleep(100); |
| 104 | |||
| 105 | spin_lock_irqsave(&rtc->lock, flags); | ||
| 106 | |||
| 107 | rtc_delayed_write(time, rtc, RTC_TIME); | 106 | rtc_delayed_write(time, rtc, RTC_TIME); |
| 107 | mutex_unlock(&rtc->mutex_time); | ||
| 108 | 108 | ||
| 109 | spin_unlock_irqrestore(&rtc->lock, flags); | ||
| 110 | out: | 109 | out: |
| 111 | return ret; | 110 | return ret; |
| 112 | } | 111 | } |
| @@ -230,6 +229,7 @@ static __init int armada38x_rtc_probe(struct platform_device *pdev) | |||
| 230 | return -ENOMEM; | 229 | return -ENOMEM; |
| 231 | 230 | ||
| 232 | spin_lock_init(&rtc->lock); | 231 | spin_lock_init(&rtc->lock); |
| 232 | mutex_init(&rtc->mutex_time); | ||
| 233 | 233 | ||
| 234 | res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "rtc"); | 234 | res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "rtc"); |
| 235 | rtc->regs = devm_ioremap_resource(&pdev->dev, res); | 235 | rtc->regs = devm_ioremap_resource(&pdev->dev, res); |
diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig index 198f96b7fb45..72b059081559 100644 --- a/drivers/spi/Kconfig +++ b/drivers/spi/Kconfig | |||
| @@ -78,6 +78,7 @@ config SPI_ATMEL | |||
| 78 | config SPI_BCM2835 | 78 | config SPI_BCM2835 |
| 79 | tristate "BCM2835 SPI controller" | 79 | tristate "BCM2835 SPI controller" |
| 80 | depends on ARCH_BCM2835 || COMPILE_TEST | 80 | depends on ARCH_BCM2835 || COMPILE_TEST |
| 81 | depends on GPIOLIB | ||
| 81 | help | 82 | help |
| 82 | This selects a driver for the Broadcom BCM2835 SPI master. | 83 | This selects a driver for the Broadcom BCM2835 SPI master. |
| 83 | 84 | ||
| @@ -302,7 +303,7 @@ config SPI_FSL_SPI | |||
| 302 | config SPI_FSL_DSPI | 303 | config SPI_FSL_DSPI |
| 303 | tristate "Freescale DSPI controller" | 304 | tristate "Freescale DSPI controller" |
| 304 | select REGMAP_MMIO | 305 | select REGMAP_MMIO |
| 305 | depends on SOC_VF610 || COMPILE_TEST | 306 | depends on SOC_VF610 || SOC_LS1021A || COMPILE_TEST |
| 306 | help | 307 | help |
| 307 | This enables support for the Freescale DSPI controller in master | 308 | This enables support for the Freescale DSPI controller in master |
| 308 | mode. VF610 platform uses the controller. | 309 | mode. VF610 platform uses the controller. |
diff --git a/drivers/spi/spi-bcm2835.c b/drivers/spi/spi-bcm2835.c index f63864a893c5..37875cf942f7 100644 --- a/drivers/spi/spi-bcm2835.c +++ b/drivers/spi/spi-bcm2835.c | |||
| @@ -164,13 +164,12 @@ static int bcm2835_spi_transfer_one_poll(struct spi_master *master, | |||
| 164 | unsigned long xfer_time_us) | 164 | unsigned long xfer_time_us) |
| 165 | { | 165 | { |
| 166 | struct bcm2835_spi *bs = spi_master_get_devdata(master); | 166 | struct bcm2835_spi *bs = spi_master_get_devdata(master); |
| 167 | unsigned long timeout = jiffies + | 167 | /* set timeout to 1 second of maximum polling */ |
| 168 | max(4 * xfer_time_us * HZ / 1000000, 2uL); | 168 | unsigned long timeout = jiffies + HZ; |
| 169 | 169 | ||
| 170 | /* enable HW block without interrupts */ | 170 | /* enable HW block without interrupts */ |
| 171 | bcm2835_wr(bs, BCM2835_SPI_CS, cs | BCM2835_SPI_CS_TA); | 171 | bcm2835_wr(bs, BCM2835_SPI_CS, cs | BCM2835_SPI_CS_TA); |
| 172 | 172 | ||
| 173 | /* set timeout to 4x the expected time, or 2 jiffies */ | ||
| 174 | /* loop until finished the transfer */ | 173 | /* loop until finished the transfer */ |
| 175 | while (bs->rx_len) { | 174 | while (bs->rx_len) { |
| 176 | /* read from fifo as much as possible */ | 175 | /* read from fifo as much as possible */ |
diff --git a/drivers/spi/spi-bitbang.c b/drivers/spi/spi-bitbang.c index 5ef6638d5e8a..840a4984d365 100644 --- a/drivers/spi/spi-bitbang.c +++ b/drivers/spi/spi-bitbang.c | |||
| @@ -180,7 +180,6 @@ int spi_bitbang_setup(struct spi_device *spi) | |||
| 180 | { | 180 | { |
| 181 | struct spi_bitbang_cs *cs = spi->controller_state; | 181 | struct spi_bitbang_cs *cs = spi->controller_state; |
| 182 | struct spi_bitbang *bitbang; | 182 | struct spi_bitbang *bitbang; |
| 183 | int retval; | ||
| 184 | unsigned long flags; | 183 | unsigned long flags; |
| 185 | 184 | ||
| 186 | bitbang = spi_master_get_devdata(spi->master); | 185 | bitbang = spi_master_get_devdata(spi->master); |
| @@ -197,9 +196,11 @@ int spi_bitbang_setup(struct spi_device *spi) | |||
| 197 | if (!cs->txrx_word) | 196 | if (!cs->txrx_word) |
| 198 | return -EINVAL; | 197 | return -EINVAL; |
| 199 | 198 | ||
| 200 | retval = bitbang->setup_transfer(spi, NULL); | 199 | if (bitbang->setup_transfer) { |
| 201 | if (retval < 0) | 200 | int retval = bitbang->setup_transfer(spi, NULL); |
| 202 | return retval; | 201 | if (retval < 0) |
| 202 | return retval; | ||
| 203 | } | ||
| 203 | 204 | ||
| 204 | dev_dbg(&spi->dev, "%s, %u nsec/bit\n", __func__, 2 * cs->nsecs); | 205 | dev_dbg(&spi->dev, "%s, %u nsec/bit\n", __func__, 2 * cs->nsecs); |
| 205 | 206 | ||
| @@ -295,9 +296,11 @@ static int spi_bitbang_transfer_one(struct spi_master *master, | |||
| 295 | 296 | ||
| 296 | /* init (-1) or override (1) transfer params */ | 297 | /* init (-1) or override (1) transfer params */ |
| 297 | if (do_setup != 0) { | 298 | if (do_setup != 0) { |
| 298 | status = bitbang->setup_transfer(spi, t); | 299 | if (bitbang->setup_transfer) { |
| 299 | if (status < 0) | 300 | status = bitbang->setup_transfer(spi, t); |
| 300 | break; | 301 | if (status < 0) |
| 302 | break; | ||
| 303 | } | ||
| 301 | if (do_setup == -1) | 304 | if (do_setup == -1) |
| 302 | do_setup = 0; | 305 | do_setup = 0; |
| 303 | } | 306 | } |
diff --git a/drivers/spi/spi-fsl-cpm.c b/drivers/spi/spi-fsl-cpm.c index 9c46a3058743..896add8cfd3b 100644 --- a/drivers/spi/spi-fsl-cpm.c +++ b/drivers/spi/spi-fsl-cpm.c | |||
| @@ -24,6 +24,7 @@ | |||
| 24 | #include <linux/of_address.h> | 24 | #include <linux/of_address.h> |
| 25 | #include <linux/spi/spi.h> | 25 | #include <linux/spi/spi.h> |
| 26 | #include <linux/types.h> | 26 | #include <linux/types.h> |
| 27 | #include <linux/platform_device.h> | ||
| 27 | 28 | ||
| 28 | #include "spi-fsl-cpm.h" | 29 | #include "spi-fsl-cpm.h" |
| 29 | #include "spi-fsl-lib.h" | 30 | #include "spi-fsl-lib.h" |
| @@ -269,17 +270,6 @@ static unsigned long fsl_spi_cpm_get_pram(struct mpc8xxx_spi *mspi) | |||
| 269 | if (mspi->flags & SPI_CPM2) { | 270 | if (mspi->flags & SPI_CPM2) { |
| 270 | pram_ofs = cpm_muram_alloc(SPI_PRAM_SIZE, 64); | 271 | pram_ofs = cpm_muram_alloc(SPI_PRAM_SIZE, 64); |
| 271 | out_be16(spi_base, pram_ofs); | 272 | out_be16(spi_base, pram_ofs); |
| 272 | } else { | ||
| 273 | struct spi_pram __iomem *pram = spi_base; | ||
| 274 | u16 rpbase = in_be16(&pram->rpbase); | ||
| 275 | |||
| 276 | /* Microcode relocation patch applied? */ | ||
| 277 | if (rpbase) { | ||
| 278 | pram_ofs = rpbase; | ||
| 279 | } else { | ||
| 280 | pram_ofs = cpm_muram_alloc(SPI_PRAM_SIZE, 64); | ||
| 281 | out_be16(spi_base, pram_ofs); | ||
| 282 | } | ||
| 283 | } | 273 | } |
| 284 | 274 | ||
| 285 | iounmap(spi_base); | 275 | iounmap(spi_base); |
| @@ -292,7 +282,6 @@ int fsl_spi_cpm_init(struct mpc8xxx_spi *mspi) | |||
| 292 | struct device_node *np = dev->of_node; | 282 | struct device_node *np = dev->of_node; |
| 293 | const u32 *iprop; | 283 | const u32 *iprop; |
| 294 | int size; | 284 | int size; |
| 295 | unsigned long pram_ofs; | ||
| 296 | unsigned long bds_ofs; | 285 | unsigned long bds_ofs; |
| 297 | 286 | ||
| 298 | if (!(mspi->flags & SPI_CPM_MODE)) | 287 | if (!(mspi->flags & SPI_CPM_MODE)) |
| @@ -319,8 +308,26 @@ int fsl_spi_cpm_init(struct mpc8xxx_spi *mspi) | |||
| 319 | } | 308 | } |
| 320 | } | 309 | } |
| 321 | 310 | ||
| 322 | pram_ofs = fsl_spi_cpm_get_pram(mspi); | 311 | if (mspi->flags & SPI_CPM1) { |
| 323 | if (IS_ERR_VALUE(pram_ofs)) { | 312 | struct resource *res; |
| 313 | void *pram; | ||
| 314 | |||
| 315 | res = platform_get_resource(to_platform_device(dev), | ||
| 316 | IORESOURCE_MEM, 1); | ||
| 317 | pram = devm_ioremap_resource(dev, res); | ||
| 318 | if (IS_ERR(pram)) | ||
| 319 | mspi->pram = NULL; | ||
| 320 | else | ||
| 321 | mspi->pram = pram; | ||
| 322 | } else { | ||
| 323 | unsigned long pram_ofs = fsl_spi_cpm_get_pram(mspi); | ||
| 324 | |||
| 325 | if (IS_ERR_VALUE(pram_ofs)) | ||
| 326 | mspi->pram = NULL; | ||
| 327 | else | ||
| 328 | mspi->pram = cpm_muram_addr(pram_ofs); | ||
| 329 | } | ||
| 330 | if (mspi->pram == NULL) { | ||
| 324 | dev_err(dev, "can't allocate spi parameter ram\n"); | 331 | dev_err(dev, "can't allocate spi parameter ram\n"); |
| 325 | goto err_pram; | 332 | goto err_pram; |
| 326 | } | 333 | } |
| @@ -346,8 +353,6 @@ int fsl_spi_cpm_init(struct mpc8xxx_spi *mspi) | |||
| 346 | goto err_dummy_rx; | 353 | goto err_dummy_rx; |
| 347 | } | 354 | } |
| 348 | 355 | ||
| 349 | mspi->pram = cpm_muram_addr(pram_ofs); | ||
| 350 | |||
| 351 | mspi->tx_bd = cpm_muram_addr(bds_ofs); | 356 | mspi->tx_bd = cpm_muram_addr(bds_ofs); |
| 352 | mspi->rx_bd = cpm_muram_addr(bds_ofs + sizeof(*mspi->tx_bd)); | 357 | mspi->rx_bd = cpm_muram_addr(bds_ofs + sizeof(*mspi->tx_bd)); |
| 353 | 358 | ||
| @@ -375,7 +380,8 @@ err_dummy_rx: | |||
| 375 | err_dummy_tx: | 380 | err_dummy_tx: |
| 376 | cpm_muram_free(bds_ofs); | 381 | cpm_muram_free(bds_ofs); |
| 377 | err_bds: | 382 | err_bds: |
| 378 | cpm_muram_free(pram_ofs); | 383 | if (!(mspi->flags & SPI_CPM1)) |
| 384 | cpm_muram_free(cpm_muram_offset(mspi->pram)); | ||
| 379 | err_pram: | 385 | err_pram: |
| 380 | fsl_spi_free_dummy_rx(); | 386 | fsl_spi_free_dummy_rx(); |
| 381 | return -ENOMEM; | 387 | return -ENOMEM; |
diff --git a/drivers/spi/spi-fsl-espi.c b/drivers/spi/spi-fsl-espi.c index d0a73a09a9bd..80d245ac846f 100644 --- a/drivers/spi/spi-fsl-espi.c +++ b/drivers/spi/spi-fsl-espi.c | |||
| @@ -359,14 +359,16 @@ static void fsl_espi_rw_trans(struct spi_message *m, | |||
| 359 | struct fsl_espi_transfer *trans, u8 *rx_buff) | 359 | struct fsl_espi_transfer *trans, u8 *rx_buff) |
| 360 | { | 360 | { |
| 361 | struct fsl_espi_transfer *espi_trans = trans; | 361 | struct fsl_espi_transfer *espi_trans = trans; |
| 362 | unsigned int n_tx = espi_trans->n_tx; | 362 | unsigned int total_len = espi_trans->len; |
| 363 | unsigned int n_rx = espi_trans->n_rx; | ||
| 364 | struct spi_transfer *t; | 363 | struct spi_transfer *t; |
| 365 | u8 *local_buf; | 364 | u8 *local_buf; |
| 366 | u8 *rx_buf = rx_buff; | 365 | u8 *rx_buf = rx_buff; |
| 367 | unsigned int trans_len; | 366 | unsigned int trans_len; |
| 368 | unsigned int addr; | 367 | unsigned int addr; |
| 369 | int i, pos, loop; | 368 | unsigned int tx_only; |
| 369 | unsigned int rx_pos = 0; | ||
| 370 | unsigned int pos; | ||
| 371 | int i, loop; | ||
| 370 | 372 | ||
| 371 | local_buf = kzalloc(SPCOM_TRANLEN_MAX, GFP_KERNEL); | 373 | local_buf = kzalloc(SPCOM_TRANLEN_MAX, GFP_KERNEL); |
| 372 | if (!local_buf) { | 374 | if (!local_buf) { |
| @@ -374,36 +376,48 @@ static void fsl_espi_rw_trans(struct spi_message *m, | |||
| 374 | return; | 376 | return; |
| 375 | } | 377 | } |
| 376 | 378 | ||
| 377 | for (pos = 0, loop = 0; pos < n_rx; pos += trans_len, loop++) { | 379 | for (pos = 0, loop = 0; pos < total_len; pos += trans_len, loop++) { |
| 378 | trans_len = n_rx - pos; | 380 | trans_len = total_len - pos; |
| 379 | if (trans_len > SPCOM_TRANLEN_MAX - n_tx) | ||
| 380 | trans_len = SPCOM_TRANLEN_MAX - n_tx; | ||
| 381 | 381 | ||
| 382 | i = 0; | 382 | i = 0; |
| 383 | tx_only = 0; | ||
| 383 | list_for_each_entry(t, &m->transfers, transfer_list) { | 384 | list_for_each_entry(t, &m->transfers, transfer_list) { |
| 384 | if (t->tx_buf) { | 385 | if (t->tx_buf) { |
| 385 | memcpy(local_buf + i, t->tx_buf, t->len); | 386 | memcpy(local_buf + i, t->tx_buf, t->len); |
| 386 | i += t->len; | 387 | i += t->len; |
| 388 | if (!t->rx_buf) | ||
| 389 | tx_only += t->len; | ||
| 387 | } | 390 | } |
| 388 | } | 391 | } |
| 389 | 392 | ||
| 393 | /* Add additional TX bytes to compensate SPCOM_TRANLEN_MAX */ | ||
| 394 | if (loop > 0) | ||
| 395 | trans_len += tx_only; | ||
| 396 | |||
| 397 | if (trans_len > SPCOM_TRANLEN_MAX) | ||
| 398 | trans_len = SPCOM_TRANLEN_MAX; | ||
| 399 | |||
| 400 | /* Update device offset */ | ||
| 390 | if (pos > 0) { | 401 | if (pos > 0) { |
| 391 | addr = fsl_espi_cmd2addr(local_buf); | 402 | addr = fsl_espi_cmd2addr(local_buf); |
| 392 | addr += pos; | 403 | addr += rx_pos; |
| 393 | fsl_espi_addr2cmd(addr, local_buf); | 404 | fsl_espi_addr2cmd(addr, local_buf); |
| 394 | } | 405 | } |
| 395 | 406 | ||
| 396 | espi_trans->n_tx = n_tx; | 407 | espi_trans->len = trans_len; |
| 397 | espi_trans->n_rx = trans_len; | ||
| 398 | espi_trans->len = trans_len + n_tx; | ||
| 399 | espi_trans->tx_buf = local_buf; | 408 | espi_trans->tx_buf = local_buf; |
| 400 | espi_trans->rx_buf = local_buf; | 409 | espi_trans->rx_buf = local_buf; |
| 401 | fsl_espi_do_trans(m, espi_trans); | 410 | fsl_espi_do_trans(m, espi_trans); |
| 402 | 411 | ||
| 403 | memcpy(rx_buf + pos, espi_trans->rx_buf + n_tx, trans_len); | 412 | /* If there is at least one RX byte then copy it to rx_buf */ |
| 413 | if (tx_only < SPCOM_TRANLEN_MAX) | ||
| 414 | memcpy(rx_buf + rx_pos, espi_trans->rx_buf + tx_only, | ||
| 415 | trans_len - tx_only); | ||
| 416 | |||
| 417 | rx_pos += trans_len - tx_only; | ||
| 404 | 418 | ||
| 405 | if (loop > 0) | 419 | if (loop > 0) |
| 406 | espi_trans->actual_length += espi_trans->len - n_tx; | 420 | espi_trans->actual_length += espi_trans->len - tx_only; |
| 407 | else | 421 | else |
| 408 | espi_trans->actual_length += espi_trans->len; | 422 | espi_trans->actual_length += espi_trans->len; |
| 409 | } | 423 | } |
| @@ -418,6 +432,7 @@ static int fsl_espi_do_one_msg(struct spi_master *master, | |||
| 418 | u8 *rx_buf = NULL; | 432 | u8 *rx_buf = NULL; |
| 419 | unsigned int n_tx = 0; | 433 | unsigned int n_tx = 0; |
| 420 | unsigned int n_rx = 0; | 434 | unsigned int n_rx = 0; |
| 435 | unsigned int xfer_len = 0; | ||
| 421 | struct fsl_espi_transfer espi_trans; | 436 | struct fsl_espi_transfer espi_trans; |
| 422 | 437 | ||
| 423 | list_for_each_entry(t, &m->transfers, transfer_list) { | 438 | list_for_each_entry(t, &m->transfers, transfer_list) { |
| @@ -427,11 +442,13 @@ static int fsl_espi_do_one_msg(struct spi_master *master, | |||
| 427 | n_rx += t->len; | 442 | n_rx += t->len; |
| 428 | rx_buf = t->rx_buf; | 443 | rx_buf = t->rx_buf; |
| 429 | } | 444 | } |
| 445 | if ((t->tx_buf) || (t->rx_buf)) | ||
| 446 | xfer_len += t->len; | ||
| 430 | } | 447 | } |
| 431 | 448 | ||
| 432 | espi_trans.n_tx = n_tx; | 449 | espi_trans.n_tx = n_tx; |
| 433 | espi_trans.n_rx = n_rx; | 450 | espi_trans.n_rx = n_rx; |
| 434 | espi_trans.len = n_tx + n_rx; | 451 | espi_trans.len = xfer_len; |
| 435 | espi_trans.actual_length = 0; | 452 | espi_trans.actual_length = 0; |
| 436 | espi_trans.status = 0; | 453 | espi_trans.status = 0; |
| 437 | 454 | ||
diff --git a/drivers/spi/spi-omap2-mcspi.c b/drivers/spi/spi-omap2-mcspi.c index 4df8942058de..d1a5b9fc3eba 100644 --- a/drivers/spi/spi-omap2-mcspi.c +++ b/drivers/spi/spi-omap2-mcspi.c | |||
| @@ -1210,6 +1210,7 @@ static int omap2_mcspi_transfer_one_message(struct spi_master *master, | |||
| 1210 | struct omap2_mcspi *mcspi; | 1210 | struct omap2_mcspi *mcspi; |
| 1211 | struct omap2_mcspi_dma *mcspi_dma; | 1211 | struct omap2_mcspi_dma *mcspi_dma; |
| 1212 | struct spi_transfer *t; | 1212 | struct spi_transfer *t; |
| 1213 | int status; | ||
| 1213 | 1214 | ||
| 1214 | spi = m->spi; | 1215 | spi = m->spi; |
| 1215 | mcspi = spi_master_get_devdata(master); | 1216 | mcspi = spi_master_get_devdata(master); |
| @@ -1229,7 +1230,8 @@ static int omap2_mcspi_transfer_one_message(struct spi_master *master, | |||
| 1229 | tx_buf ? "tx" : "", | 1230 | tx_buf ? "tx" : "", |
| 1230 | rx_buf ? "rx" : "", | 1231 | rx_buf ? "rx" : "", |
| 1231 | t->bits_per_word); | 1232 | t->bits_per_word); |
| 1232 | return -EINVAL; | 1233 | status = -EINVAL; |
| 1234 | goto out; | ||
| 1233 | } | 1235 | } |
| 1234 | 1236 | ||
| 1235 | if (m->is_dma_mapped || len < DMA_MIN_BYTES) | 1237 | if (m->is_dma_mapped || len < DMA_MIN_BYTES) |
| @@ -1241,7 +1243,8 @@ static int omap2_mcspi_transfer_one_message(struct spi_master *master, | |||
| 1241 | if (dma_mapping_error(mcspi->dev, t->tx_dma)) { | 1243 | if (dma_mapping_error(mcspi->dev, t->tx_dma)) { |
| 1242 | dev_dbg(mcspi->dev, "dma %cX %d bytes error\n", | 1244 | dev_dbg(mcspi->dev, "dma %cX %d bytes error\n", |
| 1243 | 'T', len); | 1245 | 'T', len); |
| 1244 | return -EINVAL; | 1246 | status = -EINVAL; |
| 1247 | goto out; | ||
| 1245 | } | 1248 | } |
| 1246 | } | 1249 | } |
| 1247 | if (mcspi_dma->dma_rx && rx_buf != NULL) { | 1250 | if (mcspi_dma->dma_rx && rx_buf != NULL) { |
| @@ -1253,14 +1256,19 @@ static int omap2_mcspi_transfer_one_message(struct spi_master *master, | |||
| 1253 | if (tx_buf != NULL) | 1256 | if (tx_buf != NULL) |
| 1254 | dma_unmap_single(mcspi->dev, t->tx_dma, | 1257 | dma_unmap_single(mcspi->dev, t->tx_dma, |
| 1255 | len, DMA_TO_DEVICE); | 1258 | len, DMA_TO_DEVICE); |
| 1256 | return -EINVAL; | 1259 | status = -EINVAL; |
| 1260 | goto out; | ||
| 1257 | } | 1261 | } |
| 1258 | } | 1262 | } |
| 1259 | } | 1263 | } |
| 1260 | 1264 | ||
| 1261 | omap2_mcspi_work(mcspi, m); | 1265 | omap2_mcspi_work(mcspi, m); |
| 1266 | /* spi_finalize_current_message() changes the status inside the | ||
| 1267 | * spi_message, save the status here. */ | ||
| 1268 | status = m->status; | ||
| 1269 | out: | ||
| 1262 | spi_finalize_current_message(master); | 1270 | spi_finalize_current_message(master); |
| 1263 | return 0; | 1271 | return status; |
| 1264 | } | 1272 | } |
| 1265 | 1273 | ||
| 1266 | static int omap2_mcspi_master_setup(struct omap2_mcspi *mcspi) | 1274 | static int omap2_mcspi_master_setup(struct omap2_mcspi *mcspi) |
diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c index d5d7d2235163..50910d85df5a 100644 --- a/drivers/spi/spi.c +++ b/drivers/spi/spi.c | |||
| @@ -583,6 +583,15 @@ static int spi_unmap_msg(struct spi_master *master, struct spi_message *msg) | |||
| 583 | rx_dev = master->dma_rx->device->dev; | 583 | rx_dev = master->dma_rx->device->dev; |
| 584 | 584 | ||
| 585 | list_for_each_entry(xfer, &msg->transfers, transfer_list) { | 585 | list_for_each_entry(xfer, &msg->transfers, transfer_list) { |
| 586 | /* | ||
| 587 | * Restore the original value of tx_buf or rx_buf if they are | ||
| 588 | * NULL. | ||
| 589 | */ | ||
| 590 | if (xfer->tx_buf == master->dummy_tx) | ||
| 591 | xfer->tx_buf = NULL; | ||
| 592 | if (xfer->rx_buf == master->dummy_rx) | ||
| 593 | xfer->rx_buf = NULL; | ||
| 594 | |||
| 586 | if (!master->can_dma(master, msg->spi, xfer)) | 595 | if (!master->can_dma(master, msg->spi, xfer)) |
| 587 | continue; | 596 | continue; |
| 588 | 597 | ||
diff --git a/drivers/staging/gdm724x/gdm_mux.c b/drivers/staging/gdm724x/gdm_mux.c index 8199b0a697bb..1cf24e4edf25 100644 --- a/drivers/staging/gdm724x/gdm_mux.c +++ b/drivers/staging/gdm724x/gdm_mux.c | |||
| @@ -158,7 +158,7 @@ static int up_to_host(struct mux_rx *r) | |||
| 158 | unsigned int start_flag; | 158 | unsigned int start_flag; |
| 159 | unsigned int payload_size; | 159 | unsigned int payload_size; |
| 160 | unsigned short packet_type; | 160 | unsigned short packet_type; |
| 161 | int dummy_cnt; | 161 | int total_len; |
| 162 | u32 packet_size_sum = r->offset; | 162 | u32 packet_size_sum = r->offset; |
| 163 | int index; | 163 | int index; |
| 164 | int ret = TO_HOST_INVALID_PACKET; | 164 | int ret = TO_HOST_INVALID_PACKET; |
| @@ -176,10 +176,10 @@ static int up_to_host(struct mux_rx *r) | |||
| 176 | break; | 176 | break; |
| 177 | } | 177 | } |
| 178 | 178 | ||
| 179 | dummy_cnt = ALIGN(MUX_HEADER_SIZE + payload_size, 4); | 179 | total_len = ALIGN(MUX_HEADER_SIZE + payload_size, 4); |
| 180 | 180 | ||
| 181 | if (len - packet_size_sum < | 181 | if (len - packet_size_sum < |
| 182 | MUX_HEADER_SIZE + payload_size + dummy_cnt) { | 182 | total_len) { |
| 183 | pr_err("invalid payload : %d %d %04x\n", | 183 | pr_err("invalid payload : %d %d %04x\n", |
| 184 | payload_size, len, packet_type); | 184 | payload_size, len, packet_type); |
| 185 | break; | 185 | break; |
| @@ -202,7 +202,7 @@ static int up_to_host(struct mux_rx *r) | |||
| 202 | break; | 202 | break; |
| 203 | } | 203 | } |
| 204 | 204 | ||
| 205 | packet_size_sum += MUX_HEADER_SIZE + payload_size + dummy_cnt; | 205 | packet_size_sum += total_len; |
| 206 | if (len - packet_size_sum <= MUX_HEADER_SIZE + 2) { | 206 | if (len - packet_size_sum <= MUX_HEADER_SIZE + 2) { |
| 207 | ret = r->callback(NULL, | 207 | ret = r->callback(NULL, |
| 208 | 0, | 208 | 0, |
| @@ -361,7 +361,6 @@ static int gdm_mux_send(void *priv_dev, void *data, int len, int tty_index, | |||
| 361 | struct mux_pkt_header *mux_header; | 361 | struct mux_pkt_header *mux_header; |
| 362 | struct mux_tx *t = NULL; | 362 | struct mux_tx *t = NULL; |
| 363 | static u32 seq_num = 1; | 363 | static u32 seq_num = 1; |
| 364 | int dummy_cnt; | ||
| 365 | int total_len; | 364 | int total_len; |
| 366 | int ret; | 365 | int ret; |
| 367 | unsigned long flags; | 366 | unsigned long flags; |
| @@ -374,9 +373,7 @@ static int gdm_mux_send(void *priv_dev, void *data, int len, int tty_index, | |||
| 374 | 373 | ||
| 375 | spin_lock_irqsave(&mux_dev->write_lock, flags); | 374 | spin_lock_irqsave(&mux_dev->write_lock, flags); |
| 376 | 375 | ||
| 377 | dummy_cnt = ALIGN(MUX_HEADER_SIZE + len, 4); | 376 | total_len = ALIGN(MUX_HEADER_SIZE + len, 4); |
| 378 | |||
| 379 | total_len = len + MUX_HEADER_SIZE + dummy_cnt; | ||
| 380 | 377 | ||
| 381 | t = alloc_mux_tx(total_len); | 378 | t = alloc_mux_tx(total_len); |
| 382 | if (!t) { | 379 | if (!t) { |
| @@ -392,7 +389,8 @@ static int gdm_mux_send(void *priv_dev, void *data, int len, int tty_index, | |||
| 392 | mux_header->packet_type = __cpu_to_le16(packet_type[tty_index]); | 389 | mux_header->packet_type = __cpu_to_le16(packet_type[tty_index]); |
| 393 | 390 | ||
| 394 | memcpy(t->buf+MUX_HEADER_SIZE, data, len); | 391 | memcpy(t->buf+MUX_HEADER_SIZE, data, len); |
| 395 | memset(t->buf+MUX_HEADER_SIZE+len, 0, dummy_cnt); | 392 | memset(t->buf+MUX_HEADER_SIZE+len, 0, total_len - MUX_HEADER_SIZE - |
| 393 | len); | ||
| 396 | 394 | ||
| 397 | t->len = total_len; | 395 | t->len = total_len; |
| 398 | t->callback = cb; | 396 | t->callback = cb; |
diff --git a/drivers/staging/media/omap4iss/Kconfig b/drivers/staging/media/omap4iss/Kconfig index b78643f907e7..072dac04a750 100644 --- a/drivers/staging/media/omap4iss/Kconfig +++ b/drivers/staging/media/omap4iss/Kconfig | |||
| @@ -2,6 +2,7 @@ config VIDEO_OMAP4 | |||
| 2 | bool "OMAP 4 Camera support" | 2 | bool "OMAP 4 Camera support" |
| 3 | depends on VIDEO_V4L2=y && VIDEO_V4L2_SUBDEV_API && I2C=y && ARCH_OMAP4 | 3 | depends on VIDEO_V4L2=y && VIDEO_V4L2_SUBDEV_API && I2C=y && ARCH_OMAP4 |
| 4 | depends on HAS_DMA | 4 | depends on HAS_DMA |
| 5 | select MFD_SYSCON | ||
| 5 | select VIDEOBUF2_DMA_CONTIG | 6 | select VIDEOBUF2_DMA_CONTIG |
| 6 | ---help--- | 7 | ---help--- |
| 7 | Driver for an OMAP 4 ISS controller. | 8 | Driver for an OMAP 4 ISS controller. |
diff --git a/drivers/staging/media/omap4iss/iss.c b/drivers/staging/media/omap4iss/iss.c index e0ad5e520e2d..7ced940bd807 100644 --- a/drivers/staging/media/omap4iss/iss.c +++ b/drivers/staging/media/omap4iss/iss.c | |||
| @@ -17,6 +17,7 @@ | |||
| 17 | #include <linux/dma-mapping.h> | 17 | #include <linux/dma-mapping.h> |
| 18 | #include <linux/i2c.h> | 18 | #include <linux/i2c.h> |
| 19 | #include <linux/interrupt.h> | 19 | #include <linux/interrupt.h> |
| 20 | #include <linux/mfd/syscon.h> | ||
| 20 | #include <linux/module.h> | 21 | #include <linux/module.h> |
| 21 | #include <linux/platform_device.h> | 22 | #include <linux/platform_device.h> |
| 22 | #include <linux/slab.h> | 23 | #include <linux/slab.h> |
| @@ -1386,6 +1387,16 @@ static int iss_probe(struct platform_device *pdev) | |||
| 1386 | 1387 | ||
| 1387 | platform_set_drvdata(pdev, iss); | 1388 | platform_set_drvdata(pdev, iss); |
| 1388 | 1389 | ||
| 1390 | /* | ||
| 1391 | * TODO: When implementing DT support switch to syscon regmap lookup by | ||
| 1392 | * phandle. | ||
| 1393 | */ | ||
| 1394 | iss->syscon = syscon_regmap_lookup_by_compatible("syscon"); | ||
| 1395 | if (IS_ERR(iss->syscon)) { | ||
| 1396 | ret = PTR_ERR(iss->syscon); | ||
| 1397 | goto error; | ||
| 1398 | } | ||
| 1399 | |||
| 1389 | /* Clocks */ | 1400 | /* Clocks */ |
| 1390 | ret = iss_map_mem_resource(pdev, iss, OMAP4_ISS_MEM_TOP); | 1401 | ret = iss_map_mem_resource(pdev, iss, OMAP4_ISS_MEM_TOP); |
| 1391 | if (ret < 0) | 1402 | if (ret < 0) |
diff --git a/drivers/staging/media/omap4iss/iss.h b/drivers/staging/media/omap4iss/iss.h index 734cfeeb0314..35df8b4709e6 100644 --- a/drivers/staging/media/omap4iss/iss.h +++ b/drivers/staging/media/omap4iss/iss.h | |||
| @@ -29,6 +29,8 @@ | |||
| 29 | #include "iss_ipipe.h" | 29 | #include "iss_ipipe.h" |
| 30 | #include "iss_resizer.h" | 30 | #include "iss_resizer.h" |
| 31 | 31 | ||
| 32 | struct regmap; | ||
| 33 | |||
| 32 | #define to_iss_device(ptr_module) \ | 34 | #define to_iss_device(ptr_module) \ |
| 33 | container_of(ptr_module, struct iss_device, ptr_module) | 35 | container_of(ptr_module, struct iss_device, ptr_module) |
| 34 | #define to_device(ptr_module) \ | 36 | #define to_device(ptr_module) \ |
| @@ -79,6 +81,7 @@ struct iss_reg { | |||
| 79 | 81 | ||
| 80 | /* | 82 | /* |
| 81 | * struct iss_device - ISS device structure. | 83 | * struct iss_device - ISS device structure. |
| 84 | * @syscon: Regmap for the syscon register space | ||
| 82 | * @crashed: Bitmask of crashed entities (indexed by entity ID) | 85 | * @crashed: Bitmask of crashed entities (indexed by entity ID) |
| 83 | */ | 86 | */ |
| 84 | struct iss_device { | 87 | struct iss_device { |
| @@ -93,6 +96,7 @@ struct iss_device { | |||
| 93 | 96 | ||
| 94 | struct resource *res[OMAP4_ISS_MEM_LAST]; | 97 | struct resource *res[OMAP4_ISS_MEM_LAST]; |
| 95 | void __iomem *regs[OMAP4_ISS_MEM_LAST]; | 98 | void __iomem *regs[OMAP4_ISS_MEM_LAST]; |
| 99 | struct regmap *syscon; | ||
| 96 | 100 | ||
| 97 | u64 raw_dmamask; | 101 | u64 raw_dmamask; |
| 98 | 102 | ||
diff --git a/drivers/staging/media/omap4iss/iss_csiphy.c b/drivers/staging/media/omap4iss/iss_csiphy.c index 7c3d55d811ef..748607f8918f 100644 --- a/drivers/staging/media/omap4iss/iss_csiphy.c +++ b/drivers/staging/media/omap4iss/iss_csiphy.c | |||
| @@ -13,6 +13,7 @@ | |||
| 13 | 13 | ||
| 14 | #include <linux/delay.h> | 14 | #include <linux/delay.h> |
| 15 | #include <linux/device.h> | 15 | #include <linux/device.h> |
| 16 | #include <linux/regmap.h> | ||
| 16 | 17 | ||
| 17 | #include "../../../../arch/arm/mach-omap2/control.h" | 18 | #include "../../../../arch/arm/mach-omap2/control.h" |
| 18 | 19 | ||
| @@ -140,9 +141,11 @@ int omap4iss_csiphy_config(struct iss_device *iss, | |||
| 140 | * - bit [18] : CSIPHY1 CTRLCLK enable | 141 | * - bit [18] : CSIPHY1 CTRLCLK enable |
| 141 | * - bit [17:16] : CSIPHY1 config: 00 d-phy, 01/10 ccp2 | 142 | * - bit [17:16] : CSIPHY1 config: 00 d-phy, 01/10 ccp2 |
| 142 | */ | 143 | */ |
| 143 | cam_rx_ctrl = omap4_ctrl_pad_readl( | 144 | /* |
| 144 | OMAP4_CTRL_MODULE_PAD_CORE_CONTROL_CAMERA_RX); | 145 | * TODO: When implementing DT support specify the CONTROL_CAMERA_RX |
| 145 | 146 | * register offset in the syscon property instead of hardcoding it. | |
| 147 | */ | ||
| 148 | regmap_read(iss->syscon, 0x68, &cam_rx_ctrl); | ||
| 146 | 149 | ||
| 147 | if (subdevs->interface == ISS_INTERFACE_CSI2A_PHY1) { | 150 | if (subdevs->interface == ISS_INTERFACE_CSI2A_PHY1) { |
| 148 | cam_rx_ctrl &= ~(OMAP4_CAMERARX_CSI21_LANEENABLE_MASK | | 151 | cam_rx_ctrl &= ~(OMAP4_CAMERARX_CSI21_LANEENABLE_MASK | |
| @@ -166,8 +169,7 @@ int omap4iss_csiphy_config(struct iss_device *iss, | |||
| 166 | cam_rx_ctrl |= OMAP4_CAMERARX_CSI22_CTRLCLKEN_MASK; | 169 | cam_rx_ctrl |= OMAP4_CAMERARX_CSI22_CTRLCLKEN_MASK; |
| 167 | } | 170 | } |
| 168 | 171 | ||
| 169 | omap4_ctrl_pad_writel(cam_rx_ctrl, | 172 | regmap_write(iss->syscon, 0x68, cam_rx_ctrl); |
| 170 | OMAP4_CTRL_MODULE_PAD_CORE_CONTROL_CAMERA_RX); | ||
| 171 | 173 | ||
| 172 | /* Reset used lane count */ | 174 | /* Reset used lane count */ |
| 173 | csi2->phy->used_data_lanes = 0; | 175 | csi2->phy->used_data_lanes = 0; |
diff --git a/drivers/staging/rtl8712/rtl871x_ioctl_linux.c b/drivers/staging/rtl8712/rtl871x_ioctl_linux.c index 42fba3f5b593..cb0b6387789f 100644 --- a/drivers/staging/rtl8712/rtl871x_ioctl_linux.c +++ b/drivers/staging/rtl8712/rtl871x_ioctl_linux.c | |||
| @@ -1900,23 +1900,20 @@ static int r871x_mp_ioctl_hdl(struct net_device *dev, | |||
| 1900 | struct mp_ioctl_handler *phandler; | 1900 | struct mp_ioctl_handler *phandler; |
| 1901 | struct mp_ioctl_param *poidparam; | 1901 | struct mp_ioctl_param *poidparam; |
| 1902 | unsigned long BytesRead, BytesWritten, BytesNeeded; | 1902 | unsigned long BytesRead, BytesWritten, BytesNeeded; |
| 1903 | u8 *pparmbuf = NULL, bset; | 1903 | u8 *pparmbuf, bset; |
| 1904 | u16 len; | 1904 | u16 len; |
| 1905 | uint status; | 1905 | uint status; |
| 1906 | int ret = 0; | 1906 | int ret = 0; |
| 1907 | 1907 | ||
| 1908 | if ((!p->length) || (!p->pointer)) { | 1908 | if ((!p->length) || (!p->pointer)) |
| 1909 | ret = -EINVAL; | 1909 | return -EINVAL; |
| 1910 | goto _r871x_mp_ioctl_hdl_exit; | 1910 | |
| 1911 | } | ||
| 1912 | bset = (u8)(p->flags & 0xFFFF); | 1911 | bset = (u8)(p->flags & 0xFFFF); |
| 1913 | len = p->length; | 1912 | len = p->length; |
| 1914 | pparmbuf = NULL; | ||
| 1915 | pparmbuf = memdup_user(p->pointer, len); | 1913 | pparmbuf = memdup_user(p->pointer, len); |
| 1916 | if (IS_ERR(pparmbuf)) { | 1914 | if (IS_ERR(pparmbuf)) |
| 1917 | ret = PTR_ERR(pparmbuf); | 1915 | return PTR_ERR(pparmbuf); |
| 1918 | goto _r871x_mp_ioctl_hdl_exit; | 1916 | |
| 1919 | } | ||
| 1920 | poidparam = (struct mp_ioctl_param *)pparmbuf; | 1917 | poidparam = (struct mp_ioctl_param *)pparmbuf; |
| 1921 | if (poidparam->subcode >= MAX_MP_IOCTL_SUBCODE) { | 1918 | if (poidparam->subcode >= MAX_MP_IOCTL_SUBCODE) { |
| 1922 | ret = -EINVAL; | 1919 | ret = -EINVAL; |
diff --git a/drivers/staging/sm750fb/sm750.c b/drivers/staging/sm750fb/sm750.c index 3c7ea95dd9f9..dbbb2f879a29 100644 --- a/drivers/staging/sm750fb/sm750.c +++ b/drivers/staging/sm750fb/sm750.c | |||
| @@ -1250,7 +1250,7 @@ err_enable: | |||
| 1250 | return -ENODEV; | 1250 | return -ENODEV; |
| 1251 | } | 1251 | } |
| 1252 | 1252 | ||
| 1253 | static void __exit lynxfb_pci_remove(struct pci_dev *pdev) | 1253 | static void lynxfb_pci_remove(struct pci_dev *pdev) |
| 1254 | { | 1254 | { |
| 1255 | struct fb_info *info; | 1255 | struct fb_info *info; |
| 1256 | struct lynx_share *share; | 1256 | struct lynx_share *share; |
diff --git a/drivers/staging/vt6655/card.c b/drivers/staging/vt6655/card.c index 1cdcf49b2445..e00c0605d154 100644 --- a/drivers/staging/vt6655/card.c +++ b/drivers/staging/vt6655/card.c | |||
| @@ -362,12 +362,16 @@ bool CARDbSetPhyParameter(struct vnt_private *pDevice, u8 bb_type) | |||
| 362 | * Return Value: none | 362 | * Return Value: none |
| 363 | */ | 363 | */ |
| 364 | bool CARDbUpdateTSF(struct vnt_private *pDevice, unsigned char byRxRate, | 364 | bool CARDbUpdateTSF(struct vnt_private *pDevice, unsigned char byRxRate, |
| 365 | u64 qwBSSTimestamp, u64 qwLocalTSF) | 365 | u64 qwBSSTimestamp) |
| 366 | { | 366 | { |
| 367 | u64 local_tsf; | ||
| 367 | u64 qwTSFOffset = 0; | 368 | u64 qwTSFOffset = 0; |
| 368 | 369 | ||
| 369 | if (qwBSSTimestamp != qwLocalTSF) { | 370 | CARDbGetCurrentTSF(pDevice, &local_tsf); |
| 370 | qwTSFOffset = CARDqGetTSFOffset(byRxRate, qwBSSTimestamp, qwLocalTSF); | 371 | |
| 372 | if (qwBSSTimestamp != local_tsf) { | ||
| 373 | qwTSFOffset = CARDqGetTSFOffset(byRxRate, qwBSSTimestamp, | ||
| 374 | local_tsf); | ||
| 371 | /* adjust TSF, HW's TSF add TSF Offset reg */ | 375 | /* adjust TSF, HW's TSF add TSF Offset reg */ |
| 372 | VNSvOutPortD(pDevice->PortOffset + MAC_REG_TSFOFST, (u32)qwTSFOffset); | 376 | VNSvOutPortD(pDevice->PortOffset + MAC_REG_TSFOFST, (u32)qwTSFOffset); |
| 373 | VNSvOutPortD(pDevice->PortOffset + MAC_REG_TSFOFST + 4, (u32)(qwTSFOffset >> 32)); | 377 | VNSvOutPortD(pDevice->PortOffset + MAC_REG_TSFOFST + 4, (u32)(qwTSFOffset >> 32)); |
diff --git a/drivers/staging/vt6655/card.h b/drivers/staging/vt6655/card.h index 2dfc41952271..16cca49e680a 100644 --- a/drivers/staging/vt6655/card.h +++ b/drivers/staging/vt6655/card.h | |||
| @@ -83,7 +83,7 @@ bool CARDbRadioPowerOff(struct vnt_private *); | |||
| 83 | bool CARDbRadioPowerOn(struct vnt_private *); | 83 | bool CARDbRadioPowerOn(struct vnt_private *); |
| 84 | bool CARDbSetPhyParameter(struct vnt_private *, u8); | 84 | bool CARDbSetPhyParameter(struct vnt_private *, u8); |
| 85 | bool CARDbUpdateTSF(struct vnt_private *, unsigned char byRxRate, | 85 | bool CARDbUpdateTSF(struct vnt_private *, unsigned char byRxRate, |
| 86 | u64 qwBSSTimestamp, u64 qwLocalTSF); | 86 | u64 qwBSSTimestamp); |
| 87 | bool CARDbSetBeaconPeriod(struct vnt_private *, unsigned short wBeaconInterval); | 87 | bool CARDbSetBeaconPeriod(struct vnt_private *, unsigned short wBeaconInterval); |
| 88 | 88 | ||
| 89 | #endif /* __CARD_H__ */ | 89 | #endif /* __CARD_H__ */ |
diff --git a/drivers/staging/vt6655/device_main.c b/drivers/staging/vt6655/device_main.c index 4bb4f8ee4132..0343ae386f03 100644 --- a/drivers/staging/vt6655/device_main.c +++ b/drivers/staging/vt6655/device_main.c | |||
| @@ -912,7 +912,11 @@ static int vnt_int_report_rate(struct vnt_private *priv, | |||
| 912 | 912 | ||
| 913 | if (!(tsr1 & TSR1_TERR)) { | 913 | if (!(tsr1 & TSR1_TERR)) { |
| 914 | info->status.rates[0].idx = idx; | 914 | info->status.rates[0].idx = idx; |
| 915 | info->flags |= IEEE80211_TX_STAT_ACK; | 915 | |
| 916 | if (info->flags & IEEE80211_TX_CTL_NO_ACK) | ||
| 917 | info->flags |= IEEE80211_TX_STAT_NOACK_TRANSMITTED; | ||
| 918 | else | ||
| 919 | info->flags |= IEEE80211_TX_STAT_ACK; | ||
| 916 | } | 920 | } |
| 917 | 921 | ||
| 918 | return 0; | 922 | return 0; |
| @@ -937,9 +941,6 @@ static int device_tx_srv(struct vnt_private *pDevice, unsigned int uIdx) | |||
| 937 | /* Only the status of first TD in the chain is correct */ | 941 | /* Only the status of first TD in the chain is correct */ |
| 938 | if (pTD->m_td1TD1.byTCR & TCR_STP) { | 942 | if (pTD->m_td1TD1.byTCR & TCR_STP) { |
| 939 | if ((pTD->pTDInfo->byFlags & TD_FLAGS_NETIF_SKB) != 0) { | 943 | if ((pTD->pTDInfo->byFlags & TD_FLAGS_NETIF_SKB) != 0) { |
| 940 | |||
| 941 | vnt_int_report_rate(pDevice, pTD->pTDInfo, byTsr0, byTsr1); | ||
| 942 | |||
| 943 | if (!(byTsr1 & TSR1_TERR)) { | 944 | if (!(byTsr1 & TSR1_TERR)) { |
| 944 | if (byTsr0 != 0) { | 945 | if (byTsr0 != 0) { |
| 945 | pr_debug(" Tx[%d] OK but has error. tsr1[%02X] tsr0[%02X]\n", | 946 | pr_debug(" Tx[%d] OK but has error. tsr1[%02X] tsr0[%02X]\n", |
| @@ -958,6 +959,9 @@ static int device_tx_srv(struct vnt_private *pDevice, unsigned int uIdx) | |||
| 958 | (int)uIdx, byTsr1, byTsr0); | 959 | (int)uIdx, byTsr1, byTsr0); |
| 959 | } | 960 | } |
| 960 | } | 961 | } |
| 962 | |||
| 963 | vnt_int_report_rate(pDevice, pTD->pTDInfo, byTsr0, byTsr1); | ||
| 964 | |||
| 961 | device_free_tx_buf(pDevice, pTD); | 965 | device_free_tx_buf(pDevice, pTD); |
| 962 | pDevice->iTDUsed[uIdx]--; | 966 | pDevice->iTDUsed[uIdx]--; |
| 963 | } | 967 | } |
| @@ -989,10 +993,8 @@ static void device_free_tx_buf(struct vnt_private *pDevice, PSTxDesc pDesc) | |||
| 989 | skb->len, DMA_TO_DEVICE); | 993 | skb->len, DMA_TO_DEVICE); |
| 990 | } | 994 | } |
| 991 | 995 | ||
| 992 | if (pTDInfo->byFlags & TD_FLAGS_NETIF_SKB) | 996 | if (skb) |
| 993 | ieee80211_tx_status_irqsafe(pDevice->hw, skb); | 997 | ieee80211_tx_status_irqsafe(pDevice->hw, skb); |
| 994 | else | ||
| 995 | dev_kfree_skb_irq(skb); | ||
| 996 | 998 | ||
| 997 | pTDInfo->skb_dma = 0; | 999 | pTDInfo->skb_dma = 0; |
| 998 | pTDInfo->skb = NULL; | 1000 | pTDInfo->skb = NULL; |
| @@ -1204,14 +1206,6 @@ static int vnt_tx_packet(struct vnt_private *priv, struct sk_buff *skb) | |||
| 1204 | if (dma_idx == TYPE_AC0DMA) | 1206 | if (dma_idx == TYPE_AC0DMA) |
| 1205 | head_td->pTDInfo->byFlags = TD_FLAGS_NETIF_SKB; | 1207 | head_td->pTDInfo->byFlags = TD_FLAGS_NETIF_SKB; |
| 1206 | 1208 | ||
| 1207 | priv->iTDUsed[dma_idx]++; | ||
| 1208 | |||
| 1209 | /* Take ownership */ | ||
| 1210 | wmb(); | ||
| 1211 | head_td->m_td0TD0.f1Owner = OWNED_BY_NIC; | ||
| 1212 | |||
| 1213 | /* get Next */ | ||
| 1214 | wmb(); | ||
| 1215 | priv->apCurrTD[dma_idx] = head_td->next; | 1209 | priv->apCurrTD[dma_idx] = head_td->next; |
| 1216 | 1210 | ||
| 1217 | spin_unlock_irqrestore(&priv->lock, flags); | 1211 | spin_unlock_irqrestore(&priv->lock, flags); |
| @@ -1232,11 +1226,18 @@ static int vnt_tx_packet(struct vnt_private *priv, struct sk_buff *skb) | |||
| 1232 | 1226 | ||
| 1233 | head_td->buff_addr = cpu_to_le32(head_td->pTDInfo->skb_dma); | 1227 | head_td->buff_addr = cpu_to_le32(head_td->pTDInfo->skb_dma); |
| 1234 | 1228 | ||
| 1229 | /* Poll Transmit the adapter */ | ||
| 1230 | wmb(); | ||
| 1231 | head_td->m_td0TD0.f1Owner = OWNED_BY_NIC; | ||
| 1232 | wmb(); /* second memory barrier */ | ||
| 1233 | |||
| 1235 | if (head_td->pTDInfo->byFlags & TD_FLAGS_NETIF_SKB) | 1234 | if (head_td->pTDInfo->byFlags & TD_FLAGS_NETIF_SKB) |
| 1236 | MACvTransmitAC0(priv->PortOffset); | 1235 | MACvTransmitAC0(priv->PortOffset); |
| 1237 | else | 1236 | else |
| 1238 | MACvTransmit0(priv->PortOffset); | 1237 | MACvTransmit0(priv->PortOffset); |
| 1239 | 1238 | ||
| 1239 | priv->iTDUsed[dma_idx]++; | ||
| 1240 | |||
| 1240 | spin_unlock_irqrestore(&priv->lock, flags); | 1241 | spin_unlock_irqrestore(&priv->lock, flags); |
| 1241 | 1242 | ||
| 1242 | return 0; | 1243 | return 0; |
| @@ -1416,9 +1417,16 @@ static void vnt_bss_info_changed(struct ieee80211_hw *hw, | |||
| 1416 | 1417 | ||
| 1417 | priv->current_aid = conf->aid; | 1418 | priv->current_aid = conf->aid; |
| 1418 | 1419 | ||
| 1419 | if (changed & BSS_CHANGED_BSSID) | 1420 | if (changed & BSS_CHANGED_BSSID) { |
| 1421 | unsigned long flags; | ||
| 1422 | |||
| 1423 | spin_lock_irqsave(&priv->lock, flags); | ||
| 1424 | |||
| 1420 | MACvWriteBSSIDAddress(priv->PortOffset, (u8 *)conf->bssid); | 1425 | MACvWriteBSSIDAddress(priv->PortOffset, (u8 *)conf->bssid); |
| 1421 | 1426 | ||
| 1427 | spin_unlock_irqrestore(&priv->lock, flags); | ||
| 1428 | } | ||
| 1429 | |||
| 1422 | if (changed & BSS_CHANGED_BASIC_RATES) { | 1430 | if (changed & BSS_CHANGED_BASIC_RATES) { |
| 1423 | priv->basic_rates = conf->basic_rates; | 1431 | priv->basic_rates = conf->basic_rates; |
| 1424 | 1432 | ||
| @@ -1477,7 +1485,7 @@ static void vnt_bss_info_changed(struct ieee80211_hw *hw, | |||
| 1477 | if (changed & BSS_CHANGED_ASSOC && priv->op_mode != NL80211_IFTYPE_AP) { | 1485 | if (changed & BSS_CHANGED_ASSOC && priv->op_mode != NL80211_IFTYPE_AP) { |
| 1478 | if (conf->assoc) { | 1486 | if (conf->assoc) { |
| 1479 | CARDbUpdateTSF(priv, conf->beacon_rate->hw_value, | 1487 | CARDbUpdateTSF(priv, conf->beacon_rate->hw_value, |
| 1480 | conf->sync_device_ts, conf->sync_tsf); | 1488 | conf->sync_tsf); |
| 1481 | 1489 | ||
| 1482 | CARDbSetBeaconPeriod(priv, conf->beacon_int); | 1490 | CARDbSetBeaconPeriod(priv, conf->beacon_int); |
| 1483 | 1491 | ||
diff --git a/drivers/staging/vt6656/rxtx.c b/drivers/staging/vt6656/rxtx.c index f6c2cf8590c4..5c589962a1e8 100644 --- a/drivers/staging/vt6656/rxtx.c +++ b/drivers/staging/vt6656/rxtx.c | |||
| @@ -805,10 +805,18 @@ int vnt_tx_packet(struct vnt_private *priv, struct sk_buff *skb) | |||
| 805 | vnt_schedule_command(priv, WLAN_CMD_SETPOWER); | 805 | vnt_schedule_command(priv, WLAN_CMD_SETPOWER); |
| 806 | } | 806 | } |
| 807 | 807 | ||
| 808 | if (current_rate > RATE_11M) | 808 | if (current_rate > RATE_11M) { |
| 809 | pkt_type = priv->packet_type; | 809 | if (info->band == IEEE80211_BAND_5GHZ) { |
| 810 | else | 810 | pkt_type = PK_TYPE_11A; |
| 811 | } else { | ||
| 812 | if (tx_rate->flags & IEEE80211_TX_RC_USE_CTS_PROTECT) | ||
| 813 | pkt_type = PK_TYPE_11GB; | ||
| 814 | else | ||
| 815 | pkt_type = PK_TYPE_11GA; | ||
| 816 | } | ||
| 817 | } else { | ||
| 811 | pkt_type = PK_TYPE_11B; | 818 | pkt_type = PK_TYPE_11B; |
| 819 | } | ||
| 812 | 820 | ||
| 813 | spin_lock_irqsave(&priv->lock, flags); | 821 | spin_lock_irqsave(&priv->lock, flags); |
| 814 | 822 | ||
diff --git a/drivers/thermal/intel_powerclamp.c b/drivers/thermal/intel_powerclamp.c index 12623bc02f46..725718e97a0b 100644 --- a/drivers/thermal/intel_powerclamp.c +++ b/drivers/thermal/intel_powerclamp.c | |||
| @@ -206,51 +206,57 @@ static void find_target_mwait(void) | |||
| 206 | 206 | ||
| 207 | } | 207 | } |
| 208 | 208 | ||
| 209 | struct pkg_cstate_info { | ||
| 210 | bool skip; | ||
| 211 | int msr_index; | ||
| 212 | int cstate_id; | ||
| 213 | }; | ||
| 214 | |||
| 215 | #define PKG_CSTATE_INIT(id) { \ | ||
| 216 | .msr_index = MSR_PKG_C##id##_RESIDENCY, \ | ||
| 217 | .cstate_id = id \ | ||
| 218 | } | ||
| 219 | |||
| 220 | static struct pkg_cstate_info pkg_cstates[] = { | ||
| 221 | PKG_CSTATE_INIT(2), | ||
| 222 | PKG_CSTATE_INIT(3), | ||
| 223 | PKG_CSTATE_INIT(6), | ||
| 224 | PKG_CSTATE_INIT(7), | ||
| 225 | PKG_CSTATE_INIT(8), | ||
| 226 | PKG_CSTATE_INIT(9), | ||
| 227 | PKG_CSTATE_INIT(10), | ||
| 228 | {NULL}, | ||
| 229 | }; | ||
| 230 | |||
| 209 | static bool has_pkg_state_counter(void) | 231 | static bool has_pkg_state_counter(void) |
| 210 | { | 232 | { |
| 211 | u64 tmp; | 233 | u64 val; |
| 212 | return !rdmsrl_safe(MSR_PKG_C2_RESIDENCY, &tmp) || | 234 | struct pkg_cstate_info *info = pkg_cstates; |
| 213 | !rdmsrl_safe(MSR_PKG_C3_RESIDENCY, &tmp) || | 235 | |
| 214 | !rdmsrl_safe(MSR_PKG_C6_RESIDENCY, &tmp) || | 236 | /* check if any one of the counter msrs exists */ |
| 215 | !rdmsrl_safe(MSR_PKG_C7_RESIDENCY, &tmp); | 237 | while (info->msr_index) { |
| 238 | if (!rdmsrl_safe(info->msr_index, &val)) | ||
| 239 | return true; | ||
| 240 | info++; | ||
| 241 | } | ||
| 242 | |||
| 243 | return false; | ||
| 216 | } | 244 | } |
| 217 | 245 | ||
| 218 | static u64 pkg_state_counter(void) | 246 | static u64 pkg_state_counter(void) |
| 219 | { | 247 | { |
| 220 | u64 val; | 248 | u64 val; |
| 221 | u64 count = 0; | 249 | u64 count = 0; |
| 222 | 250 | struct pkg_cstate_info *info = pkg_cstates; | |
| 223 | static bool skip_c2; | 251 | |
| 224 | static bool skip_c3; | 252 | while (info->msr_index) { |
| 225 | static bool skip_c6; | 253 | if (!info->skip) { |
| 226 | static bool skip_c7; | 254 | if (!rdmsrl_safe(info->msr_index, &val)) |
| 227 | 255 | count += val; | |
| 228 | if (!skip_c2) { | 256 | else |
| 229 | if (!rdmsrl_safe(MSR_PKG_C2_RESIDENCY, &val)) | 257 | info->skip = true; |
| 230 | count += val; | 258 | } |
| 231 | else | 259 | info++; |
| 232 | skip_c2 = true; | ||
| 233 | } | ||
| 234 | |||
| 235 | if (!skip_c3) { | ||
| 236 | if (!rdmsrl_safe(MSR_PKG_C3_RESIDENCY, &val)) | ||
| 237 | count += val; | ||
| 238 | else | ||
| 239 | skip_c3 = true; | ||
| 240 | } | ||
| 241 | |||
| 242 | if (!skip_c6) { | ||
| 243 | if (!rdmsrl_safe(MSR_PKG_C6_RESIDENCY, &val)) | ||
| 244 | count += val; | ||
| 245 | else | ||
| 246 | skip_c6 = true; | ||
| 247 | } | ||
| 248 | |||
| 249 | if (!skip_c7) { | ||
| 250 | if (!rdmsrl_safe(MSR_PKG_C7_RESIDENCY, &val)) | ||
| 251 | count += val; | ||
| 252 | else | ||
| 253 | skip_c7 = true; | ||
| 254 | } | 260 | } |
| 255 | 261 | ||
| 256 | return count; | 262 | return count; |
| @@ -667,7 +673,7 @@ static struct thermal_cooling_device_ops powerclamp_cooling_ops = { | |||
| 667 | }; | 673 | }; |
| 668 | 674 | ||
| 669 | /* runs on Nehalem and later */ | 675 | /* runs on Nehalem and later */ |
| 670 | static const struct x86_cpu_id intel_powerclamp_ids[] = { | 676 | static const struct x86_cpu_id intel_powerclamp_ids[] __initconst = { |
| 671 | { X86_VENDOR_INTEL, 6, 0x1a}, | 677 | { X86_VENDOR_INTEL, 6, 0x1a}, |
| 672 | { X86_VENDOR_INTEL, 6, 0x1c}, | 678 | { X86_VENDOR_INTEL, 6, 0x1c}, |
| 673 | { X86_VENDOR_INTEL, 6, 0x1e}, | 679 | { X86_VENDOR_INTEL, 6, 0x1e}, |
| @@ -689,12 +695,13 @@ static const struct x86_cpu_id intel_powerclamp_ids[] = { | |||
| 689 | { X86_VENDOR_INTEL, 6, 0x46}, | 695 | { X86_VENDOR_INTEL, 6, 0x46}, |
| 690 | { X86_VENDOR_INTEL, 6, 0x4c}, | 696 | { X86_VENDOR_INTEL, 6, 0x4c}, |
| 691 | { X86_VENDOR_INTEL, 6, 0x4d}, | 697 | { X86_VENDOR_INTEL, 6, 0x4d}, |
| 698 | { X86_VENDOR_INTEL, 6, 0x4f}, | ||
| 692 | { X86_VENDOR_INTEL, 6, 0x56}, | 699 | { X86_VENDOR_INTEL, 6, 0x56}, |
| 693 | {} | 700 | {} |
| 694 | }; | 701 | }; |
| 695 | MODULE_DEVICE_TABLE(x86cpu, intel_powerclamp_ids); | 702 | MODULE_DEVICE_TABLE(x86cpu, intel_powerclamp_ids); |
| 696 | 703 | ||
| 697 | static int powerclamp_probe(void) | 704 | static int __init powerclamp_probe(void) |
| 698 | { | 705 | { |
| 699 | if (!x86_match_cpu(intel_powerclamp_ids)) { | 706 | if (!x86_match_cpu(intel_powerclamp_ids)) { |
| 700 | pr_err("Intel powerclamp does not run on family %d model %d\n", | 707 | pr_err("Intel powerclamp does not run on family %d model %d\n", |
| @@ -760,7 +767,7 @@ file_error: | |||
| 760 | debugfs_remove_recursive(debug_dir); | 767 | debugfs_remove_recursive(debug_dir); |
| 761 | } | 768 | } |
| 762 | 769 | ||
| 763 | static int powerclamp_init(void) | 770 | static int __init powerclamp_init(void) |
| 764 | { | 771 | { |
| 765 | int retval; | 772 | int retval; |
| 766 | int bitmap_size; | 773 | int bitmap_size; |
| @@ -809,7 +816,7 @@ exit_free: | |||
| 809 | } | 816 | } |
| 810 | module_init(powerclamp_init); | 817 | module_init(powerclamp_init); |
| 811 | 818 | ||
| 812 | static void powerclamp_exit(void) | 819 | static void __exit powerclamp_exit(void) |
| 813 | { | 820 | { |
| 814 | unregister_hotcpu_notifier(&powerclamp_cpu_notifier); | 821 | unregister_hotcpu_notifier(&powerclamp_cpu_notifier); |
| 815 | end_power_clamp(); | 822 | end_power_clamp(); |
diff --git a/drivers/thermal/rockchip_thermal.c b/drivers/thermal/rockchip_thermal.c index 3aa46ac7cdbc..cd8f5f93b42c 100644 --- a/drivers/thermal/rockchip_thermal.c +++ b/drivers/thermal/rockchip_thermal.c | |||
| @@ -529,7 +529,7 @@ static int rockchip_thermal_probe(struct platform_device *pdev) | |||
| 529 | 529 | ||
| 530 | thermal->pclk = devm_clk_get(&pdev->dev, "apb_pclk"); | 530 | thermal->pclk = devm_clk_get(&pdev->dev, "apb_pclk"); |
| 531 | if (IS_ERR(thermal->pclk)) { | 531 | if (IS_ERR(thermal->pclk)) { |
| 532 | error = PTR_ERR(thermal->clk); | 532 | error = PTR_ERR(thermal->pclk); |
| 533 | dev_err(&pdev->dev, "failed to get apb_pclk clock: %d\n", | 533 | dev_err(&pdev->dev, "failed to get apb_pclk clock: %d\n", |
| 534 | error); | 534 | error); |
| 535 | return error; | 535 | return error; |
diff --git a/drivers/thermal/thermal_core.h b/drivers/thermal/thermal_core.h index 0531c752fbbb..8e391812e503 100644 --- a/drivers/thermal/thermal_core.h +++ b/drivers/thermal/thermal_core.h | |||
| @@ -103,7 +103,7 @@ static inline int of_thermal_get_ntrips(struct thermal_zone_device *tz) | |||
| 103 | static inline bool of_thermal_is_trip_valid(struct thermal_zone_device *tz, | 103 | static inline bool of_thermal_is_trip_valid(struct thermal_zone_device *tz, |
| 104 | int trip) | 104 | int trip) |
| 105 | { | 105 | { |
| 106 | return 0; | 106 | return false; |
| 107 | } | 107 | } |
| 108 | static inline const struct thermal_trip * | 108 | static inline const struct thermal_trip * |
| 109 | of_thermal_get_trip_points(struct thermal_zone_device *tz) | 109 | of_thermal_get_trip_points(struct thermal_zone_device *tz) |
diff --git a/drivers/tty/hvc/hvc_xen.c b/drivers/tty/hvc/hvc_xen.c index f1e57425e39f..5bab1c684bb1 100644 --- a/drivers/tty/hvc/hvc_xen.c +++ b/drivers/tty/hvc/hvc_xen.c | |||
| @@ -299,11 +299,27 @@ static int xen_initial_domain_console_init(void) | |||
| 299 | return 0; | 299 | return 0; |
| 300 | } | 300 | } |
| 301 | 301 | ||
| 302 | static void xen_console_update_evtchn(struct xencons_info *info) | ||
| 303 | { | ||
| 304 | if (xen_hvm_domain()) { | ||
| 305 | uint64_t v; | ||
| 306 | int err; | ||
| 307 | |||
| 308 | err = hvm_get_parameter(HVM_PARAM_CONSOLE_EVTCHN, &v); | ||
| 309 | if (!err && v) | ||
| 310 | info->evtchn = v; | ||
| 311 | } else | ||
| 312 | info->evtchn = xen_start_info->console.domU.evtchn; | ||
| 313 | } | ||
| 314 | |||
| 302 | void xen_console_resume(void) | 315 | void xen_console_resume(void) |
| 303 | { | 316 | { |
| 304 | struct xencons_info *info = vtermno_to_xencons(HVC_COOKIE); | 317 | struct xencons_info *info = vtermno_to_xencons(HVC_COOKIE); |
| 305 | if (info != NULL && info->irq) | 318 | if (info != NULL && info->irq) { |
| 319 | if (!xen_initial_domain()) | ||
| 320 | xen_console_update_evtchn(info); | ||
| 306 | rebind_evtchn_irq(info->evtchn, info->irq); | 321 | rebind_evtchn_irq(info->evtchn, info->irq); |
| 322 | } | ||
| 307 | } | 323 | } |
| 308 | 324 | ||
| 309 | static void xencons_disconnect_backend(struct xencons_info *info) | 325 | static void xencons_disconnect_backend(struct xencons_info *info) |
diff --git a/drivers/vfio/pci/vfio_pci.c b/drivers/vfio/pci/vfio_pci.c index 69fab0fd15ae..e9851add6f4e 100644 --- a/drivers/vfio/pci/vfio_pci.c +++ b/drivers/vfio/pci/vfio_pci.c | |||
| @@ -907,8 +907,14 @@ static void vfio_pci_request(void *device_data, unsigned int count) | |||
| 907 | mutex_lock(&vdev->igate); | 907 | mutex_lock(&vdev->igate); |
| 908 | 908 | ||
| 909 | if (vdev->req_trigger) { | 909 | if (vdev->req_trigger) { |
| 910 | dev_dbg(&vdev->pdev->dev, "Requesting device from user\n"); | 910 | if (!(count % 10)) |
| 911 | dev_notice_ratelimited(&vdev->pdev->dev, | ||
| 912 | "Relaying device request to user (#%u)\n", | ||
| 913 | count); | ||
| 911 | eventfd_signal(vdev->req_trigger, 1); | 914 | eventfd_signal(vdev->req_trigger, 1); |
| 915 | } else if (count == 0) { | ||
| 916 | dev_warn(&vdev->pdev->dev, | ||
| 917 | "No device request channel registered, blocked until released by user\n"); | ||
| 912 | } | 918 | } |
| 913 | 919 | ||
| 914 | mutex_unlock(&vdev->igate); | 920 | mutex_unlock(&vdev->igate); |
diff --git a/drivers/vfio/vfio.c b/drivers/vfio/vfio.c index 0d336625ac71..e1278fe04b1e 100644 --- a/drivers/vfio/vfio.c +++ b/drivers/vfio/vfio.c | |||
| @@ -710,6 +710,8 @@ void *vfio_del_group_dev(struct device *dev) | |||
| 710 | void *device_data = device->device_data; | 710 | void *device_data = device->device_data; |
| 711 | struct vfio_unbound_dev *unbound; | 711 | struct vfio_unbound_dev *unbound; |
| 712 | unsigned int i = 0; | 712 | unsigned int i = 0; |
| 713 | long ret; | ||
| 714 | bool interrupted = false; | ||
| 713 | 715 | ||
| 714 | /* | 716 | /* |
| 715 | * The group exists so long as we have a device reference. Get | 717 | * The group exists so long as we have a device reference. Get |
| @@ -755,9 +757,22 @@ void *vfio_del_group_dev(struct device *dev) | |||
| 755 | 757 | ||
| 756 | vfio_device_put(device); | 758 | vfio_device_put(device); |
| 757 | 759 | ||
| 758 | } while (wait_event_interruptible_timeout(vfio.release_q, | 760 | if (interrupted) { |
| 759 | !vfio_dev_present(group, dev), | 761 | ret = wait_event_timeout(vfio.release_q, |
| 760 | HZ * 10) <= 0); | 762 | !vfio_dev_present(group, dev), HZ * 10); |
| 763 | } else { | ||
| 764 | ret = wait_event_interruptible_timeout(vfio.release_q, | ||
| 765 | !vfio_dev_present(group, dev), HZ * 10); | ||
| 766 | if (ret == -ERESTARTSYS) { | ||
| 767 | interrupted = true; | ||
| 768 | dev_warn(dev, | ||
| 769 | "Device is currently in use, task" | ||
| 770 | " \"%s\" (%d) " | ||
| 771 | "blocked until device is released", | ||
| 772 | current->comm, task_pid_nr(current)); | ||
| 773 | } | ||
| 774 | } | ||
| 775 | } while (ret <= 0); | ||
| 761 | 776 | ||
| 762 | vfio_group_put(group); | 777 | vfio_group_put(group); |
| 763 | 778 | ||
diff --git a/drivers/xen/events/events_2l.c b/drivers/xen/events/events_2l.c index 5db43fc100a4..7dd46312c180 100644 --- a/drivers/xen/events/events_2l.c +++ b/drivers/xen/events/events_2l.c | |||
| @@ -345,6 +345,15 @@ irqreturn_t xen_debug_interrupt(int irq, void *dev_id) | |||
| 345 | return IRQ_HANDLED; | 345 | return IRQ_HANDLED; |
| 346 | } | 346 | } |
| 347 | 347 | ||
| 348 | static void evtchn_2l_resume(void) | ||
| 349 | { | ||
| 350 | int i; | ||
| 351 | |||
| 352 | for_each_online_cpu(i) | ||
| 353 | memset(per_cpu(cpu_evtchn_mask, i), 0, sizeof(xen_ulong_t) * | ||
| 354 | EVTCHN_2L_NR_CHANNELS/BITS_PER_EVTCHN_WORD); | ||
| 355 | } | ||
| 356 | |||
| 348 | static const struct evtchn_ops evtchn_ops_2l = { | 357 | static const struct evtchn_ops evtchn_ops_2l = { |
| 349 | .max_channels = evtchn_2l_max_channels, | 358 | .max_channels = evtchn_2l_max_channels, |
| 350 | .nr_channels = evtchn_2l_max_channels, | 359 | .nr_channels = evtchn_2l_max_channels, |
| @@ -356,6 +365,7 @@ static const struct evtchn_ops evtchn_ops_2l = { | |||
| 356 | .mask = evtchn_2l_mask, | 365 | .mask = evtchn_2l_mask, |
| 357 | .unmask = evtchn_2l_unmask, | 366 | .unmask = evtchn_2l_unmask, |
| 358 | .handle_events = evtchn_2l_handle_events, | 367 | .handle_events = evtchn_2l_handle_events, |
| 368 | .resume = evtchn_2l_resume, | ||
| 359 | }; | 369 | }; |
| 360 | 370 | ||
| 361 | void __init xen_evtchn_2l_init(void) | 371 | void __init xen_evtchn_2l_init(void) |
diff --git a/drivers/xen/events/events_base.c b/drivers/xen/events/events_base.c index 70fba973a107..2b8553bd8715 100644 --- a/drivers/xen/events/events_base.c +++ b/drivers/xen/events/events_base.c | |||
| @@ -529,8 +529,8 @@ static unsigned int __startup_pirq(unsigned int irq) | |||
| 529 | if (rc) | 529 | if (rc) |
| 530 | goto err; | 530 | goto err; |
| 531 | 531 | ||
| 532 | bind_evtchn_to_cpu(evtchn, 0); | ||
| 533 | info->evtchn = evtchn; | 532 | info->evtchn = evtchn; |
| 533 | bind_evtchn_to_cpu(evtchn, 0); | ||
| 534 | 534 | ||
| 535 | rc = xen_evtchn_port_setup(info); | 535 | rc = xen_evtchn_port_setup(info); |
| 536 | if (rc) | 536 | if (rc) |
| @@ -1279,8 +1279,9 @@ void rebind_evtchn_irq(int evtchn, int irq) | |||
| 1279 | 1279 | ||
| 1280 | mutex_unlock(&irq_mapping_update_lock); | 1280 | mutex_unlock(&irq_mapping_update_lock); |
| 1281 | 1281 | ||
| 1282 | /* new event channels are always bound to cpu 0 */ | 1282 | bind_evtchn_to_cpu(evtchn, info->cpu); |
| 1283 | irq_set_affinity(irq, cpumask_of(0)); | 1283 | /* This will be deferred until interrupt is processed */ |
| 1284 | irq_set_affinity(irq, cpumask_of(info->cpu)); | ||
| 1284 | 1285 | ||
| 1285 | /* Unmask the event channel. */ | 1286 | /* Unmask the event channel. */ |
| 1286 | enable_irq(irq); | 1287 | enable_irq(irq); |
diff --git a/drivers/xen/gntdev.c b/drivers/xen/gntdev.c index d5bb1a33d0a3..89274850741b 100644 --- a/drivers/xen/gntdev.c +++ b/drivers/xen/gntdev.c | |||
| @@ -327,30 +327,10 @@ static int map_grant_pages(struct grant_map *map) | |||
| 327 | return err; | 327 | return err; |
| 328 | } | 328 | } |
| 329 | 329 | ||
| 330 | struct unmap_grant_pages_callback_data | ||
| 331 | { | ||
| 332 | struct completion completion; | ||
| 333 | int result; | ||
| 334 | }; | ||
| 335 | |||
| 336 | static void unmap_grant_callback(int result, | ||
| 337 | struct gntab_unmap_queue_data *data) | ||
| 338 | { | ||
| 339 | struct unmap_grant_pages_callback_data* d = data->data; | ||
| 340 | |||
| 341 | d->result = result; | ||
| 342 | complete(&d->completion); | ||
| 343 | } | ||
| 344 | |||
| 345 | static int __unmap_grant_pages(struct grant_map *map, int offset, int pages) | 330 | static int __unmap_grant_pages(struct grant_map *map, int offset, int pages) |
| 346 | { | 331 | { |
| 347 | int i, err = 0; | 332 | int i, err = 0; |
| 348 | struct gntab_unmap_queue_data unmap_data; | 333 | struct gntab_unmap_queue_data unmap_data; |
| 349 | struct unmap_grant_pages_callback_data data; | ||
| 350 | |||
| 351 | init_completion(&data.completion); | ||
| 352 | unmap_data.data = &data; | ||
| 353 | unmap_data.done= &unmap_grant_callback; | ||
| 354 | 334 | ||
| 355 | if (map->notify.flags & UNMAP_NOTIFY_CLEAR_BYTE) { | 335 | if (map->notify.flags & UNMAP_NOTIFY_CLEAR_BYTE) { |
| 356 | int pgno = (map->notify.addr >> PAGE_SHIFT); | 336 | int pgno = (map->notify.addr >> PAGE_SHIFT); |
| @@ -367,11 +347,9 @@ static int __unmap_grant_pages(struct grant_map *map, int offset, int pages) | |||
| 367 | unmap_data.pages = map->pages + offset; | 347 | unmap_data.pages = map->pages + offset; |
| 368 | unmap_data.count = pages; | 348 | unmap_data.count = pages; |
| 369 | 349 | ||
| 370 | gnttab_unmap_refs_async(&unmap_data); | 350 | err = gnttab_unmap_refs_sync(&unmap_data); |
| 371 | 351 | if (err) | |
| 372 | wait_for_completion(&data.completion); | 352 | return err; |
| 373 | if (data.result) | ||
| 374 | return data.result; | ||
| 375 | 353 | ||
| 376 | for (i = 0; i < pages; i++) { | 354 | for (i = 0; i < pages; i++) { |
| 377 | if (map->unmap_ops[offset+i].status) | 355 | if (map->unmap_ops[offset+i].status) |
diff --git a/drivers/xen/grant-table.c b/drivers/xen/grant-table.c index 17972fbacddc..b1c7170e5c9e 100644 --- a/drivers/xen/grant-table.c +++ b/drivers/xen/grant-table.c | |||
| @@ -123,6 +123,11 @@ struct gnttab_ops { | |||
| 123 | int (*query_foreign_access)(grant_ref_t ref); | 123 | int (*query_foreign_access)(grant_ref_t ref); |
| 124 | }; | 124 | }; |
| 125 | 125 | ||
| 126 | struct unmap_refs_callback_data { | ||
| 127 | struct completion completion; | ||
| 128 | int result; | ||
| 129 | }; | ||
| 130 | |||
| 126 | static struct gnttab_ops *gnttab_interface; | 131 | static struct gnttab_ops *gnttab_interface; |
| 127 | 132 | ||
| 128 | static int grant_table_version; | 133 | static int grant_table_version; |
| @@ -863,6 +868,29 @@ void gnttab_unmap_refs_async(struct gntab_unmap_queue_data* item) | |||
| 863 | } | 868 | } |
| 864 | EXPORT_SYMBOL_GPL(gnttab_unmap_refs_async); | 869 | EXPORT_SYMBOL_GPL(gnttab_unmap_refs_async); |
| 865 | 870 | ||
| 871 | static void unmap_refs_callback(int result, | ||
| 872 | struct gntab_unmap_queue_data *data) | ||
| 873 | { | ||
| 874 | struct unmap_refs_callback_data *d = data->data; | ||
| 875 | |||
| 876 | d->result = result; | ||
| 877 | complete(&d->completion); | ||
| 878 | } | ||
| 879 | |||
| 880 | int gnttab_unmap_refs_sync(struct gntab_unmap_queue_data *item) | ||
| 881 | { | ||
| 882 | struct unmap_refs_callback_data data; | ||
| 883 | |||
| 884 | init_completion(&data.completion); | ||
| 885 | item->data = &data; | ||
| 886 | item->done = &unmap_refs_callback; | ||
| 887 | gnttab_unmap_refs_async(item); | ||
| 888 | wait_for_completion(&data.completion); | ||
| 889 | |||
| 890 | return data.result; | ||
| 891 | } | ||
| 892 | EXPORT_SYMBOL_GPL(gnttab_unmap_refs_sync); | ||
| 893 | |||
| 866 | static int gnttab_map_frames_v1(xen_pfn_t *frames, unsigned int nr_gframes) | 894 | static int gnttab_map_frames_v1(xen_pfn_t *frames, unsigned int nr_gframes) |
| 867 | { | 895 | { |
| 868 | int rc; | 896 | int rc; |
diff --git a/drivers/xen/manage.c b/drivers/xen/manage.c index bf1940706422..9e6a85104a20 100644 --- a/drivers/xen/manage.c +++ b/drivers/xen/manage.c | |||
| @@ -131,6 +131,8 @@ static void do_suspend(void) | |||
| 131 | goto out_resume; | 131 | goto out_resume; |
| 132 | } | 132 | } |
| 133 | 133 | ||
| 134 | xen_arch_suspend(); | ||
| 135 | |||
| 134 | si.cancelled = 1; | 136 | si.cancelled = 1; |
| 135 | 137 | ||
| 136 | err = stop_machine(xen_suspend, &si, cpumask_of(0)); | 138 | err = stop_machine(xen_suspend, &si, cpumask_of(0)); |
| @@ -148,11 +150,12 @@ static void do_suspend(void) | |||
| 148 | si.cancelled = 1; | 150 | si.cancelled = 1; |
| 149 | } | 151 | } |
| 150 | 152 | ||
| 153 | xen_arch_resume(); | ||
| 154 | |||
| 151 | out_resume: | 155 | out_resume: |
| 152 | if (!si.cancelled) { | 156 | if (!si.cancelled) |
| 153 | xen_arch_resume(); | ||
| 154 | xs_resume(); | 157 | xs_resume(); |
| 155 | } else | 158 | else |
| 156 | xs_suspend_cancel(); | 159 | xs_suspend_cancel(); |
| 157 | 160 | ||
| 158 | dpm_resume_end(si.cancelled ? PMSG_THAW : PMSG_RESTORE); | 161 | dpm_resume_end(si.cancelled ? PMSG_THAW : PMSG_RESTORE); |
diff --git a/drivers/xen/swiotlb-xen.c b/drivers/xen/swiotlb-xen.c index 810ad419e34c..4c549323c605 100644 --- a/drivers/xen/swiotlb-xen.c +++ b/drivers/xen/swiotlb-xen.c | |||
| @@ -235,7 +235,7 @@ retry: | |||
| 235 | #define SLABS_PER_PAGE (1 << (PAGE_SHIFT - IO_TLB_SHIFT)) | 235 | #define SLABS_PER_PAGE (1 << (PAGE_SHIFT - IO_TLB_SHIFT)) |
| 236 | #define IO_TLB_MIN_SLABS ((1<<20) >> IO_TLB_SHIFT) | 236 | #define IO_TLB_MIN_SLABS ((1<<20) >> IO_TLB_SHIFT) |
| 237 | while ((SLABS_PER_PAGE << order) > IO_TLB_MIN_SLABS) { | 237 | while ((SLABS_PER_PAGE << order) > IO_TLB_MIN_SLABS) { |
| 238 | xen_io_tlb_start = (void *)__get_free_pages(__GFP_NOWARN, order); | 238 | xen_io_tlb_start = (void *)xen_get_swiotlb_free_pages(order); |
| 239 | if (xen_io_tlb_start) | 239 | if (xen_io_tlb_start) |
| 240 | break; | 240 | break; |
| 241 | order--; | 241 | order--; |
diff --git a/drivers/xen/xen-pciback/conf_space.c b/drivers/xen/xen-pciback/conf_space.c index 75fe3d466515..9c234209d8b5 100644 --- a/drivers/xen/xen-pciback/conf_space.c +++ b/drivers/xen/xen-pciback/conf_space.c | |||
| @@ -16,8 +16,8 @@ | |||
| 16 | #include "conf_space.h" | 16 | #include "conf_space.h" |
| 17 | #include "conf_space_quirks.h" | 17 | #include "conf_space_quirks.h" |
| 18 | 18 | ||
| 19 | bool permissive; | 19 | bool xen_pcibk_permissive; |
| 20 | module_param(permissive, bool, 0644); | 20 | module_param_named(permissive, xen_pcibk_permissive, bool, 0644); |
| 21 | 21 | ||
| 22 | /* This is where xen_pcibk_read_config_byte, xen_pcibk_read_config_word, | 22 | /* This is where xen_pcibk_read_config_byte, xen_pcibk_read_config_word, |
| 23 | * xen_pcibk_write_config_word, and xen_pcibk_write_config_byte are created. */ | 23 | * xen_pcibk_write_config_word, and xen_pcibk_write_config_byte are created. */ |
| @@ -262,7 +262,7 @@ int xen_pcibk_config_write(struct pci_dev *dev, int offset, int size, u32 value) | |||
| 262 | * This means that some fields may still be read-only because | 262 | * This means that some fields may still be read-only because |
| 263 | * they have entries in the config_field list that intercept | 263 | * they have entries in the config_field list that intercept |
| 264 | * the write and do nothing. */ | 264 | * the write and do nothing. */ |
| 265 | if (dev_data->permissive || permissive) { | 265 | if (dev_data->permissive || xen_pcibk_permissive) { |
| 266 | switch (size) { | 266 | switch (size) { |
| 267 | case 1: | 267 | case 1: |
| 268 | err = pci_write_config_byte(dev, offset, | 268 | err = pci_write_config_byte(dev, offset, |
diff --git a/drivers/xen/xen-pciback/conf_space.h b/drivers/xen/xen-pciback/conf_space.h index 2e1d73d1d5d0..62461a8ba1d6 100644 --- a/drivers/xen/xen-pciback/conf_space.h +++ b/drivers/xen/xen-pciback/conf_space.h | |||
| @@ -64,7 +64,7 @@ struct config_field_entry { | |||
| 64 | void *data; | 64 | void *data; |
| 65 | }; | 65 | }; |
| 66 | 66 | ||
| 67 | extern bool permissive; | 67 | extern bool xen_pcibk_permissive; |
| 68 | 68 | ||
| 69 | #define OFFSET(cfg_entry) ((cfg_entry)->base_offset+(cfg_entry)->field->offset) | 69 | #define OFFSET(cfg_entry) ((cfg_entry)->base_offset+(cfg_entry)->field->offset) |
| 70 | 70 | ||
diff --git a/drivers/xen/xen-pciback/conf_space_header.c b/drivers/xen/xen-pciback/conf_space_header.c index c2260a0456c9..ad3d17d29c81 100644 --- a/drivers/xen/xen-pciback/conf_space_header.c +++ b/drivers/xen/xen-pciback/conf_space_header.c | |||
| @@ -118,7 +118,7 @@ static int command_write(struct pci_dev *dev, int offset, u16 value, void *data) | |||
| 118 | 118 | ||
| 119 | cmd->val = value; | 119 | cmd->val = value; |
| 120 | 120 | ||
| 121 | if (!permissive && (!dev_data || !dev_data->permissive)) | 121 | if (!xen_pcibk_permissive && (!dev_data || !dev_data->permissive)) |
| 122 | return 0; | 122 | return 0; |
| 123 | 123 | ||
| 124 | /* Only allow the guest to control certain bits. */ | 124 | /* Only allow the guest to control certain bits. */ |
diff --git a/drivers/xen/xenbus/xenbus_probe.c b/drivers/xen/xenbus/xenbus_probe.c index 564b31584860..5390a674b5e3 100644 --- a/drivers/xen/xenbus/xenbus_probe.c +++ b/drivers/xen/xenbus/xenbus_probe.c | |||
| @@ -57,6 +57,7 @@ | |||
| 57 | #include <xen/xen.h> | 57 | #include <xen/xen.h> |
| 58 | #include <xen/xenbus.h> | 58 | #include <xen/xenbus.h> |
| 59 | #include <xen/events.h> | 59 | #include <xen/events.h> |
| 60 | #include <xen/xen-ops.h> | ||
| 60 | #include <xen/page.h> | 61 | #include <xen/page.h> |
| 61 | 62 | ||
| 62 | #include <xen/hvm.h> | 63 | #include <xen/hvm.h> |
| @@ -735,6 +736,30 @@ static int __init xenstored_local_init(void) | |||
| 735 | return err; | 736 | return err; |
| 736 | } | 737 | } |
| 737 | 738 | ||
| 739 | static int xenbus_resume_cb(struct notifier_block *nb, | ||
| 740 | unsigned long action, void *data) | ||
| 741 | { | ||
| 742 | int err = 0; | ||
| 743 | |||
| 744 | if (xen_hvm_domain()) { | ||
| 745 | uint64_t v; | ||
| 746 | |||
| 747 | err = hvm_get_parameter(HVM_PARAM_STORE_EVTCHN, &v); | ||
| 748 | if (!err && v) | ||
| 749 | xen_store_evtchn = v; | ||
| 750 | else | ||
| 751 | pr_warn("Cannot update xenstore event channel: %d\n", | ||
| 752 | err); | ||
| 753 | } else | ||
| 754 | xen_store_evtchn = xen_start_info->store_evtchn; | ||
| 755 | |||
| 756 | return err; | ||
| 757 | } | ||
| 758 | |||
| 759 | static struct notifier_block xenbus_resume_nb = { | ||
| 760 | .notifier_call = xenbus_resume_cb, | ||
| 761 | }; | ||
| 762 | |||
| 738 | static int __init xenbus_init(void) | 763 | static int __init xenbus_init(void) |
| 739 | { | 764 | { |
| 740 | int err = 0; | 765 | int err = 0; |
| @@ -793,6 +818,10 @@ static int __init xenbus_init(void) | |||
| 793 | goto out_error; | 818 | goto out_error; |
| 794 | } | 819 | } |
| 795 | 820 | ||
| 821 | if ((xen_store_domain_type != XS_LOCAL) && | ||
| 822 | (xen_store_domain_type != XS_UNKNOWN)) | ||
| 823 | xen_resume_notifier_register(&xenbus_resume_nb); | ||
| 824 | |||
| 796 | #ifdef CONFIG_XEN_COMPAT_XENFS | 825 | #ifdef CONFIG_XEN_COMPAT_XENFS |
| 797 | /* | 826 | /* |
| 798 | * Create xenfs mountpoint in /proc for compatibility with | 827 | * Create xenfs mountpoint in /proc for compatibility with |
