diff options
Diffstat (limited to 'drivers')
160 files changed, 2310 insertions, 1081 deletions
diff --git a/drivers/acpi/Makefile b/drivers/acpi/Makefile index ecb743bf05a5..536562c626a2 100644 --- a/drivers/acpi/Makefile +++ b/drivers/acpi/Makefile | |||
@@ -24,7 +24,7 @@ acpi-y += nvs.o | |||
24 | # Power management related files | 24 | # Power management related files |
25 | acpi-y += wakeup.o | 25 | acpi-y += wakeup.o |
26 | acpi-y += sleep.o | 26 | acpi-y += sleep.o |
27 | acpi-$(CONFIG_PM) += device_pm.o | 27 | acpi-y += device_pm.o |
28 | acpi-$(CONFIG_ACPI_SLEEP) += proc.o | 28 | acpi-$(CONFIG_ACPI_SLEEP) += proc.o |
29 | 29 | ||
30 | 30 | ||
@@ -38,7 +38,6 @@ acpi-y += processor_core.o | |||
38 | acpi-y += ec.o | 38 | acpi-y += ec.o |
39 | acpi-$(CONFIG_ACPI_DOCK) += dock.o | 39 | acpi-$(CONFIG_ACPI_DOCK) += dock.o |
40 | acpi-y += pci_root.o pci_link.o pci_irq.o | 40 | acpi-y += pci_root.o pci_link.o pci_irq.o |
41 | acpi-y += csrt.o | ||
42 | acpi-$(CONFIG_X86_INTEL_LPSS) += acpi_lpss.o | 41 | acpi-$(CONFIG_X86_INTEL_LPSS) += acpi_lpss.o |
43 | acpi-y += acpi_platform.o | 42 | acpi-y += acpi_platform.o |
44 | acpi-y += power.o | 43 | acpi-y += power.o |
diff --git a/drivers/acpi/acpi_lpss.c b/drivers/acpi/acpi_lpss.c index b1c95422ce74..652fd5ce303c 100644 --- a/drivers/acpi/acpi_lpss.c +++ b/drivers/acpi/acpi_lpss.c | |||
@@ -35,11 +35,16 @@ ACPI_MODULE_NAME("acpi_lpss"); | |||
35 | 35 | ||
36 | struct lpss_device_desc { | 36 | struct lpss_device_desc { |
37 | bool clk_required; | 37 | bool clk_required; |
38 | const char *clk_parent; | 38 | const char *clkdev_name; |
39 | bool ltr_required; | 39 | bool ltr_required; |
40 | unsigned int prv_offset; | 40 | unsigned int prv_offset; |
41 | }; | 41 | }; |
42 | 42 | ||
43 | static struct lpss_device_desc lpss_dma_desc = { | ||
44 | .clk_required = true, | ||
45 | .clkdev_name = "hclk", | ||
46 | }; | ||
47 | |||
43 | struct lpss_private_data { | 48 | struct lpss_private_data { |
44 | void __iomem *mmio_base; | 49 | void __iomem *mmio_base; |
45 | resource_size_t mmio_size; | 50 | resource_size_t mmio_size; |
@@ -49,7 +54,6 @@ struct lpss_private_data { | |||
49 | 54 | ||
50 | static struct lpss_device_desc lpt_dev_desc = { | 55 | static struct lpss_device_desc lpt_dev_desc = { |
51 | .clk_required = true, | 56 | .clk_required = true, |
52 | .clk_parent = "lpss_clk", | ||
53 | .prv_offset = 0x800, | 57 | .prv_offset = 0x800, |
54 | .ltr_required = true, | 58 | .ltr_required = true, |
55 | }; | 59 | }; |
@@ -60,6 +64,9 @@ static struct lpss_device_desc lpt_sdio_dev_desc = { | |||
60 | }; | 64 | }; |
61 | 65 | ||
62 | static const struct acpi_device_id acpi_lpss_device_ids[] = { | 66 | static const struct acpi_device_id acpi_lpss_device_ids[] = { |
67 | /* Generic LPSS devices */ | ||
68 | { "INTL9C60", (unsigned long)&lpss_dma_desc }, | ||
69 | |||
63 | /* Lynxpoint LPSS devices */ | 70 | /* Lynxpoint LPSS devices */ |
64 | { "INT33C0", (unsigned long)&lpt_dev_desc }, | 71 | { "INT33C0", (unsigned long)&lpt_dev_desc }, |
65 | { "INT33C1", (unsigned long)&lpt_dev_desc }, | 72 | { "INT33C1", (unsigned long)&lpt_dev_desc }, |
@@ -91,16 +98,27 @@ static int register_device_clock(struct acpi_device *adev, | |||
91 | struct lpss_private_data *pdata) | 98 | struct lpss_private_data *pdata) |
92 | { | 99 | { |
93 | const struct lpss_device_desc *dev_desc = pdata->dev_desc; | 100 | const struct lpss_device_desc *dev_desc = pdata->dev_desc; |
101 | struct lpss_clk_data *clk_data; | ||
94 | 102 | ||
95 | if (!lpss_clk_dev) | 103 | if (!lpss_clk_dev) |
96 | lpt_register_clock_device(); | 104 | lpt_register_clock_device(); |
97 | 105 | ||
98 | if (!dev_desc->clk_parent || !pdata->mmio_base | 106 | clk_data = platform_get_drvdata(lpss_clk_dev); |
107 | if (!clk_data) | ||
108 | return -ENODEV; | ||
109 | |||
110 | if (dev_desc->clkdev_name) { | ||
111 | clk_register_clkdev(clk_data->clk, dev_desc->clkdev_name, | ||
112 | dev_name(&adev->dev)); | ||
113 | return 0; | ||
114 | } | ||
115 | |||
116 | if (!pdata->mmio_base | ||
99 | || pdata->mmio_size < dev_desc->prv_offset + LPSS_CLK_SIZE) | 117 | || pdata->mmio_size < dev_desc->prv_offset + LPSS_CLK_SIZE) |
100 | return -ENODATA; | 118 | return -ENODATA; |
101 | 119 | ||
102 | pdata->clk = clk_register_gate(NULL, dev_name(&adev->dev), | 120 | pdata->clk = clk_register_gate(NULL, dev_name(&adev->dev), |
103 | dev_desc->clk_parent, 0, | 121 | clk_data->name, 0, |
104 | pdata->mmio_base + dev_desc->prv_offset, | 122 | pdata->mmio_base + dev_desc->prv_offset, |
105 | 0, 0, NULL); | 123 | 0, 0, NULL); |
106 | if (IS_ERR(pdata->clk)) | 124 | if (IS_ERR(pdata->clk)) |
diff --git a/drivers/acpi/apei/cper.c b/drivers/acpi/apei/cper.c index fefc2ca7cc3e..33dc6a004802 100644 --- a/drivers/acpi/apei/cper.c +++ b/drivers/acpi/apei/cper.c | |||
@@ -250,10 +250,6 @@ static const char *cper_pcie_port_type_strs[] = { | |||
250 | static void cper_print_pcie(const char *pfx, const struct cper_sec_pcie *pcie, | 250 | static void cper_print_pcie(const char *pfx, const struct cper_sec_pcie *pcie, |
251 | const struct acpi_hest_generic_data *gdata) | 251 | const struct acpi_hest_generic_data *gdata) |
252 | { | 252 | { |
253 | #ifdef CONFIG_ACPI_APEI_PCIEAER | ||
254 | struct pci_dev *dev; | ||
255 | #endif | ||
256 | |||
257 | if (pcie->validation_bits & CPER_PCIE_VALID_PORT_TYPE) | 253 | if (pcie->validation_bits & CPER_PCIE_VALID_PORT_TYPE) |
258 | printk("%s""port_type: %d, %s\n", pfx, pcie->port_type, | 254 | printk("%s""port_type: %d, %s\n", pfx, pcie->port_type, |
259 | pcie->port_type < ARRAY_SIZE(cper_pcie_port_type_strs) ? | 255 | pcie->port_type < ARRAY_SIZE(cper_pcie_port_type_strs) ? |
@@ -285,20 +281,6 @@ static void cper_print_pcie(const char *pfx, const struct cper_sec_pcie *pcie, | |||
285 | printk( | 281 | printk( |
286 | "%s""bridge: secondary_status: 0x%04x, control: 0x%04x\n", | 282 | "%s""bridge: secondary_status: 0x%04x, control: 0x%04x\n", |
287 | pfx, pcie->bridge.secondary_status, pcie->bridge.control); | 283 | pfx, pcie->bridge.secondary_status, pcie->bridge.control); |
288 | #ifdef CONFIG_ACPI_APEI_PCIEAER | ||
289 | dev = pci_get_domain_bus_and_slot(pcie->device_id.segment, | ||
290 | pcie->device_id.bus, pcie->device_id.function); | ||
291 | if (!dev) { | ||
292 | pr_err("PCI AER Cannot get PCI device %04x:%02x:%02x.%d\n", | ||
293 | pcie->device_id.segment, pcie->device_id.bus, | ||
294 | pcie->device_id.slot, pcie->device_id.function); | ||
295 | return; | ||
296 | } | ||
297 | if (pcie->validation_bits & CPER_PCIE_VALID_AER_INFO) | ||
298 | cper_print_aer(pfx, dev, gdata->error_severity, | ||
299 | (struct aer_capability_regs *) pcie->aer_info); | ||
300 | pci_dev_put(dev); | ||
301 | #endif | ||
302 | } | 284 | } |
303 | 285 | ||
304 | static const char *apei_estatus_section_flag_strs[] = { | 286 | static const char *apei_estatus_section_flag_strs[] = { |
diff --git a/drivers/acpi/apei/ghes.c b/drivers/acpi/apei/ghes.c index d668a8ae602b..403baf4dffc1 100644 --- a/drivers/acpi/apei/ghes.c +++ b/drivers/acpi/apei/ghes.c | |||
@@ -454,7 +454,9 @@ static void ghes_do_proc(struct ghes *ghes, | |||
454 | aer_severity = cper_severity_to_aer(sev); | 454 | aer_severity = cper_severity_to_aer(sev); |
455 | aer_recover_queue(pcie_err->device_id.segment, | 455 | aer_recover_queue(pcie_err->device_id.segment, |
456 | pcie_err->device_id.bus, | 456 | pcie_err->device_id.bus, |
457 | devfn, aer_severity); | 457 | devfn, aer_severity, |
458 | (struct aer_capability_regs *) | ||
459 | pcie_err->aer_info); | ||
458 | } | 460 | } |
459 | 461 | ||
460 | } | 462 | } |
diff --git a/drivers/acpi/csrt.c b/drivers/acpi/csrt.c deleted file mode 100644 index 5c15a91faf0b..000000000000 --- a/drivers/acpi/csrt.c +++ /dev/null | |||
@@ -1,159 +0,0 @@ | |||
1 | /* | ||
2 | * Support for Core System Resources Table (CSRT) | ||
3 | * | ||
4 | * Copyright (C) 2013, Intel Corporation | ||
5 | * Authors: Mika Westerberg <mika.westerberg@linux.intel.com> | ||
6 | * Andy Shevchenko <andriy.shevchenko@linux.intel.com> | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License version 2 as | ||
10 | * published by the Free Software Foundation. | ||
11 | */ | ||
12 | |||
13 | #define pr_fmt(fmt) "ACPI: CSRT: " fmt | ||
14 | |||
15 | #include <linux/acpi.h> | ||
16 | #include <linux/device.h> | ||
17 | #include <linux/kernel.h> | ||
18 | #include <linux/module.h> | ||
19 | #include <linux/platform_device.h> | ||
20 | #include <linux/sizes.h> | ||
21 | |||
22 | ACPI_MODULE_NAME("CSRT"); | ||
23 | |||
24 | static int __init acpi_csrt_parse_shared_info(struct platform_device *pdev, | ||
25 | const struct acpi_csrt_group *grp) | ||
26 | { | ||
27 | const struct acpi_csrt_shared_info *si; | ||
28 | struct resource res[3]; | ||
29 | size_t nres; | ||
30 | int ret; | ||
31 | |||
32 | memset(res, 0, sizeof(res)); | ||
33 | nres = 0; | ||
34 | |||
35 | si = (const struct acpi_csrt_shared_info *)&grp[1]; | ||
36 | /* | ||
37 | * The peripherals that are listed on CSRT typically support only | ||
38 | * 32-bit addresses so we only use the low part of MMIO base for | ||
39 | * now. | ||
40 | */ | ||
41 | if (!si->mmio_base_high && si->mmio_base_low) { | ||
42 | /* | ||
43 | * There is no size of the memory resource in shared_info | ||
44 | * so we assume that it is 4k here. | ||
45 | */ | ||
46 | res[nres].start = si->mmio_base_low; | ||
47 | res[nres].end = res[0].start + SZ_4K - 1; | ||
48 | res[nres++].flags = IORESOURCE_MEM; | ||
49 | } | ||
50 | |||
51 | if (si->gsi_interrupt) { | ||
52 | int irq = acpi_register_gsi(NULL, si->gsi_interrupt, | ||
53 | si->interrupt_mode, | ||
54 | si->interrupt_polarity); | ||
55 | res[nres].start = irq; | ||
56 | res[nres].end = irq; | ||
57 | res[nres++].flags = IORESOURCE_IRQ; | ||
58 | } | ||
59 | |||
60 | if (si->base_request_line || si->num_handshake_signals) { | ||
61 | /* | ||
62 | * We pass the driver a DMA resource describing the range | ||
63 | * of request lines the device supports. | ||
64 | */ | ||
65 | res[nres].start = si->base_request_line; | ||
66 | res[nres].end = res[nres].start + si->num_handshake_signals - 1; | ||
67 | res[nres++].flags = IORESOURCE_DMA; | ||
68 | } | ||
69 | |||
70 | ret = platform_device_add_resources(pdev, res, nres); | ||
71 | if (ret) { | ||
72 | if (si->gsi_interrupt) | ||
73 | acpi_unregister_gsi(si->gsi_interrupt); | ||
74 | return ret; | ||
75 | } | ||
76 | |||
77 | return 0; | ||
78 | } | ||
79 | |||
80 | static int __init | ||
81 | acpi_csrt_parse_resource_group(const struct acpi_csrt_group *grp) | ||
82 | { | ||
83 | struct platform_device *pdev; | ||
84 | char vendor[5], name[16]; | ||
85 | int ret, i; | ||
86 | |||
87 | vendor[0] = grp->vendor_id; | ||
88 | vendor[1] = grp->vendor_id >> 8; | ||
89 | vendor[2] = grp->vendor_id >> 16; | ||
90 | vendor[3] = grp->vendor_id >> 24; | ||
91 | vendor[4] = '\0'; | ||
92 | |||
93 | if (grp->shared_info_length != sizeof(struct acpi_csrt_shared_info)) | ||
94 | return -ENODEV; | ||
95 | |||
96 | snprintf(name, sizeof(name), "%s%04X", vendor, grp->device_id); | ||
97 | pdev = platform_device_alloc(name, PLATFORM_DEVID_AUTO); | ||
98 | if (!pdev) | ||
99 | return -ENOMEM; | ||
100 | |||
101 | /* Add resources based on the shared info */ | ||
102 | ret = acpi_csrt_parse_shared_info(pdev, grp); | ||
103 | if (ret) | ||
104 | goto fail; | ||
105 | |||
106 | ret = platform_device_add(pdev); | ||
107 | if (ret) | ||
108 | goto fail; | ||
109 | |||
110 | for (i = 0; i < pdev->num_resources; i++) | ||
111 | dev_dbg(&pdev->dev, "%pR\n", &pdev->resource[i]); | ||
112 | |||
113 | return 0; | ||
114 | |||
115 | fail: | ||
116 | platform_device_put(pdev); | ||
117 | return ret; | ||
118 | } | ||
119 | |||
120 | /* | ||
121 | * CSRT or Core System Resources Table is a proprietary ACPI table | ||
122 | * introduced by Microsoft. This table can contain devices that are not in | ||
123 | * the system DSDT table. In particular DMA controllers might be described | ||
124 | * here. | ||
125 | * | ||
126 | * We present these devices as normal platform devices that don't have ACPI | ||
127 | * IDs or handle. The platform device name will be something like | ||
128 | * <VENDOR><DEVID>.<n>.auto for example: INTL9C06.0.auto. | ||
129 | */ | ||
130 | void __init acpi_csrt_init(void) | ||
131 | { | ||
132 | struct acpi_csrt_group *grp, *end; | ||
133 | struct acpi_table_csrt *csrt; | ||
134 | acpi_status status; | ||
135 | int ret; | ||
136 | |||
137 | status = acpi_get_table(ACPI_SIG_CSRT, 0, | ||
138 | (struct acpi_table_header **)&csrt); | ||
139 | if (ACPI_FAILURE(status)) { | ||
140 | if (status != AE_NOT_FOUND) | ||
141 | pr_warn("failed to get the CSRT table\n"); | ||
142 | return; | ||
143 | } | ||
144 | |||
145 | pr_debug("parsing CSRT table for devices\n"); | ||
146 | |||
147 | grp = (struct acpi_csrt_group *)(csrt + 1); | ||
148 | end = (struct acpi_csrt_group *)((void *)csrt + csrt->header.length); | ||
149 | |||
150 | while (grp < end) { | ||
151 | ret = acpi_csrt_parse_resource_group(grp); | ||
152 | if (ret) { | ||
153 | pr_warn("error in parsing resource group: %d\n", ret); | ||
154 | return; | ||
155 | } | ||
156 | |||
157 | grp = (struct acpi_csrt_group *)((void *)grp + grp->length); | ||
158 | } | ||
159 | } | ||
diff --git a/drivers/acpi/device_pm.c b/drivers/acpi/device_pm.c index 96de787e6104..bc493aa3af19 100644 --- a/drivers/acpi/device_pm.c +++ b/drivers/acpi/device_pm.c | |||
@@ -37,68 +37,6 @@ | |||
37 | #define _COMPONENT ACPI_POWER_COMPONENT | 37 | #define _COMPONENT ACPI_POWER_COMPONENT |
38 | ACPI_MODULE_NAME("device_pm"); | 38 | ACPI_MODULE_NAME("device_pm"); |
39 | 39 | ||
40 | static DEFINE_MUTEX(acpi_pm_notifier_lock); | ||
41 | |||
42 | /** | ||
43 | * acpi_add_pm_notifier - Register PM notifier for given ACPI device. | ||
44 | * @adev: ACPI device to add the notifier for. | ||
45 | * @context: Context information to pass to the notifier routine. | ||
46 | * | ||
47 | * NOTE: @adev need not be a run-wake or wakeup device to be a valid source of | ||
48 | * PM wakeup events. For example, wakeup events may be generated for bridges | ||
49 | * if one of the devices below the bridge is signaling wakeup, even if the | ||
50 | * bridge itself doesn't have a wakeup GPE associated with it. | ||
51 | */ | ||
52 | acpi_status acpi_add_pm_notifier(struct acpi_device *adev, | ||
53 | acpi_notify_handler handler, void *context) | ||
54 | { | ||
55 | acpi_status status = AE_ALREADY_EXISTS; | ||
56 | |||
57 | mutex_lock(&acpi_pm_notifier_lock); | ||
58 | |||
59 | if (adev->wakeup.flags.notifier_present) | ||
60 | goto out; | ||
61 | |||
62 | status = acpi_install_notify_handler(adev->handle, | ||
63 | ACPI_SYSTEM_NOTIFY, | ||
64 | handler, context); | ||
65 | if (ACPI_FAILURE(status)) | ||
66 | goto out; | ||
67 | |||
68 | adev->wakeup.flags.notifier_present = true; | ||
69 | |||
70 | out: | ||
71 | mutex_unlock(&acpi_pm_notifier_lock); | ||
72 | return status; | ||
73 | } | ||
74 | |||
75 | /** | ||
76 | * acpi_remove_pm_notifier - Unregister PM notifier from given ACPI device. | ||
77 | * @adev: ACPI device to remove the notifier from. | ||
78 | */ | ||
79 | acpi_status acpi_remove_pm_notifier(struct acpi_device *adev, | ||
80 | acpi_notify_handler handler) | ||
81 | { | ||
82 | acpi_status status = AE_BAD_PARAMETER; | ||
83 | |||
84 | mutex_lock(&acpi_pm_notifier_lock); | ||
85 | |||
86 | if (!adev->wakeup.flags.notifier_present) | ||
87 | goto out; | ||
88 | |||
89 | status = acpi_remove_notify_handler(adev->handle, | ||
90 | ACPI_SYSTEM_NOTIFY, | ||
91 | handler); | ||
92 | if (ACPI_FAILURE(status)) | ||
93 | goto out; | ||
94 | |||
95 | adev->wakeup.flags.notifier_present = false; | ||
96 | |||
97 | out: | ||
98 | mutex_unlock(&acpi_pm_notifier_lock); | ||
99 | return status; | ||
100 | } | ||
101 | |||
102 | /** | 40 | /** |
103 | * acpi_power_state_string - String representation of ACPI device power state. | 41 | * acpi_power_state_string - String representation of ACPI device power state. |
104 | * @state: ACPI device power state to return the string representation of. | 42 | * @state: ACPI device power state to return the string representation of. |
@@ -385,6 +323,69 @@ bool acpi_bus_power_manageable(acpi_handle handle) | |||
385 | } | 323 | } |
386 | EXPORT_SYMBOL(acpi_bus_power_manageable); | 324 | EXPORT_SYMBOL(acpi_bus_power_manageable); |
387 | 325 | ||
326 | #ifdef CONFIG_PM | ||
327 | static DEFINE_MUTEX(acpi_pm_notifier_lock); | ||
328 | |||
329 | /** | ||
330 | * acpi_add_pm_notifier - Register PM notifier for given ACPI device. | ||
331 | * @adev: ACPI device to add the notifier for. | ||
332 | * @context: Context information to pass to the notifier routine. | ||
333 | * | ||
334 | * NOTE: @adev need not be a run-wake or wakeup device to be a valid source of | ||
335 | * PM wakeup events. For example, wakeup events may be generated for bridges | ||
336 | * if one of the devices below the bridge is signaling wakeup, even if the | ||
337 | * bridge itself doesn't have a wakeup GPE associated with it. | ||
338 | */ | ||
339 | acpi_status acpi_add_pm_notifier(struct acpi_device *adev, | ||
340 | acpi_notify_handler handler, void *context) | ||
341 | { | ||
342 | acpi_status status = AE_ALREADY_EXISTS; | ||
343 | |||
344 | mutex_lock(&acpi_pm_notifier_lock); | ||
345 | |||
346 | if (adev->wakeup.flags.notifier_present) | ||
347 | goto out; | ||
348 | |||
349 | status = acpi_install_notify_handler(adev->handle, | ||
350 | ACPI_SYSTEM_NOTIFY, | ||
351 | handler, context); | ||
352 | if (ACPI_FAILURE(status)) | ||
353 | goto out; | ||
354 | |||
355 | adev->wakeup.flags.notifier_present = true; | ||
356 | |||
357 | out: | ||
358 | mutex_unlock(&acpi_pm_notifier_lock); | ||
359 | return status; | ||
360 | } | ||
361 | |||
362 | /** | ||
363 | * acpi_remove_pm_notifier - Unregister PM notifier from given ACPI device. | ||
364 | * @adev: ACPI device to remove the notifier from. | ||
365 | */ | ||
366 | acpi_status acpi_remove_pm_notifier(struct acpi_device *adev, | ||
367 | acpi_notify_handler handler) | ||
368 | { | ||
369 | acpi_status status = AE_BAD_PARAMETER; | ||
370 | |||
371 | mutex_lock(&acpi_pm_notifier_lock); | ||
372 | |||
373 | if (!adev->wakeup.flags.notifier_present) | ||
374 | goto out; | ||
375 | |||
376 | status = acpi_remove_notify_handler(adev->handle, | ||
377 | ACPI_SYSTEM_NOTIFY, | ||
378 | handler); | ||
379 | if (ACPI_FAILURE(status)) | ||
380 | goto out; | ||
381 | |||
382 | adev->wakeup.flags.notifier_present = false; | ||
383 | |||
384 | out: | ||
385 | mutex_unlock(&acpi_pm_notifier_lock); | ||
386 | return status; | ||
387 | } | ||
388 | |||
388 | bool acpi_bus_can_wakeup(acpi_handle handle) | 389 | bool acpi_bus_can_wakeup(acpi_handle handle) |
389 | { | 390 | { |
390 | struct acpi_device *device; | 391 | struct acpi_device *device; |
@@ -1023,3 +1024,4 @@ void acpi_dev_pm_remove_dependent(acpi_handle handle, struct device *depdev) | |||
1023 | mutex_unlock(&adev->physical_node_lock); | 1024 | mutex_unlock(&adev->physical_node_lock); |
1024 | } | 1025 | } |
1025 | EXPORT_SYMBOL_GPL(acpi_dev_pm_remove_dependent); | 1026 | EXPORT_SYMBOL_GPL(acpi_dev_pm_remove_dependent); |
1027 | #endif /* CONFIG_PM */ | ||
diff --git a/drivers/acpi/internal.h b/drivers/acpi/internal.h index 6f1afd9118c8..297cbf456f86 100644 --- a/drivers/acpi/internal.h +++ b/drivers/acpi/internal.h | |||
@@ -35,7 +35,6 @@ void acpi_pci_link_init(void); | |||
35 | void acpi_pci_root_hp_init(void); | 35 | void acpi_pci_root_hp_init(void); |
36 | void acpi_platform_init(void); | 36 | void acpi_platform_init(void); |
37 | int acpi_sysfs_init(void); | 37 | int acpi_sysfs_init(void); |
38 | void acpi_csrt_init(void); | ||
39 | #ifdef CONFIG_ACPI_CONTAINER | 38 | #ifdef CONFIG_ACPI_CONTAINER |
40 | void acpi_container_init(void); | 39 | void acpi_container_init(void); |
41 | #else | 40 | #else |
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c index c1bc608339a6..44225cb15f3a 100644 --- a/drivers/acpi/scan.c +++ b/drivers/acpi/scan.c | |||
@@ -2043,7 +2043,6 @@ int __init acpi_scan_init(void) | |||
2043 | acpi_pci_link_init(); | 2043 | acpi_pci_link_init(); |
2044 | acpi_platform_init(); | 2044 | acpi_platform_init(); |
2045 | acpi_lpss_init(); | 2045 | acpi_lpss_init(); |
2046 | acpi_csrt_init(); | ||
2047 | acpi_container_init(); | 2046 | acpi_container_init(); |
2048 | acpi_memory_hotplug_init(); | 2047 | acpi_memory_hotplug_init(); |
2049 | 2048 | ||
diff --git a/drivers/acpi/video_detect.c b/drivers/acpi/video_detect.c index 66f67626f02e..e6bd910bc6ed 100644 --- a/drivers/acpi/video_detect.c +++ b/drivers/acpi/video_detect.c | |||
@@ -161,6 +161,14 @@ static struct dmi_system_id video_detect_dmi_table[] = { | |||
161 | DMI_MATCH(DMI_PRODUCT_NAME, "UL30VT"), | 161 | DMI_MATCH(DMI_PRODUCT_NAME, "UL30VT"), |
162 | }, | 162 | }, |
163 | }, | 163 | }, |
164 | { | ||
165 | .callback = video_detect_force_vendor, | ||
166 | .ident = "Asus UL30A", | ||
167 | .matches = { | ||
168 | DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."), | ||
169 | DMI_MATCH(DMI_PRODUCT_NAME, "UL30A"), | ||
170 | }, | ||
171 | }, | ||
164 | { }, | 172 | { }, |
165 | }; | 173 | }; |
166 | 174 | ||
diff --git a/drivers/bcma/scan.c b/drivers/bcma/scan.c index bca9c80056fe..8bffa5c9818c 100644 --- a/drivers/bcma/scan.c +++ b/drivers/bcma/scan.c | |||
@@ -84,6 +84,8 @@ static const struct bcma_device_id_name bcma_bcm_device_names[] = { | |||
84 | { BCMA_CORE_I2S, "I2S" }, | 84 | { BCMA_CORE_I2S, "I2S" }, |
85 | { BCMA_CORE_SDR_DDR1_MEM_CTL, "SDR/DDR1 Memory Controller" }, | 85 | { BCMA_CORE_SDR_DDR1_MEM_CTL, "SDR/DDR1 Memory Controller" }, |
86 | { BCMA_CORE_SHIM, "SHIM" }, | 86 | { BCMA_CORE_SHIM, "SHIM" }, |
87 | { BCMA_CORE_PCIE2, "PCIe Gen2" }, | ||
88 | { BCMA_CORE_ARM_CR4, "ARM CR4" }, | ||
87 | { BCMA_CORE_DEFAULT, "Default" }, | 89 | { BCMA_CORE_DEFAULT, "Default" }, |
88 | }; | 90 | }; |
89 | 91 | ||
diff --git a/drivers/block/brd.c b/drivers/block/brd.c index f1a29f8e9d33..9bf4371755f2 100644 --- a/drivers/block/brd.c +++ b/drivers/block/brd.c | |||
@@ -117,13 +117,13 @@ static struct page *brd_insert_page(struct brd_device *brd, sector_t sector) | |||
117 | 117 | ||
118 | spin_lock(&brd->brd_lock); | 118 | spin_lock(&brd->brd_lock); |
119 | idx = sector >> PAGE_SECTORS_SHIFT; | 119 | idx = sector >> PAGE_SECTORS_SHIFT; |
120 | page->index = idx; | ||
120 | if (radix_tree_insert(&brd->brd_pages, idx, page)) { | 121 | if (radix_tree_insert(&brd->brd_pages, idx, page)) { |
121 | __free_page(page); | 122 | __free_page(page); |
122 | page = radix_tree_lookup(&brd->brd_pages, idx); | 123 | page = radix_tree_lookup(&brd->brd_pages, idx); |
123 | BUG_ON(!page); | 124 | BUG_ON(!page); |
124 | BUG_ON(page->index != idx); | 125 | BUG_ON(page->index != idx); |
125 | } else | 126 | } |
126 | page->index = idx; | ||
127 | spin_unlock(&brd->brd_lock); | 127 | spin_unlock(&brd->brd_lock); |
128 | 128 | ||
129 | radix_tree_preload_end(); | 129 | radix_tree_preload_end(); |
diff --git a/drivers/block/xsysace.c b/drivers/block/xsysace.c index f8ef15f37c5e..3fd130fdfbc1 100644 --- a/drivers/block/xsysace.c +++ b/drivers/block/xsysace.c | |||
@@ -1160,8 +1160,7 @@ static int ace_probe(struct platform_device *dev) | |||
1160 | dev_dbg(&dev->dev, "ace_probe(%p)\n", dev); | 1160 | dev_dbg(&dev->dev, "ace_probe(%p)\n", dev); |
1161 | 1161 | ||
1162 | /* device id and bus width */ | 1162 | /* device id and bus width */ |
1163 | of_property_read_u32(dev->dev.of_node, "port-number", &id); | 1163 | if (of_property_read_u32(dev->dev.of_node, "port-number", &id)) |
1164 | if (id < 0) | ||
1165 | id = 0; | 1164 | id = 0; |
1166 | if (of_find_property(dev->dev.of_node, "8-bit", NULL)) | 1165 | if (of_find_property(dev->dev.of_node, "8-bit", NULL)) |
1167 | bus_width = ACE_BUS_WIDTH_8; | 1166 | bus_width = ACE_BUS_WIDTH_8; |
diff --git a/drivers/char/random.c b/drivers/char/random.c index cd9a6211dcad..35487e8ded59 100644 --- a/drivers/char/random.c +++ b/drivers/char/random.c | |||
@@ -865,16 +865,24 @@ static size_t account(struct entropy_store *r, size_t nbytes, int min, | |||
865 | if (r->entropy_count / 8 < min + reserved) { | 865 | if (r->entropy_count / 8 < min + reserved) { |
866 | nbytes = 0; | 866 | nbytes = 0; |
867 | } else { | 867 | } else { |
868 | int entropy_count, orig; | ||
869 | retry: | ||
870 | entropy_count = orig = ACCESS_ONCE(r->entropy_count); | ||
868 | /* If limited, never pull more than available */ | 871 | /* If limited, never pull more than available */ |
869 | if (r->limit && nbytes + reserved >= r->entropy_count / 8) | 872 | if (r->limit && nbytes + reserved >= entropy_count / 8) |
870 | nbytes = r->entropy_count/8 - reserved; | 873 | nbytes = entropy_count/8 - reserved; |
871 | 874 | ||
872 | if (r->entropy_count / 8 >= nbytes + reserved) | 875 | if (entropy_count / 8 >= nbytes + reserved) { |
873 | r->entropy_count -= nbytes*8; | 876 | entropy_count -= nbytes*8; |
874 | else | 877 | if (cmpxchg(&r->entropy_count, orig, entropy_count) != orig) |
875 | r->entropy_count = reserved; | 878 | goto retry; |
879 | } else { | ||
880 | entropy_count = reserved; | ||
881 | if (cmpxchg(&r->entropy_count, orig, entropy_count) != orig) | ||
882 | goto retry; | ||
883 | } | ||
876 | 884 | ||
877 | if (r->entropy_count < random_write_wakeup_thresh) | 885 | if (entropy_count < random_write_wakeup_thresh) |
878 | wakeup_write = 1; | 886 | wakeup_write = 1; |
879 | } | 887 | } |
880 | 888 | ||
@@ -957,10 +965,23 @@ static ssize_t extract_entropy(struct entropy_store *r, void *buf, | |||
957 | { | 965 | { |
958 | ssize_t ret = 0, i; | 966 | ssize_t ret = 0, i; |
959 | __u8 tmp[EXTRACT_SIZE]; | 967 | __u8 tmp[EXTRACT_SIZE]; |
968 | unsigned long flags; | ||
960 | 969 | ||
961 | /* if last_data isn't primed, we need EXTRACT_SIZE extra bytes */ | 970 | /* if last_data isn't primed, we need EXTRACT_SIZE extra bytes */ |
962 | if (fips_enabled && !r->last_data_init) | 971 | if (fips_enabled) { |
963 | nbytes += EXTRACT_SIZE; | 972 | spin_lock_irqsave(&r->lock, flags); |
973 | if (!r->last_data_init) { | ||
974 | r->last_data_init = true; | ||
975 | spin_unlock_irqrestore(&r->lock, flags); | ||
976 | trace_extract_entropy(r->name, EXTRACT_SIZE, | ||
977 | r->entropy_count, _RET_IP_); | ||
978 | xfer_secondary_pool(r, EXTRACT_SIZE); | ||
979 | extract_buf(r, tmp); | ||
980 | spin_lock_irqsave(&r->lock, flags); | ||
981 | memcpy(r->last_data, tmp, EXTRACT_SIZE); | ||
982 | } | ||
983 | spin_unlock_irqrestore(&r->lock, flags); | ||
984 | } | ||
964 | 985 | ||
965 | trace_extract_entropy(r->name, nbytes, r->entropy_count, _RET_IP_); | 986 | trace_extract_entropy(r->name, nbytes, r->entropy_count, _RET_IP_); |
966 | xfer_secondary_pool(r, nbytes); | 987 | xfer_secondary_pool(r, nbytes); |
@@ -970,19 +991,6 @@ static ssize_t extract_entropy(struct entropy_store *r, void *buf, | |||
970 | extract_buf(r, tmp); | 991 | extract_buf(r, tmp); |
971 | 992 | ||
972 | if (fips_enabled) { | 993 | if (fips_enabled) { |
973 | unsigned long flags; | ||
974 | |||
975 | |||
976 | /* prime last_data value if need be, per fips 140-2 */ | ||
977 | if (!r->last_data_init) { | ||
978 | spin_lock_irqsave(&r->lock, flags); | ||
979 | memcpy(r->last_data, tmp, EXTRACT_SIZE); | ||
980 | r->last_data_init = true; | ||
981 | nbytes -= EXTRACT_SIZE; | ||
982 | spin_unlock_irqrestore(&r->lock, flags); | ||
983 | extract_buf(r, tmp); | ||
984 | } | ||
985 | |||
986 | spin_lock_irqsave(&r->lock, flags); | 994 | spin_lock_irqsave(&r->lock, flags); |
987 | if (!memcmp(tmp, r->last_data, EXTRACT_SIZE)) | 995 | if (!memcmp(tmp, r->last_data, EXTRACT_SIZE)) |
988 | panic("Hardware RNG duplicated output!\n"); | 996 | panic("Hardware RNG duplicated output!\n"); |
diff --git a/drivers/clk/clk-si5351.c b/drivers/clk/clk-si5351.c index 892728412e9d..24f553673b72 100644 --- a/drivers/clk/clk-si5351.c +++ b/drivers/clk/clk-si5351.c | |||
@@ -932,7 +932,7 @@ static unsigned long si5351_clkout_recalc_rate(struct clk_hw *hw, | |||
932 | unsigned char reg; | 932 | unsigned char reg; |
933 | unsigned char rdiv; | 933 | unsigned char rdiv; |
934 | 934 | ||
935 | if (hwdata->num > 5) | 935 | if (hwdata->num <= 5) |
936 | reg = si5351_msynth_params_address(hwdata->num) + 2; | 936 | reg = si5351_msynth_params_address(hwdata->num) + 2; |
937 | else | 937 | else |
938 | reg = SI5351_CLK6_7_OUTPUT_DIVIDER; | 938 | reg = SI5351_CLK6_7_OUTPUT_DIVIDER; |
@@ -1477,6 +1477,16 @@ static int si5351_i2c_probe(struct i2c_client *client, | |||
1477 | return -EINVAL; | 1477 | return -EINVAL; |
1478 | } | 1478 | } |
1479 | drvdata->onecell.clks[n] = clk; | 1479 | drvdata->onecell.clks[n] = clk; |
1480 | |||
1481 | /* set initial clkout rate */ | ||
1482 | if (pdata->clkout[n].rate != 0) { | ||
1483 | int ret; | ||
1484 | ret = clk_set_rate(clk, pdata->clkout[n].rate); | ||
1485 | if (ret != 0) { | ||
1486 | dev_err(&client->dev, "Cannot set rate : %d\n", | ||
1487 | ret); | ||
1488 | } | ||
1489 | } | ||
1480 | } | 1490 | } |
1481 | 1491 | ||
1482 | ret = of_clk_add_provider(client->dev.of_node, of_clk_src_onecell_get, | 1492 | ret = of_clk_add_provider(client->dev.of_node, of_clk_src_onecell_get, |
diff --git a/drivers/clk/clk-vt8500.c b/drivers/clk/clk-vt8500.c index debf688afa8e..553ac35bcc91 100644 --- a/drivers/clk/clk-vt8500.c +++ b/drivers/clk/clk-vt8500.c | |||
@@ -183,7 +183,7 @@ static int vt8500_dclk_set_rate(struct clk_hw *hw, unsigned long rate, | |||
183 | writel(divisor, cdev->div_reg); | 183 | writel(divisor, cdev->div_reg); |
184 | vt8500_pmc_wait_busy(); | 184 | vt8500_pmc_wait_busy(); |
185 | 185 | ||
186 | spin_lock_irqsave(cdev->lock, flags); | 186 | spin_unlock_irqrestore(cdev->lock, flags); |
187 | 187 | ||
188 | return 0; | 188 | return 0; |
189 | } | 189 | } |
diff --git a/drivers/clk/mxs/clk-imx28.c b/drivers/clk/mxs/clk-imx28.c index d0e5eed146de..4faf0afc44cd 100644 --- a/drivers/clk/mxs/clk-imx28.c +++ b/drivers/clk/mxs/clk-imx28.c | |||
@@ -10,6 +10,7 @@ | |||
10 | */ | 10 | */ |
11 | 11 | ||
12 | #include <linux/clk.h> | 12 | #include <linux/clk.h> |
13 | #include <linux/clk/mxs.h> | ||
13 | #include <linux/clkdev.h> | 14 | #include <linux/clkdev.h> |
14 | #include <linux/err.h> | 15 | #include <linux/err.h> |
15 | #include <linux/init.h> | 16 | #include <linux/init.h> |
diff --git a/drivers/clk/samsung/clk-exynos4.c b/drivers/clk/samsung/clk-exynos4.c index d0940e69d034..3c1f88868f29 100644 --- a/drivers/clk/samsung/clk-exynos4.c +++ b/drivers/clk/samsung/clk-exynos4.c | |||
@@ -791,7 +791,8 @@ struct samsung_gate_clock exynos4210_gate_clks[] __initdata = { | |||
791 | GATE(smmu_pcie, "smmu_pcie", "aclk133", GATE_IP_FSYS, 18, 0, 0), | 791 | GATE(smmu_pcie, "smmu_pcie", "aclk133", GATE_IP_FSYS, 18, 0, 0), |
792 | GATE(modemif, "modemif", "aclk100", GATE_IP_PERIL, 28, 0, 0), | 792 | GATE(modemif, "modemif", "aclk100", GATE_IP_PERIL, 28, 0, 0), |
793 | GATE(chipid, "chipid", "aclk100", E4210_GATE_IP_PERIR, 0, 0, 0), | 793 | GATE(chipid, "chipid", "aclk100", E4210_GATE_IP_PERIR, 0, 0, 0), |
794 | GATE(sysreg, "sysreg", "aclk100", E4210_GATE_IP_PERIR, 0, 0, 0), | 794 | GATE(sysreg, "sysreg", "aclk100", E4210_GATE_IP_PERIR, 0, |
795 | CLK_IGNORE_UNUSED, 0), | ||
795 | GATE(hdmi_cec, "hdmi_cec", "aclk100", E4210_GATE_IP_PERIR, 11, 0, 0), | 796 | GATE(hdmi_cec, "hdmi_cec", "aclk100", E4210_GATE_IP_PERIR, 11, 0, 0), |
796 | GATE(smmu_rotator, "smmu_rotator", "aclk200", | 797 | GATE(smmu_rotator, "smmu_rotator", "aclk200", |
797 | E4210_GATE_IP_IMAGE, 4, 0, 0), | 798 | E4210_GATE_IP_IMAGE, 4, 0, 0), |
@@ -819,7 +820,8 @@ struct samsung_gate_clock exynos4x12_gate_clks[] __initdata = { | |||
819 | GATE(smmu_mdma, "smmu_mdma", "aclk200", E4X12_GATE_IP_IMAGE, 5, 0, 0), | 820 | GATE(smmu_mdma, "smmu_mdma", "aclk200", E4X12_GATE_IP_IMAGE, 5, 0, 0), |
820 | GATE(mipi_hsi, "mipi_hsi", "aclk133", GATE_IP_FSYS, 10, 0, 0), | 821 | GATE(mipi_hsi, "mipi_hsi", "aclk133", GATE_IP_FSYS, 10, 0, 0), |
821 | GATE(chipid, "chipid", "aclk100", E4X12_GATE_IP_PERIR, 0, 0, 0), | 822 | GATE(chipid, "chipid", "aclk100", E4X12_GATE_IP_PERIR, 0, 0, 0), |
822 | GATE(sysreg, "sysreg", "aclk100", E4X12_GATE_IP_PERIR, 1, 0, 0), | 823 | GATE(sysreg, "sysreg", "aclk100", E4X12_GATE_IP_PERIR, 1, |
824 | CLK_IGNORE_UNUSED, 0), | ||
823 | GATE(hdmi_cec, "hdmi_cec", "aclk100", E4X12_GATE_IP_PERIR, 11, 0, 0), | 825 | GATE(hdmi_cec, "hdmi_cec", "aclk100", E4X12_GATE_IP_PERIR, 11, 0, 0), |
824 | GATE(sclk_mdnie0, "sclk_mdnie0", "div_mdnie0", | 826 | GATE(sclk_mdnie0, "sclk_mdnie0", "div_mdnie0", |
825 | SRC_MASK_LCD0, 4, CLK_SET_RATE_PARENT, 0), | 827 | SRC_MASK_LCD0, 4, CLK_SET_RATE_PARENT, 0), |
diff --git a/drivers/clk/tegra/clk-tegra20.c b/drivers/clk/tegra/clk-tegra20.c index 8292a00c3de9..075db0c99edb 100644 --- a/drivers/clk/tegra/clk-tegra20.c +++ b/drivers/clk/tegra/clk-tegra20.c | |||
@@ -872,6 +872,14 @@ static void __init tegra20_periph_clk_init(void) | |||
872 | struct clk *clk; | 872 | struct clk *clk; |
873 | int i; | 873 | int i; |
874 | 874 | ||
875 | /* ac97 */ | ||
876 | clk = tegra_clk_register_periph_gate("ac97", "pll_a_out0", | ||
877 | TEGRA_PERIPH_ON_APB, | ||
878 | clk_base, 0, 3, &periph_l_regs, | ||
879 | periph_clk_enb_refcnt); | ||
880 | clk_register_clkdev(clk, NULL, "tegra20-ac97"); | ||
881 | clks[ac97] = clk; | ||
882 | |||
875 | /* apbdma */ | 883 | /* apbdma */ |
876 | clk = tegra_clk_register_periph_gate("apbdma", "pclk", 0, clk_base, | 884 | clk = tegra_clk_register_periph_gate("apbdma", "pclk", 0, clk_base, |
877 | 0, 34, &periph_h_regs, | 885 | 0, 34, &periph_h_regs, |
@@ -1234,9 +1242,6 @@ static __initdata struct tegra_clk_init_table init_table[] = { | |||
1234 | {uartc, pll_p, 0, 0}, | 1242 | {uartc, pll_p, 0, 0}, |
1235 | {uartd, pll_p, 0, 0}, | 1243 | {uartd, pll_p, 0, 0}, |
1236 | {uarte, pll_p, 0, 0}, | 1244 | {uarte, pll_p, 0, 0}, |
1237 | {usbd, clk_max, 12000000, 0}, | ||
1238 | {usb2, clk_max, 12000000, 0}, | ||
1239 | {usb3, clk_max, 12000000, 0}, | ||
1240 | {pll_a, clk_max, 56448000, 1}, | 1245 | {pll_a, clk_max, 56448000, 1}, |
1241 | {pll_a_out0, clk_max, 11289600, 1}, | 1246 | {pll_a_out0, clk_max, 11289600, 1}, |
1242 | {cdev1, clk_max, 0, 1}, | 1247 | {cdev1, clk_max, 0, 1}, |
diff --git a/drivers/clk/ux500/clk-sysctrl.c b/drivers/clk/ux500/clk-sysctrl.c index bc7e9bde792b..e364c9d4aa60 100644 --- a/drivers/clk/ux500/clk-sysctrl.c +++ b/drivers/clk/ux500/clk-sysctrl.c | |||
@@ -145,7 +145,13 @@ static struct clk *clk_reg_sysctrl(struct device *dev, | |||
145 | return ERR_PTR(-ENOMEM); | 145 | return ERR_PTR(-ENOMEM); |
146 | } | 146 | } |
147 | 147 | ||
148 | for (i = 0; i < num_parents; i++) { | 148 | /* set main clock registers */ |
149 | clk->reg_sel[0] = reg_sel[0]; | ||
150 | clk->reg_bits[0] = reg_bits[0]; | ||
151 | clk->reg_mask[0] = reg_mask[0]; | ||
152 | |||
153 | /* handle clocks with more than one parent */ | ||
154 | for (i = 1; i < num_parents; i++) { | ||
149 | clk->reg_sel[i] = reg_sel[i]; | 155 | clk->reg_sel[i] = reg_sel[i]; |
150 | clk->reg_bits[i] = reg_bits[i]; | 156 | clk->reg_bits[i] = reg_bits[i]; |
151 | clk->reg_mask[i] = reg_mask[i]; | 157 | clk->reg_mask[i] = reg_mask[i]; |
diff --git a/drivers/clk/ux500/u8500_clk.c b/drivers/clk/ux500/u8500_clk.c index 0b4f35a5ffc2..80069c370a47 100644 --- a/drivers/clk/ux500/u8500_clk.c +++ b/drivers/clk/ux500/u8500_clk.c | |||
@@ -325,7 +325,7 @@ void u8500_clk_init(u32 clkrst1_base, u32 clkrst2_base, u32 clkrst3_base, | |||
325 | clk = clk_reg_prcc_pclk("p3_pclk0", "per3clk", clkrst3_base, | 325 | clk = clk_reg_prcc_pclk("p3_pclk0", "per3clk", clkrst3_base, |
326 | BIT(0), 0); | 326 | BIT(0), 0); |
327 | clk_register_clkdev(clk, "fsmc", NULL); | 327 | clk_register_clkdev(clk, "fsmc", NULL); |
328 | clk_register_clkdev(clk, NULL, "smsc911x"); | 328 | clk_register_clkdev(clk, NULL, "smsc911x.0"); |
329 | 329 | ||
330 | clk = clk_reg_prcc_pclk("p3_pclk1", "per3clk", clkrst3_base, | 330 | clk = clk_reg_prcc_pclk("p3_pclk1", "per3clk", clkrst3_base, |
331 | BIT(1), 0); | 331 | BIT(1), 0); |
diff --git a/drivers/clk/x86/clk-lpt.c b/drivers/clk/x86/clk-lpt.c index 5cf4f4686406..4f45eee9e33b 100644 --- a/drivers/clk/x86/clk-lpt.c +++ b/drivers/clk/x86/clk-lpt.c | |||
@@ -15,22 +15,29 @@ | |||
15 | #include <linux/clk-provider.h> | 15 | #include <linux/clk-provider.h> |
16 | #include <linux/err.h> | 16 | #include <linux/err.h> |
17 | #include <linux/module.h> | 17 | #include <linux/module.h> |
18 | #include <linux/platform_data/clk-lpss.h> | ||
18 | #include <linux/platform_device.h> | 19 | #include <linux/platform_device.h> |
19 | 20 | ||
20 | #define PRV_CLOCK_PARAMS 0x800 | 21 | #define PRV_CLOCK_PARAMS 0x800 |
21 | 22 | ||
22 | static int lpt_clk_probe(struct platform_device *pdev) | 23 | static int lpt_clk_probe(struct platform_device *pdev) |
23 | { | 24 | { |
25 | struct lpss_clk_data *drvdata; | ||
24 | struct clk *clk; | 26 | struct clk *clk; |
25 | 27 | ||
28 | drvdata = devm_kzalloc(&pdev->dev, sizeof(*drvdata), GFP_KERNEL); | ||
29 | if (!drvdata) | ||
30 | return -ENOMEM; | ||
31 | |||
26 | /* LPSS free running clock */ | 32 | /* LPSS free running clock */ |
27 | clk = clk_register_fixed_rate(&pdev->dev, "lpss_clk", NULL, CLK_IS_ROOT, | 33 | drvdata->name = "lpss_clk"; |
28 | 100000000); | 34 | clk = clk_register_fixed_rate(&pdev->dev, drvdata->name, NULL, |
35 | CLK_IS_ROOT, 100000000); | ||
29 | if (IS_ERR(clk)) | 36 | if (IS_ERR(clk)) |
30 | return PTR_ERR(clk); | 37 | return PTR_ERR(clk); |
31 | 38 | ||
32 | /* Shared DMA clock */ | 39 | drvdata->clk = clk; |
33 | clk_register_clkdev(clk, "hclk", "INTL9C60.0.auto"); | 40 | platform_set_drvdata(pdev, drvdata); |
34 | return 0; | 41 | return 0; |
35 | } | 42 | } |
36 | 43 | ||
diff --git a/drivers/cpufreq/Kconfig.x86 b/drivers/cpufreq/Kconfig.x86 index 2b8a8c374548..6bd63d63d356 100644 --- a/drivers/cpufreq/Kconfig.x86 +++ b/drivers/cpufreq/Kconfig.x86 | |||
@@ -272,7 +272,7 @@ config X86_LONGHAUL | |||
272 | config X86_E_POWERSAVER | 272 | config X86_E_POWERSAVER |
273 | tristate "VIA C7 Enhanced PowerSaver (DANGEROUS)" | 273 | tristate "VIA C7 Enhanced PowerSaver (DANGEROUS)" |
274 | select CPU_FREQ_TABLE | 274 | select CPU_FREQ_TABLE |
275 | depends on X86_32 | 275 | depends on X86_32 && ACPI_PROCESSOR |
276 | help | 276 | help |
277 | This adds the CPUFreq driver for VIA C7 processors. However, this driver | 277 | This adds the CPUFreq driver for VIA C7 processors. However, this driver |
278 | does not have any safeguards to prevent operating the CPU out of spec | 278 | does not have any safeguards to prevent operating the CPU out of spec |
diff --git a/drivers/cpufreq/arm_big_little_dt.c b/drivers/cpufreq/arm_big_little_dt.c index 173ed059d95f..fd9e3ea6a480 100644 --- a/drivers/cpufreq/arm_big_little_dt.c +++ b/drivers/cpufreq/arm_big_little_dt.c | |||
@@ -19,70 +19,75 @@ | |||
19 | 19 | ||
20 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | 20 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt |
21 | 21 | ||
22 | #include <linux/cpu.h> | ||
22 | #include <linux/cpufreq.h> | 23 | #include <linux/cpufreq.h> |
23 | #include <linux/device.h> | 24 | #include <linux/device.h> |
24 | #include <linux/export.h> | 25 | #include <linux/export.h> |
25 | #include <linux/module.h> | 26 | #include <linux/module.h> |
26 | #include <linux/of.h> | 27 | #include <linux/of.h> |
27 | #include <linux/opp.h> | 28 | #include <linux/opp.h> |
29 | #include <linux/platform_device.h> | ||
28 | #include <linux/slab.h> | 30 | #include <linux/slab.h> |
29 | #include <linux/types.h> | 31 | #include <linux/types.h> |
30 | #include "arm_big_little.h" | 32 | #include "arm_big_little.h" |
31 | 33 | ||
32 | static int dt_init_opp_table(struct device *cpu_dev) | 34 | /* get cpu node with valid operating-points */ |
35 | static struct device_node *get_cpu_node_with_valid_op(int cpu) | ||
33 | { | 36 | { |
34 | struct device_node *np, *parent; | 37 | struct device_node *np = NULL, *parent; |
35 | int count = 0, ret; | 38 | int count = 0; |
36 | 39 | ||
37 | parent = of_find_node_by_path("/cpus"); | 40 | parent = of_find_node_by_path("/cpus"); |
38 | if (!parent) { | 41 | if (!parent) { |
39 | pr_err("failed to find OF /cpus\n"); | 42 | pr_err("failed to find OF /cpus\n"); |
40 | return -ENOENT; | 43 | return NULL; |
41 | } | 44 | } |
42 | 45 | ||
43 | for_each_child_of_node(parent, np) { | 46 | for_each_child_of_node(parent, np) { |
44 | if (count++ != cpu_dev->id) | 47 | if (count++ != cpu) |
45 | continue; | 48 | continue; |
46 | if (!of_get_property(np, "operating-points", NULL)) { | 49 | if (!of_get_property(np, "operating-points", NULL)) { |
47 | ret = -ENODATA; | 50 | of_node_put(np); |
48 | } else { | 51 | np = NULL; |
49 | cpu_dev->of_node = np; | ||
50 | ret = of_init_opp_table(cpu_dev); | ||
51 | } | 52 | } |
52 | of_node_put(np); | ||
53 | of_node_put(parent); | ||
54 | 53 | ||
55 | return ret; | 54 | break; |
56 | } | 55 | } |
57 | 56 | ||
58 | return -ENODEV; | 57 | of_node_put(parent); |
58 | return np; | ||
59 | } | ||
60 | |||
61 | static int dt_init_opp_table(struct device *cpu_dev) | ||
62 | { | ||
63 | struct device_node *np; | ||
64 | int ret; | ||
65 | |||
66 | np = get_cpu_node_with_valid_op(cpu_dev->id); | ||
67 | if (!np) | ||
68 | return -ENODATA; | ||
69 | |||
70 | cpu_dev->of_node = np; | ||
71 | ret = of_init_opp_table(cpu_dev); | ||
72 | of_node_put(np); | ||
73 | |||
74 | return ret; | ||
59 | } | 75 | } |
60 | 76 | ||
61 | static int dt_get_transition_latency(struct device *cpu_dev) | 77 | static int dt_get_transition_latency(struct device *cpu_dev) |
62 | { | 78 | { |
63 | struct device_node *np, *parent; | 79 | struct device_node *np; |
64 | u32 transition_latency = CPUFREQ_ETERNAL; | 80 | u32 transition_latency = CPUFREQ_ETERNAL; |
65 | int count = 0; | ||
66 | 81 | ||
67 | parent = of_find_node_by_path("/cpus"); | 82 | np = get_cpu_node_with_valid_op(cpu_dev->id); |
68 | if (!parent) { | 83 | if (!np) |
69 | pr_info("Failed to find OF /cpus. Use CPUFREQ_ETERNAL transition latency\n"); | ||
70 | return CPUFREQ_ETERNAL; | 84 | return CPUFREQ_ETERNAL; |
71 | } | ||
72 | |||
73 | for_each_child_of_node(parent, np) { | ||
74 | if (count++ != cpu_dev->id) | ||
75 | continue; | ||
76 | 85 | ||
77 | of_property_read_u32(np, "clock-latency", &transition_latency); | 86 | of_property_read_u32(np, "clock-latency", &transition_latency); |
78 | of_node_put(np); | 87 | of_node_put(np); |
79 | of_node_put(parent); | ||
80 | 88 | ||
81 | return transition_latency; | 89 | pr_debug("%s: clock-latency: %d\n", __func__, transition_latency); |
82 | } | 90 | return transition_latency; |
83 | |||
84 | pr_info("clock-latency isn't found, use CPUFREQ_ETERNAL transition latency\n"); | ||
85 | return CPUFREQ_ETERNAL; | ||
86 | } | 91 | } |
87 | 92 | ||
88 | static struct cpufreq_arm_bL_ops dt_bL_ops = { | 93 | static struct cpufreq_arm_bL_ops dt_bL_ops = { |
@@ -91,17 +96,33 @@ static struct cpufreq_arm_bL_ops dt_bL_ops = { | |||
91 | .init_opp_table = dt_init_opp_table, | 96 | .init_opp_table = dt_init_opp_table, |
92 | }; | 97 | }; |
93 | 98 | ||
94 | static int generic_bL_init(void) | 99 | static int generic_bL_probe(struct platform_device *pdev) |
95 | { | 100 | { |
101 | struct device_node *np; | ||
102 | |||
103 | np = get_cpu_node_with_valid_op(0); | ||
104 | if (!np) | ||
105 | return -ENODEV; | ||
106 | |||
107 | of_node_put(np); | ||
96 | return bL_cpufreq_register(&dt_bL_ops); | 108 | return bL_cpufreq_register(&dt_bL_ops); |
97 | } | 109 | } |
98 | module_init(generic_bL_init); | ||
99 | 110 | ||
100 | static void generic_bL_exit(void) | 111 | static int generic_bL_remove(struct platform_device *pdev) |
101 | { | 112 | { |
102 | return bL_cpufreq_unregister(&dt_bL_ops); | 113 | bL_cpufreq_unregister(&dt_bL_ops); |
114 | return 0; | ||
103 | } | 115 | } |
104 | module_exit(generic_bL_exit); | 116 | |
117 | static struct platform_driver generic_bL_platdrv = { | ||
118 | .driver = { | ||
119 | .name = "arm-bL-cpufreq-dt", | ||
120 | .owner = THIS_MODULE, | ||
121 | }, | ||
122 | .probe = generic_bL_probe, | ||
123 | .remove = generic_bL_remove, | ||
124 | }; | ||
125 | module_platform_driver(generic_bL_platdrv); | ||
105 | 126 | ||
106 | MODULE_AUTHOR("Viresh Kumar <viresh.kumar@linaro.org>"); | 127 | MODULE_AUTHOR("Viresh Kumar <viresh.kumar@linaro.org>"); |
107 | MODULE_DESCRIPTION("Generic ARM big LITTLE cpufreq driver via DT"); | 128 | MODULE_DESCRIPTION("Generic ARM big LITTLE cpufreq driver via DT"); |
diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c index 4b8c7f297d74..2d53f47d1747 100644 --- a/drivers/cpufreq/cpufreq.c +++ b/drivers/cpufreq/cpufreq.c | |||
@@ -1729,18 +1729,23 @@ static int __cpufreq_set_policy(struct cpufreq_policy *data, | |||
1729 | /* end old governor */ | 1729 | /* end old governor */ |
1730 | if (data->governor) { | 1730 | if (data->governor) { |
1731 | __cpufreq_governor(data, CPUFREQ_GOV_STOP); | 1731 | __cpufreq_governor(data, CPUFREQ_GOV_STOP); |
1732 | unlock_policy_rwsem_write(policy->cpu); | ||
1732 | __cpufreq_governor(data, | 1733 | __cpufreq_governor(data, |
1733 | CPUFREQ_GOV_POLICY_EXIT); | 1734 | CPUFREQ_GOV_POLICY_EXIT); |
1735 | lock_policy_rwsem_write(policy->cpu); | ||
1734 | } | 1736 | } |
1735 | 1737 | ||
1736 | /* start new governor */ | 1738 | /* start new governor */ |
1737 | data->governor = policy->governor; | 1739 | data->governor = policy->governor; |
1738 | if (!__cpufreq_governor(data, CPUFREQ_GOV_POLICY_INIT)) { | 1740 | if (!__cpufreq_governor(data, CPUFREQ_GOV_POLICY_INIT)) { |
1739 | if (!__cpufreq_governor(data, CPUFREQ_GOV_START)) | 1741 | if (!__cpufreq_governor(data, CPUFREQ_GOV_START)) { |
1740 | failed = 0; | 1742 | failed = 0; |
1741 | else | 1743 | } else { |
1744 | unlock_policy_rwsem_write(policy->cpu); | ||
1742 | __cpufreq_governor(data, | 1745 | __cpufreq_governor(data, |
1743 | CPUFREQ_GOV_POLICY_EXIT); | 1746 | CPUFREQ_GOV_POLICY_EXIT); |
1747 | lock_policy_rwsem_write(policy->cpu); | ||
1748 | } | ||
1744 | } | 1749 | } |
1745 | 1750 | ||
1746 | if (failed) { | 1751 | if (failed) { |
diff --git a/drivers/cpufreq/intel_pstate.c b/drivers/cpufreq/intel_pstate.c index 9c36ace92a39..07f2840ad805 100644 --- a/drivers/cpufreq/intel_pstate.c +++ b/drivers/cpufreq/intel_pstate.c | |||
@@ -521,6 +521,7 @@ static void intel_pstate_timer_func(unsigned long __data) | |||
521 | static const struct x86_cpu_id intel_pstate_cpu_ids[] = { | 521 | static const struct x86_cpu_id intel_pstate_cpu_ids[] = { |
522 | ICPU(0x2a, default_policy), | 522 | ICPU(0x2a, default_policy), |
523 | ICPU(0x2d, default_policy), | 523 | ICPU(0x2d, default_policy), |
524 | ICPU(0x3a, default_policy), | ||
524 | {} | 525 | {} |
525 | }; | 526 | }; |
526 | MODULE_DEVICE_TABLE(x86cpu, intel_pstate_cpu_ids); | 527 | MODULE_DEVICE_TABLE(x86cpu, intel_pstate_cpu_ids); |
diff --git a/drivers/crypto/caam/caamalg.c b/drivers/crypto/caam/caamalg.c index 765fdf5ce579..bf416a8391a7 100644 --- a/drivers/crypto/caam/caamalg.c +++ b/drivers/crypto/caam/caamalg.c | |||
@@ -1154,7 +1154,7 @@ static struct aead_edesc *aead_edesc_alloc(struct aead_request *req, | |||
1154 | dst_nents = sg_count(req->dst, req->cryptlen, &dst_chained); | 1154 | dst_nents = sg_count(req->dst, req->cryptlen, &dst_chained); |
1155 | 1155 | ||
1156 | sgc = dma_map_sg_chained(jrdev, req->assoc, assoc_nents ? : 1, | 1156 | sgc = dma_map_sg_chained(jrdev, req->assoc, assoc_nents ? : 1, |
1157 | DMA_BIDIRECTIONAL, assoc_chained); | 1157 | DMA_TO_DEVICE, assoc_chained); |
1158 | if (likely(req->src == req->dst)) { | 1158 | if (likely(req->src == req->dst)) { |
1159 | sgc = dma_map_sg_chained(jrdev, req->src, src_nents ? : 1, | 1159 | sgc = dma_map_sg_chained(jrdev, req->src, src_nents ? : 1, |
1160 | DMA_BIDIRECTIONAL, src_chained); | 1160 | DMA_BIDIRECTIONAL, src_chained); |
@@ -1336,7 +1336,7 @@ static struct aead_edesc *aead_giv_edesc_alloc(struct aead_givcrypt_request | |||
1336 | dst_nents = sg_count(req->dst, req->cryptlen, &dst_chained); | 1336 | dst_nents = sg_count(req->dst, req->cryptlen, &dst_chained); |
1337 | 1337 | ||
1338 | sgc = dma_map_sg_chained(jrdev, req->assoc, assoc_nents ? : 1, | 1338 | sgc = dma_map_sg_chained(jrdev, req->assoc, assoc_nents ? : 1, |
1339 | DMA_BIDIRECTIONAL, assoc_chained); | 1339 | DMA_TO_DEVICE, assoc_chained); |
1340 | if (likely(req->src == req->dst)) { | 1340 | if (likely(req->src == req->dst)) { |
1341 | sgc = dma_map_sg_chained(jrdev, req->src, src_nents ? : 1, | 1341 | sgc = dma_map_sg_chained(jrdev, req->src, src_nents ? : 1, |
1342 | DMA_BIDIRECTIONAL, src_chained); | 1342 | DMA_BIDIRECTIONAL, src_chained); |
diff --git a/drivers/crypto/nx/nx-aes-cbc.c b/drivers/crypto/nx/nx-aes-cbc.c index a76d4c4f29f5..35d483f8db66 100644 --- a/drivers/crypto/nx/nx-aes-cbc.c +++ b/drivers/crypto/nx/nx-aes-cbc.c | |||
@@ -126,6 +126,7 @@ struct crypto_alg nx_cbc_aes_alg = { | |||
126 | .cra_blocksize = AES_BLOCK_SIZE, | 126 | .cra_blocksize = AES_BLOCK_SIZE, |
127 | .cra_ctxsize = sizeof(struct nx_crypto_ctx), | 127 | .cra_ctxsize = sizeof(struct nx_crypto_ctx), |
128 | .cra_type = &crypto_blkcipher_type, | 128 | .cra_type = &crypto_blkcipher_type, |
129 | .cra_alignmask = 0xf, | ||
129 | .cra_module = THIS_MODULE, | 130 | .cra_module = THIS_MODULE, |
130 | .cra_init = nx_crypto_ctx_aes_cbc_init, | 131 | .cra_init = nx_crypto_ctx_aes_cbc_init, |
131 | .cra_exit = nx_crypto_ctx_exit, | 132 | .cra_exit = nx_crypto_ctx_exit, |
diff --git a/drivers/crypto/nx/nx-aes-ecb.c b/drivers/crypto/nx/nx-aes-ecb.c index ba5f1611336f..7bbc9a81da21 100644 --- a/drivers/crypto/nx/nx-aes-ecb.c +++ b/drivers/crypto/nx/nx-aes-ecb.c | |||
@@ -123,6 +123,7 @@ struct crypto_alg nx_ecb_aes_alg = { | |||
123 | .cra_priority = 300, | 123 | .cra_priority = 300, |
124 | .cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER, | 124 | .cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER, |
125 | .cra_blocksize = AES_BLOCK_SIZE, | 125 | .cra_blocksize = AES_BLOCK_SIZE, |
126 | .cra_alignmask = 0xf, | ||
126 | .cra_ctxsize = sizeof(struct nx_crypto_ctx), | 127 | .cra_ctxsize = sizeof(struct nx_crypto_ctx), |
127 | .cra_type = &crypto_blkcipher_type, | 128 | .cra_type = &crypto_blkcipher_type, |
128 | .cra_module = THIS_MODULE, | 129 | .cra_module = THIS_MODULE, |
diff --git a/drivers/crypto/nx/nx-aes-gcm.c b/drivers/crypto/nx/nx-aes-gcm.c index c8109edc5cfb..6cca6c392b00 100644 --- a/drivers/crypto/nx/nx-aes-gcm.c +++ b/drivers/crypto/nx/nx-aes-gcm.c | |||
@@ -219,7 +219,7 @@ static int gcm_aes_nx_crypt(struct aead_request *req, int enc) | |||
219 | if (enc) | 219 | if (enc) |
220 | NX_CPB_FDM(csbcpb) |= NX_FDM_ENDE_ENCRYPT; | 220 | NX_CPB_FDM(csbcpb) |= NX_FDM_ENDE_ENCRYPT; |
221 | else | 221 | else |
222 | nbytes -= AES_BLOCK_SIZE; | 222 | nbytes -= crypto_aead_authsize(crypto_aead_reqtfm(req)); |
223 | 223 | ||
224 | csbcpb->cpb.aes_gcm.bit_length_data = nbytes * 8; | 224 | csbcpb->cpb.aes_gcm.bit_length_data = nbytes * 8; |
225 | 225 | ||
diff --git a/drivers/crypto/nx/nx-sha256.c b/drivers/crypto/nx/nx-sha256.c index 9767315f8c0b..67024f2f0b78 100644 --- a/drivers/crypto/nx/nx-sha256.c +++ b/drivers/crypto/nx/nx-sha256.c | |||
@@ -69,7 +69,7 @@ static int nx_sha256_update(struct shash_desc *desc, const u8 *data, | |||
69 | * 1: <= SHA256_BLOCK_SIZE: copy into state, return 0 | 69 | * 1: <= SHA256_BLOCK_SIZE: copy into state, return 0 |
70 | * 2: > SHA256_BLOCK_SIZE: process X blocks, copy in leftover | 70 | * 2: > SHA256_BLOCK_SIZE: process X blocks, copy in leftover |
71 | */ | 71 | */ |
72 | if (len + sctx->count <= SHA256_BLOCK_SIZE) { | 72 | if (len + sctx->count < SHA256_BLOCK_SIZE) { |
73 | memcpy(sctx->buf + sctx->count, data, len); | 73 | memcpy(sctx->buf + sctx->count, data, len); |
74 | sctx->count += len; | 74 | sctx->count += len; |
75 | goto out; | 75 | goto out; |
@@ -110,7 +110,8 @@ static int nx_sha256_update(struct shash_desc *desc, const u8 *data, | |||
110 | atomic_inc(&(nx_ctx->stats->sha256_ops)); | 110 | atomic_inc(&(nx_ctx->stats->sha256_ops)); |
111 | 111 | ||
112 | /* copy the leftover back into the state struct */ | 112 | /* copy the leftover back into the state struct */ |
113 | memcpy(sctx->buf, data + len - leftover, leftover); | 113 | if (leftover) |
114 | memcpy(sctx->buf, data + len - leftover, leftover); | ||
114 | sctx->count = leftover; | 115 | sctx->count = leftover; |
115 | 116 | ||
116 | csbcpb->cpb.sha256.message_bit_length += (u64) | 117 | csbcpb->cpb.sha256.message_bit_length += (u64) |
@@ -130,6 +131,7 @@ static int nx_sha256_final(struct shash_desc *desc, u8 *out) | |||
130 | struct nx_sg *in_sg, *out_sg; | 131 | struct nx_sg *in_sg, *out_sg; |
131 | int rc; | 132 | int rc; |
132 | 133 | ||
134 | |||
133 | if (NX_CPB_FDM(csbcpb) & NX_FDM_CONTINUATION) { | 135 | if (NX_CPB_FDM(csbcpb) & NX_FDM_CONTINUATION) { |
134 | /* we've hit the nx chip previously, now we're finalizing, | 136 | /* we've hit the nx chip previously, now we're finalizing, |
135 | * so copy over the partial digest */ | 137 | * so copy over the partial digest */ |
@@ -162,7 +164,7 @@ static int nx_sha256_final(struct shash_desc *desc, u8 *out) | |||
162 | 164 | ||
163 | atomic_inc(&(nx_ctx->stats->sha256_ops)); | 165 | atomic_inc(&(nx_ctx->stats->sha256_ops)); |
164 | 166 | ||
165 | atomic64_add(csbcpb->cpb.sha256.message_bit_length, | 167 | atomic64_add(csbcpb->cpb.sha256.message_bit_length / 8, |
166 | &(nx_ctx->stats->sha256_bytes)); | 168 | &(nx_ctx->stats->sha256_bytes)); |
167 | memcpy(out, csbcpb->cpb.sha256.message_digest, SHA256_DIGEST_SIZE); | 169 | memcpy(out, csbcpb->cpb.sha256.message_digest, SHA256_DIGEST_SIZE); |
168 | out: | 170 | out: |
diff --git a/drivers/crypto/nx/nx-sha512.c b/drivers/crypto/nx/nx-sha512.c index 3177b8c3d5f1..08eee1122349 100644 --- a/drivers/crypto/nx/nx-sha512.c +++ b/drivers/crypto/nx/nx-sha512.c | |||
@@ -69,7 +69,7 @@ static int nx_sha512_update(struct shash_desc *desc, const u8 *data, | |||
69 | * 1: <= SHA512_BLOCK_SIZE: copy into state, return 0 | 69 | * 1: <= SHA512_BLOCK_SIZE: copy into state, return 0 |
70 | * 2: > SHA512_BLOCK_SIZE: process X blocks, copy in leftover | 70 | * 2: > SHA512_BLOCK_SIZE: process X blocks, copy in leftover |
71 | */ | 71 | */ |
72 | if ((u64)len + sctx->count[0] <= SHA512_BLOCK_SIZE) { | 72 | if ((u64)len + sctx->count[0] < SHA512_BLOCK_SIZE) { |
73 | memcpy(sctx->buf + sctx->count[0], data, len); | 73 | memcpy(sctx->buf + sctx->count[0], data, len); |
74 | sctx->count[0] += len; | 74 | sctx->count[0] += len; |
75 | goto out; | 75 | goto out; |
@@ -110,7 +110,8 @@ static int nx_sha512_update(struct shash_desc *desc, const u8 *data, | |||
110 | atomic_inc(&(nx_ctx->stats->sha512_ops)); | 110 | atomic_inc(&(nx_ctx->stats->sha512_ops)); |
111 | 111 | ||
112 | /* copy the leftover back into the state struct */ | 112 | /* copy the leftover back into the state struct */ |
113 | memcpy(sctx->buf, data + len - leftover, leftover); | 113 | if (leftover) |
114 | memcpy(sctx->buf, data + len - leftover, leftover); | ||
114 | sctx->count[0] = leftover; | 115 | sctx->count[0] = leftover; |
115 | 116 | ||
116 | spbc_bits = csbcpb->cpb.sha512.spbc * 8; | 117 | spbc_bits = csbcpb->cpb.sha512.spbc * 8; |
@@ -168,7 +169,7 @@ static int nx_sha512_final(struct shash_desc *desc, u8 *out) | |||
168 | goto out; | 169 | goto out; |
169 | 170 | ||
170 | atomic_inc(&(nx_ctx->stats->sha512_ops)); | 171 | atomic_inc(&(nx_ctx->stats->sha512_ops)); |
171 | atomic64_add(csbcpb->cpb.sha512.message_bit_length_lo, | 172 | atomic64_add(csbcpb->cpb.sha512.message_bit_length_lo / 8, |
172 | &(nx_ctx->stats->sha512_bytes)); | 173 | &(nx_ctx->stats->sha512_bytes)); |
173 | 174 | ||
174 | memcpy(out, csbcpb->cpb.sha512.message_digest, SHA512_DIGEST_SIZE); | 175 | memcpy(out, csbcpb->cpb.sha512.message_digest, SHA512_DIGEST_SIZE); |
diff --git a/drivers/crypto/nx/nx.c b/drivers/crypto/nx/nx.c index c767f232e693..bbdab6e5ccf0 100644 --- a/drivers/crypto/nx/nx.c +++ b/drivers/crypto/nx/nx.c | |||
@@ -211,44 +211,20 @@ int nx_build_sg_lists(struct nx_crypto_ctx *nx_ctx, | |||
211 | { | 211 | { |
212 | struct nx_sg *nx_insg = nx_ctx->in_sg; | 212 | struct nx_sg *nx_insg = nx_ctx->in_sg; |
213 | struct nx_sg *nx_outsg = nx_ctx->out_sg; | 213 | struct nx_sg *nx_outsg = nx_ctx->out_sg; |
214 | struct blkcipher_walk walk; | ||
215 | int rc; | ||
216 | |||
217 | blkcipher_walk_init(&walk, dst, src, nbytes); | ||
218 | rc = blkcipher_walk_virt_block(desc, &walk, AES_BLOCK_SIZE); | ||
219 | if (rc) | ||
220 | goto out; | ||
221 | 214 | ||
222 | if (iv) | 215 | if (iv) |
223 | memcpy(iv, walk.iv, AES_BLOCK_SIZE); | 216 | memcpy(iv, desc->info, AES_BLOCK_SIZE); |
224 | 217 | ||
225 | while (walk.nbytes) { | 218 | nx_insg = nx_walk_and_build(nx_insg, nx_ctx->ap->sglen, src, 0, nbytes); |
226 | nx_insg = nx_build_sg_list(nx_insg, walk.src.virt.addr, | 219 | nx_outsg = nx_walk_and_build(nx_outsg, nx_ctx->ap->sglen, dst, 0, nbytes); |
227 | walk.nbytes, nx_ctx->ap->sglen); | ||
228 | nx_outsg = nx_build_sg_list(nx_outsg, walk.dst.virt.addr, | ||
229 | walk.nbytes, nx_ctx->ap->sglen); | ||
230 | |||
231 | rc = blkcipher_walk_done(desc, &walk, 0); | ||
232 | if (rc) | ||
233 | break; | ||
234 | } | ||
235 | |||
236 | if (walk.nbytes) { | ||
237 | nx_insg = nx_build_sg_list(nx_insg, walk.src.virt.addr, | ||
238 | walk.nbytes, nx_ctx->ap->sglen); | ||
239 | nx_outsg = nx_build_sg_list(nx_outsg, walk.dst.virt.addr, | ||
240 | walk.nbytes, nx_ctx->ap->sglen); | ||
241 | |||
242 | rc = 0; | ||
243 | } | ||
244 | 220 | ||
245 | /* these lengths should be negative, which will indicate to phyp that | 221 | /* these lengths should be negative, which will indicate to phyp that |
246 | * the input and output parameters are scatterlists, not linear | 222 | * the input and output parameters are scatterlists, not linear |
247 | * buffers */ | 223 | * buffers */ |
248 | nx_ctx->op.inlen = (nx_ctx->in_sg - nx_insg) * sizeof(struct nx_sg); | 224 | nx_ctx->op.inlen = (nx_ctx->in_sg - nx_insg) * sizeof(struct nx_sg); |
249 | nx_ctx->op.outlen = (nx_ctx->out_sg - nx_outsg) * sizeof(struct nx_sg); | 225 | nx_ctx->op.outlen = (nx_ctx->out_sg - nx_outsg) * sizeof(struct nx_sg); |
250 | out: | 226 | |
251 | return rc; | 227 | return 0; |
252 | } | 228 | } |
253 | 229 | ||
254 | /** | 230 | /** |
@@ -454,6 +430,8 @@ static int nx_register_algs(void) | |||
454 | if (rc) | 430 | if (rc) |
455 | goto out; | 431 | goto out; |
456 | 432 | ||
433 | nx_driver.of.status = NX_OKAY; | ||
434 | |||
457 | rc = crypto_register_alg(&nx_ecb_aes_alg); | 435 | rc = crypto_register_alg(&nx_ecb_aes_alg); |
458 | if (rc) | 436 | if (rc) |
459 | goto out; | 437 | goto out; |
@@ -498,8 +476,6 @@ static int nx_register_algs(void) | |||
498 | if (rc) | 476 | if (rc) |
499 | goto out_unreg_s512; | 477 | goto out_unreg_s512; |
500 | 478 | ||
501 | nx_driver.of.status = NX_OKAY; | ||
502 | |||
503 | goto out; | 479 | goto out; |
504 | 480 | ||
505 | out_unreg_s512: | 481 | out_unreg_s512: |
diff --git a/drivers/dma/acpi-dma.c b/drivers/dma/acpi-dma.c index ba6fc62e9651..5a18f82f732a 100644 --- a/drivers/dma/acpi-dma.c +++ b/drivers/dma/acpi-dma.c | |||
@@ -4,7 +4,8 @@ | |||
4 | * Based on of-dma.c | 4 | * Based on of-dma.c |
5 | * | 5 | * |
6 | * Copyright (C) 2013, Intel Corporation | 6 | * Copyright (C) 2013, Intel Corporation |
7 | * Author: Andy Shevchenko <andriy.shevchenko@linux.intel.com> | 7 | * Authors: Andy Shevchenko <andriy.shevchenko@linux.intel.com> |
8 | * Mika Westerberg <mika.westerberg@linux.intel.com> | ||
8 | * | 9 | * |
9 | * This program is free software; you can redistribute it and/or modify | 10 | * This program is free software; you can redistribute it and/or modify |
10 | * it under the terms of the GNU General Public License version 2 as | 11 | * it under the terms of the GNU General Public License version 2 as |
@@ -16,6 +17,7 @@ | |||
16 | #include <linux/list.h> | 17 | #include <linux/list.h> |
17 | #include <linux/mutex.h> | 18 | #include <linux/mutex.h> |
18 | #include <linux/slab.h> | 19 | #include <linux/slab.h> |
20 | #include <linux/ioport.h> | ||
19 | #include <linux/acpi.h> | 21 | #include <linux/acpi.h> |
20 | #include <linux/acpi_dma.h> | 22 | #include <linux/acpi_dma.h> |
21 | 23 | ||
@@ -23,6 +25,117 @@ static LIST_HEAD(acpi_dma_list); | |||
23 | static DEFINE_MUTEX(acpi_dma_lock); | 25 | static DEFINE_MUTEX(acpi_dma_lock); |
24 | 26 | ||
25 | /** | 27 | /** |
28 | * acpi_dma_parse_resource_group - match device and parse resource group | ||
29 | * @grp: CSRT resource group | ||
30 | * @adev: ACPI device to match with | ||
31 | * @adma: struct acpi_dma of the given DMA controller | ||
32 | * | ||
33 | * Returns 1 on success, 0 when no information is available, or appropriate | ||
34 | * errno value on error. | ||
35 | * | ||
36 | * In order to match a device from DSDT table to the corresponding CSRT device | ||
37 | * we use MMIO address and IRQ. | ||
38 | */ | ||
39 | static int acpi_dma_parse_resource_group(const struct acpi_csrt_group *grp, | ||
40 | struct acpi_device *adev, struct acpi_dma *adma) | ||
41 | { | ||
42 | const struct acpi_csrt_shared_info *si; | ||
43 | struct list_head resource_list; | ||
44 | struct resource_list_entry *rentry; | ||
45 | resource_size_t mem = 0, irq = 0; | ||
46 | u32 vendor_id; | ||
47 | int ret; | ||
48 | |||
49 | if (grp->shared_info_length != sizeof(struct acpi_csrt_shared_info)) | ||
50 | return -ENODEV; | ||
51 | |||
52 | INIT_LIST_HEAD(&resource_list); | ||
53 | ret = acpi_dev_get_resources(adev, &resource_list, NULL, NULL); | ||
54 | if (ret <= 0) | ||
55 | return 0; | ||
56 | |||
57 | list_for_each_entry(rentry, &resource_list, node) { | ||
58 | if (resource_type(&rentry->res) == IORESOURCE_MEM) | ||
59 | mem = rentry->res.start; | ||
60 | else if (resource_type(&rentry->res) == IORESOURCE_IRQ) | ||
61 | irq = rentry->res.start; | ||
62 | } | ||
63 | |||
64 | acpi_dev_free_resource_list(&resource_list); | ||
65 | |||
66 | /* Consider initial zero values as resource not found */ | ||
67 | if (mem == 0 && irq == 0) | ||
68 | return 0; | ||
69 | |||
70 | si = (const struct acpi_csrt_shared_info *)&grp[1]; | ||
71 | |||
72 | /* Match device by MMIO and IRQ */ | ||
73 | if (si->mmio_base_low != mem || si->gsi_interrupt != irq) | ||
74 | return 0; | ||
75 | |||
76 | vendor_id = le32_to_cpu(grp->vendor_id); | ||
77 | dev_dbg(&adev->dev, "matches with %.4s%04X (rev %u)\n", | ||
78 | (char *)&vendor_id, grp->device_id, grp->revision); | ||
79 | |||
80 | /* Check if the request line range is available */ | ||
81 | if (si->base_request_line == 0 && si->num_handshake_signals == 0) | ||
82 | return 0; | ||
83 | |||
84 | adma->base_request_line = si->base_request_line; | ||
85 | adma->end_request_line = si->base_request_line + | ||
86 | si->num_handshake_signals - 1; | ||
87 | |||
88 | dev_dbg(&adev->dev, "request line base: 0x%04x end: 0x%04x\n", | ||
89 | adma->base_request_line, adma->end_request_line); | ||
90 | |||
91 | return 1; | ||
92 | } | ||
93 | |||
94 | /** | ||
95 | * acpi_dma_parse_csrt - parse CSRT to exctract additional DMA resources | ||
96 | * @adev: ACPI device to match with | ||
97 | * @adma: struct acpi_dma of the given DMA controller | ||
98 | * | ||
99 | * CSRT or Core System Resources Table is a proprietary ACPI table | ||
100 | * introduced by Microsoft. This table can contain devices that are not in | ||
101 | * the system DSDT table. In particular DMA controllers might be described | ||
102 | * here. | ||
103 | * | ||
104 | * We are using this table to get the request line range of the specific DMA | ||
105 | * controller to be used later. | ||
106 | * | ||
107 | */ | ||
108 | static void acpi_dma_parse_csrt(struct acpi_device *adev, struct acpi_dma *adma) | ||
109 | { | ||
110 | struct acpi_csrt_group *grp, *end; | ||
111 | struct acpi_table_csrt *csrt; | ||
112 | acpi_status status; | ||
113 | int ret; | ||
114 | |||
115 | status = acpi_get_table(ACPI_SIG_CSRT, 0, | ||
116 | (struct acpi_table_header **)&csrt); | ||
117 | if (ACPI_FAILURE(status)) { | ||
118 | if (status != AE_NOT_FOUND) | ||
119 | dev_warn(&adev->dev, "failed to get the CSRT table\n"); | ||
120 | return; | ||
121 | } | ||
122 | |||
123 | grp = (struct acpi_csrt_group *)(csrt + 1); | ||
124 | end = (struct acpi_csrt_group *)((void *)csrt + csrt->header.length); | ||
125 | |||
126 | while (grp < end) { | ||
127 | ret = acpi_dma_parse_resource_group(grp, adev, adma); | ||
128 | if (ret < 0) { | ||
129 | dev_warn(&adev->dev, | ||
130 | "error in parsing resource group\n"); | ||
131 | return; | ||
132 | } | ||
133 | |||
134 | grp = (struct acpi_csrt_group *)((void *)grp + grp->length); | ||
135 | } | ||
136 | } | ||
137 | |||
138 | /** | ||
26 | * acpi_dma_controller_register - Register a DMA controller to ACPI DMA helpers | 139 | * acpi_dma_controller_register - Register a DMA controller to ACPI DMA helpers |
27 | * @dev: struct device of DMA controller | 140 | * @dev: struct device of DMA controller |
28 | * @acpi_dma_xlate: translation function which converts a dma specifier | 141 | * @acpi_dma_xlate: translation function which converts a dma specifier |
@@ -61,6 +174,8 @@ int acpi_dma_controller_register(struct device *dev, | |||
61 | adma->acpi_dma_xlate = acpi_dma_xlate; | 174 | adma->acpi_dma_xlate = acpi_dma_xlate; |
62 | adma->data = data; | 175 | adma->data = data; |
63 | 176 | ||
177 | acpi_dma_parse_csrt(adev, adma); | ||
178 | |||
64 | /* Now queue acpi_dma controller structure in list */ | 179 | /* Now queue acpi_dma controller structure in list */ |
65 | mutex_lock(&acpi_dma_lock); | 180 | mutex_lock(&acpi_dma_lock); |
66 | list_add_tail(&adma->dma_controllers, &acpi_dma_list); | 181 | list_add_tail(&adma->dma_controllers, &acpi_dma_list); |
@@ -149,6 +264,45 @@ void devm_acpi_dma_controller_free(struct device *dev) | |||
149 | } | 264 | } |
150 | EXPORT_SYMBOL_GPL(devm_acpi_dma_controller_free); | 265 | EXPORT_SYMBOL_GPL(devm_acpi_dma_controller_free); |
151 | 266 | ||
267 | /** | ||
268 | * acpi_dma_update_dma_spec - prepare dma specifier to pass to translation function | ||
269 | * @adma: struct acpi_dma of DMA controller | ||
270 | * @dma_spec: dma specifier to update | ||
271 | * | ||
272 | * Returns 0, if no information is avaiable, -1 on mismatch, and 1 otherwise. | ||
273 | * | ||
274 | * Accordingly to ACPI 5.0 Specification Table 6-170 "Fixed DMA Resource | ||
275 | * Descriptor": | ||
276 | * DMA Request Line bits is a platform-relative number uniquely | ||
277 | * identifying the request line assigned. Request line-to-Controller | ||
278 | * mapping is done in a controller-specific OS driver. | ||
279 | * That's why we can safely adjust slave_id when the appropriate controller is | ||
280 | * found. | ||
281 | */ | ||
282 | static int acpi_dma_update_dma_spec(struct acpi_dma *adma, | ||
283 | struct acpi_dma_spec *dma_spec) | ||
284 | { | ||
285 | /* Set link to the DMA controller device */ | ||
286 | dma_spec->dev = adma->dev; | ||
287 | |||
288 | /* Check if the request line range is available */ | ||
289 | if (adma->base_request_line == 0 && adma->end_request_line == 0) | ||
290 | return 0; | ||
291 | |||
292 | /* Check if slave_id falls to the range */ | ||
293 | if (dma_spec->slave_id < adma->base_request_line || | ||
294 | dma_spec->slave_id > adma->end_request_line) | ||
295 | return -1; | ||
296 | |||
297 | /* | ||
298 | * Here we adjust slave_id. It should be a relative number to the base | ||
299 | * request line. | ||
300 | */ | ||
301 | dma_spec->slave_id -= adma->base_request_line; | ||
302 | |||
303 | return 1; | ||
304 | } | ||
305 | |||
152 | struct acpi_dma_parser_data { | 306 | struct acpi_dma_parser_data { |
153 | struct acpi_dma_spec dma_spec; | 307 | struct acpi_dma_spec dma_spec; |
154 | size_t index; | 308 | size_t index; |
@@ -193,6 +347,7 @@ struct dma_chan *acpi_dma_request_slave_chan_by_index(struct device *dev, | |||
193 | struct acpi_device *adev; | 347 | struct acpi_device *adev; |
194 | struct acpi_dma *adma; | 348 | struct acpi_dma *adma; |
195 | struct dma_chan *chan = NULL; | 349 | struct dma_chan *chan = NULL; |
350 | int found; | ||
196 | 351 | ||
197 | /* Check if the device was enumerated by ACPI */ | 352 | /* Check if the device was enumerated by ACPI */ |
198 | if (!dev || !ACPI_HANDLE(dev)) | 353 | if (!dev || !ACPI_HANDLE(dev)) |
@@ -219,9 +374,20 @@ struct dma_chan *acpi_dma_request_slave_chan_by_index(struct device *dev, | |||
219 | mutex_lock(&acpi_dma_lock); | 374 | mutex_lock(&acpi_dma_lock); |
220 | 375 | ||
221 | list_for_each_entry(adma, &acpi_dma_list, dma_controllers) { | 376 | list_for_each_entry(adma, &acpi_dma_list, dma_controllers) { |
222 | dma_spec->dev = adma->dev; | 377 | /* |
378 | * We are not going to call translation function if slave_id | ||
379 | * doesn't fall to the request range. | ||
380 | */ | ||
381 | found = acpi_dma_update_dma_spec(adma, dma_spec); | ||
382 | if (found < 0) | ||
383 | continue; | ||
223 | chan = adma->acpi_dma_xlate(dma_spec, adma); | 384 | chan = adma->acpi_dma_xlate(dma_spec, adma); |
224 | if (chan) | 385 | /* |
386 | * Try to get a channel only from the DMA controller that | ||
387 | * matches the slave_id. See acpi_dma_update_dma_spec() | ||
388 | * description for the details. | ||
389 | */ | ||
390 | if (found > 0 || chan) | ||
225 | break; | 391 | break; |
226 | } | 392 | } |
227 | 393 | ||
diff --git a/drivers/edac/amd64_edac_inj.c b/drivers/edac/amd64_edac_inj.c index 8c171fa1cb9b..845f04786c2d 100644 --- a/drivers/edac/amd64_edac_inj.c +++ b/drivers/edac/amd64_edac_inj.c | |||
@@ -202,9 +202,9 @@ static DEVICE_ATTR(inject_word, S_IRUGO | S_IWUSR, | |||
202 | amd64_inject_word_show, amd64_inject_word_store); | 202 | amd64_inject_word_show, amd64_inject_word_store); |
203 | static DEVICE_ATTR(inject_ecc_vector, S_IRUGO | S_IWUSR, | 203 | static DEVICE_ATTR(inject_ecc_vector, S_IRUGO | S_IWUSR, |
204 | amd64_inject_ecc_vector_show, amd64_inject_ecc_vector_store); | 204 | amd64_inject_ecc_vector_show, amd64_inject_ecc_vector_store); |
205 | static DEVICE_ATTR(inject_write, S_IRUGO | S_IWUSR, | 205 | static DEVICE_ATTR(inject_write, S_IWUSR, |
206 | NULL, amd64_inject_write_store); | 206 | NULL, amd64_inject_write_store); |
207 | static DEVICE_ATTR(inject_read, S_IRUGO | S_IWUSR, | 207 | static DEVICE_ATTR(inject_read, S_IWUSR, |
208 | NULL, amd64_inject_read_store); | 208 | NULL, amd64_inject_read_store); |
209 | 209 | ||
210 | 210 | ||
diff --git a/drivers/firmware/efi/efivars.c b/drivers/firmware/efi/efivars.c index b623c599e572..8bd1bb6dbe47 100644 --- a/drivers/firmware/efi/efivars.c +++ b/drivers/firmware/efi/efivars.c | |||
@@ -523,13 +523,11 @@ static void efivar_update_sysfs_entries(struct work_struct *work) | |||
523 | struct efivar_entry *entry; | 523 | struct efivar_entry *entry; |
524 | int err; | 524 | int err; |
525 | 525 | ||
526 | entry = kzalloc(sizeof(*entry), GFP_KERNEL); | ||
527 | if (!entry) | ||
528 | return; | ||
529 | |||
530 | /* Add new sysfs entries */ | 526 | /* Add new sysfs entries */ |
531 | while (1) { | 527 | while (1) { |
532 | memset(entry, 0, sizeof(*entry)); | 528 | entry = kzalloc(sizeof(*entry), GFP_KERNEL); |
529 | if (!entry) | ||
530 | return; | ||
533 | 531 | ||
534 | err = efivar_init(efivar_update_sysfs_entry, entry, | 532 | err = efivar_init(efivar_update_sysfs_entry, entry, |
535 | true, false, &efivar_sysfs_list); | 533 | true, false, &efivar_sysfs_list); |
diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig index 87d567089f13..573c449c49b9 100644 --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig | |||
@@ -636,7 +636,7 @@ config GPIO_MAX7301 | |||
636 | 636 | ||
637 | config GPIO_MCP23S08 | 637 | config GPIO_MCP23S08 |
638 | tristate "Microchip MCP23xxx I/O expander" | 638 | tristate "Microchip MCP23xxx I/O expander" |
639 | depends on SPI_MASTER || I2C | 639 | depends on (SPI_MASTER && !I2C) || I2C |
640 | help | 640 | help |
641 | SPI/I2C driver for Microchip MCP23S08/MCP23S17/MCP23008/MCP23017 | 641 | SPI/I2C driver for Microchip MCP23S08/MCP23S17/MCP23008/MCP23017 |
642 | I/O expanders. | 642 | I/O expanders. |
diff --git a/drivers/gpio/gpio-langwell.c b/drivers/gpio/gpio-langwell.c index 634c3d37f7b5..62ef10a641c4 100644 --- a/drivers/gpio/gpio-langwell.c +++ b/drivers/gpio/gpio-langwell.c | |||
@@ -324,6 +324,7 @@ static int lnw_gpio_probe(struct pci_dev *pdev, | |||
324 | resource_size_t start, len; | 324 | resource_size_t start, len; |
325 | struct lnw_gpio *lnw; | 325 | struct lnw_gpio *lnw; |
326 | u32 gpio_base; | 326 | u32 gpio_base; |
327 | u32 irq_base; | ||
327 | int retval; | 328 | int retval; |
328 | int ngpio = id->driver_data; | 329 | int ngpio = id->driver_data; |
329 | 330 | ||
@@ -345,6 +346,7 @@ static int lnw_gpio_probe(struct pci_dev *pdev, | |||
345 | retval = -EFAULT; | 346 | retval = -EFAULT; |
346 | goto err_ioremap; | 347 | goto err_ioremap; |
347 | } | 348 | } |
349 | irq_base = *(u32 *)base; | ||
348 | gpio_base = *((u32 *)base + 1); | 350 | gpio_base = *((u32 *)base + 1); |
349 | /* release the IO mapping, since we already get the info from bar1 */ | 351 | /* release the IO mapping, since we already get the info from bar1 */ |
350 | iounmap(base); | 352 | iounmap(base); |
@@ -365,13 +367,6 @@ static int lnw_gpio_probe(struct pci_dev *pdev, | |||
365 | goto err_ioremap; | 367 | goto err_ioremap; |
366 | } | 368 | } |
367 | 369 | ||
368 | lnw->domain = irq_domain_add_linear(pdev->dev.of_node, ngpio, | ||
369 | &lnw_gpio_irq_ops, lnw); | ||
370 | if (!lnw->domain) { | ||
371 | retval = -ENOMEM; | ||
372 | goto err_ioremap; | ||
373 | } | ||
374 | |||
375 | lnw->reg_base = base; | 370 | lnw->reg_base = base; |
376 | lnw->chip.label = dev_name(&pdev->dev); | 371 | lnw->chip.label = dev_name(&pdev->dev); |
377 | lnw->chip.request = lnw_gpio_request; | 372 | lnw->chip.request = lnw_gpio_request; |
@@ -384,6 +379,14 @@ static int lnw_gpio_probe(struct pci_dev *pdev, | |||
384 | lnw->chip.ngpio = ngpio; | 379 | lnw->chip.ngpio = ngpio; |
385 | lnw->chip.can_sleep = 0; | 380 | lnw->chip.can_sleep = 0; |
386 | lnw->pdev = pdev; | 381 | lnw->pdev = pdev; |
382 | |||
383 | lnw->domain = irq_domain_add_simple(pdev->dev.of_node, ngpio, irq_base, | ||
384 | &lnw_gpio_irq_ops, lnw); | ||
385 | if (!lnw->domain) { | ||
386 | retval = -ENOMEM; | ||
387 | goto err_ioremap; | ||
388 | } | ||
389 | |||
387 | pci_set_drvdata(pdev, lnw); | 390 | pci_set_drvdata(pdev, lnw); |
388 | retval = gpiochip_add(&lnw->chip); | 391 | retval = gpiochip_add(&lnw->chip); |
389 | if (retval) { | 392 | if (retval) { |
diff --git a/drivers/gpio/gpio-ml-ioh.c b/drivers/gpio/gpio-ml-ioh.c index b73366523fae..0966f2637ad2 100644 --- a/drivers/gpio/gpio-ml-ioh.c +++ b/drivers/gpio/gpio-ml-ioh.c | |||
@@ -496,8 +496,7 @@ err_irq_alloc_descs: | |||
496 | err_gpiochip_add: | 496 | err_gpiochip_add: |
497 | while (--i >= 0) { | 497 | while (--i >= 0) { |
498 | chip--; | 498 | chip--; |
499 | ret = gpiochip_remove(&chip->gpio); | 499 | if (gpiochip_remove(&chip->gpio)) |
500 | if (ret) | ||
501 | dev_err(&pdev->dev, "Failed gpiochip_remove(%d)\n", i); | 500 | dev_err(&pdev->dev, "Failed gpiochip_remove(%d)\n", i); |
502 | } | 501 | } |
503 | kfree(chip_save); | 502 | kfree(chip_save); |
diff --git a/drivers/gpio/gpio-mxs.c b/drivers/gpio/gpio-mxs.c index 25000b0f8453..f8e6af20dfbf 100644 --- a/drivers/gpio/gpio-mxs.c +++ b/drivers/gpio/gpio-mxs.c | |||
@@ -326,7 +326,8 @@ static int mxs_gpio_probe(struct platform_device *pdev) | |||
326 | 326 | ||
327 | err = bgpio_init(&port->bgc, &pdev->dev, 4, | 327 | err = bgpio_init(&port->bgc, &pdev->dev, 4, |
328 | port->base + PINCTRL_DIN(port), | 328 | port->base + PINCTRL_DIN(port), |
329 | port->base + PINCTRL_DOUT(port), NULL, | 329 | port->base + PINCTRL_DOUT(port) + MXS_SET, |
330 | port->base + PINCTRL_DOUT(port) + MXS_CLR, | ||
330 | port->base + PINCTRL_DOE(port), NULL, 0); | 331 | port->base + PINCTRL_DOE(port), NULL, 0); |
331 | if (err) | 332 | if (err) |
332 | goto out_irqdesc_free; | 333 | goto out_irqdesc_free; |
diff --git a/drivers/gpio/gpio-omap.c b/drivers/gpio/gpio-omap.c index 2050891d9c65..d3f7d2db870f 100644 --- a/drivers/gpio/gpio-omap.c +++ b/drivers/gpio/gpio-omap.c | |||
@@ -69,6 +69,7 @@ struct gpio_bank { | |||
69 | bool is_mpuio; | 69 | bool is_mpuio; |
70 | bool dbck_flag; | 70 | bool dbck_flag; |
71 | bool loses_context; | 71 | bool loses_context; |
72 | bool context_valid; | ||
72 | int stride; | 73 | int stride; |
73 | u32 width; | 74 | u32 width; |
74 | int context_loss_count; | 75 | int context_loss_count; |
@@ -1128,6 +1129,10 @@ static int omap_gpio_probe(struct platform_device *pdev) | |||
1128 | bank->loses_context = true; | 1129 | bank->loses_context = true; |
1129 | } else { | 1130 | } else { |
1130 | bank->loses_context = pdata->loses_context; | 1131 | bank->loses_context = pdata->loses_context; |
1132 | |||
1133 | if (bank->loses_context) | ||
1134 | bank->get_context_loss_count = | ||
1135 | pdata->get_context_loss_count; | ||
1131 | } | 1136 | } |
1132 | 1137 | ||
1133 | 1138 | ||
@@ -1178,9 +1183,6 @@ static int omap_gpio_probe(struct platform_device *pdev) | |||
1178 | omap_gpio_chip_init(bank); | 1183 | omap_gpio_chip_init(bank); |
1179 | omap_gpio_show_rev(bank); | 1184 | omap_gpio_show_rev(bank); |
1180 | 1185 | ||
1181 | if (bank->loses_context) | ||
1182 | bank->get_context_loss_count = pdata->get_context_loss_count; | ||
1183 | |||
1184 | pm_runtime_put(bank->dev); | 1186 | pm_runtime_put(bank->dev); |
1185 | 1187 | ||
1186 | list_add_tail(&bank->node, &omap_gpio_list); | 1188 | list_add_tail(&bank->node, &omap_gpio_list); |
@@ -1259,6 +1261,8 @@ update_gpio_context_count: | |||
1259 | return 0; | 1261 | return 0; |
1260 | } | 1262 | } |
1261 | 1263 | ||
1264 | static void omap_gpio_init_context(struct gpio_bank *p); | ||
1265 | |||
1262 | static int omap_gpio_runtime_resume(struct device *dev) | 1266 | static int omap_gpio_runtime_resume(struct device *dev) |
1263 | { | 1267 | { |
1264 | struct platform_device *pdev = to_platform_device(dev); | 1268 | struct platform_device *pdev = to_platform_device(dev); |
@@ -1268,6 +1272,20 @@ static int omap_gpio_runtime_resume(struct device *dev) | |||
1268 | int c; | 1272 | int c; |
1269 | 1273 | ||
1270 | spin_lock_irqsave(&bank->lock, flags); | 1274 | spin_lock_irqsave(&bank->lock, flags); |
1275 | |||
1276 | /* | ||
1277 | * On the first resume during the probe, the context has not | ||
1278 | * been initialised and so initialise it now. Also initialise | ||
1279 | * the context loss count. | ||
1280 | */ | ||
1281 | if (bank->loses_context && !bank->context_valid) { | ||
1282 | omap_gpio_init_context(bank); | ||
1283 | |||
1284 | if (bank->get_context_loss_count) | ||
1285 | bank->context_loss_count = | ||
1286 | bank->get_context_loss_count(bank->dev); | ||
1287 | } | ||
1288 | |||
1271 | _gpio_dbck_enable(bank); | 1289 | _gpio_dbck_enable(bank); |
1272 | 1290 | ||
1273 | /* | 1291 | /* |
@@ -1384,6 +1402,29 @@ void omap2_gpio_resume_after_idle(void) | |||
1384 | } | 1402 | } |
1385 | 1403 | ||
1386 | #if defined(CONFIG_PM_RUNTIME) | 1404 | #if defined(CONFIG_PM_RUNTIME) |
1405 | static void omap_gpio_init_context(struct gpio_bank *p) | ||
1406 | { | ||
1407 | struct omap_gpio_reg_offs *regs = p->regs; | ||
1408 | void __iomem *base = p->base; | ||
1409 | |||
1410 | p->context.ctrl = __raw_readl(base + regs->ctrl); | ||
1411 | p->context.oe = __raw_readl(base + regs->direction); | ||
1412 | p->context.wake_en = __raw_readl(base + regs->wkup_en); | ||
1413 | p->context.leveldetect0 = __raw_readl(base + regs->leveldetect0); | ||
1414 | p->context.leveldetect1 = __raw_readl(base + regs->leveldetect1); | ||
1415 | p->context.risingdetect = __raw_readl(base + regs->risingdetect); | ||
1416 | p->context.fallingdetect = __raw_readl(base + regs->fallingdetect); | ||
1417 | p->context.irqenable1 = __raw_readl(base + regs->irqenable); | ||
1418 | p->context.irqenable2 = __raw_readl(base + regs->irqenable2); | ||
1419 | |||
1420 | if (regs->set_dataout && p->regs->clr_dataout) | ||
1421 | p->context.dataout = __raw_readl(base + regs->set_dataout); | ||
1422 | else | ||
1423 | p->context.dataout = __raw_readl(base + regs->dataout); | ||
1424 | |||
1425 | p->context_valid = true; | ||
1426 | } | ||
1427 | |||
1387 | static void omap_gpio_restore_context(struct gpio_bank *bank) | 1428 | static void omap_gpio_restore_context(struct gpio_bank *bank) |
1388 | { | 1429 | { |
1389 | __raw_writel(bank->context.wake_en, | 1430 | __raw_writel(bank->context.wake_en, |
@@ -1421,6 +1462,7 @@ static void omap_gpio_restore_context(struct gpio_bank *bank) | |||
1421 | #else | 1462 | #else |
1422 | #define omap_gpio_runtime_suspend NULL | 1463 | #define omap_gpio_runtime_suspend NULL |
1423 | #define omap_gpio_runtime_resume NULL | 1464 | #define omap_gpio_runtime_resume NULL |
1465 | static void omap_gpio_init_context(struct gpio_bank *p) {} | ||
1424 | #endif | 1466 | #endif |
1425 | 1467 | ||
1426 | static const struct dev_pm_ops gpio_pm_ops = { | 1468 | static const struct dev_pm_ops gpio_pm_ops = { |
diff --git a/drivers/gpio/gpio-pch.c b/drivers/gpio/gpio-pch.c index cdf599687cf7..0fec097e838d 100644 --- a/drivers/gpio/gpio-pch.c +++ b/drivers/gpio/gpio-pch.c | |||
@@ -424,8 +424,7 @@ end: | |||
424 | err_request_irq: | 424 | err_request_irq: |
425 | irq_free_descs(irq_base, gpio_pins[chip->ioh]); | 425 | irq_free_descs(irq_base, gpio_pins[chip->ioh]); |
426 | 426 | ||
427 | ret = gpiochip_remove(&chip->gpio); | 427 | if (gpiochip_remove(&chip->gpio)) |
428 | if (ret) | ||
429 | dev_err(&pdev->dev, "%s gpiochip_remove failed\n", __func__); | 428 | dev_err(&pdev->dev, "%s gpiochip_remove failed\n", __func__); |
430 | 429 | ||
431 | err_gpiochip_add: | 430 | err_gpiochip_add: |
diff --git a/drivers/gpio/gpio-sch.c b/drivers/gpio/gpio-sch.c index 1e4de16ceb41..5af65719b95d 100644 --- a/drivers/gpio/gpio-sch.c +++ b/drivers/gpio/gpio-sch.c | |||
@@ -272,10 +272,8 @@ static int sch_gpio_probe(struct platform_device *pdev) | |||
272 | return 0; | 272 | return 0; |
273 | 273 | ||
274 | err_sch_gpio_resume: | 274 | err_sch_gpio_resume: |
275 | err = gpiochip_remove(&sch_gpio_core); | 275 | if (gpiochip_remove(&sch_gpio_core)) |
276 | if (err) | 276 | dev_err(&pdev->dev, "%s gpiochip_remove failed\n", __func__); |
277 | dev_err(&pdev->dev, "%s failed, %d\n", | ||
278 | "gpiochip_remove()", err); | ||
279 | 277 | ||
280 | err_sch_gpio_core: | 278 | err_sch_gpio_core: |
281 | release_region(res->start, resource_size(res)); | 279 | release_region(res->start, resource_size(res)); |
diff --git a/drivers/gpio/gpio-viperboard.c b/drivers/gpio/gpio-viperboard.c index 095ab14cea4d..5ac2919197fe 100644 --- a/drivers/gpio/gpio-viperboard.c +++ b/drivers/gpio/gpio-viperboard.c | |||
@@ -446,7 +446,8 @@ static int vprbrd_gpio_probe(struct platform_device *pdev) | |||
446 | return ret; | 446 | return ret; |
447 | 447 | ||
448 | err_gpiob: | 448 | err_gpiob: |
449 | ret = gpiochip_remove(&vb_gpio->gpioa); | 449 | if (gpiochip_remove(&vb_gpio->gpioa)) |
450 | dev_err(&pdev->dev, "%s gpiochip_remove failed\n", __func__); | ||
450 | 451 | ||
451 | err_gpioa: | 452 | err_gpioa: |
452 | return ret; | 453 | return ret; |
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index a6cf8e843973..970ad17c99ab 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c | |||
@@ -91,14 +91,11 @@ i915_gem_wait_for_error(struct i915_gpu_error *error) | |||
91 | { | 91 | { |
92 | int ret; | 92 | int ret; |
93 | 93 | ||
94 | #define EXIT_COND (!i915_reset_in_progress(error)) | 94 | #define EXIT_COND (!i915_reset_in_progress(error) || \ |
95 | i915_terminally_wedged(error)) | ||
95 | if (EXIT_COND) | 96 | if (EXIT_COND) |
96 | return 0; | 97 | return 0; |
97 | 98 | ||
98 | /* GPU is already declared terminally dead, give up. */ | ||
99 | if (i915_terminally_wedged(error)) | ||
100 | return -EIO; | ||
101 | |||
102 | /* | 99 | /* |
103 | * Only wait 10 seconds for the gpu reset to complete to avoid hanging | 100 | * Only wait 10 seconds for the gpu reset to complete to avoid hanging |
104 | * userspace. If it takes that long something really bad is going on and | 101 | * userspace. If it takes that long something really bad is going on and |
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index ad1117bebd7e..56746dcac40f 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c | |||
@@ -7937,6 +7937,11 @@ intel_modeset_check_state(struct drm_device *dev) | |||
7937 | memset(&pipe_config, 0, sizeof(pipe_config)); | 7937 | memset(&pipe_config, 0, sizeof(pipe_config)); |
7938 | active = dev_priv->display.get_pipe_config(crtc, | 7938 | active = dev_priv->display.get_pipe_config(crtc, |
7939 | &pipe_config); | 7939 | &pipe_config); |
7940 | |||
7941 | /* hw state is inconsistent with the pipe A quirk */ | ||
7942 | if (crtc->pipe == PIPE_A && dev_priv->quirks & QUIRK_PIPEA_FORCE) | ||
7943 | active = crtc->active; | ||
7944 | |||
7940 | WARN(crtc->active != active, | 7945 | WARN(crtc->active != active, |
7941 | "crtc active state doesn't match with hw state " | 7946 | "crtc active state doesn't match with hw state " |
7942 | "(expected %i, found %i)\n", crtc->active, active); | 7947 | "(expected %i, found %i)\n", crtc->active, active); |
diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c index f36f1baabd5a..29412cc89c7a 100644 --- a/drivers/gpu/drm/i915/intel_lvds.c +++ b/drivers/gpu/drm/i915/intel_lvds.c | |||
@@ -815,10 +815,10 @@ static const struct dmi_system_id intel_no_lvds[] = { | |||
815 | }, | 815 | }, |
816 | { | 816 | { |
817 | .callback = intel_no_lvds_dmi_callback, | 817 | .callback = intel_no_lvds_dmi_callback, |
818 | .ident = "Hewlett-Packard HP t5740e Thin Client", | 818 | .ident = "Hewlett-Packard HP t5740", |
819 | .matches = { | 819 | .matches = { |
820 | DMI_MATCH(DMI_BOARD_VENDOR, "Hewlett-Packard"), | 820 | DMI_MATCH(DMI_BOARD_VENDOR, "Hewlett-Packard"), |
821 | DMI_MATCH(DMI_PRODUCT_NAME, "HP t5740e Thin Client"), | 821 | DMI_MATCH(DMI_PRODUCT_NAME, " t5740"), |
822 | }, | 822 | }, |
823 | }, | 823 | }, |
824 | { | 824 | { |
diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c index d15428404b9a..4c47b449b775 100644 --- a/drivers/gpu/drm/i915/intel_sdvo.c +++ b/drivers/gpu/drm/i915/intel_sdvo.c | |||
@@ -1776,7 +1776,7 @@ static void intel_sdvo_get_lvds_modes(struct drm_connector *connector) | |||
1776 | * Assume that the preferred modes are | 1776 | * Assume that the preferred modes are |
1777 | * arranged in priority order. | 1777 | * arranged in priority order. |
1778 | */ | 1778 | */ |
1779 | intel_ddc_get_modes(connector, intel_sdvo->i2c); | 1779 | intel_ddc_get_modes(connector, &intel_sdvo->ddc); |
1780 | if (list_empty(&connector->probed_modes) == false) | 1780 | if (list_empty(&connector->probed_modes) == false) |
1781 | goto end; | 1781 | goto end; |
1782 | 1782 | ||
diff --git a/drivers/gpu/drm/omapdrm/omap_drv.c b/drivers/gpu/drm/omapdrm/omap_drv.c index 9c53c25e5201..826586ffbe83 100644 --- a/drivers/gpu/drm/omapdrm/omap_drv.c +++ b/drivers/gpu/drm/omapdrm/omap_drv.c | |||
@@ -649,6 +649,9 @@ static void pdev_shutdown(struct platform_device *device) | |||
649 | 649 | ||
650 | static int pdev_probe(struct platform_device *device) | 650 | static int pdev_probe(struct platform_device *device) |
651 | { | 651 | { |
652 | if (omapdss_is_initialized() == false) | ||
653 | return -EPROBE_DEFER; | ||
654 | |||
652 | DBG("%s", device->name); | 655 | DBG("%s", device->name); |
653 | return drm_platform_init(&omap_drm_driver, device); | 656 | return drm_platform_init(&omap_drm_driver, device); |
654 | } | 657 | } |
diff --git a/drivers/infiniband/ulp/srpt/ib_srpt.c b/drivers/infiniband/ulp/srpt/ib_srpt.c index b08ca7a9f76b..3f3f0416fbdd 100644 --- a/drivers/infiniband/ulp/srpt/ib_srpt.c +++ b/drivers/infiniband/ulp/srpt/ib_srpt.c | |||
@@ -2227,6 +2227,27 @@ static void srpt_close_ch(struct srpt_rdma_ch *ch) | |||
2227 | } | 2227 | } |
2228 | 2228 | ||
2229 | /** | 2229 | /** |
2230 | * srpt_shutdown_session() - Whether or not a session may be shut down. | ||
2231 | */ | ||
2232 | static int srpt_shutdown_session(struct se_session *se_sess) | ||
2233 | { | ||
2234 | struct srpt_rdma_ch *ch = se_sess->fabric_sess_ptr; | ||
2235 | unsigned long flags; | ||
2236 | |||
2237 | spin_lock_irqsave(&ch->spinlock, flags); | ||
2238 | if (ch->in_shutdown) { | ||
2239 | spin_unlock_irqrestore(&ch->spinlock, flags); | ||
2240 | return true; | ||
2241 | } | ||
2242 | |||
2243 | ch->in_shutdown = true; | ||
2244 | target_sess_cmd_list_set_waiting(se_sess); | ||
2245 | spin_unlock_irqrestore(&ch->spinlock, flags); | ||
2246 | |||
2247 | return true; | ||
2248 | } | ||
2249 | |||
2250 | /** | ||
2230 | * srpt_drain_channel() - Drain a channel by resetting the IB queue pair. | 2251 | * srpt_drain_channel() - Drain a channel by resetting the IB queue pair. |
2231 | * @cm_id: Pointer to the CM ID of the channel to be drained. | 2252 | * @cm_id: Pointer to the CM ID of the channel to be drained. |
2232 | * | 2253 | * |
@@ -2264,6 +2285,9 @@ static void srpt_drain_channel(struct ib_cm_id *cm_id) | |||
2264 | spin_unlock_irq(&sdev->spinlock); | 2285 | spin_unlock_irq(&sdev->spinlock); |
2265 | 2286 | ||
2266 | if (do_reset) { | 2287 | if (do_reset) { |
2288 | if (ch->sess) | ||
2289 | srpt_shutdown_session(ch->sess); | ||
2290 | |||
2267 | ret = srpt_ch_qp_err(ch); | 2291 | ret = srpt_ch_qp_err(ch); |
2268 | if (ret < 0) | 2292 | if (ret < 0) |
2269 | printk(KERN_ERR "Setting queue pair in error state" | 2293 | printk(KERN_ERR "Setting queue pair in error state" |
@@ -2328,7 +2352,7 @@ static void srpt_release_channel_work(struct work_struct *w) | |||
2328 | se_sess = ch->sess; | 2352 | se_sess = ch->sess; |
2329 | BUG_ON(!se_sess); | 2353 | BUG_ON(!se_sess); |
2330 | 2354 | ||
2331 | target_wait_for_sess_cmds(se_sess, 0); | 2355 | target_wait_for_sess_cmds(se_sess); |
2332 | 2356 | ||
2333 | transport_deregister_session_configfs(se_sess); | 2357 | transport_deregister_session_configfs(se_sess); |
2334 | transport_deregister_session(se_sess); | 2358 | transport_deregister_session(se_sess); |
@@ -3467,14 +3491,6 @@ static void srpt_release_cmd(struct se_cmd *se_cmd) | |||
3467 | } | 3491 | } |
3468 | 3492 | ||
3469 | /** | 3493 | /** |
3470 | * srpt_shutdown_session() - Whether or not a session may be shut down. | ||
3471 | */ | ||
3472 | static int srpt_shutdown_session(struct se_session *se_sess) | ||
3473 | { | ||
3474 | return true; | ||
3475 | } | ||
3476 | |||
3477 | /** | ||
3478 | * srpt_close_session() - Forcibly close a session. | 3494 | * srpt_close_session() - Forcibly close a session. |
3479 | * | 3495 | * |
3480 | * Callback function invoked by the TCM core to clean up sessions associated | 3496 | * Callback function invoked by the TCM core to clean up sessions associated |
diff --git a/drivers/infiniband/ulp/srpt/ib_srpt.h b/drivers/infiniband/ulp/srpt/ib_srpt.h index 4caf55cda7b1..3dae156905de 100644 --- a/drivers/infiniband/ulp/srpt/ib_srpt.h +++ b/drivers/infiniband/ulp/srpt/ib_srpt.h | |||
@@ -325,6 +325,7 @@ struct srpt_rdma_ch { | |||
325 | u8 sess_name[36]; | 325 | u8 sess_name[36]; |
326 | struct work_struct release_work; | 326 | struct work_struct release_work; |
327 | struct completion *release_done; | 327 | struct completion *release_done; |
328 | bool in_shutdown; | ||
328 | }; | 329 | }; |
329 | 330 | ||
330 | /** | 331 | /** |
diff --git a/drivers/isdn/capi/kcapi.c b/drivers/isdn/capi/kcapi.c index 9b1b274c7d25..c123709acf82 100644 --- a/drivers/isdn/capi/kcapi.c +++ b/drivers/isdn/capi/kcapi.c | |||
@@ -93,7 +93,7 @@ capi_ctr_put(struct capi_ctr *ctr) | |||
93 | 93 | ||
94 | static inline struct capi_ctr *get_capi_ctr_by_nr(u16 contr) | 94 | static inline struct capi_ctr *get_capi_ctr_by_nr(u16 contr) |
95 | { | 95 | { |
96 | if (contr - 1 >= CAPI_MAXCONTR) | 96 | if (contr < 1 || contr - 1 >= CAPI_MAXCONTR) |
97 | return NULL; | 97 | return NULL; |
98 | 98 | ||
99 | return capi_controller[contr - 1]; | 99 | return capi_controller[contr - 1]; |
@@ -103,7 +103,7 @@ static inline struct capi20_appl *__get_capi_appl_by_nr(u16 applid) | |||
103 | { | 103 | { |
104 | lockdep_assert_held(&capi_controller_lock); | 104 | lockdep_assert_held(&capi_controller_lock); |
105 | 105 | ||
106 | if (applid - 1 >= CAPI_MAXAPPL) | 106 | if (applid < 1 || applid - 1 >= CAPI_MAXAPPL) |
107 | return NULL; | 107 | return NULL; |
108 | 108 | ||
109 | return capi_applications[applid - 1]; | 109 | return capi_applications[applid - 1]; |
@@ -111,7 +111,7 @@ static inline struct capi20_appl *__get_capi_appl_by_nr(u16 applid) | |||
111 | 111 | ||
112 | static inline struct capi20_appl *get_capi_appl_by_nr(u16 applid) | 112 | static inline struct capi20_appl *get_capi_appl_by_nr(u16 applid) |
113 | { | 113 | { |
114 | if (applid - 1 >= CAPI_MAXAPPL) | 114 | if (applid < 1 || applid - 1 >= CAPI_MAXAPPL) |
115 | return NULL; | 115 | return NULL; |
116 | 116 | ||
117 | return rcu_dereference(capi_applications[applid - 1]); | 117 | return rcu_dereference(capi_applications[applid - 1]); |
diff --git a/drivers/leds/leds-ot200.c b/drivers/leds/leds-ot200.c index ee14662ed5ce..98cae529373f 100644 --- a/drivers/leds/leds-ot200.c +++ b/drivers/leds/leds-ot200.c | |||
@@ -47,37 +47,37 @@ static struct ot200_led leds[] = { | |||
47 | { | 47 | { |
48 | .name = "led_1", | 48 | .name = "led_1", |
49 | .port = 0x49, | 49 | .port = 0x49, |
50 | .mask = BIT(7), | 50 | .mask = BIT(6), |
51 | }, | 51 | }, |
52 | { | 52 | { |
53 | .name = "led_2", | 53 | .name = "led_2", |
54 | .port = 0x49, | 54 | .port = 0x49, |
55 | .mask = BIT(6), | 55 | .mask = BIT(5), |
56 | }, | 56 | }, |
57 | { | 57 | { |
58 | .name = "led_3", | 58 | .name = "led_3", |
59 | .port = 0x49, | 59 | .port = 0x49, |
60 | .mask = BIT(5), | 60 | .mask = BIT(4), |
61 | }, | 61 | }, |
62 | { | 62 | { |
63 | .name = "led_4", | 63 | .name = "led_4", |
64 | .port = 0x49, | 64 | .port = 0x49, |
65 | .mask = BIT(4), | 65 | .mask = BIT(3), |
66 | }, | 66 | }, |
67 | { | 67 | { |
68 | .name = "led_5", | 68 | .name = "led_5", |
69 | .port = 0x49, | 69 | .port = 0x49, |
70 | .mask = BIT(3), | 70 | .mask = BIT(2), |
71 | }, | 71 | }, |
72 | { | 72 | { |
73 | .name = "led_6", | 73 | .name = "led_6", |
74 | .port = 0x49, | 74 | .port = 0x49, |
75 | .mask = BIT(2), | 75 | .mask = BIT(1), |
76 | }, | 76 | }, |
77 | { | 77 | { |
78 | .name = "led_7", | 78 | .name = "led_7", |
79 | .port = 0x49, | 79 | .port = 0x49, |
80 | .mask = BIT(1), | 80 | .mask = BIT(0), |
81 | } | 81 | } |
82 | }; | 82 | }; |
83 | 83 | ||
diff --git a/drivers/media/pci/zoran/zoran.h b/drivers/media/pci/zoran/zoran.h index ca2754a3cd63..5e040085c2ff 100644 --- a/drivers/media/pci/zoran/zoran.h +++ b/drivers/media/pci/zoran/zoran.h | |||
@@ -176,7 +176,7 @@ struct zoran_fh; | |||
176 | 176 | ||
177 | struct zoran_mapping { | 177 | struct zoran_mapping { |
178 | struct zoran_fh *fh; | 178 | struct zoran_fh *fh; |
179 | int count; | 179 | atomic_t count; |
180 | }; | 180 | }; |
181 | 181 | ||
182 | struct zoran_buffer { | 182 | struct zoran_buffer { |
diff --git a/drivers/media/pci/zoran/zoran_driver.c b/drivers/media/pci/zoran/zoran_driver.c index 1168a84a737d..d133c30c3fdc 100644 --- a/drivers/media/pci/zoran/zoran_driver.c +++ b/drivers/media/pci/zoran/zoran_driver.c | |||
@@ -2803,8 +2803,7 @@ static void | |||
2803 | zoran_vm_open (struct vm_area_struct *vma) | 2803 | zoran_vm_open (struct vm_area_struct *vma) |
2804 | { | 2804 | { |
2805 | struct zoran_mapping *map = vma->vm_private_data; | 2805 | struct zoran_mapping *map = vma->vm_private_data; |
2806 | 2806 | atomic_inc(&map->count); | |
2807 | map->count++; | ||
2808 | } | 2807 | } |
2809 | 2808 | ||
2810 | static void | 2809 | static void |
@@ -2815,7 +2814,7 @@ zoran_vm_close (struct vm_area_struct *vma) | |||
2815 | struct zoran *zr = fh->zr; | 2814 | struct zoran *zr = fh->zr; |
2816 | int i; | 2815 | int i; |
2817 | 2816 | ||
2818 | if (--map->count > 0) | 2817 | if (!atomic_dec_and_mutex_lock(&map->count, &zr->resource_lock)) |
2819 | return; | 2818 | return; |
2820 | 2819 | ||
2821 | dprintk(3, KERN_INFO "%s: %s - munmap(%s)\n", ZR_DEVNAME(zr), | 2820 | dprintk(3, KERN_INFO "%s: %s - munmap(%s)\n", ZR_DEVNAME(zr), |
@@ -2828,14 +2827,16 @@ zoran_vm_close (struct vm_area_struct *vma) | |||
2828 | kfree(map); | 2827 | kfree(map); |
2829 | 2828 | ||
2830 | /* Any buffers still mapped? */ | 2829 | /* Any buffers still mapped? */ |
2831 | for (i = 0; i < fh->buffers.num_buffers; i++) | 2830 | for (i = 0; i < fh->buffers.num_buffers; i++) { |
2832 | if (fh->buffers.buffer[i].map) | 2831 | if (fh->buffers.buffer[i].map) { |
2832 | mutex_unlock(&zr->resource_lock); | ||
2833 | return; | 2833 | return; |
2834 | } | ||
2835 | } | ||
2834 | 2836 | ||
2835 | dprintk(3, KERN_INFO "%s: %s - free %s buffers\n", ZR_DEVNAME(zr), | 2837 | dprintk(3, KERN_INFO "%s: %s - free %s buffers\n", ZR_DEVNAME(zr), |
2836 | __func__, mode_name(fh->map_mode)); | 2838 | __func__, mode_name(fh->map_mode)); |
2837 | 2839 | ||
2838 | mutex_lock(&zr->resource_lock); | ||
2839 | 2840 | ||
2840 | if (fh->map_mode == ZORAN_MAP_MODE_RAW) { | 2841 | if (fh->map_mode == ZORAN_MAP_MODE_RAW) { |
2841 | if (fh->buffers.active != ZORAN_FREE) { | 2842 | if (fh->buffers.active != ZORAN_FREE) { |
@@ -2939,7 +2940,7 @@ zoran_mmap (struct file *file, | |||
2939 | goto mmap_unlock_and_return; | 2940 | goto mmap_unlock_and_return; |
2940 | } | 2941 | } |
2941 | map->fh = fh; | 2942 | map->fh = fh; |
2942 | map->count = 1; | 2943 | atomic_set(&map->count, 1); |
2943 | 2944 | ||
2944 | vma->vm_ops = &zoran_vm_ops; | 2945 | vma->vm_ops = &zoran_vm_ops; |
2945 | vma->vm_flags |= VM_DONTEXPAND; | 2946 | vma->vm_flags |= VM_DONTEXPAND; |
diff --git a/drivers/media/platform/omap/omap_vout.c b/drivers/media/platform/omap/omap_vout.c index 477268a2415f..d338b19da544 100644 --- a/drivers/media/platform/omap/omap_vout.c +++ b/drivers/media/platform/omap/omap_vout.c | |||
@@ -2150,6 +2150,9 @@ static int __init omap_vout_probe(struct platform_device *pdev) | |||
2150 | struct omap_dss_device *def_display; | 2150 | struct omap_dss_device *def_display; |
2151 | struct omap2video_device *vid_dev = NULL; | 2151 | struct omap2video_device *vid_dev = NULL; |
2152 | 2152 | ||
2153 | if (omapdss_is_initialized() == false) | ||
2154 | return -EPROBE_DEFER; | ||
2155 | |||
2153 | ret = omapdss_compat_init(); | 2156 | ret = omapdss_compat_init(); |
2154 | if (ret) { | 2157 | if (ret) { |
2155 | dev_err(&pdev->dev, "failed to init dss\n"); | 2158 | dev_err(&pdev->dev, "failed to init dss\n"); |
diff --git a/drivers/net/bonding/bond_3ad.c b/drivers/net/bonding/bond_3ad.c index fc58d118d844..390061d09693 100644 --- a/drivers/net/bonding/bond_3ad.c +++ b/drivers/net/bonding/bond_3ad.c | |||
@@ -2360,14 +2360,15 @@ int bond_3ad_set_carrier(struct bonding *bond) | |||
2360 | } | 2360 | } |
2361 | 2361 | ||
2362 | /** | 2362 | /** |
2363 | * bond_3ad_get_active_agg_info - get information of the active aggregator | 2363 | * __bond_3ad_get_active_agg_info - get information of the active aggregator |
2364 | * @bond: bonding struct to work on | 2364 | * @bond: bonding struct to work on |
2365 | * @ad_info: ad_info struct to fill with the bond's info | 2365 | * @ad_info: ad_info struct to fill with the bond's info |
2366 | * | 2366 | * |
2367 | * Returns: 0 on success | 2367 | * Returns: 0 on success |
2368 | * < 0 on error | 2368 | * < 0 on error |
2369 | */ | 2369 | */ |
2370 | int bond_3ad_get_active_agg_info(struct bonding *bond, struct ad_info *ad_info) | 2370 | int __bond_3ad_get_active_agg_info(struct bonding *bond, |
2371 | struct ad_info *ad_info) | ||
2371 | { | 2372 | { |
2372 | struct aggregator *aggregator = NULL; | 2373 | struct aggregator *aggregator = NULL; |
2373 | struct port *port; | 2374 | struct port *port; |
@@ -2391,6 +2392,18 @@ int bond_3ad_get_active_agg_info(struct bonding *bond, struct ad_info *ad_info) | |||
2391 | return -1; | 2392 | return -1; |
2392 | } | 2393 | } |
2393 | 2394 | ||
2395 | /* Wrapper used to hold bond->lock so no slave manipulation can occur */ | ||
2396 | int bond_3ad_get_active_agg_info(struct bonding *bond, struct ad_info *ad_info) | ||
2397 | { | ||
2398 | int ret; | ||
2399 | |||
2400 | read_lock(&bond->lock); | ||
2401 | ret = __bond_3ad_get_active_agg_info(bond, ad_info); | ||
2402 | read_unlock(&bond->lock); | ||
2403 | |||
2404 | return ret; | ||
2405 | } | ||
2406 | |||
2394 | int bond_3ad_xmit_xor(struct sk_buff *skb, struct net_device *dev) | 2407 | int bond_3ad_xmit_xor(struct sk_buff *skb, struct net_device *dev) |
2395 | { | 2408 | { |
2396 | struct slave *slave, *start_at; | 2409 | struct slave *slave, *start_at; |
@@ -2402,8 +2415,8 @@ int bond_3ad_xmit_xor(struct sk_buff *skb, struct net_device *dev) | |||
2402 | struct ad_info ad_info; | 2415 | struct ad_info ad_info; |
2403 | int res = 1; | 2416 | int res = 1; |
2404 | 2417 | ||
2405 | if (bond_3ad_get_active_agg_info(bond, &ad_info)) { | 2418 | if (__bond_3ad_get_active_agg_info(bond, &ad_info)) { |
2406 | pr_debug("%s: Error: bond_3ad_get_active_agg_info failed\n", | 2419 | pr_debug("%s: Error: __bond_3ad_get_active_agg_info failed\n", |
2407 | dev->name); | 2420 | dev->name); |
2408 | goto out; | 2421 | goto out; |
2409 | } | 2422 | } |
diff --git a/drivers/net/bonding/bond_3ad.h b/drivers/net/bonding/bond_3ad.h index 0cfaa4afdece..5d91ad0cc041 100644 --- a/drivers/net/bonding/bond_3ad.h +++ b/drivers/net/bonding/bond_3ad.h | |||
@@ -273,6 +273,8 @@ void bond_3ad_adapter_speed_changed(struct slave *slave); | |||
273 | void bond_3ad_adapter_duplex_changed(struct slave *slave); | 273 | void bond_3ad_adapter_duplex_changed(struct slave *slave); |
274 | void bond_3ad_handle_link_change(struct slave *slave, char link); | 274 | void bond_3ad_handle_link_change(struct slave *slave, char link); |
275 | int bond_3ad_get_active_agg_info(struct bonding *bond, struct ad_info *ad_info); | 275 | int bond_3ad_get_active_agg_info(struct bonding *bond, struct ad_info *ad_info); |
276 | int __bond_3ad_get_active_agg_info(struct bonding *bond, | ||
277 | struct ad_info *ad_info); | ||
276 | int bond_3ad_xmit_xor(struct sk_buff *skb, struct net_device *dev); | 278 | int bond_3ad_xmit_xor(struct sk_buff *skb, struct net_device *dev); |
277 | int bond_3ad_lacpdu_recv(const struct sk_buff *skb, struct bonding *bond, | 279 | int bond_3ad_lacpdu_recv(const struct sk_buff *skb, struct bonding *bond, |
278 | struct slave *slave); | 280 | struct slave *slave); |
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index d0aade04e49a..29b846cbfb48 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c | |||
@@ -1362,6 +1362,7 @@ static netdev_features_t bond_fix_features(struct net_device *dev, | |||
1362 | slave->dev->features, | 1362 | slave->dev->features, |
1363 | mask); | 1363 | mask); |
1364 | } | 1364 | } |
1365 | features = netdev_add_tso_features(features, mask); | ||
1365 | 1366 | ||
1366 | out: | 1367 | out: |
1367 | read_unlock(&bond->lock); | 1368 | read_unlock(&bond->lock); |
@@ -2555,8 +2556,8 @@ static void bond_arp_send(struct net_device *slave_dev, int arp_op, __be32 dest_ | |||
2555 | { | 2556 | { |
2556 | struct sk_buff *skb; | 2557 | struct sk_buff *skb; |
2557 | 2558 | ||
2558 | pr_debug("arp %d on slave %s: dst %x src %x vid %d\n", arp_op, | 2559 | pr_debug("arp %d on slave %s: dst %pI4 src %pI4 vid %d\n", arp_op, |
2559 | slave_dev->name, dest_ip, src_ip, vlan_id); | 2560 | slave_dev->name, &dest_ip, &src_ip, vlan_id); |
2560 | 2561 | ||
2561 | skb = arp_create(arp_op, ETH_P_ARP, dest_ip, slave_dev, src_ip, | 2562 | skb = arp_create(arp_op, ETH_P_ARP, dest_ip, slave_dev, src_ip, |
2562 | NULL, slave_dev->dev_addr, NULL); | 2563 | NULL, slave_dev->dev_addr, NULL); |
@@ -2588,7 +2589,7 @@ static void bond_arp_send_all(struct bonding *bond, struct slave *slave) | |||
2588 | __be32 addr; | 2589 | __be32 addr; |
2589 | if (!targets[i]) | 2590 | if (!targets[i]) |
2590 | break; | 2591 | break; |
2591 | pr_debug("basa: target %x\n", targets[i]); | 2592 | pr_debug("basa: target %pI4\n", &targets[i]); |
2592 | if (!bond_vlan_used(bond)) { | 2593 | if (!bond_vlan_used(bond)) { |
2593 | pr_debug("basa: empty vlan: arp_send\n"); | 2594 | pr_debug("basa: empty vlan: arp_send\n"); |
2594 | addr = bond_confirm_addr(bond->dev, targets[i], 0); | 2595 | addr = bond_confirm_addr(bond->dev, targets[i], 0); |
@@ -4470,7 +4471,7 @@ int bond_parse_parm(const char *buf, const struct bond_parm_tbl *tbl) | |||
4470 | 4471 | ||
4471 | static int bond_check_params(struct bond_params *params) | 4472 | static int bond_check_params(struct bond_params *params) |
4472 | { | 4473 | { |
4473 | int arp_validate_value, fail_over_mac_value, primary_reselect_value; | 4474 | int arp_validate_value, fail_over_mac_value, primary_reselect_value, i; |
4474 | 4475 | ||
4475 | /* | 4476 | /* |
4476 | * Convert string parameters. | 4477 | * Convert string parameters. |
@@ -4650,19 +4651,18 @@ static int bond_check_params(struct bond_params *params) | |||
4650 | arp_interval = BOND_LINK_ARP_INTERV; | 4651 | arp_interval = BOND_LINK_ARP_INTERV; |
4651 | } | 4652 | } |
4652 | 4653 | ||
4653 | for (arp_ip_count = 0; | 4654 | for (arp_ip_count = 0, i = 0; |
4654 | (arp_ip_count < BOND_MAX_ARP_TARGETS) && arp_ip_target[arp_ip_count]; | 4655 | (arp_ip_count < BOND_MAX_ARP_TARGETS) && arp_ip_target[i]; i++) { |
4655 | arp_ip_count++) { | ||
4656 | /* not complete check, but should be good enough to | 4656 | /* not complete check, but should be good enough to |
4657 | catch mistakes */ | 4657 | catch mistakes */ |
4658 | __be32 ip = in_aton(arp_ip_target[arp_ip_count]); | 4658 | __be32 ip = in_aton(arp_ip_target[i]); |
4659 | if (!isdigit(arp_ip_target[arp_ip_count][0]) || | 4659 | if (!isdigit(arp_ip_target[i][0]) || ip == 0 || |
4660 | ip == 0 || ip == htonl(INADDR_BROADCAST)) { | 4660 | ip == htonl(INADDR_BROADCAST)) { |
4661 | pr_warning("Warning: bad arp_ip_target module parameter (%s), ARP monitoring will not be performed\n", | 4661 | pr_warning("Warning: bad arp_ip_target module parameter (%s), ARP monitoring will not be performed\n", |
4662 | arp_ip_target[arp_ip_count]); | 4662 | arp_ip_target[i]); |
4663 | arp_interval = 0; | 4663 | arp_interval = 0; |
4664 | } else { | 4664 | } else { |
4665 | arp_target[arp_ip_count] = ip; | 4665 | arp_target[arp_ip_count++] = ip; |
4666 | } | 4666 | } |
4667 | } | 4667 | } |
4668 | 4668 | ||
@@ -4696,8 +4696,6 @@ static int bond_check_params(struct bond_params *params) | |||
4696 | if (miimon) { | 4696 | if (miimon) { |
4697 | pr_info("MII link monitoring set to %d ms\n", miimon); | 4697 | pr_info("MII link monitoring set to %d ms\n", miimon); |
4698 | } else if (arp_interval) { | 4698 | } else if (arp_interval) { |
4699 | int i; | ||
4700 | |||
4701 | pr_info("ARP monitoring set to %d ms, validate %s, with %d target(s):", | 4699 | pr_info("ARP monitoring set to %d ms, validate %s, with %d target(s):", |
4702 | arp_interval, | 4700 | arp_interval, |
4703 | arp_validate_tbl[arp_validate_value].modename, | 4701 | arp_validate_tbl[arp_validate_value].modename, |
diff --git a/drivers/net/bonding/bond_procfs.c b/drivers/net/bonding/bond_procfs.c index 94d06f1307b8..4060d41f0ee7 100644 --- a/drivers/net/bonding/bond_procfs.c +++ b/drivers/net/bonding/bond_procfs.c | |||
@@ -130,7 +130,7 @@ static void bond_info_show_master(struct seq_file *seq) | |||
130 | seq_printf(seq, "Aggregator selection policy (ad_select): %s\n", | 130 | seq_printf(seq, "Aggregator selection policy (ad_select): %s\n", |
131 | ad_select_tbl[bond->params.ad_select].modename); | 131 | ad_select_tbl[bond->params.ad_select].modename); |
132 | 132 | ||
133 | if (bond_3ad_get_active_agg_info(bond, &ad_info)) { | 133 | if (__bond_3ad_get_active_agg_info(bond, &ad_info)) { |
134 | seq_printf(seq, "bond %s has no active aggregator\n", | 134 | seq_printf(seq, "bond %s has no active aggregator\n", |
135 | bond->dev->name); | 135 | bond->dev->name); |
136 | } else { | 136 | } else { |
diff --git a/drivers/net/bonding/bond_sysfs.c b/drivers/net/bonding/bond_sysfs.c index ea7a388f4843..d7434e0a610e 100644 --- a/drivers/net/bonding/bond_sysfs.c +++ b/drivers/net/bonding/bond_sysfs.c | |||
@@ -316,6 +316,9 @@ static ssize_t bonding_store_mode(struct device *d, | |||
316 | int new_value, ret = count; | 316 | int new_value, ret = count; |
317 | struct bonding *bond = to_bond(d); | 317 | struct bonding *bond = to_bond(d); |
318 | 318 | ||
319 | if (!rtnl_trylock()) | ||
320 | return restart_syscall(); | ||
321 | |||
319 | if (bond->dev->flags & IFF_UP) { | 322 | if (bond->dev->flags & IFF_UP) { |
320 | pr_err("unable to update mode of %s because interface is up.\n", | 323 | pr_err("unable to update mode of %s because interface is up.\n", |
321 | bond->dev->name); | 324 | bond->dev->name); |
@@ -352,6 +355,7 @@ static ssize_t bonding_store_mode(struct device *d, | |||
352 | bond->dev->name, bond_mode_tbl[new_value].modename, | 355 | bond->dev->name, bond_mode_tbl[new_value].modename, |
353 | new_value); | 356 | new_value); |
354 | out: | 357 | out: |
358 | rtnl_unlock(); | ||
355 | return ret; | 359 | return ret; |
356 | } | 360 | } |
357 | static DEVICE_ATTR(mode, S_IRUGO | S_IWUSR, | 361 | static DEVICE_ATTR(mode, S_IRUGO | S_IWUSR, |
@@ -1315,7 +1319,6 @@ static ssize_t bonding_show_mii_status(struct device *d, | |||
1315 | } | 1319 | } |
1316 | static DEVICE_ATTR(mii_status, S_IRUGO, bonding_show_mii_status, NULL); | 1320 | static DEVICE_ATTR(mii_status, S_IRUGO, bonding_show_mii_status, NULL); |
1317 | 1321 | ||
1318 | |||
1319 | /* | 1322 | /* |
1320 | * Show current 802.3ad aggregator ID. | 1323 | * Show current 802.3ad aggregator ID. |
1321 | */ | 1324 | */ |
@@ -1329,7 +1332,7 @@ static ssize_t bonding_show_ad_aggregator(struct device *d, | |||
1329 | if (bond->params.mode == BOND_MODE_8023AD) { | 1332 | if (bond->params.mode == BOND_MODE_8023AD) { |
1330 | struct ad_info ad_info; | 1333 | struct ad_info ad_info; |
1331 | count = sprintf(buf, "%d\n", | 1334 | count = sprintf(buf, "%d\n", |
1332 | (bond_3ad_get_active_agg_info(bond, &ad_info)) | 1335 | bond_3ad_get_active_agg_info(bond, &ad_info) |
1333 | ? 0 : ad_info.aggregator_id); | 1336 | ? 0 : ad_info.aggregator_id); |
1334 | } | 1337 | } |
1335 | 1338 | ||
@@ -1351,7 +1354,7 @@ static ssize_t bonding_show_ad_num_ports(struct device *d, | |||
1351 | if (bond->params.mode == BOND_MODE_8023AD) { | 1354 | if (bond->params.mode == BOND_MODE_8023AD) { |
1352 | struct ad_info ad_info; | 1355 | struct ad_info ad_info; |
1353 | count = sprintf(buf, "%d\n", | 1356 | count = sprintf(buf, "%d\n", |
1354 | (bond_3ad_get_active_agg_info(bond, &ad_info)) | 1357 | bond_3ad_get_active_agg_info(bond, &ad_info) |
1355 | ? 0 : ad_info.ports); | 1358 | ? 0 : ad_info.ports); |
1356 | } | 1359 | } |
1357 | 1360 | ||
@@ -1373,7 +1376,7 @@ static ssize_t bonding_show_ad_actor_key(struct device *d, | |||
1373 | if (bond->params.mode == BOND_MODE_8023AD) { | 1376 | if (bond->params.mode == BOND_MODE_8023AD) { |
1374 | struct ad_info ad_info; | 1377 | struct ad_info ad_info; |
1375 | count = sprintf(buf, "%d\n", | 1378 | count = sprintf(buf, "%d\n", |
1376 | (bond_3ad_get_active_agg_info(bond, &ad_info)) | 1379 | bond_3ad_get_active_agg_info(bond, &ad_info) |
1377 | ? 0 : ad_info.actor_key); | 1380 | ? 0 : ad_info.actor_key); |
1378 | } | 1381 | } |
1379 | 1382 | ||
@@ -1395,7 +1398,7 @@ static ssize_t bonding_show_ad_partner_key(struct device *d, | |||
1395 | if (bond->params.mode == BOND_MODE_8023AD) { | 1398 | if (bond->params.mode == BOND_MODE_8023AD) { |
1396 | struct ad_info ad_info; | 1399 | struct ad_info ad_info; |
1397 | count = sprintf(buf, "%d\n", | 1400 | count = sprintf(buf, "%d\n", |
1398 | (bond_3ad_get_active_agg_info(bond, &ad_info)) | 1401 | bond_3ad_get_active_agg_info(bond, &ad_info) |
1399 | ? 0 : ad_info.partner_key); | 1402 | ? 0 : ad_info.partner_key); |
1400 | } | 1403 | } |
1401 | 1404 | ||
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c index b8fbe266ab68..be59ec4b2c30 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c | |||
@@ -3313,6 +3313,7 @@ static void bnx2x_set_pbd_gso_e2(struct sk_buff *skb, u32 *parsing_data, | |||
3313 | */ | 3313 | */ |
3314 | static void bnx2x_set_pbd_gso(struct sk_buff *skb, | 3314 | static void bnx2x_set_pbd_gso(struct sk_buff *skb, |
3315 | struct eth_tx_parse_bd_e1x *pbd, | 3315 | struct eth_tx_parse_bd_e1x *pbd, |
3316 | struct eth_tx_start_bd *tx_start_bd, | ||
3316 | u32 xmit_type) | 3317 | u32 xmit_type) |
3317 | { | 3318 | { |
3318 | pbd->lso_mss = cpu_to_le16(skb_shinfo(skb)->gso_size); | 3319 | pbd->lso_mss = cpu_to_le16(skb_shinfo(skb)->gso_size); |
@@ -3326,11 +3327,14 @@ static void bnx2x_set_pbd_gso(struct sk_buff *skb, | |||
3326 | ip_hdr(skb)->daddr, | 3327 | ip_hdr(skb)->daddr, |
3327 | 0, IPPROTO_TCP, 0)); | 3328 | 0, IPPROTO_TCP, 0)); |
3328 | 3329 | ||
3329 | } else | 3330 | /* GSO on 57710/57711 needs FW to calculate IP checksum */ |
3331 | tx_start_bd->bd_flags.as_bitfield |= ETH_TX_BD_FLAGS_IP_CSUM; | ||
3332 | } else { | ||
3330 | pbd->tcp_pseudo_csum = | 3333 | pbd->tcp_pseudo_csum = |
3331 | bswab16(~csum_ipv6_magic(&ipv6_hdr(skb)->saddr, | 3334 | bswab16(~csum_ipv6_magic(&ipv6_hdr(skb)->saddr, |
3332 | &ipv6_hdr(skb)->daddr, | 3335 | &ipv6_hdr(skb)->daddr, |
3333 | 0, IPPROTO_TCP, 0)); | 3336 | 0, IPPROTO_TCP, 0)); |
3337 | } | ||
3334 | 3338 | ||
3335 | pbd->global_data |= | 3339 | pbd->global_data |= |
3336 | cpu_to_le16(ETH_TX_PARSE_BD_E1X_PSEUDO_CS_WITHOUT_LEN); | 3340 | cpu_to_le16(ETH_TX_PARSE_BD_E1X_PSEUDO_CS_WITHOUT_LEN); |
@@ -3814,7 +3818,8 @@ netdev_tx_t bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
3814 | bnx2x_set_pbd_gso_e2(skb, &pbd_e2_parsing_data, | 3818 | bnx2x_set_pbd_gso_e2(skb, &pbd_e2_parsing_data, |
3815 | xmit_type); | 3819 | xmit_type); |
3816 | else | 3820 | else |
3817 | bnx2x_set_pbd_gso(skb, pbd_e1x, xmit_type); | 3821 | bnx2x_set_pbd_gso(skb, pbd_e1x, tx_start_bd, |
3822 | xmit_type); | ||
3818 | } | 3823 | } |
3819 | 3824 | ||
3820 | /* Set the PBD's parsing_data field if not zero | 3825 | /* Set the PBD's parsing_data field if not zero |
diff --git a/drivers/net/ethernet/broadcom/tg3.c b/drivers/net/ethernet/broadcom/tg3.c index 728d42ab2a76..1f2dd928888a 100644 --- a/drivers/net/ethernet/broadcom/tg3.c +++ b/drivers/net/ethernet/broadcom/tg3.c | |||
@@ -94,10 +94,10 @@ static inline void _tg3_flag_clear(enum TG3_FLAGS flag, unsigned long *bits) | |||
94 | 94 | ||
95 | #define DRV_MODULE_NAME "tg3" | 95 | #define DRV_MODULE_NAME "tg3" |
96 | #define TG3_MAJ_NUM 3 | 96 | #define TG3_MAJ_NUM 3 |
97 | #define TG3_MIN_NUM 131 | 97 | #define TG3_MIN_NUM 132 |
98 | #define DRV_MODULE_VERSION \ | 98 | #define DRV_MODULE_VERSION \ |
99 | __stringify(TG3_MAJ_NUM) "." __stringify(TG3_MIN_NUM) | 99 | __stringify(TG3_MAJ_NUM) "." __stringify(TG3_MIN_NUM) |
100 | #define DRV_MODULE_RELDATE "April 09, 2013" | 100 | #define DRV_MODULE_RELDATE "May 21, 2013" |
101 | 101 | ||
102 | #define RESET_KIND_SHUTDOWN 0 | 102 | #define RESET_KIND_SHUTDOWN 0 |
103 | #define RESET_KIND_INIT 1 | 103 | #define RESET_KIND_INIT 1 |
@@ -2957,6 +2957,31 @@ static int tg3_5700_link_polarity(struct tg3 *tp, u32 speed) | |||
2957 | return 0; | 2957 | return 0; |
2958 | } | 2958 | } |
2959 | 2959 | ||
2960 | static bool tg3_phy_power_bug(struct tg3 *tp) | ||
2961 | { | ||
2962 | switch (tg3_asic_rev(tp)) { | ||
2963 | case ASIC_REV_5700: | ||
2964 | case ASIC_REV_5704: | ||
2965 | return true; | ||
2966 | case ASIC_REV_5780: | ||
2967 | if (tp->phy_flags & TG3_PHYFLG_MII_SERDES) | ||
2968 | return true; | ||
2969 | return false; | ||
2970 | case ASIC_REV_5717: | ||
2971 | if (!tp->pci_fn) | ||
2972 | return true; | ||
2973 | return false; | ||
2974 | case ASIC_REV_5719: | ||
2975 | case ASIC_REV_5720: | ||
2976 | if ((tp->phy_flags & TG3_PHYFLG_PHY_SERDES) && | ||
2977 | !tp->pci_fn) | ||
2978 | return true; | ||
2979 | return false; | ||
2980 | } | ||
2981 | |||
2982 | return false; | ||
2983 | } | ||
2984 | |||
2960 | static void tg3_power_down_phy(struct tg3 *tp, bool do_low_power) | 2985 | static void tg3_power_down_phy(struct tg3 *tp, bool do_low_power) |
2961 | { | 2986 | { |
2962 | u32 val; | 2987 | u32 val; |
@@ -3016,12 +3041,7 @@ static void tg3_power_down_phy(struct tg3 *tp, bool do_low_power) | |||
3016 | /* The PHY should not be powered down on some chips because | 3041 | /* The PHY should not be powered down on some chips because |
3017 | * of bugs. | 3042 | * of bugs. |
3018 | */ | 3043 | */ |
3019 | if (tg3_asic_rev(tp) == ASIC_REV_5700 || | 3044 | if (tg3_phy_power_bug(tp)) |
3020 | tg3_asic_rev(tp) == ASIC_REV_5704 || | ||
3021 | (tg3_asic_rev(tp) == ASIC_REV_5780 && | ||
3022 | (tp->phy_flags & TG3_PHYFLG_MII_SERDES)) || | ||
3023 | (tg3_asic_rev(tp) == ASIC_REV_5717 && | ||
3024 | !tp->pci_fn)) | ||
3025 | return; | 3045 | return; |
3026 | 3046 | ||
3027 | if (tg3_chip_rev(tp) == CHIPREV_5784_AX || | 3047 | if (tg3_chip_rev(tp) == CHIPREV_5784_AX || |
@@ -7428,6 +7448,20 @@ static inline int tg3_4g_overflow_test(dma_addr_t mapping, int len) | |||
7428 | return (base > 0xffffdcc0) && (base + len + 8 < base); | 7448 | return (base > 0xffffdcc0) && (base + len + 8 < base); |
7429 | } | 7449 | } |
7430 | 7450 | ||
7451 | /* Test for TSO DMA buffers that cross into regions which are within MSS bytes | ||
7452 | * of any 4GB boundaries: 4G, 8G, etc | ||
7453 | */ | ||
7454 | static inline int tg3_4g_tso_overflow_test(struct tg3 *tp, dma_addr_t mapping, | ||
7455 | u32 len, u32 mss) | ||
7456 | { | ||
7457 | if (tg3_asic_rev(tp) == ASIC_REV_5762 && mss) { | ||
7458 | u32 base = (u32) mapping & 0xffffffff; | ||
7459 | |||
7460 | return ((base + len + (mss & 0x3fff)) < base); | ||
7461 | } | ||
7462 | return 0; | ||
7463 | } | ||
7464 | |||
7431 | /* Test for DMA addresses > 40-bit */ | 7465 | /* Test for DMA addresses > 40-bit */ |
7432 | static inline int tg3_40bit_overflow_test(struct tg3 *tp, dma_addr_t mapping, | 7466 | static inline int tg3_40bit_overflow_test(struct tg3 *tp, dma_addr_t mapping, |
7433 | int len) | 7467 | int len) |
@@ -7464,6 +7498,9 @@ static bool tg3_tx_frag_set(struct tg3_napi *tnapi, u32 *entry, u32 *budget, | |||
7464 | if (tg3_4g_overflow_test(map, len)) | 7498 | if (tg3_4g_overflow_test(map, len)) |
7465 | hwbug = true; | 7499 | hwbug = true; |
7466 | 7500 | ||
7501 | if (tg3_4g_tso_overflow_test(tp, map, len, mss)) | ||
7502 | hwbug = true; | ||
7503 | |||
7467 | if (tg3_40bit_overflow_test(tp, map, len)) | 7504 | if (tg3_40bit_overflow_test(tp, map, len)) |
7468 | hwbug = true; | 7505 | hwbug = true; |
7469 | 7506 | ||
@@ -8874,6 +8911,10 @@ static int tg3_chip_reset(struct tg3 *tp) | |||
8874 | tg3_halt_cpu(tp, RX_CPU_BASE); | 8911 | tg3_halt_cpu(tp, RX_CPU_BASE); |
8875 | } | 8912 | } |
8876 | 8913 | ||
8914 | err = tg3_poll_fw(tp); | ||
8915 | if (err) | ||
8916 | return err; | ||
8917 | |||
8877 | tw32(GRC_MODE, tp->grc_mode); | 8918 | tw32(GRC_MODE, tp->grc_mode); |
8878 | 8919 | ||
8879 | if (tg3_chip_rev_id(tp) == CHIPREV_ID_5705_A0) { | 8920 | if (tg3_chip_rev_id(tp) == CHIPREV_ID_5705_A0) { |
@@ -8904,10 +8945,6 @@ static int tg3_chip_reset(struct tg3 *tp) | |||
8904 | 8945 | ||
8905 | tg3_ape_unlock(tp, TG3_APE_LOCK_GRC); | 8946 | tg3_ape_unlock(tp, TG3_APE_LOCK_GRC); |
8906 | 8947 | ||
8907 | err = tg3_poll_fw(tp); | ||
8908 | if (err) | ||
8909 | return err; | ||
8910 | |||
8911 | tg3_mdio_start(tp); | 8948 | tg3_mdio_start(tp); |
8912 | 8949 | ||
8913 | if (tg3_flag(tp, PCI_EXPRESS) && | 8950 | if (tg3_flag(tp, PCI_EXPRESS) && |
diff --git a/drivers/net/ethernet/cadence/macb.c b/drivers/net/ethernet/cadence/macb.c index 6be513deb17f..c89aa41dd448 100644 --- a/drivers/net/ethernet/cadence/macb.c +++ b/drivers/net/ethernet/cadence/macb.c | |||
@@ -485,7 +485,8 @@ static void macb_tx_interrupt(struct macb *bp) | |||
485 | status = macb_readl(bp, TSR); | 485 | status = macb_readl(bp, TSR); |
486 | macb_writel(bp, TSR, status); | 486 | macb_writel(bp, TSR, status); |
487 | 487 | ||
488 | macb_writel(bp, ISR, MACB_BIT(TCOMP)); | 488 | if (bp->caps & MACB_CAPS_ISR_CLEAR_ON_WRITE) |
489 | macb_writel(bp, ISR, MACB_BIT(TCOMP)); | ||
489 | 490 | ||
490 | netdev_vdbg(bp->dev, "macb_tx_interrupt status = 0x%03lx\n", | 491 | netdev_vdbg(bp->dev, "macb_tx_interrupt status = 0x%03lx\n", |
491 | (unsigned long)status); | 492 | (unsigned long)status); |
@@ -738,7 +739,8 @@ static irqreturn_t macb_interrupt(int irq, void *dev_id) | |||
738 | * now. | 739 | * now. |
739 | */ | 740 | */ |
740 | macb_writel(bp, IDR, MACB_RX_INT_FLAGS); | 741 | macb_writel(bp, IDR, MACB_RX_INT_FLAGS); |
741 | macb_writel(bp, ISR, MACB_BIT(RCOMP)); | 742 | if (bp->caps & MACB_CAPS_ISR_CLEAR_ON_WRITE) |
743 | macb_writel(bp, ISR, MACB_BIT(RCOMP)); | ||
742 | 744 | ||
743 | if (napi_schedule_prep(&bp->napi)) { | 745 | if (napi_schedule_prep(&bp->napi)) { |
744 | netdev_vdbg(bp->dev, "scheduling RX softirq\n"); | 746 | netdev_vdbg(bp->dev, "scheduling RX softirq\n"); |
@@ -1062,6 +1064,17 @@ static void macb_configure_dma(struct macb *bp) | |||
1062 | } | 1064 | } |
1063 | } | 1065 | } |
1064 | 1066 | ||
1067 | /* | ||
1068 | * Configure peripheral capacities according to integration options used | ||
1069 | */ | ||
1070 | static void macb_configure_caps(struct macb *bp) | ||
1071 | { | ||
1072 | if (macb_is_gem(bp)) { | ||
1073 | if (GEM_BF(IRQCOR, gem_readl(bp, DCFG1)) == 0) | ||
1074 | bp->caps |= MACB_CAPS_ISR_CLEAR_ON_WRITE; | ||
1075 | } | ||
1076 | } | ||
1077 | |||
1065 | static void macb_init_hw(struct macb *bp) | 1078 | static void macb_init_hw(struct macb *bp) |
1066 | { | 1079 | { |
1067 | u32 config; | 1080 | u32 config; |
@@ -1084,6 +1097,7 @@ static void macb_init_hw(struct macb *bp) | |||
1084 | bp->duplex = DUPLEX_HALF; | 1097 | bp->duplex = DUPLEX_HALF; |
1085 | 1098 | ||
1086 | macb_configure_dma(bp); | 1099 | macb_configure_dma(bp); |
1100 | macb_configure_caps(bp); | ||
1087 | 1101 | ||
1088 | /* Initialize TX and RX buffers */ | 1102 | /* Initialize TX and RX buffers */ |
1089 | macb_writel(bp, RBQP, bp->rx_ring_dma); | 1103 | macb_writel(bp, RBQP, bp->rx_ring_dma); |
diff --git a/drivers/net/ethernet/cadence/macb.h b/drivers/net/ethernet/cadence/macb.h index 993d70380688..548c0ecae869 100644 --- a/drivers/net/ethernet/cadence/macb.h +++ b/drivers/net/ethernet/cadence/macb.h | |||
@@ -300,6 +300,8 @@ | |||
300 | #define MACB_REV_SIZE 16 | 300 | #define MACB_REV_SIZE 16 |
301 | 301 | ||
302 | /* Bitfields in DCFG1. */ | 302 | /* Bitfields in DCFG1. */ |
303 | #define GEM_IRQCOR_OFFSET 23 | ||
304 | #define GEM_IRQCOR_SIZE 1 | ||
303 | #define GEM_DBWDEF_OFFSET 25 | 305 | #define GEM_DBWDEF_OFFSET 25 |
304 | #define GEM_DBWDEF_SIZE 3 | 306 | #define GEM_DBWDEF_SIZE 3 |
305 | 307 | ||
@@ -323,6 +325,9 @@ | |||
323 | #define MACB_MAN_READ 2 | 325 | #define MACB_MAN_READ 2 |
324 | #define MACB_MAN_CODE 2 | 326 | #define MACB_MAN_CODE 2 |
325 | 327 | ||
328 | /* Capability mask bits */ | ||
329 | #define MACB_CAPS_ISR_CLEAR_ON_WRITE 0x1 | ||
330 | |||
326 | /* Bit manipulation macros */ | 331 | /* Bit manipulation macros */ |
327 | #define MACB_BIT(name) \ | 332 | #define MACB_BIT(name) \ |
328 | (1 << MACB_##name##_OFFSET) | 333 | (1 << MACB_##name##_OFFSET) |
@@ -574,6 +579,8 @@ struct macb { | |||
574 | unsigned int speed; | 579 | unsigned int speed; |
575 | unsigned int duplex; | 580 | unsigned int duplex; |
576 | 581 | ||
582 | u32 caps; | ||
583 | |||
577 | phy_interface_t phy_interface; | 584 | phy_interface_t phy_interface; |
578 | 585 | ||
579 | /* AT91RM9200 transmit */ | 586 | /* AT91RM9200 transmit */ |
diff --git a/drivers/net/ethernet/emulex/benet/be_cmds.c b/drivers/net/ethernet/emulex/benet/be_cmds.c index fd7b547698ab..a236ecd27cf3 100644 --- a/drivers/net/ethernet/emulex/benet/be_cmds.c +++ b/drivers/net/ethernet/emulex/benet/be_cmds.c | |||
@@ -2976,22 +2976,17 @@ static struct be_nic_resource_desc *be_get_nic_desc(u8 *buf, u32 desc_count, | |||
2976 | for (i = 0; i < desc_count; i++) { | 2976 | for (i = 0; i < desc_count; i++) { |
2977 | desc->desc_len = desc->desc_len ? : RESOURCE_DESC_SIZE; | 2977 | desc->desc_len = desc->desc_len ? : RESOURCE_DESC_SIZE; |
2978 | if (((void *)desc + desc->desc_len) > | 2978 | if (((void *)desc + desc->desc_len) > |
2979 | (void *)(buf + max_buf_size)) { | 2979 | (void *)(buf + max_buf_size)) |
2980 | desc = NULL; | 2980 | return NULL; |
2981 | break; | ||
2982 | } | ||
2983 | 2981 | ||
2984 | if (desc->desc_type == NIC_RESOURCE_DESC_TYPE_V0 || | 2982 | if (desc->desc_type == NIC_RESOURCE_DESC_TYPE_V0 || |
2985 | desc->desc_type == NIC_RESOURCE_DESC_TYPE_V1) | 2983 | desc->desc_type == NIC_RESOURCE_DESC_TYPE_V1) |
2986 | break; | 2984 | return desc; |
2987 | 2985 | ||
2988 | desc = (void *)desc + desc->desc_len; | 2986 | desc = (void *)desc + desc->desc_len; |
2989 | } | 2987 | } |
2990 | 2988 | ||
2991 | if (!desc || i == MAX_RESOURCE_DESC) | 2989 | return NULL; |
2992 | return NULL; | ||
2993 | |||
2994 | return desc; | ||
2995 | } | 2990 | } |
2996 | 2991 | ||
2997 | /* Uses Mbox */ | 2992 | /* Uses Mbox */ |
diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c index a444110b060f..ca2967b0f18b 100644 --- a/drivers/net/ethernet/emulex/benet/be_main.c +++ b/drivers/net/ethernet/emulex/benet/be_main.c | |||
@@ -780,26 +780,18 @@ static struct sk_buff *be_insert_vlan_in_pkt(struct be_adapter *adapter, | |||
780 | if (unlikely(!skb)) | 780 | if (unlikely(!skb)) |
781 | return skb; | 781 | return skb; |
782 | 782 | ||
783 | if (vlan_tx_tag_present(skb)) { | 783 | if (vlan_tx_tag_present(skb)) |
784 | vlan_tag = be_get_tx_vlan_tag(adapter, skb); | 784 | vlan_tag = be_get_tx_vlan_tag(adapter, skb); |
785 | skb = __vlan_put_tag(skb, htons(ETH_P_8021Q), vlan_tag); | 785 | else if (qnq_async_evt_rcvd(adapter) && adapter->pvid) |
786 | if (skb) | 786 | vlan_tag = adapter->pvid; |
787 | skb->vlan_tci = 0; | ||
788 | } | ||
789 | |||
790 | if (qnq_async_evt_rcvd(adapter) && adapter->pvid) { | ||
791 | if (!vlan_tag) | ||
792 | vlan_tag = adapter->pvid; | ||
793 | if (skip_hw_vlan) | ||
794 | *skip_hw_vlan = true; | ||
795 | } | ||
796 | 787 | ||
797 | if (vlan_tag) { | 788 | if (vlan_tag) { |
798 | skb = __vlan_put_tag(skb, htons(ETH_P_8021Q), vlan_tag); | 789 | skb = __vlan_put_tag(skb, htons(ETH_P_8021Q), vlan_tag); |
799 | if (unlikely(!skb)) | 790 | if (unlikely(!skb)) |
800 | return skb; | 791 | return skb; |
801 | |||
802 | skb->vlan_tci = 0; | 792 | skb->vlan_tci = 0; |
793 | if (skip_hw_vlan) | ||
794 | *skip_hw_vlan = true; | ||
803 | } | 795 | } |
804 | 796 | ||
805 | /* Insert the outer VLAN, if any */ | 797 | /* Insert the outer VLAN, if any */ |
diff --git a/drivers/net/ethernet/freescale/fec_main.c b/drivers/net/ethernet/freescale/fec_main.c index ca9825ca88c9..85a06037b242 100644 --- a/drivers/net/ethernet/freescale/fec_main.c +++ b/drivers/net/ethernet/freescale/fec_main.c | |||
@@ -109,7 +109,7 @@ static struct platform_device_id fec_devtype[] = { | |||
109 | .driver_data = FEC_QUIRK_ENET_MAC | FEC_QUIRK_HAS_GBIT | | 109 | .driver_data = FEC_QUIRK_ENET_MAC | FEC_QUIRK_HAS_GBIT | |
110 | FEC_QUIRK_HAS_BUFDESC_EX | FEC_QUIRK_HAS_CSUM, | 110 | FEC_QUIRK_HAS_BUFDESC_EX | FEC_QUIRK_HAS_CSUM, |
111 | }, { | 111 | }, { |
112 | .name = "mvf-fec", | 112 | .name = "mvf600-fec", |
113 | .driver_data = FEC_QUIRK_ENET_MAC, | 113 | .driver_data = FEC_QUIRK_ENET_MAC, |
114 | }, { | 114 | }, { |
115 | /* sentinel */ | 115 | /* sentinel */ |
@@ -122,7 +122,7 @@ enum imx_fec_type { | |||
122 | IMX27_FEC, /* runs on i.mx27/35/51 */ | 122 | IMX27_FEC, /* runs on i.mx27/35/51 */ |
123 | IMX28_FEC, | 123 | IMX28_FEC, |
124 | IMX6Q_FEC, | 124 | IMX6Q_FEC, |
125 | MVF_FEC, | 125 | MVF600_FEC, |
126 | }; | 126 | }; |
127 | 127 | ||
128 | static const struct of_device_id fec_dt_ids[] = { | 128 | static const struct of_device_id fec_dt_ids[] = { |
@@ -130,7 +130,7 @@ static const struct of_device_id fec_dt_ids[] = { | |||
130 | { .compatible = "fsl,imx27-fec", .data = &fec_devtype[IMX27_FEC], }, | 130 | { .compatible = "fsl,imx27-fec", .data = &fec_devtype[IMX27_FEC], }, |
131 | { .compatible = "fsl,imx28-fec", .data = &fec_devtype[IMX28_FEC], }, | 131 | { .compatible = "fsl,imx28-fec", .data = &fec_devtype[IMX28_FEC], }, |
132 | { .compatible = "fsl,imx6q-fec", .data = &fec_devtype[IMX6Q_FEC], }, | 132 | { .compatible = "fsl,imx6q-fec", .data = &fec_devtype[IMX6Q_FEC], }, |
133 | { .compatible = "fsl,mvf-fec", .data = &fec_devtype[MVF_FEC], }, | 133 | { .compatible = "fsl,mvf600-fec", .data = &fec_devtype[MVF600_FEC], }, |
134 | { /* sentinel */ } | 134 | { /* sentinel */ } |
135 | }; | 135 | }; |
136 | MODULE_DEVICE_TABLE(of, fec_dt_ids); | 136 | MODULE_DEVICE_TABLE(of, fec_dt_ids); |
@@ -451,7 +451,7 @@ fec_restart(struct net_device *ndev, int duplex) | |||
451 | netif_device_detach(ndev); | 451 | netif_device_detach(ndev); |
452 | napi_disable(&fep->napi); | 452 | napi_disable(&fep->napi); |
453 | netif_stop_queue(ndev); | 453 | netif_stop_queue(ndev); |
454 | netif_tx_lock(ndev); | 454 | netif_tx_lock_bh(ndev); |
455 | } | 455 | } |
456 | 456 | ||
457 | /* Whack a reset. We should wait for this. */ | 457 | /* Whack a reset. We should wait for this. */ |
@@ -616,10 +616,10 @@ fec_restart(struct net_device *ndev, int duplex) | |||
616 | writel(FEC_DEFAULT_IMASK, fep->hwp + FEC_IMASK); | 616 | writel(FEC_DEFAULT_IMASK, fep->hwp + FEC_IMASK); |
617 | 617 | ||
618 | if (netif_running(ndev)) { | 618 | if (netif_running(ndev)) { |
619 | netif_device_attach(ndev); | 619 | netif_tx_unlock_bh(ndev); |
620 | napi_enable(&fep->napi); | ||
621 | netif_wake_queue(ndev); | 620 | netif_wake_queue(ndev); |
622 | netif_tx_unlock(ndev); | 621 | napi_enable(&fep->napi); |
622 | netif_device_attach(ndev); | ||
623 | } | 623 | } |
624 | } | 624 | } |
625 | 625 | ||
diff --git a/drivers/net/ethernet/freescale/gianfar_ptp.c b/drivers/net/ethernet/freescale/gianfar_ptp.c index 576e4b858fce..083ea2b4d20a 100644 --- a/drivers/net/ethernet/freescale/gianfar_ptp.c +++ b/drivers/net/ethernet/freescale/gianfar_ptp.c | |||
@@ -524,6 +524,7 @@ static int gianfar_ptp_probe(struct platform_device *dev) | |||
524 | return 0; | 524 | return 0; |
525 | 525 | ||
526 | no_clock: | 526 | no_clock: |
527 | iounmap(etsects->regs); | ||
527 | no_ioremap: | 528 | no_ioremap: |
528 | release_resource(etsects->rsrc); | 529 | release_resource(etsects->rsrc); |
529 | no_resource: | 530 | no_resource: |
diff --git a/drivers/net/ethernet/icplus/ipg.h b/drivers/net/ethernet/icplus/ipg.h index 6ce027355fcf..abb300a31912 100644 --- a/drivers/net/ethernet/icplus/ipg.h +++ b/drivers/net/ethernet/icplus/ipg.h | |||
@@ -195,57 +195,57 @@ enum ipg_regs { | |||
195 | /* TFD data structure masks. */ | 195 | /* TFD data structure masks. */ |
196 | 196 | ||
197 | /* TFDList, TFC */ | 197 | /* TFDList, TFC */ |
198 | #define IPG_TFC_RSVD_MASK 0x0000FFFF9FFFFFFF | 198 | #define IPG_TFC_RSVD_MASK 0x0000FFFF9FFFFFFFULL |
199 | #define IPG_TFC_FRAMEID 0x000000000000FFFF | 199 | #define IPG_TFC_FRAMEID 0x000000000000FFFFULL |
200 | #define IPG_TFC_WORDALIGN 0x0000000000030000 | 200 | #define IPG_TFC_WORDALIGN 0x0000000000030000ULL |
201 | #define IPG_TFC_WORDALIGNTODWORD 0x0000000000000000 | 201 | #define IPG_TFC_WORDALIGNTODWORD 0x0000000000000000ULL |
202 | #define IPG_TFC_WORDALIGNTOWORD 0x0000000000020000 | 202 | #define IPG_TFC_WORDALIGNTOWORD 0x0000000000020000ULL |
203 | #define IPG_TFC_WORDALIGNDISABLED 0x0000000000030000 | 203 | #define IPG_TFC_WORDALIGNDISABLED 0x0000000000030000ULL |
204 | #define IPG_TFC_TCPCHECKSUMENABLE 0x0000000000040000 | 204 | #define IPG_TFC_TCPCHECKSUMENABLE 0x0000000000040000ULL |
205 | #define IPG_TFC_UDPCHECKSUMENABLE 0x0000000000080000 | 205 | #define IPG_TFC_UDPCHECKSUMENABLE 0x0000000000080000ULL |
206 | #define IPG_TFC_IPCHECKSUMENABLE 0x0000000000100000 | 206 | #define IPG_TFC_IPCHECKSUMENABLE 0x0000000000100000ULL |
207 | #define IPG_TFC_FCSAPPENDDISABLE 0x0000000000200000 | 207 | #define IPG_TFC_FCSAPPENDDISABLE 0x0000000000200000ULL |
208 | #define IPG_TFC_TXINDICATE 0x0000000000400000 | 208 | #define IPG_TFC_TXINDICATE 0x0000000000400000ULL |
209 | #define IPG_TFC_TXDMAINDICATE 0x0000000000800000 | 209 | #define IPG_TFC_TXDMAINDICATE 0x0000000000800000ULL |
210 | #define IPG_TFC_FRAGCOUNT 0x000000000F000000 | 210 | #define IPG_TFC_FRAGCOUNT 0x000000000F000000ULL |
211 | #define IPG_TFC_VLANTAGINSERT 0x0000000010000000 | 211 | #define IPG_TFC_VLANTAGINSERT 0x0000000010000000ULL |
212 | #define IPG_TFC_TFDDONE 0x0000000080000000 | 212 | #define IPG_TFC_TFDDONE 0x0000000080000000ULL |
213 | #define IPG_TFC_VID 0x00000FFF00000000 | 213 | #define IPG_TFC_VID 0x00000FFF00000000ULL |
214 | #define IPG_TFC_CFI 0x0000100000000000 | 214 | #define IPG_TFC_CFI 0x0000100000000000ULL |
215 | #define IPG_TFC_USERPRIORITY 0x0000E00000000000 | 215 | #define IPG_TFC_USERPRIORITY 0x0000E00000000000ULL |
216 | 216 | ||
217 | /* TFDList, FragInfo */ | 217 | /* TFDList, FragInfo */ |
218 | #define IPG_TFI_RSVD_MASK 0xFFFF00FFFFFFFFFF | 218 | #define IPG_TFI_RSVD_MASK 0xFFFF00FFFFFFFFFFULL |
219 | #define IPG_TFI_FRAGADDR 0x000000FFFFFFFFFF | 219 | #define IPG_TFI_FRAGADDR 0x000000FFFFFFFFFFULL |
220 | #define IPG_TFI_FRAGLEN 0xFFFF000000000000LL | 220 | #define IPG_TFI_FRAGLEN 0xFFFF000000000000ULL |
221 | 221 | ||
222 | /* RFD data structure masks. */ | 222 | /* RFD data structure masks. */ |
223 | 223 | ||
224 | /* RFDList, RFS */ | 224 | /* RFDList, RFS */ |
225 | #define IPG_RFS_RSVD_MASK 0x0000FFFFFFFFFFFF | 225 | #define IPG_RFS_RSVD_MASK 0x0000FFFFFFFFFFFFULL |
226 | #define IPG_RFS_RXFRAMELEN 0x000000000000FFFF | 226 | #define IPG_RFS_RXFRAMELEN 0x000000000000FFFFULL |
227 | #define IPG_RFS_RXFIFOOVERRUN 0x0000000000010000 | 227 | #define IPG_RFS_RXFIFOOVERRUN 0x0000000000010000ULL |
228 | #define IPG_RFS_RXRUNTFRAME 0x0000000000020000 | 228 | #define IPG_RFS_RXRUNTFRAME 0x0000000000020000ULL |
229 | #define IPG_RFS_RXALIGNMENTERROR 0x0000000000040000 | 229 | #define IPG_RFS_RXALIGNMENTERROR 0x0000000000040000ULL |
230 | #define IPG_RFS_RXFCSERROR 0x0000000000080000 | 230 | #define IPG_RFS_RXFCSERROR 0x0000000000080000ULL |
231 | #define IPG_RFS_RXOVERSIZEDFRAME 0x0000000000100000 | 231 | #define IPG_RFS_RXOVERSIZEDFRAME 0x0000000000100000ULL |
232 | #define IPG_RFS_RXLENGTHERROR 0x0000000000200000 | 232 | #define IPG_RFS_RXLENGTHERROR 0x0000000000200000ULL |
233 | #define IPG_RFS_VLANDETECTED 0x0000000000400000 | 233 | #define IPG_RFS_VLANDETECTED 0x0000000000400000ULL |
234 | #define IPG_RFS_TCPDETECTED 0x0000000000800000 | 234 | #define IPG_RFS_TCPDETECTED 0x0000000000800000ULL |
235 | #define IPG_RFS_TCPERROR 0x0000000001000000 | 235 | #define IPG_RFS_TCPERROR 0x0000000001000000ULL |
236 | #define IPG_RFS_UDPDETECTED 0x0000000002000000 | 236 | #define IPG_RFS_UDPDETECTED 0x0000000002000000ULL |
237 | #define IPG_RFS_UDPERROR 0x0000000004000000 | 237 | #define IPG_RFS_UDPERROR 0x0000000004000000ULL |
238 | #define IPG_RFS_IPDETECTED 0x0000000008000000 | 238 | #define IPG_RFS_IPDETECTED 0x0000000008000000ULL |
239 | #define IPG_RFS_IPERROR 0x0000000010000000 | 239 | #define IPG_RFS_IPERROR 0x0000000010000000ULL |
240 | #define IPG_RFS_FRAMESTART 0x0000000020000000 | 240 | #define IPG_RFS_FRAMESTART 0x0000000020000000ULL |
241 | #define IPG_RFS_FRAMEEND 0x0000000040000000 | 241 | #define IPG_RFS_FRAMEEND 0x0000000040000000ULL |
242 | #define IPG_RFS_RFDDONE 0x0000000080000000 | 242 | #define IPG_RFS_RFDDONE 0x0000000080000000ULL |
243 | #define IPG_RFS_TCI 0x0000FFFF00000000 | 243 | #define IPG_RFS_TCI 0x0000FFFF00000000ULL |
244 | 244 | ||
245 | /* RFDList, FragInfo */ | 245 | /* RFDList, FragInfo */ |
246 | #define IPG_RFI_RSVD_MASK 0xFFFF00FFFFFFFFFF | 246 | #define IPG_RFI_RSVD_MASK 0xFFFF00FFFFFFFFFFULL |
247 | #define IPG_RFI_FRAGADDR 0x000000FFFFFFFFFF | 247 | #define IPG_RFI_FRAGADDR 0x000000FFFFFFFFFFULL |
248 | #define IPG_RFI_FRAGLEN 0xFFFF000000000000LL | 248 | #define IPG_RFI_FRAGLEN 0xFFFF000000000000ULL |
249 | 249 | ||
250 | /* I/O Register masks. */ | 250 | /* I/O Register masks. */ |
251 | 251 | ||
diff --git a/drivers/net/ethernet/marvell/mv643xx_eth.c b/drivers/net/ethernet/marvell/mv643xx_eth.c index d0afeea181fb..2ad1494efbb3 100644 --- a/drivers/net/ethernet/marvell/mv643xx_eth.c +++ b/drivers/net/ethernet/marvell/mv643xx_eth.c | |||
@@ -867,7 +867,7 @@ static int txq_reclaim(struct tx_queue *txq, int budget, int force) | |||
867 | struct netdev_queue *nq = netdev_get_tx_queue(mp->dev, txq->index); | 867 | struct netdev_queue *nq = netdev_get_tx_queue(mp->dev, txq->index); |
868 | int reclaimed; | 868 | int reclaimed; |
869 | 869 | ||
870 | __netif_tx_lock(nq, smp_processor_id()); | 870 | __netif_tx_lock_bh(nq); |
871 | 871 | ||
872 | reclaimed = 0; | 872 | reclaimed = 0; |
873 | while (reclaimed < budget && txq->tx_desc_count > 0) { | 873 | while (reclaimed < budget && txq->tx_desc_count > 0) { |
@@ -913,7 +913,7 @@ static int txq_reclaim(struct tx_queue *txq, int budget, int force) | |||
913 | dev_kfree_skb(skb); | 913 | dev_kfree_skb(skb); |
914 | } | 914 | } |
915 | 915 | ||
916 | __netif_tx_unlock(nq); | 916 | __netif_tx_unlock_bh(nq); |
917 | 917 | ||
918 | if (reclaimed < budget) | 918 | if (reclaimed < budget) |
919 | mp->work_tx &= ~(1 << txq->index); | 919 | mp->work_tx &= ~(1 << txq->index); |
@@ -2745,7 +2745,7 @@ static int mv643xx_eth_probe(struct platform_device *pdev) | |||
2745 | 2745 | ||
2746 | INIT_WORK(&mp->tx_timeout_task, tx_timeout_task); | 2746 | INIT_WORK(&mp->tx_timeout_task, tx_timeout_task); |
2747 | 2747 | ||
2748 | netif_napi_add(dev, &mp->napi, mv643xx_eth_poll, 128); | 2748 | netif_napi_add(dev, &mp->napi, mv643xx_eth_poll, NAPI_POLL_WEIGHT); |
2749 | 2749 | ||
2750 | init_timer(&mp->rx_oom); | 2750 | init_timer(&mp->rx_oom); |
2751 | mp->rx_oom.data = (unsigned long)mp; | 2751 | mp->rx_oom.data = (unsigned long)mp; |
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h b/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h index 019c5f78732e..c1b693cb3df3 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h | |||
@@ -907,8 +907,11 @@ struct qlcnic_ipaddr { | |||
907 | #define QLCNIC_FW_HANG 0x4000 | 907 | #define QLCNIC_FW_HANG 0x4000 |
908 | #define QLCNIC_FW_LRO_MSS_CAP 0x8000 | 908 | #define QLCNIC_FW_LRO_MSS_CAP 0x8000 |
909 | #define QLCNIC_TX_INTR_SHARED 0x10000 | 909 | #define QLCNIC_TX_INTR_SHARED 0x10000 |
910 | #define QLCNIC_APP_CHANGED_FLAGS 0x20000 | ||
910 | #define QLCNIC_IS_MSI_FAMILY(adapter) \ | 911 | #define QLCNIC_IS_MSI_FAMILY(adapter) \ |
911 | ((adapter)->flags & (QLCNIC_MSI_ENABLED | QLCNIC_MSIX_ENABLED)) | 912 | ((adapter)->flags & (QLCNIC_MSI_ENABLED | QLCNIC_MSIX_ENABLED)) |
913 | #define QLCNIC_IS_TSO_CAPABLE(adapter) \ | ||
914 | ((adapter)->ahw->capabilities & QLCNIC_FW_CAPABILITY_TSO) | ||
912 | 915 | ||
913 | #define QLCNIC_DEF_NUM_STS_DESC_RINGS 4 | 916 | #define QLCNIC_DEF_NUM_STS_DESC_RINGS 4 |
914 | #define QLCNIC_MSIX_TBL_SPACE 8192 | 917 | #define QLCNIC_MSIX_TBL_SPACE 8192 |
@@ -1034,6 +1037,7 @@ struct qlcnic_adapter { | |||
1034 | spinlock_t rx_mac_learn_lock; | 1037 | spinlock_t rx_mac_learn_lock; |
1035 | u32 file_prd_off; /*File fw product offset*/ | 1038 | u32 file_prd_off; /*File fw product offset*/ |
1036 | u32 fw_version; | 1039 | u32 fw_version; |
1040 | u32 offload_flags; | ||
1037 | const struct firmware *fw; | 1041 | const struct firmware *fw; |
1038 | }; | 1042 | }; |
1039 | 1043 | ||
@@ -1542,6 +1546,8 @@ void qlcnic_add_lb_filter(struct qlcnic_adapter *, struct sk_buff *, int, u16); | |||
1542 | int qlcnic_83xx_configure_opmode(struct qlcnic_adapter *adapter); | 1546 | int qlcnic_83xx_configure_opmode(struct qlcnic_adapter *adapter); |
1543 | int qlcnic_read_mac_addr(struct qlcnic_adapter *); | 1547 | int qlcnic_read_mac_addr(struct qlcnic_adapter *); |
1544 | int qlcnic_setup_netdev(struct qlcnic_adapter *, struct net_device *, int); | 1548 | int qlcnic_setup_netdev(struct qlcnic_adapter *, struct net_device *, int); |
1549 | void qlcnic_set_netdev_features(struct qlcnic_adapter *, | ||
1550 | struct qlcnic_esw_func_cfg *); | ||
1545 | void qlcnic_sriov_vf_schedule_multi(struct net_device *); | 1551 | void qlcnic_sriov_vf_schedule_multi(struct net_device *); |
1546 | void qlcnic_vf_add_mc_list(struct net_device *, u16); | 1552 | void qlcnic_vf_add_mc_list(struct net_device *, u16); |
1547 | 1553 | ||
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c index c67d1eb35e8f..5e7fb1dfb97b 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c | |||
@@ -382,8 +382,6 @@ static int qlcnic_83xx_idc_tx_soft_reset(struct qlcnic_adapter *adapter) | |||
382 | clear_bit(__QLCNIC_RESETTING, &adapter->state); | 382 | clear_bit(__QLCNIC_RESETTING, &adapter->state); |
383 | dev_err(&adapter->pdev->dev, "%s:\n", __func__); | 383 | dev_err(&adapter->pdev->dev, "%s:\n", __func__); |
384 | 384 | ||
385 | adapter->netdev->trans_start = jiffies; | ||
386 | |||
387 | return 0; | 385 | return 0; |
388 | } | 386 | } |
389 | 387 | ||
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.c index 6a6512ba9f38..106a12f2a02f 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.c | |||
@@ -973,16 +973,57 @@ int qlcnic_change_mtu(struct net_device *netdev, int mtu) | |||
973 | return rc; | 973 | return rc; |
974 | } | 974 | } |
975 | 975 | ||
976 | static netdev_features_t qlcnic_process_flags(struct qlcnic_adapter *adapter, | ||
977 | netdev_features_t features) | ||
978 | { | ||
979 | u32 offload_flags = adapter->offload_flags; | ||
980 | |||
981 | if (offload_flags & BIT_0) { | ||
982 | features |= NETIF_F_RXCSUM | NETIF_F_IP_CSUM | | ||
983 | NETIF_F_IPV6_CSUM; | ||
984 | adapter->rx_csum = 1; | ||
985 | if (QLCNIC_IS_TSO_CAPABLE(adapter)) { | ||
986 | if (!(offload_flags & BIT_1)) | ||
987 | features &= ~NETIF_F_TSO; | ||
988 | else | ||
989 | features |= NETIF_F_TSO; | ||
990 | |||
991 | if (!(offload_flags & BIT_2)) | ||
992 | features &= ~NETIF_F_TSO6; | ||
993 | else | ||
994 | features |= NETIF_F_TSO6; | ||
995 | } | ||
996 | } else { | ||
997 | features &= ~(NETIF_F_RXCSUM | | ||
998 | NETIF_F_IP_CSUM | | ||
999 | NETIF_F_IPV6_CSUM); | ||
1000 | |||
1001 | if (QLCNIC_IS_TSO_CAPABLE(adapter)) | ||
1002 | features &= ~(NETIF_F_TSO | NETIF_F_TSO6); | ||
1003 | adapter->rx_csum = 0; | ||
1004 | } | ||
1005 | |||
1006 | return features; | ||
1007 | } | ||
976 | 1008 | ||
977 | netdev_features_t qlcnic_fix_features(struct net_device *netdev, | 1009 | netdev_features_t qlcnic_fix_features(struct net_device *netdev, |
978 | netdev_features_t features) | 1010 | netdev_features_t features) |
979 | { | 1011 | { |
980 | struct qlcnic_adapter *adapter = netdev_priv(netdev); | 1012 | struct qlcnic_adapter *adapter = netdev_priv(netdev); |
1013 | netdev_features_t changed; | ||
981 | 1014 | ||
982 | if ((adapter->flags & QLCNIC_ESWITCH_ENABLED) && | 1015 | if (qlcnic_82xx_check(adapter) && |
983 | qlcnic_82xx_check(adapter)) { | 1016 | (adapter->flags & QLCNIC_ESWITCH_ENABLED)) { |
984 | netdev_features_t changed = features ^ netdev->features; | 1017 | if (adapter->flags & QLCNIC_APP_CHANGED_FLAGS) { |
985 | features ^= changed & (NETIF_F_ALL_CSUM | NETIF_F_RXCSUM); | 1018 | features = qlcnic_process_flags(adapter, features); |
1019 | } else { | ||
1020 | changed = features ^ netdev->features; | ||
1021 | features ^= changed & (NETIF_F_RXCSUM | | ||
1022 | NETIF_F_IP_CSUM | | ||
1023 | NETIF_F_IPV6_CSUM | | ||
1024 | NETIF_F_TSO | | ||
1025 | NETIF_F_TSO6); | ||
1026 | } | ||
986 | } | 1027 | } |
987 | 1028 | ||
988 | if (!(features & NETIF_F_RXCSUM)) | 1029 | if (!(features & NETIF_F_RXCSUM)) |
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c index 8fb836d4129f..aeb26a850679 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c | |||
@@ -84,14 +84,9 @@ static int qlcnic_start_firmware(struct qlcnic_adapter *); | |||
84 | static void qlcnic_free_lb_filters_mem(struct qlcnic_adapter *adapter); | 84 | static void qlcnic_free_lb_filters_mem(struct qlcnic_adapter *adapter); |
85 | static void qlcnic_dev_set_npar_ready(struct qlcnic_adapter *); | 85 | static void qlcnic_dev_set_npar_ready(struct qlcnic_adapter *); |
86 | static int qlcnicvf_start_firmware(struct qlcnic_adapter *); | 86 | static int qlcnicvf_start_firmware(struct qlcnic_adapter *); |
87 | static void qlcnic_set_netdev_features(struct qlcnic_adapter *, | ||
88 | struct qlcnic_esw_func_cfg *); | ||
89 | static int qlcnic_vlan_rx_add(struct net_device *, __be16, u16); | 87 | static int qlcnic_vlan_rx_add(struct net_device *, __be16, u16); |
90 | static int qlcnic_vlan_rx_del(struct net_device *, __be16, u16); | 88 | static int qlcnic_vlan_rx_del(struct net_device *, __be16, u16); |
91 | 89 | ||
92 | #define QLCNIC_IS_TSO_CAPABLE(adapter) \ | ||
93 | ((adapter)->ahw->capabilities & QLCNIC_FW_CAPABILITY_TSO) | ||
94 | |||
95 | static u32 qlcnic_vlan_tx_check(struct qlcnic_adapter *adapter) | 90 | static u32 qlcnic_vlan_tx_check(struct qlcnic_adapter *adapter) |
96 | { | 91 | { |
97 | struct qlcnic_hardware_context *ahw = adapter->ahw; | 92 | struct qlcnic_hardware_context *ahw = adapter->ahw; |
@@ -1074,8 +1069,6 @@ void qlcnic_set_eswitch_port_features(struct qlcnic_adapter *adapter, | |||
1074 | 1069 | ||
1075 | if (!esw_cfg->promisc_mode) | 1070 | if (!esw_cfg->promisc_mode) |
1076 | adapter->flags |= QLCNIC_PROMISC_DISABLED; | 1071 | adapter->flags |= QLCNIC_PROMISC_DISABLED; |
1077 | |||
1078 | qlcnic_set_netdev_features(adapter, esw_cfg); | ||
1079 | } | 1072 | } |
1080 | 1073 | ||
1081 | int qlcnic_set_eswitch_port_config(struct qlcnic_adapter *adapter) | 1074 | int qlcnic_set_eswitch_port_config(struct qlcnic_adapter *adapter) |
@@ -1090,51 +1083,23 @@ int qlcnic_set_eswitch_port_config(struct qlcnic_adapter *adapter) | |||
1090 | return -EIO; | 1083 | return -EIO; |
1091 | qlcnic_set_vlan_config(adapter, &esw_cfg); | 1084 | qlcnic_set_vlan_config(adapter, &esw_cfg); |
1092 | qlcnic_set_eswitch_port_features(adapter, &esw_cfg); | 1085 | qlcnic_set_eswitch_port_features(adapter, &esw_cfg); |
1086 | qlcnic_set_netdev_features(adapter, &esw_cfg); | ||
1093 | 1087 | ||
1094 | return 0; | 1088 | return 0; |
1095 | } | 1089 | } |
1096 | 1090 | ||
1097 | static void | 1091 | void qlcnic_set_netdev_features(struct qlcnic_adapter *adapter, |
1098 | qlcnic_set_netdev_features(struct qlcnic_adapter *adapter, | 1092 | struct qlcnic_esw_func_cfg *esw_cfg) |
1099 | struct qlcnic_esw_func_cfg *esw_cfg) | ||
1100 | { | 1093 | { |
1101 | struct net_device *netdev = adapter->netdev; | 1094 | struct net_device *netdev = adapter->netdev; |
1102 | unsigned long features, vlan_features; | ||
1103 | 1095 | ||
1104 | if (qlcnic_83xx_check(adapter)) | 1096 | if (qlcnic_83xx_check(adapter)) |
1105 | return; | 1097 | return; |
1106 | 1098 | ||
1107 | features = (NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_RXCSUM | | 1099 | adapter->offload_flags = esw_cfg->offload_flags; |
1108 | NETIF_F_IPV6_CSUM | NETIF_F_GRO); | 1100 | adapter->flags |= QLCNIC_APP_CHANGED_FLAGS; |
1109 | vlan_features = (NETIF_F_SG | NETIF_F_IP_CSUM | | 1101 | netdev_update_features(netdev); |
1110 | NETIF_F_IPV6_CSUM); | 1102 | adapter->flags &= ~QLCNIC_APP_CHANGED_FLAGS; |
1111 | |||
1112 | if (QLCNIC_IS_TSO_CAPABLE(adapter)) { | ||
1113 | features |= (NETIF_F_TSO | NETIF_F_TSO6); | ||
1114 | vlan_features |= (NETIF_F_TSO | NETIF_F_TSO6); | ||
1115 | } | ||
1116 | |||
1117 | if (netdev->features & NETIF_F_LRO) | ||
1118 | features |= NETIF_F_LRO; | ||
1119 | |||
1120 | if (esw_cfg->offload_flags & BIT_0) { | ||
1121 | netdev->features |= features; | ||
1122 | adapter->rx_csum = 1; | ||
1123 | if (!(esw_cfg->offload_flags & BIT_1)) { | ||
1124 | netdev->features &= ~NETIF_F_TSO; | ||
1125 | features &= ~NETIF_F_TSO; | ||
1126 | } | ||
1127 | if (!(esw_cfg->offload_flags & BIT_2)) { | ||
1128 | netdev->features &= ~NETIF_F_TSO6; | ||
1129 | features &= ~NETIF_F_TSO6; | ||
1130 | } | ||
1131 | } else { | ||
1132 | netdev->features &= ~features; | ||
1133 | features &= ~features; | ||
1134 | adapter->rx_csum = 0; | ||
1135 | } | ||
1136 | |||
1137 | netdev->vlan_features = (features & vlan_features); | ||
1138 | } | 1103 | } |
1139 | 1104 | ||
1140 | static int | 1105 | static int |
@@ -2016,8 +1981,10 @@ qlcnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
2016 | pci_enable_pcie_error_reporting(pdev); | 1981 | pci_enable_pcie_error_reporting(pdev); |
2017 | 1982 | ||
2018 | ahw = kzalloc(sizeof(struct qlcnic_hardware_context), GFP_KERNEL); | 1983 | ahw = kzalloc(sizeof(struct qlcnic_hardware_context), GFP_KERNEL); |
2019 | if (!ahw) | 1984 | if (!ahw) { |
1985 | err = -ENOMEM; | ||
2020 | goto err_out_free_res; | 1986 | goto err_out_free_res; |
1987 | } | ||
2021 | 1988 | ||
2022 | switch (ent->device) { | 1989 | switch (ent->device) { |
2023 | case PCI_DEVICE_ID_QLOGIC_QLE824X: | 1990 | case PCI_DEVICE_ID_QLOGIC_QLE824X: |
@@ -2053,6 +2020,7 @@ qlcnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
2053 | 2020 | ||
2054 | adapter->qlcnic_wq = create_singlethread_workqueue("qlcnic"); | 2021 | adapter->qlcnic_wq = create_singlethread_workqueue("qlcnic"); |
2055 | if (adapter->qlcnic_wq == NULL) { | 2022 | if (adapter->qlcnic_wq == NULL) { |
2023 | err = -ENOMEM; | ||
2056 | dev_err(&pdev->dev, "Failed to create workqueue\n"); | 2024 | dev_err(&pdev->dev, "Failed to create workqueue\n"); |
2057 | goto err_out_free_netdev; | 2025 | goto err_out_free_netdev; |
2058 | } | 2026 | } |
@@ -2133,6 +2101,10 @@ qlcnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
2133 | goto err_out_disable_msi; | 2101 | goto err_out_disable_msi; |
2134 | } | 2102 | } |
2135 | 2103 | ||
2104 | err = qlcnic_get_act_pci_func(adapter); | ||
2105 | if (err) | ||
2106 | goto err_out_disable_mbx_intr; | ||
2107 | |||
2136 | err = qlcnic_setup_netdev(adapter, netdev, pci_using_dac); | 2108 | err = qlcnic_setup_netdev(adapter, netdev, pci_using_dac); |
2137 | if (err) | 2109 | if (err) |
2138 | goto err_out_disable_mbx_intr; | 2110 | goto err_out_disable_mbx_intr; |
@@ -2162,9 +2134,6 @@ qlcnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
2162 | break; | 2134 | break; |
2163 | } | 2135 | } |
2164 | 2136 | ||
2165 | if (qlcnic_get_act_pci_func(adapter)) | ||
2166 | goto err_out_disable_mbx_intr; | ||
2167 | |||
2168 | if (adapter->drv_mac_learn) | 2137 | if (adapter->drv_mac_learn) |
2169 | qlcnic_alloc_lb_filters_mem(adapter); | 2138 | qlcnic_alloc_lb_filters_mem(adapter); |
2170 | 2139 | ||
@@ -3149,10 +3118,8 @@ qlcnic_check_health(struct qlcnic_adapter *adapter) | |||
3149 | if (adapter->need_fw_reset) | 3118 | if (adapter->need_fw_reset) |
3150 | goto detach; | 3119 | goto detach; |
3151 | 3120 | ||
3152 | if (adapter->ahw->reset_context && qlcnic_auto_fw_reset) { | 3121 | if (adapter->ahw->reset_context && qlcnic_auto_fw_reset) |
3153 | qlcnic_reset_hw_context(adapter); | 3122 | qlcnic_reset_hw_context(adapter); |
3154 | adapter->netdev->trans_start = jiffies; | ||
3155 | } | ||
3156 | 3123 | ||
3157 | return 0; | 3124 | return 0; |
3158 | } | 3125 | } |
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_common.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_common.c index 3869c3864deb..196b2d100407 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_common.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_common.c | |||
@@ -1734,7 +1734,6 @@ static int qlcnic_sriov_vf_handle_context_reset(struct qlcnic_adapter *adapter) | |||
1734 | 1734 | ||
1735 | if (!qlcnic_sriov_vf_reinit_driver(adapter)) { | 1735 | if (!qlcnic_sriov_vf_reinit_driver(adapter)) { |
1736 | qlcnic_sriov_vf_attach(adapter); | 1736 | qlcnic_sriov_vf_attach(adapter); |
1737 | adapter->netdev->trans_start = jiffies; | ||
1738 | adapter->tx_timeo_cnt = 0; | 1737 | adapter->tx_timeo_cnt = 0; |
1739 | adapter->reset_ctx_cnt = 0; | 1738 | adapter->reset_ctx_cnt = 0; |
1740 | adapter->fw_fail_cnt = 0; | 1739 | adapter->fw_fail_cnt = 0; |
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sysfs.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sysfs.c index 4e22e794a186..e7a2fe21b649 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sysfs.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sysfs.c | |||
@@ -544,6 +544,9 @@ static ssize_t qlcnic_sysfs_write_esw_config(struct file *file, | |||
544 | switch (esw_cfg[i].op_mode) { | 544 | switch (esw_cfg[i].op_mode) { |
545 | case QLCNIC_PORT_DEFAULTS: | 545 | case QLCNIC_PORT_DEFAULTS: |
546 | qlcnic_set_eswitch_port_features(adapter, &esw_cfg[i]); | 546 | qlcnic_set_eswitch_port_features(adapter, &esw_cfg[i]); |
547 | rtnl_lock(); | ||
548 | qlcnic_set_netdev_features(adapter, &esw_cfg[i]); | ||
549 | rtnl_unlock(); | ||
547 | break; | 550 | break; |
548 | case QLCNIC_ADD_VLAN: | 551 | case QLCNIC_ADD_VLAN: |
549 | qlcnic_set_vlan_config(adapter, &esw_cfg[i]); | 552 | qlcnic_set_vlan_config(adapter, &esw_cfg[i]); |
diff --git a/drivers/net/ethernet/realtek/8139cp.c b/drivers/net/ethernet/realtek/8139cp.c index 7d1fb9ad1296..03523459c406 100644 --- a/drivers/net/ethernet/realtek/8139cp.c +++ b/drivers/net/ethernet/realtek/8139cp.c | |||
@@ -1136,6 +1136,7 @@ static void cp_clean_rings (struct cp_private *cp) | |||
1136 | cp->dev->stats.tx_dropped++; | 1136 | cp->dev->stats.tx_dropped++; |
1137 | } | 1137 | } |
1138 | } | 1138 | } |
1139 | netdev_reset_queue(cp->dev); | ||
1139 | 1140 | ||
1140 | memset(cp->rx_ring, 0, sizeof(struct cp_desc) * CP_RX_RING_SIZE); | 1141 | memset(cp->rx_ring, 0, sizeof(struct cp_desc) * CP_RX_RING_SIZE); |
1141 | memset(cp->tx_ring, 0, sizeof(struct cp_desc) * CP_TX_RING_SIZE); | 1142 | memset(cp->tx_ring, 0, sizeof(struct cp_desc) * CP_TX_RING_SIZE); |
diff --git a/drivers/net/ethernet/realtek/r8169.c b/drivers/net/ethernet/realtek/r8169.c index 79c520b64fdd..393f961a013c 100644 --- a/drivers/net/ethernet/realtek/r8169.c +++ b/drivers/net/ethernet/realtek/r8169.c | |||
@@ -5856,7 +5856,20 @@ err_out: | |||
5856 | return -EIO; | 5856 | return -EIO; |
5857 | } | 5857 | } |
5858 | 5858 | ||
5859 | static inline void rtl8169_tso_csum(struct rtl8169_private *tp, | 5859 | static bool rtl_skb_pad(struct sk_buff *skb) |
5860 | { | ||
5861 | if (skb_padto(skb, ETH_ZLEN)) | ||
5862 | return false; | ||
5863 | skb_put(skb, ETH_ZLEN - skb->len); | ||
5864 | return true; | ||
5865 | } | ||
5866 | |||
5867 | static bool rtl_test_hw_pad_bug(struct rtl8169_private *tp, struct sk_buff *skb) | ||
5868 | { | ||
5869 | return skb->len < ETH_ZLEN && tp->mac_version == RTL_GIGA_MAC_VER_34; | ||
5870 | } | ||
5871 | |||
5872 | static inline bool rtl8169_tso_csum(struct rtl8169_private *tp, | ||
5860 | struct sk_buff *skb, u32 *opts) | 5873 | struct sk_buff *skb, u32 *opts) |
5861 | { | 5874 | { |
5862 | const struct rtl_tx_desc_info *info = tx_desc_info + tp->txd_version; | 5875 | const struct rtl_tx_desc_info *info = tx_desc_info + tp->txd_version; |
@@ -5869,13 +5882,20 @@ static inline void rtl8169_tso_csum(struct rtl8169_private *tp, | |||
5869 | } else if (skb->ip_summed == CHECKSUM_PARTIAL) { | 5882 | } else if (skb->ip_summed == CHECKSUM_PARTIAL) { |
5870 | const struct iphdr *ip = ip_hdr(skb); | 5883 | const struct iphdr *ip = ip_hdr(skb); |
5871 | 5884 | ||
5885 | if (unlikely(rtl_test_hw_pad_bug(tp, skb))) | ||
5886 | return skb_checksum_help(skb) == 0 && rtl_skb_pad(skb); | ||
5887 | |||
5872 | if (ip->protocol == IPPROTO_TCP) | 5888 | if (ip->protocol == IPPROTO_TCP) |
5873 | opts[offset] |= info->checksum.tcp; | 5889 | opts[offset] |= info->checksum.tcp; |
5874 | else if (ip->protocol == IPPROTO_UDP) | 5890 | else if (ip->protocol == IPPROTO_UDP) |
5875 | opts[offset] |= info->checksum.udp; | 5891 | opts[offset] |= info->checksum.udp; |
5876 | else | 5892 | else |
5877 | WARN_ON_ONCE(1); | 5893 | WARN_ON_ONCE(1); |
5894 | } else { | ||
5895 | if (unlikely(rtl_test_hw_pad_bug(tp, skb))) | ||
5896 | return rtl_skb_pad(skb); | ||
5878 | } | 5897 | } |
5898 | return true; | ||
5879 | } | 5899 | } |
5880 | 5900 | ||
5881 | static netdev_tx_t rtl8169_start_xmit(struct sk_buff *skb, | 5901 | static netdev_tx_t rtl8169_start_xmit(struct sk_buff *skb, |
@@ -5896,17 +5916,15 @@ static netdev_tx_t rtl8169_start_xmit(struct sk_buff *skb, | |||
5896 | goto err_stop_0; | 5916 | goto err_stop_0; |
5897 | } | 5917 | } |
5898 | 5918 | ||
5899 | /* 8168evl does not automatically pad to minimum length. */ | ||
5900 | if (unlikely(tp->mac_version == RTL_GIGA_MAC_VER_34 && | ||
5901 | skb->len < ETH_ZLEN)) { | ||
5902 | if (skb_padto(skb, ETH_ZLEN)) | ||
5903 | goto err_update_stats; | ||
5904 | skb_put(skb, ETH_ZLEN - skb->len); | ||
5905 | } | ||
5906 | |||
5907 | if (unlikely(le32_to_cpu(txd->opts1) & DescOwn)) | 5919 | if (unlikely(le32_to_cpu(txd->opts1) & DescOwn)) |
5908 | goto err_stop_0; | 5920 | goto err_stop_0; |
5909 | 5921 | ||
5922 | opts[1] = cpu_to_le32(rtl8169_tx_vlan_tag(skb)); | ||
5923 | opts[0] = DescOwn; | ||
5924 | |||
5925 | if (!rtl8169_tso_csum(tp, skb, opts)) | ||
5926 | goto err_update_stats; | ||
5927 | |||
5910 | len = skb_headlen(skb); | 5928 | len = skb_headlen(skb); |
5911 | mapping = dma_map_single(d, skb->data, len, DMA_TO_DEVICE); | 5929 | mapping = dma_map_single(d, skb->data, len, DMA_TO_DEVICE); |
5912 | if (unlikely(dma_mapping_error(d, mapping))) { | 5930 | if (unlikely(dma_mapping_error(d, mapping))) { |
@@ -5918,11 +5936,6 @@ static netdev_tx_t rtl8169_start_xmit(struct sk_buff *skb, | |||
5918 | tp->tx_skb[entry].len = len; | 5936 | tp->tx_skb[entry].len = len; |
5919 | txd->addr = cpu_to_le64(mapping); | 5937 | txd->addr = cpu_to_le64(mapping); |
5920 | 5938 | ||
5921 | opts[1] = cpu_to_le32(rtl8169_tx_vlan_tag(skb)); | ||
5922 | opts[0] = DescOwn; | ||
5923 | |||
5924 | rtl8169_tso_csum(tp, skb, opts); | ||
5925 | |||
5926 | frags = rtl8169_xmit_frags(tp, skb, opts); | 5939 | frags = rtl8169_xmit_frags(tp, skb, opts); |
5927 | if (frags < 0) | 5940 | if (frags < 0) |
5928 | goto err_dma_1; | 5941 | goto err_dma_1; |
diff --git a/drivers/net/ethernet/sfc/efx.c b/drivers/net/ethernet/sfc/efx.c index 01b99206139a..39e4cb39de29 100644 --- a/drivers/net/ethernet/sfc/efx.c +++ b/drivers/net/ethernet/sfc/efx.c | |||
@@ -638,14 +638,16 @@ static void efx_start_datapath(struct efx_nic *efx) | |||
638 | EFX_MAX_FRAME_LEN(efx->net_dev->mtu) + | 638 | EFX_MAX_FRAME_LEN(efx->net_dev->mtu) + |
639 | efx->type->rx_buffer_padding); | 639 | efx->type->rx_buffer_padding); |
640 | rx_buf_len = (sizeof(struct efx_rx_page_state) + | 640 | rx_buf_len = (sizeof(struct efx_rx_page_state) + |
641 | EFX_PAGE_IP_ALIGN + efx->rx_dma_len); | 641 | NET_IP_ALIGN + efx->rx_dma_len); |
642 | if (rx_buf_len <= PAGE_SIZE) { | 642 | if (rx_buf_len <= PAGE_SIZE) { |
643 | efx->rx_scatter = false; | 643 | efx->rx_scatter = false; |
644 | efx->rx_buffer_order = 0; | 644 | efx->rx_buffer_order = 0; |
645 | } else if (efx->type->can_rx_scatter) { | 645 | } else if (efx->type->can_rx_scatter) { |
646 | BUILD_BUG_ON(EFX_RX_USR_BUF_SIZE % L1_CACHE_BYTES); | ||
646 | BUILD_BUG_ON(sizeof(struct efx_rx_page_state) + | 647 | BUILD_BUG_ON(sizeof(struct efx_rx_page_state) + |
647 | EFX_PAGE_IP_ALIGN + EFX_RX_USR_BUF_SIZE > | 648 | 2 * ALIGN(NET_IP_ALIGN + EFX_RX_USR_BUF_SIZE, |
648 | PAGE_SIZE / 2); | 649 | EFX_RX_BUF_ALIGNMENT) > |
650 | PAGE_SIZE); | ||
649 | efx->rx_scatter = true; | 651 | efx->rx_scatter = true; |
650 | efx->rx_dma_len = EFX_RX_USR_BUF_SIZE; | 652 | efx->rx_dma_len = EFX_RX_USR_BUF_SIZE; |
651 | efx->rx_buffer_order = 0; | 653 | efx->rx_buffer_order = 0; |
diff --git a/drivers/net/ethernet/sfc/net_driver.h b/drivers/net/ethernet/sfc/net_driver.h index 9bd433a095c5..39d6bd77f015 100644 --- a/drivers/net/ethernet/sfc/net_driver.h +++ b/drivers/net/ethernet/sfc/net_driver.h | |||
@@ -72,8 +72,20 @@ | |||
72 | /* Maximum possible MTU the driver supports */ | 72 | /* Maximum possible MTU the driver supports */ |
73 | #define EFX_MAX_MTU (9 * 1024) | 73 | #define EFX_MAX_MTU (9 * 1024) |
74 | 74 | ||
75 | /* Size of an RX scatter buffer. Small enough to pack 2 into a 4K page. */ | 75 | /* Size of an RX scatter buffer. Small enough to pack 2 into a 4K page, |
76 | #define EFX_RX_USR_BUF_SIZE 1824 | 76 | * and should be a multiple of the cache line size. |
77 | */ | ||
78 | #define EFX_RX_USR_BUF_SIZE (2048 - 256) | ||
79 | |||
80 | /* If possible, we should ensure cache line alignment at start and end | ||
81 | * of every buffer. Otherwise, we just need to ensure 4-byte | ||
82 | * alignment of the network header. | ||
83 | */ | ||
84 | #if NET_IP_ALIGN == 0 | ||
85 | #define EFX_RX_BUF_ALIGNMENT L1_CACHE_BYTES | ||
86 | #else | ||
87 | #define EFX_RX_BUF_ALIGNMENT 4 | ||
88 | #endif | ||
77 | 89 | ||
78 | /* Forward declare Precision Time Protocol (PTP) support structure. */ | 90 | /* Forward declare Precision Time Protocol (PTP) support structure. */ |
79 | struct efx_ptp_data; | 91 | struct efx_ptp_data; |
@@ -468,24 +480,11 @@ enum nic_state { | |||
468 | }; | 480 | }; |
469 | 481 | ||
470 | /* | 482 | /* |
471 | * Alignment of page-allocated RX buffers | ||
472 | * | ||
473 | * Controls the number of bytes inserted at the start of an RX buffer. | ||
474 | * This is the equivalent of NET_IP_ALIGN [which controls the alignment | ||
475 | * of the skb->head for hardware DMA]. | ||
476 | */ | ||
477 | #ifdef CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS | ||
478 | #define EFX_PAGE_IP_ALIGN 0 | ||
479 | #else | ||
480 | #define EFX_PAGE_IP_ALIGN NET_IP_ALIGN | ||
481 | #endif | ||
482 | |||
483 | /* | ||
484 | * Alignment of the skb->head which wraps a page-allocated RX buffer | 483 | * Alignment of the skb->head which wraps a page-allocated RX buffer |
485 | * | 484 | * |
486 | * The skb allocated to wrap an rx_buffer can have this alignment. Since | 485 | * The skb allocated to wrap an rx_buffer can have this alignment. Since |
487 | * the data is memcpy'd from the rx_buf, it does not need to be equal to | 486 | * the data is memcpy'd from the rx_buf, it does not need to be equal to |
488 | * EFX_PAGE_IP_ALIGN. | 487 | * NET_IP_ALIGN. |
489 | */ | 488 | */ |
490 | #define EFX_PAGE_SKB_ALIGN 2 | 489 | #define EFX_PAGE_SKB_ALIGN 2 |
491 | 490 | ||
diff --git a/drivers/net/ethernet/sfc/rx.c b/drivers/net/ethernet/sfc/rx.c index e73e30bac10e..a7dfe36cabf4 100644 --- a/drivers/net/ethernet/sfc/rx.c +++ b/drivers/net/ethernet/sfc/rx.c | |||
@@ -93,8 +93,8 @@ static inline void efx_sync_rx_buffer(struct efx_nic *efx, | |||
93 | 93 | ||
94 | void efx_rx_config_page_split(struct efx_nic *efx) | 94 | void efx_rx_config_page_split(struct efx_nic *efx) |
95 | { | 95 | { |
96 | efx->rx_page_buf_step = ALIGN(efx->rx_dma_len + EFX_PAGE_IP_ALIGN, | 96 | efx->rx_page_buf_step = ALIGN(efx->rx_dma_len + NET_IP_ALIGN, |
97 | L1_CACHE_BYTES); | 97 | EFX_RX_BUF_ALIGNMENT); |
98 | efx->rx_bufs_per_page = efx->rx_buffer_order ? 1 : | 98 | efx->rx_bufs_per_page = efx->rx_buffer_order ? 1 : |
99 | ((PAGE_SIZE - sizeof(struct efx_rx_page_state)) / | 99 | ((PAGE_SIZE - sizeof(struct efx_rx_page_state)) / |
100 | efx->rx_page_buf_step); | 100 | efx->rx_page_buf_step); |
@@ -188,9 +188,9 @@ static int efx_init_rx_buffers(struct efx_rx_queue *rx_queue) | |||
188 | do { | 188 | do { |
189 | index = rx_queue->added_count & rx_queue->ptr_mask; | 189 | index = rx_queue->added_count & rx_queue->ptr_mask; |
190 | rx_buf = efx_rx_buffer(rx_queue, index); | 190 | rx_buf = efx_rx_buffer(rx_queue, index); |
191 | rx_buf->dma_addr = dma_addr + EFX_PAGE_IP_ALIGN; | 191 | rx_buf->dma_addr = dma_addr + NET_IP_ALIGN; |
192 | rx_buf->page = page; | 192 | rx_buf->page = page; |
193 | rx_buf->page_offset = page_offset + EFX_PAGE_IP_ALIGN; | 193 | rx_buf->page_offset = page_offset + NET_IP_ALIGN; |
194 | rx_buf->len = efx->rx_dma_len; | 194 | rx_buf->len = efx->rx_dma_len; |
195 | rx_buf->flags = 0; | 195 | rx_buf->flags = 0; |
196 | ++rx_queue->added_count; | 196 | ++rx_queue->added_count; |
diff --git a/drivers/net/usb/qmi_wwan.c b/drivers/net/usb/qmi_wwan.c index cf887c2384e9..86adfa0a912e 100644 --- a/drivers/net/usb/qmi_wwan.c +++ b/drivers/net/usb/qmi_wwan.c | |||
@@ -582,6 +582,7 @@ static const struct usb_device_id products[] = { | |||
582 | {QMI_FIXED_INTF(0x1bbb, 0x011e, 4)}, /* Telekom Speedstick LTE II (Alcatel One Touch L100V LTE) */ | 582 | {QMI_FIXED_INTF(0x1bbb, 0x011e, 4)}, /* Telekom Speedstick LTE II (Alcatel One Touch L100V LTE) */ |
583 | {QMI_FIXED_INTF(0x2357, 0x0201, 4)}, /* TP-LINK HSUPA Modem MA180 */ | 583 | {QMI_FIXED_INTF(0x2357, 0x0201, 4)}, /* TP-LINK HSUPA Modem MA180 */ |
584 | {QMI_FIXED_INTF(0x1bc7, 0x1200, 5)}, /* Telit LE920 */ | 584 | {QMI_FIXED_INTF(0x1bc7, 0x1200, 5)}, /* Telit LE920 */ |
585 | {QMI_FIXED_INTF(0x1e2d, 0x12d1, 4)}, /* Cinterion PLxx */ | ||
585 | 586 | ||
586 | /* 4. Gobi 1000 devices */ | 587 | /* 4. Gobi 1000 devices */ |
587 | {QMI_GOBI1K_DEVICE(0x05c6, 0x9212)}, /* Acer Gobi Modem Device */ | 588 | {QMI_GOBI1K_DEVICE(0x05c6, 0x9212)}, /* Acer Gobi Modem Device */ |
diff --git a/drivers/net/usb/rtl8150.c b/drivers/net/usb/rtl8150.c index a491d3a95393..6cbdac67f3a0 100644 --- a/drivers/net/usb/rtl8150.c +++ b/drivers/net/usb/rtl8150.c | |||
@@ -130,19 +130,23 @@ struct rtl8150 { | |||
130 | struct usb_device *udev; | 130 | struct usb_device *udev; |
131 | struct tasklet_struct tl; | 131 | struct tasklet_struct tl; |
132 | struct net_device *netdev; | 132 | struct net_device *netdev; |
133 | struct urb *rx_urb, *tx_urb, *intr_urb, *ctrl_urb; | 133 | struct urb *rx_urb, *tx_urb, *intr_urb; |
134 | struct sk_buff *tx_skb, *rx_skb; | 134 | struct sk_buff *tx_skb, *rx_skb; |
135 | struct sk_buff *rx_skb_pool[RX_SKB_POOL_SIZE]; | 135 | struct sk_buff *rx_skb_pool[RX_SKB_POOL_SIZE]; |
136 | spinlock_t rx_pool_lock; | 136 | spinlock_t rx_pool_lock; |
137 | struct usb_ctrlrequest dr; | 137 | struct usb_ctrlrequest dr; |
138 | int intr_interval; | 138 | int intr_interval; |
139 | __le16 rx_creg; | ||
140 | u8 *intr_buff; | 139 | u8 *intr_buff; |
141 | u8 phy; | 140 | u8 phy; |
142 | }; | 141 | }; |
143 | 142 | ||
144 | typedef struct rtl8150 rtl8150_t; | 143 | typedef struct rtl8150 rtl8150_t; |
145 | 144 | ||
145 | struct async_req { | ||
146 | struct usb_ctrlrequest dr; | ||
147 | u16 rx_creg; | ||
148 | }; | ||
149 | |||
146 | static const char driver_name [] = "rtl8150"; | 150 | static const char driver_name [] = "rtl8150"; |
147 | 151 | ||
148 | /* | 152 | /* |
@@ -164,51 +168,47 @@ static int set_registers(rtl8150_t * dev, u16 indx, u16 size, void *data) | |||
164 | indx, 0, data, size, 500); | 168 | indx, 0, data, size, 500); |
165 | } | 169 | } |
166 | 170 | ||
167 | static void ctrl_callback(struct urb *urb) | 171 | static void async_set_reg_cb(struct urb *urb) |
168 | { | 172 | { |
169 | rtl8150_t *dev; | 173 | struct async_req *req = (struct async_req *)urb->context; |
170 | int status = urb->status; | 174 | int status = urb->status; |
171 | 175 | ||
172 | switch (status) { | 176 | if (status < 0) |
173 | case 0: | 177 | dev_dbg(&urb->dev->dev, "%s failed with %d", __func__, status); |
174 | break; | 178 | kfree(req); |
175 | case -EINPROGRESS: | 179 | usb_free_urb(urb); |
176 | break; | ||
177 | case -ENOENT: | ||
178 | break; | ||
179 | default: | ||
180 | if (printk_ratelimit()) | ||
181 | dev_warn(&urb->dev->dev, "ctrl urb status %d\n", status); | ||
182 | } | ||
183 | dev = urb->context; | ||
184 | clear_bit(RX_REG_SET, &dev->flags); | ||
185 | } | 180 | } |
186 | 181 | ||
187 | static int async_set_registers(rtl8150_t * dev, u16 indx, u16 size) | 182 | static int async_set_registers(rtl8150_t *dev, u16 indx, u16 size, u16 reg) |
188 | { | 183 | { |
189 | int ret; | 184 | int res = -ENOMEM; |
190 | 185 | struct urb *async_urb; | |
191 | if (test_bit(RX_REG_SET, &dev->flags)) | 186 | struct async_req *req; |
192 | return -EAGAIN; | ||
193 | 187 | ||
194 | dev->dr.bRequestType = RTL8150_REQT_WRITE; | 188 | req = kmalloc(sizeof(struct async_req), GFP_ATOMIC); |
195 | dev->dr.bRequest = RTL8150_REQ_SET_REGS; | 189 | if (req == NULL) |
196 | dev->dr.wValue = cpu_to_le16(indx); | 190 | return res; |
197 | dev->dr.wIndex = 0; | 191 | async_urb = usb_alloc_urb(0, GFP_ATOMIC); |
198 | dev->dr.wLength = cpu_to_le16(size); | 192 | if (async_urb == NULL) { |
199 | dev->ctrl_urb->transfer_buffer_length = size; | 193 | kfree(req); |
200 | usb_fill_control_urb(dev->ctrl_urb, dev->udev, | 194 | return res; |
201 | usb_sndctrlpipe(dev->udev, 0), (char *) &dev->dr, | 195 | } |
202 | &dev->rx_creg, size, ctrl_callback, dev); | 196 | req->rx_creg = cpu_to_le16(reg); |
203 | if ((ret = usb_submit_urb(dev->ctrl_urb, GFP_ATOMIC))) { | 197 | req->dr.bRequestType = RTL8150_REQT_WRITE; |
204 | if (ret == -ENODEV) | 198 | req->dr.bRequest = RTL8150_REQ_SET_REGS; |
199 | req->dr.wIndex = 0; | ||
200 | req->dr.wValue = cpu_to_le16(indx); | ||
201 | req->dr.wLength = cpu_to_le16(size); | ||
202 | usb_fill_control_urb(async_urb, dev->udev, | ||
203 | usb_sndctrlpipe(dev->udev, 0), (void *)&req->dr, | ||
204 | &req->rx_creg, size, async_set_reg_cb, req); | ||
205 | res = usb_submit_urb(async_urb, GFP_ATOMIC); | ||
206 | if (res) { | ||
207 | if (res == -ENODEV) | ||
205 | netif_device_detach(dev->netdev); | 208 | netif_device_detach(dev->netdev); |
206 | dev_err(&dev->udev->dev, | 209 | dev_err(&dev->udev->dev, "%s failed with %d\n", __func__, res); |
207 | "control request submission failed: %d\n", ret); | 210 | } |
208 | } else | 211 | return res; |
209 | set_bit(RX_REG_SET, &dev->flags); | ||
210 | |||
211 | return ret; | ||
212 | } | 212 | } |
213 | 213 | ||
214 | static int read_mii_word(rtl8150_t * dev, u8 phy, __u8 indx, u16 * reg) | 214 | static int read_mii_word(rtl8150_t * dev, u8 phy, __u8 indx, u16 * reg) |
@@ -330,13 +330,6 @@ static int alloc_all_urbs(rtl8150_t * dev) | |||
330 | usb_free_urb(dev->tx_urb); | 330 | usb_free_urb(dev->tx_urb); |
331 | return 0; | 331 | return 0; |
332 | } | 332 | } |
333 | dev->ctrl_urb = usb_alloc_urb(0, GFP_KERNEL); | ||
334 | if (!dev->ctrl_urb) { | ||
335 | usb_free_urb(dev->rx_urb); | ||
336 | usb_free_urb(dev->tx_urb); | ||
337 | usb_free_urb(dev->intr_urb); | ||
338 | return 0; | ||
339 | } | ||
340 | 333 | ||
341 | return 1; | 334 | return 1; |
342 | } | 335 | } |
@@ -346,7 +339,6 @@ static void free_all_urbs(rtl8150_t * dev) | |||
346 | usb_free_urb(dev->rx_urb); | 339 | usb_free_urb(dev->rx_urb); |
347 | usb_free_urb(dev->tx_urb); | 340 | usb_free_urb(dev->tx_urb); |
348 | usb_free_urb(dev->intr_urb); | 341 | usb_free_urb(dev->intr_urb); |
349 | usb_free_urb(dev->ctrl_urb); | ||
350 | } | 342 | } |
351 | 343 | ||
352 | static void unlink_all_urbs(rtl8150_t * dev) | 344 | static void unlink_all_urbs(rtl8150_t * dev) |
@@ -354,7 +346,6 @@ static void unlink_all_urbs(rtl8150_t * dev) | |||
354 | usb_kill_urb(dev->rx_urb); | 346 | usb_kill_urb(dev->rx_urb); |
355 | usb_kill_urb(dev->tx_urb); | 347 | usb_kill_urb(dev->tx_urb); |
356 | usb_kill_urb(dev->intr_urb); | 348 | usb_kill_urb(dev->intr_urb); |
357 | usb_kill_urb(dev->ctrl_urb); | ||
358 | } | 349 | } |
359 | 350 | ||
360 | static inline struct sk_buff *pull_skb(rtl8150_t *dev) | 351 | static inline struct sk_buff *pull_skb(rtl8150_t *dev) |
@@ -629,7 +620,6 @@ static int enable_net_traffic(rtl8150_t * dev) | |||
629 | } | 620 | } |
630 | /* RCR bit7=1 attach Rx info at the end; =0 HW CRC (which is broken) */ | 621 | /* RCR bit7=1 attach Rx info at the end; =0 HW CRC (which is broken) */ |
631 | rcr = 0x9e; | 622 | rcr = 0x9e; |
632 | dev->rx_creg = cpu_to_le16(rcr); | ||
633 | tcr = 0xd8; | 623 | tcr = 0xd8; |
634 | cr = 0x0c; | 624 | cr = 0x0c; |
635 | if (!(rcr & 0x80)) | 625 | if (!(rcr & 0x80)) |
@@ -662,20 +652,22 @@ static void rtl8150_tx_timeout(struct net_device *netdev) | |||
662 | static void rtl8150_set_multicast(struct net_device *netdev) | 652 | static void rtl8150_set_multicast(struct net_device *netdev) |
663 | { | 653 | { |
664 | rtl8150_t *dev = netdev_priv(netdev); | 654 | rtl8150_t *dev = netdev_priv(netdev); |
655 | u16 rx_creg = 0x9e; | ||
656 | |||
665 | netif_stop_queue(netdev); | 657 | netif_stop_queue(netdev); |
666 | if (netdev->flags & IFF_PROMISC) { | 658 | if (netdev->flags & IFF_PROMISC) { |
667 | dev->rx_creg |= cpu_to_le16(0x0001); | 659 | rx_creg |= 0x0001; |
668 | dev_info(&netdev->dev, "%s: promiscuous mode\n", netdev->name); | 660 | dev_info(&netdev->dev, "%s: promiscuous mode\n", netdev->name); |
669 | } else if (!netdev_mc_empty(netdev) || | 661 | } else if (!netdev_mc_empty(netdev) || |
670 | (netdev->flags & IFF_ALLMULTI)) { | 662 | (netdev->flags & IFF_ALLMULTI)) { |
671 | dev->rx_creg &= cpu_to_le16(0xfffe); | 663 | rx_creg &= 0xfffe; |
672 | dev->rx_creg |= cpu_to_le16(0x0002); | 664 | rx_creg |= 0x0002; |
673 | dev_info(&netdev->dev, "%s: allmulti set\n", netdev->name); | 665 | dev_info(&netdev->dev, "%s: allmulti set\n", netdev->name); |
674 | } else { | 666 | } else { |
675 | /* ~RX_MULTICAST, ~RX_PROMISCUOUS */ | 667 | /* ~RX_MULTICAST, ~RX_PROMISCUOUS */ |
676 | dev->rx_creg &= cpu_to_le16(0x00fc); | 668 | rx_creg &= 0x00fc; |
677 | } | 669 | } |
678 | async_set_registers(dev, RCR, 2); | 670 | async_set_registers(dev, RCR, sizeof(rx_creg), rx_creg); |
679 | netif_wake_queue(netdev); | 671 | netif_wake_queue(netdev); |
680 | } | 672 | } |
681 | 673 | ||
diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c index 655bb25eed2b..c9e00387d999 100644 --- a/drivers/net/virtio_net.c +++ b/drivers/net/virtio_net.c | |||
@@ -636,10 +636,11 @@ static int virtnet_open(struct net_device *dev) | |||
636 | struct virtnet_info *vi = netdev_priv(dev); | 636 | struct virtnet_info *vi = netdev_priv(dev); |
637 | int i; | 637 | int i; |
638 | 638 | ||
639 | for (i = 0; i < vi->curr_queue_pairs; i++) { | 639 | for (i = 0; i < vi->max_queue_pairs; i++) { |
640 | /* Make sure we have some buffers: if oom use wq. */ | 640 | if (i < vi->curr_queue_pairs) |
641 | if (!try_fill_recv(&vi->rq[i], GFP_KERNEL)) | 641 | /* Make sure we have some buffers: if oom use wq. */ |
642 | schedule_delayed_work(&vi->refill, 0); | 642 | if (!try_fill_recv(&vi->rq[i], GFP_KERNEL)) |
643 | schedule_delayed_work(&vi->refill, 0); | ||
643 | virtnet_napi_enable(&vi->rq[i]); | 644 | virtnet_napi_enable(&vi->rq[i]); |
644 | } | 645 | } |
645 | 646 | ||
diff --git a/drivers/net/vxlan.c b/drivers/net/vxlan.c index ba81f3c39a83..3b1d2ee7156b 100644 --- a/drivers/net/vxlan.c +++ b/drivers/net/vxlan.c | |||
@@ -301,7 +301,7 @@ static inline struct hlist_head *vxlan_fdb_head(struct vxlan_dev *vxlan, | |||
301 | } | 301 | } |
302 | 302 | ||
303 | /* Look up Ethernet address in forwarding table */ | 303 | /* Look up Ethernet address in forwarding table */ |
304 | static struct vxlan_fdb *vxlan_find_mac(struct vxlan_dev *vxlan, | 304 | static struct vxlan_fdb *__vxlan_find_mac(struct vxlan_dev *vxlan, |
305 | const u8 *mac) | 305 | const u8 *mac) |
306 | 306 | ||
307 | { | 307 | { |
@@ -316,6 +316,18 @@ static struct vxlan_fdb *vxlan_find_mac(struct vxlan_dev *vxlan, | |||
316 | return NULL; | 316 | return NULL; |
317 | } | 317 | } |
318 | 318 | ||
319 | static struct vxlan_fdb *vxlan_find_mac(struct vxlan_dev *vxlan, | ||
320 | const u8 *mac) | ||
321 | { | ||
322 | struct vxlan_fdb *f; | ||
323 | |||
324 | f = __vxlan_find_mac(vxlan, mac); | ||
325 | if (f) | ||
326 | f->used = jiffies; | ||
327 | |||
328 | return f; | ||
329 | } | ||
330 | |||
319 | /* Add/update destinations for multicast */ | 331 | /* Add/update destinations for multicast */ |
320 | static int vxlan_fdb_append(struct vxlan_fdb *f, | 332 | static int vxlan_fdb_append(struct vxlan_fdb *f, |
321 | __be32 ip, __be16 port, __u32 vni, __u32 ifindex) | 333 | __be32 ip, __be16 port, __u32 vni, __u32 ifindex) |
@@ -353,7 +365,7 @@ static int vxlan_fdb_create(struct vxlan_dev *vxlan, | |||
353 | struct vxlan_fdb *f; | 365 | struct vxlan_fdb *f; |
354 | int notify = 0; | 366 | int notify = 0; |
355 | 367 | ||
356 | f = vxlan_find_mac(vxlan, mac); | 368 | f = __vxlan_find_mac(vxlan, mac); |
357 | if (f) { | 369 | if (f) { |
358 | if (flags & NLM_F_EXCL) { | 370 | if (flags & NLM_F_EXCL) { |
359 | netdev_dbg(vxlan->dev, | 371 | netdev_dbg(vxlan->dev, |
@@ -563,7 +575,6 @@ static void vxlan_snoop(struct net_device *dev, | |||
563 | 575 | ||
564 | f = vxlan_find_mac(vxlan, src_mac); | 576 | f = vxlan_find_mac(vxlan, src_mac); |
565 | if (likely(f)) { | 577 | if (likely(f)) { |
566 | f->used = jiffies; | ||
567 | if (likely(f->remote.remote_ip == src_ip)) | 578 | if (likely(f->remote.remote_ip == src_ip)) |
568 | return; | 579 | return; |
569 | 580 | ||
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_calib.c b/drivers/net/wireless/ath/ath9k/ar9003_calib.c index 639ba7d18ea4..6988e1d081f2 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_calib.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_calib.c | |||
@@ -965,7 +965,7 @@ static void ar9003_hw_do_manual_peak_cal(struct ath_hw *ah, | |||
965 | { | 965 | { |
966 | int i; | 966 | int i; |
967 | 967 | ||
968 | if (!AR_SREV_9462(ah) && !AR_SREV_9565(ah)) | 968 | if (!AR_SREV_9462(ah) && !AR_SREV_9565(ah) && !AR_SREV_9485(ah)) |
969 | return; | 969 | return; |
970 | 970 | ||
971 | for (i = 0; i < AR9300_MAX_CHAINS; i++) { | 971 | for (i = 0; i < AR9300_MAX_CHAINS; i++) { |
diff --git a/drivers/net/wireless/ath/ath9k/ar9485_initvals.h b/drivers/net/wireless/ath/ath9k/ar9485_initvals.h index 712f415b8c08..88ff1d7b53ab 100644 --- a/drivers/net/wireless/ath/ath9k/ar9485_initvals.h +++ b/drivers/net/wireless/ath/ath9k/ar9485_initvals.h | |||
@@ -1020,7 +1020,7 @@ static const u32 ar9485_1_1_baseband_postamble[][5] = { | |||
1020 | {0x0000a284, 0x00000000, 0x00000000, 0x000002a0, 0x000002a0}, | 1020 | {0x0000a284, 0x00000000, 0x00000000, 0x000002a0, 0x000002a0}, |
1021 | {0x0000a288, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | 1021 | {0x0000a288, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, |
1022 | {0x0000a28c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | 1022 | {0x0000a28c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, |
1023 | {0x0000a2c4, 0x00158d18, 0x00158d18, 0x00158d18, 0x00158d18}, | 1023 | {0x0000a2c4, 0x00158d18, 0x00158d18, 0x00058d18, 0x00058d18}, |
1024 | {0x0000a2d0, 0x00071981, 0x00071981, 0x00071982, 0x00071982}, | 1024 | {0x0000a2d0, 0x00071981, 0x00071981, 0x00071982, 0x00071982}, |
1025 | {0x0000a2d8, 0xf999a83a, 0xf999a83a, 0xf999a83a, 0xf999a83a}, | 1025 | {0x0000a2d8, 0xf999a83a, 0xf999a83a, 0xf999a83a, 0xf999a83a}, |
1026 | {0x0000a358, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | 1026 | {0x0000a358, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, |
diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h index 8a1888d02070..366002f266f8 100644 --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h | |||
@@ -254,6 +254,7 @@ struct ath_atx_tid { | |||
254 | int sched; | 254 | int sched; |
255 | int paused; | 255 | int paused; |
256 | u8 state; | 256 | u8 state; |
257 | bool stop_cb; | ||
257 | }; | 258 | }; |
258 | 259 | ||
259 | struct ath_node { | 260 | struct ath_node { |
@@ -351,7 +352,8 @@ void ath_tx_tasklet(struct ath_softc *sc); | |||
351 | void ath_tx_edma_tasklet(struct ath_softc *sc); | 352 | void ath_tx_edma_tasklet(struct ath_softc *sc); |
352 | int ath_tx_aggr_start(struct ath_softc *sc, struct ieee80211_sta *sta, | 353 | int ath_tx_aggr_start(struct ath_softc *sc, struct ieee80211_sta *sta, |
353 | u16 tid, u16 *ssn); | 354 | u16 tid, u16 *ssn); |
354 | void ath_tx_aggr_stop(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid); | 355 | bool ath_tx_aggr_stop(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid, |
356 | bool flush); | ||
355 | void ath_tx_aggr_resume(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid); | 357 | void ath_tx_aggr_resume(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid); |
356 | 358 | ||
357 | void ath_tx_aggr_wakeup(struct ath_softc *sc, struct ath_node *an); | 359 | void ath_tx_aggr_wakeup(struct ath_softc *sc, struct ath_node *an); |
diff --git a/drivers/net/wireless/ath/ath9k/debug.c b/drivers/net/wireless/ath/ath9k/debug.c index e6307b86363a..b37eb8d38811 100644 --- a/drivers/net/wireless/ath/ath9k/debug.c +++ b/drivers/net/wireless/ath/ath9k/debug.c | |||
@@ -2008,6 +2008,14 @@ void ath9k_get_et_stats(struct ieee80211_hw *hw, | |||
2008 | WARN_ON(i != ATH9K_SSTATS_LEN); | 2008 | WARN_ON(i != ATH9K_SSTATS_LEN); |
2009 | } | 2009 | } |
2010 | 2010 | ||
2011 | void ath9k_deinit_debug(struct ath_softc *sc) | ||
2012 | { | ||
2013 | if (config_enabled(CONFIG_ATH9K_DEBUGFS) && sc->rfs_chan_spec_scan) { | ||
2014 | relay_close(sc->rfs_chan_spec_scan); | ||
2015 | sc->rfs_chan_spec_scan = NULL; | ||
2016 | } | ||
2017 | } | ||
2018 | |||
2011 | int ath9k_init_debug(struct ath_hw *ah) | 2019 | int ath9k_init_debug(struct ath_hw *ah) |
2012 | { | 2020 | { |
2013 | struct ath_common *common = ath9k_hw_common(ah); | 2021 | struct ath_common *common = ath9k_hw_common(ah); |
diff --git a/drivers/net/wireless/ath/ath9k/debug.h b/drivers/net/wireless/ath/ath9k/debug.h index 794a7ec83a24..9d49aab8b989 100644 --- a/drivers/net/wireless/ath/ath9k/debug.h +++ b/drivers/net/wireless/ath/ath9k/debug.h | |||
@@ -304,6 +304,7 @@ struct ath9k_debug { | |||
304 | }; | 304 | }; |
305 | 305 | ||
306 | int ath9k_init_debug(struct ath_hw *ah); | 306 | int ath9k_init_debug(struct ath_hw *ah); |
307 | void ath9k_deinit_debug(struct ath_softc *sc); | ||
307 | 308 | ||
308 | void ath_debug_stat_interrupt(struct ath_softc *sc, enum ath9k_int status); | 309 | void ath_debug_stat_interrupt(struct ath_softc *sc, enum ath9k_int status); |
309 | void ath_debug_stat_tx(struct ath_softc *sc, struct ath_buf *bf, | 310 | void ath_debug_stat_tx(struct ath_softc *sc, struct ath_buf *bf, |
@@ -339,6 +340,10 @@ static inline int ath9k_init_debug(struct ath_hw *ah) | |||
339 | return 0; | 340 | return 0; |
340 | } | 341 | } |
341 | 342 | ||
343 | static inline void ath9k_deinit_debug(struct ath_softc *sc) | ||
344 | { | ||
345 | } | ||
346 | |||
342 | static inline void ath_debug_stat_interrupt(struct ath_softc *sc, | 347 | static inline void ath_debug_stat_interrupt(struct ath_softc *sc, |
343 | enum ath9k_int status) | 348 | enum ath9k_int status) |
344 | { | 349 | { |
diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c index 0237b2868961..aba415103f94 100644 --- a/drivers/net/wireless/ath/ath9k/init.c +++ b/drivers/net/wireless/ath/ath9k/init.c | |||
@@ -906,7 +906,7 @@ int ath9k_init_device(u16 devid, struct ath_softc *sc, | |||
906 | if (!ath_is_world_regd(reg)) { | 906 | if (!ath_is_world_regd(reg)) { |
907 | error = regulatory_hint(hw->wiphy, reg->alpha2); | 907 | error = regulatory_hint(hw->wiphy, reg->alpha2); |
908 | if (error) | 908 | if (error) |
909 | goto unregister; | 909 | goto debug_cleanup; |
910 | } | 910 | } |
911 | 911 | ||
912 | ath_init_leds(sc); | 912 | ath_init_leds(sc); |
@@ -914,6 +914,8 @@ int ath9k_init_device(u16 devid, struct ath_softc *sc, | |||
914 | 914 | ||
915 | return 0; | 915 | return 0; |
916 | 916 | ||
917 | debug_cleanup: | ||
918 | ath9k_deinit_debug(sc); | ||
917 | unregister: | 919 | unregister: |
918 | ieee80211_unregister_hw(hw); | 920 | ieee80211_unregister_hw(hw); |
919 | rx_cleanup: | 921 | rx_cleanup: |
@@ -942,11 +944,6 @@ static void ath9k_deinit_softc(struct ath_softc *sc) | |||
942 | sc->dfs_detector->exit(sc->dfs_detector); | 944 | sc->dfs_detector->exit(sc->dfs_detector); |
943 | 945 | ||
944 | ath9k_eeprom_release(sc); | 946 | ath9k_eeprom_release(sc); |
945 | |||
946 | if (config_enabled(CONFIG_ATH9K_DEBUGFS) && sc->rfs_chan_spec_scan) { | ||
947 | relay_close(sc->rfs_chan_spec_scan); | ||
948 | sc->rfs_chan_spec_scan = NULL; | ||
949 | } | ||
950 | } | 947 | } |
951 | 948 | ||
952 | void ath9k_deinit_device(struct ath_softc *sc) | 949 | void ath9k_deinit_device(struct ath_softc *sc) |
@@ -960,6 +957,7 @@ void ath9k_deinit_device(struct ath_softc *sc) | |||
960 | 957 | ||
961 | ath9k_ps_restore(sc); | 958 | ath9k_ps_restore(sc); |
962 | 959 | ||
960 | ath9k_deinit_debug(sc); | ||
963 | ieee80211_unregister_hw(hw); | 961 | ieee80211_unregister_hw(hw); |
964 | ath_rx_cleanup(sc); | 962 | ath_rx_cleanup(sc); |
965 | ath9k_deinit_softc(sc); | 963 | ath9k_deinit_softc(sc); |
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index a18414b5948b..2382d1262e7f 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c | |||
@@ -1687,6 +1687,7 @@ static int ath9k_ampdu_action(struct ieee80211_hw *hw, | |||
1687 | u16 tid, u16 *ssn, u8 buf_size) | 1687 | u16 tid, u16 *ssn, u8 buf_size) |
1688 | { | 1688 | { |
1689 | struct ath_softc *sc = hw->priv; | 1689 | struct ath_softc *sc = hw->priv; |
1690 | bool flush = false; | ||
1690 | int ret = 0; | 1691 | int ret = 0; |
1691 | 1692 | ||
1692 | local_bh_disable(); | 1693 | local_bh_disable(); |
@@ -1703,12 +1704,13 @@ static int ath9k_ampdu_action(struct ieee80211_hw *hw, | |||
1703 | ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid); | 1704 | ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid); |
1704 | ath9k_ps_restore(sc); | 1705 | ath9k_ps_restore(sc); |
1705 | break; | 1706 | break; |
1706 | case IEEE80211_AMPDU_TX_STOP_CONT: | ||
1707 | case IEEE80211_AMPDU_TX_STOP_FLUSH: | 1707 | case IEEE80211_AMPDU_TX_STOP_FLUSH: |
1708 | case IEEE80211_AMPDU_TX_STOP_FLUSH_CONT: | 1708 | case IEEE80211_AMPDU_TX_STOP_FLUSH_CONT: |
1709 | flush = true; | ||
1710 | case IEEE80211_AMPDU_TX_STOP_CONT: | ||
1709 | ath9k_ps_wakeup(sc); | 1711 | ath9k_ps_wakeup(sc); |
1710 | ath_tx_aggr_stop(sc, sta, tid); | 1712 | if (ath_tx_aggr_stop(sc, sta, tid, flush)) |
1711 | ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid); | 1713 | ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid); |
1712 | ath9k_ps_restore(sc); | 1714 | ath9k_ps_restore(sc); |
1713 | break; | 1715 | break; |
1714 | case IEEE80211_AMPDU_TX_OPERATIONAL: | 1716 | case IEEE80211_AMPDU_TX_OPERATIONAL: |
diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c index eab0fcb7ded6..14bb3354ea64 100644 --- a/drivers/net/wireless/ath/ath9k/xmit.c +++ b/drivers/net/wireless/ath/ath9k/xmit.c | |||
@@ -164,7 +164,20 @@ static void ath_set_rates(struct ieee80211_vif *vif, struct ieee80211_sta *sta, | |||
164 | ARRAY_SIZE(bf->rates)); | 164 | ARRAY_SIZE(bf->rates)); |
165 | } | 165 | } |
166 | 166 | ||
167 | static void ath_tx_flush_tid(struct ath_softc *sc, struct ath_atx_tid *tid) | 167 | static void ath_tx_clear_tid(struct ath_softc *sc, struct ath_atx_tid *tid) |
168 | { | ||
169 | tid->state &= ~AGGR_ADDBA_COMPLETE; | ||
170 | tid->state &= ~AGGR_CLEANUP; | ||
171 | if (!tid->stop_cb) | ||
172 | return; | ||
173 | |||
174 | ieee80211_start_tx_ba_cb_irqsafe(tid->an->vif, tid->an->sta->addr, | ||
175 | tid->tidno); | ||
176 | tid->stop_cb = false; | ||
177 | } | ||
178 | |||
179 | static void ath_tx_flush_tid(struct ath_softc *sc, struct ath_atx_tid *tid, | ||
180 | bool flush_packets) | ||
168 | { | 181 | { |
169 | struct ath_txq *txq = tid->ac->txq; | 182 | struct ath_txq *txq = tid->ac->txq; |
170 | struct sk_buff *skb; | 183 | struct sk_buff *skb; |
@@ -181,16 +194,15 @@ static void ath_tx_flush_tid(struct ath_softc *sc, struct ath_atx_tid *tid) | |||
181 | while ((skb = __skb_dequeue(&tid->buf_q))) { | 194 | while ((skb = __skb_dequeue(&tid->buf_q))) { |
182 | fi = get_frame_info(skb); | 195 | fi = get_frame_info(skb); |
183 | bf = fi->bf; | 196 | bf = fi->bf; |
197 | if (!bf && !flush_packets) | ||
198 | bf = ath_tx_setup_buffer(sc, txq, tid, skb); | ||
184 | 199 | ||
185 | if (!bf) { | 200 | if (!bf) { |
186 | bf = ath_tx_setup_buffer(sc, txq, tid, skb); | 201 | ieee80211_free_txskb(sc->hw, skb); |
187 | if (!bf) { | 202 | continue; |
188 | ieee80211_free_txskb(sc->hw, skb); | ||
189 | continue; | ||
190 | } | ||
191 | } | 203 | } |
192 | 204 | ||
193 | if (fi->retries) { | 205 | if (fi->retries || flush_packets) { |
194 | list_add_tail(&bf->list, &bf_head); | 206 | list_add_tail(&bf->list, &bf_head); |
195 | ath_tx_update_baw(sc, tid, bf->bf_state.seqno); | 207 | ath_tx_update_baw(sc, tid, bf->bf_state.seqno); |
196 | ath_tx_complete_buf(sc, bf, txq, &bf_head, &ts, 0); | 208 | ath_tx_complete_buf(sc, bf, txq, &bf_head, &ts, 0); |
@@ -201,12 +213,10 @@ static void ath_tx_flush_tid(struct ath_softc *sc, struct ath_atx_tid *tid) | |||
201 | } | 213 | } |
202 | } | 214 | } |
203 | 215 | ||
204 | if (tid->baw_head == tid->baw_tail) { | 216 | if (tid->baw_head == tid->baw_tail) |
205 | tid->state &= ~AGGR_ADDBA_COMPLETE; | 217 | ath_tx_clear_tid(sc, tid); |
206 | tid->state &= ~AGGR_CLEANUP; | ||
207 | } | ||
208 | 218 | ||
209 | if (sendbar) { | 219 | if (sendbar && !flush_packets) { |
210 | ath_txq_unlock(sc, txq); | 220 | ath_txq_unlock(sc, txq); |
211 | ath_send_bar(tid, tid->seq_start); | 221 | ath_send_bar(tid, tid->seq_start); |
212 | ath_txq_lock(sc, txq); | 222 | ath_txq_lock(sc, txq); |
@@ -277,9 +287,7 @@ static void ath_tid_drain(struct ath_softc *sc, struct ath_txq *txq, | |||
277 | 287 | ||
278 | list_add_tail(&bf->list, &bf_head); | 288 | list_add_tail(&bf->list, &bf_head); |
279 | 289 | ||
280 | if (fi->retries) | 290 | ath_tx_update_baw(sc, tid, bf->bf_state.seqno); |
281 | ath_tx_update_baw(sc, tid, bf->bf_state.seqno); | ||
282 | |||
283 | ath_tx_complete_buf(sc, bf, txq, &bf_head, &ts, 0); | 291 | ath_tx_complete_buf(sc, bf, txq, &bf_head, &ts, 0); |
284 | } | 292 | } |
285 | 293 | ||
@@ -602,7 +610,7 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq, | |||
602 | } | 610 | } |
603 | 611 | ||
604 | if (tid->state & AGGR_CLEANUP) | 612 | if (tid->state & AGGR_CLEANUP) |
605 | ath_tx_flush_tid(sc, tid); | 613 | ath_tx_flush_tid(sc, tid, false); |
606 | 614 | ||
607 | rcu_read_unlock(); | 615 | rcu_read_unlock(); |
608 | 616 | ||
@@ -620,6 +628,7 @@ static void ath_tx_process_buffer(struct ath_softc *sc, struct ath_txq *txq, | |||
620 | struct ath_tx_status *ts, struct ath_buf *bf, | 628 | struct ath_tx_status *ts, struct ath_buf *bf, |
621 | struct list_head *bf_head) | 629 | struct list_head *bf_head) |
622 | { | 630 | { |
631 | struct ieee80211_tx_info *info; | ||
623 | bool txok, flush; | 632 | bool txok, flush; |
624 | 633 | ||
625 | txok = !(ts->ts_status & ATH9K_TXERR_MASK); | 634 | txok = !(ts->ts_status & ATH9K_TXERR_MASK); |
@@ -631,8 +640,12 @@ static void ath_tx_process_buffer(struct ath_softc *sc, struct ath_txq *txq, | |||
631 | txq->axq_ampdu_depth--; | 640 | txq->axq_ampdu_depth--; |
632 | 641 | ||
633 | if (!bf_isampdu(bf)) { | 642 | if (!bf_isampdu(bf)) { |
634 | if (!flush) | 643 | if (!flush) { |
644 | info = IEEE80211_SKB_CB(bf->bf_mpdu); | ||
645 | memcpy(info->control.rates, bf->rates, | ||
646 | sizeof(info->control.rates)); | ||
635 | ath_tx_rc_status(sc, bf, ts, 1, txok ? 0 : 1, txok); | 647 | ath_tx_rc_status(sc, bf, ts, 1, txok ? 0 : 1, txok); |
648 | } | ||
636 | ath_tx_complete_buf(sc, bf, txq, bf_head, ts, txok); | 649 | ath_tx_complete_buf(sc, bf, txq, bf_head, ts, txok); |
637 | } else | 650 | } else |
638 | ath_tx_complete_aggr(sc, txq, bf, bf_head, ts, txok); | 651 | ath_tx_complete_aggr(sc, txq, bf, bf_head, ts, txok); |
@@ -676,7 +689,7 @@ static u32 ath_lookup_rate(struct ath_softc *sc, struct ath_buf *bf, | |||
676 | 689 | ||
677 | skb = bf->bf_mpdu; | 690 | skb = bf->bf_mpdu; |
678 | tx_info = IEEE80211_SKB_CB(skb); | 691 | tx_info = IEEE80211_SKB_CB(skb); |
679 | rates = tx_info->control.rates; | 692 | rates = bf->rates; |
680 | 693 | ||
681 | /* | 694 | /* |
682 | * Find the lowest frame length among the rate series that will have a | 695 | * Find the lowest frame length among the rate series that will have a |
@@ -1256,18 +1269,23 @@ int ath_tx_aggr_start(struct ath_softc *sc, struct ieee80211_sta *sta, | |||
1256 | return 0; | 1269 | return 0; |
1257 | } | 1270 | } |
1258 | 1271 | ||
1259 | void ath_tx_aggr_stop(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid) | 1272 | bool ath_tx_aggr_stop(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid, |
1273 | bool flush) | ||
1260 | { | 1274 | { |
1261 | struct ath_node *an = (struct ath_node *)sta->drv_priv; | 1275 | struct ath_node *an = (struct ath_node *)sta->drv_priv; |
1262 | struct ath_atx_tid *txtid = ATH_AN_2_TID(an, tid); | 1276 | struct ath_atx_tid *txtid = ATH_AN_2_TID(an, tid); |
1263 | struct ath_txq *txq = txtid->ac->txq; | 1277 | struct ath_txq *txq = txtid->ac->txq; |
1278 | bool ret = !flush; | ||
1279 | |||
1280 | if (flush) | ||
1281 | txtid->stop_cb = false; | ||
1264 | 1282 | ||
1265 | if (txtid->state & AGGR_CLEANUP) | 1283 | if (txtid->state & AGGR_CLEANUP) |
1266 | return; | 1284 | return false; |
1267 | 1285 | ||
1268 | if (!(txtid->state & AGGR_ADDBA_COMPLETE)) { | 1286 | if (!(txtid->state & AGGR_ADDBA_COMPLETE)) { |
1269 | txtid->state &= ~AGGR_ADDBA_PROGRESS; | 1287 | txtid->state &= ~AGGR_ADDBA_PROGRESS; |
1270 | return; | 1288 | return ret; |
1271 | } | 1289 | } |
1272 | 1290 | ||
1273 | ath_txq_lock(sc, txq); | 1291 | ath_txq_lock(sc, txq); |
@@ -1279,13 +1297,17 @@ void ath_tx_aggr_stop(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid) | |||
1279 | * TID can only be reused after all in-progress subframes have been | 1297 | * TID can only be reused after all in-progress subframes have been |
1280 | * completed. | 1298 | * completed. |
1281 | */ | 1299 | */ |
1282 | if (txtid->baw_head != txtid->baw_tail) | 1300 | if (txtid->baw_head != txtid->baw_tail) { |
1283 | txtid->state |= AGGR_CLEANUP; | 1301 | txtid->state |= AGGR_CLEANUP; |
1284 | else | 1302 | ret = false; |
1303 | txtid->stop_cb = !flush; | ||
1304 | } else { | ||
1285 | txtid->state &= ~AGGR_ADDBA_COMPLETE; | 1305 | txtid->state &= ~AGGR_ADDBA_COMPLETE; |
1306 | } | ||
1286 | 1307 | ||
1287 | ath_tx_flush_tid(sc, txtid); | 1308 | ath_tx_flush_tid(sc, txtid, flush); |
1288 | ath_txq_unlock_complete(sc, txq); | 1309 | ath_txq_unlock_complete(sc, txq); |
1310 | return ret; | ||
1289 | } | 1311 | } |
1290 | 1312 | ||
1291 | void ath_tx_aggr_sleep(struct ieee80211_sta *sta, struct ath_softc *sc, | 1313 | void ath_tx_aggr_sleep(struct ieee80211_sta *sta, struct ath_softc *sc, |
@@ -2415,6 +2437,7 @@ void ath_tx_node_init(struct ath_softc *sc, struct ath_node *an) | |||
2415 | tid->ac = &an->ac[acno]; | 2437 | tid->ac = &an->ac[acno]; |
2416 | tid->state &= ~AGGR_ADDBA_COMPLETE; | 2438 | tid->state &= ~AGGR_ADDBA_COMPLETE; |
2417 | tid->state &= ~AGGR_ADDBA_PROGRESS; | 2439 | tid->state &= ~AGGR_ADDBA_PROGRESS; |
2440 | tid->stop_cb = false; | ||
2418 | } | 2441 | } |
2419 | 2442 | ||
2420 | for (acno = 0, ac = &an->ac[acno]; | 2443 | for (acno = 0, ac = &an->ac[acno]; |
@@ -2451,8 +2474,7 @@ void ath_tx_node_cleanup(struct ath_softc *sc, struct ath_node *an) | |||
2451 | } | 2474 | } |
2452 | 2475 | ||
2453 | ath_tid_drain(sc, txq, tid); | 2476 | ath_tid_drain(sc, txq, tid); |
2454 | tid->state &= ~AGGR_ADDBA_COMPLETE; | 2477 | ath_tx_clear_tid(sc, tid); |
2455 | tid->state &= ~AGGR_CLEANUP; | ||
2456 | 2478 | ||
2457 | ath_txq_unlock(sc, txq); | 2479 | ath_txq_unlock(sc, txq); |
2458 | } | 2480 | } |
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c index 6d758f285352..761f501959a9 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c | |||
@@ -4140,6 +4140,10 @@ static const struct ieee80211_iface_limit brcmf_iface_limits[] = { | |||
4140 | .types = BIT(NL80211_IFTYPE_P2P_CLIENT) | | 4140 | .types = BIT(NL80211_IFTYPE_P2P_CLIENT) | |
4141 | BIT(NL80211_IFTYPE_P2P_GO) | 4141 | BIT(NL80211_IFTYPE_P2P_GO) |
4142 | }, | 4142 | }, |
4143 | { | ||
4144 | .max = 1, | ||
4145 | .types = BIT(NL80211_IFTYPE_P2P_DEVICE) | ||
4146 | } | ||
4143 | }; | 4147 | }; |
4144 | static const struct ieee80211_iface_combination brcmf_iface_combos[] = { | 4148 | static const struct ieee80211_iface_combination brcmf_iface_combos[] = { |
4145 | { | 4149 | { |
@@ -4197,7 +4201,8 @@ static struct wiphy *brcmf_setup_wiphy(struct device *phydev) | |||
4197 | BIT(NL80211_IFTYPE_ADHOC) | | 4201 | BIT(NL80211_IFTYPE_ADHOC) | |
4198 | BIT(NL80211_IFTYPE_AP) | | 4202 | BIT(NL80211_IFTYPE_AP) | |
4199 | BIT(NL80211_IFTYPE_P2P_CLIENT) | | 4203 | BIT(NL80211_IFTYPE_P2P_CLIENT) | |
4200 | BIT(NL80211_IFTYPE_P2P_GO); | 4204 | BIT(NL80211_IFTYPE_P2P_GO) | |
4205 | BIT(NL80211_IFTYPE_P2P_DEVICE); | ||
4201 | wiphy->iface_combinations = brcmf_iface_combos; | 4206 | wiphy->iface_combinations = brcmf_iface_combos; |
4202 | wiphy->n_iface_combinations = ARRAY_SIZE(brcmf_iface_combos); | 4207 | wiphy->n_iface_combinations = ARRAY_SIZE(brcmf_iface_combos); |
4203 | wiphy->bands[IEEE80211_BAND_2GHZ] = &__wl_band_2ghz; | 4208 | wiphy->bands[IEEE80211_BAND_2GHZ] = &__wl_band_2ghz; |
diff --git a/drivers/net/wireless/iwlegacy/common.c b/drivers/net/wireless/iwlegacy/common.c index 592d0aa634a8..e9a3cbc409ae 100644 --- a/drivers/net/wireless/iwlegacy/common.c +++ b/drivers/net/wireless/iwlegacy/common.c | |||
@@ -1423,7 +1423,7 @@ il_setup_rx_scan_handlers(struct il_priv *il) | |||
1423 | } | 1423 | } |
1424 | EXPORT_SYMBOL(il_setup_rx_scan_handlers); | 1424 | EXPORT_SYMBOL(il_setup_rx_scan_handlers); |
1425 | 1425 | ||
1426 | inline u16 | 1426 | u16 |
1427 | il_get_active_dwell_time(struct il_priv *il, enum ieee80211_band band, | 1427 | il_get_active_dwell_time(struct il_priv *il, enum ieee80211_band band, |
1428 | u8 n_probes) | 1428 | u8 n_probes) |
1429 | { | 1429 | { |
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api.h b/drivers/net/wireless/iwlwifi/mvm/fw-api.h index 191dcae8ba47..c6384555aab4 100644 --- a/drivers/net/wireless/iwlwifi/mvm/fw-api.h +++ b/drivers/net/wireless/iwlwifi/mvm/fw-api.h | |||
@@ -173,6 +173,8 @@ enum { | |||
173 | REPLY_DEBUG_CMD = 0xf0, | 173 | REPLY_DEBUG_CMD = 0xf0, |
174 | DEBUG_LOG_MSG = 0xf7, | 174 | DEBUG_LOG_MSG = 0xf7, |
175 | 175 | ||
176 | MCAST_FILTER_CMD = 0xd0, | ||
177 | |||
176 | /* D3 commands/notifications */ | 178 | /* D3 commands/notifications */ |
177 | D3_CONFIG_CMD = 0xd3, | 179 | D3_CONFIG_CMD = 0xd3, |
178 | PROT_OFFLOAD_CONFIG_CMD = 0xd4, | 180 | PROT_OFFLOAD_CONFIG_CMD = 0xd4, |
@@ -948,4 +950,29 @@ struct iwl_set_calib_default_cmd { | |||
948 | u8 data[0]; | 950 | u8 data[0]; |
949 | } __packed; /* PHY_CALIB_OVERRIDE_VALUES_S */ | 951 | } __packed; /* PHY_CALIB_OVERRIDE_VALUES_S */ |
950 | 952 | ||
953 | #define MAX_PORT_ID_NUM 2 | ||
954 | |||
955 | /** | ||
956 | * struct iwl_mcast_filter_cmd - configure multicast filter. | ||
957 | * @filter_own: Set 1 to filter out multicast packets sent by station itself | ||
958 | * @port_id: Multicast MAC addresses array specifier. This is a strange way | ||
959 | * to identify network interface adopted in host-device IF. | ||
960 | * It is used by FW as index in array of addresses. This array has | ||
961 | * MAX_PORT_ID_NUM members. | ||
962 | * @count: Number of MAC addresses in the array | ||
963 | * @pass_all: Set 1 to pass all multicast packets. | ||
964 | * @bssid: current association BSSID. | ||
965 | * @addr_list: Place holder for array of MAC addresses. | ||
966 | * IMPORTANT: add padding if necessary to ensure DWORD alignment. | ||
967 | */ | ||
968 | struct iwl_mcast_filter_cmd { | ||
969 | u8 filter_own; | ||
970 | u8 port_id; | ||
971 | u8 count; | ||
972 | u8 pass_all; | ||
973 | u8 bssid[6]; | ||
974 | u8 reserved[2]; | ||
975 | u8 addr_list[0]; | ||
976 | } __packed; /* MCAST_FILTERING_CMD_API_S_VER_1 */ | ||
977 | |||
951 | #endif /* __fw_api_h__ */ | 978 | #endif /* __fw_api_h__ */ |
diff --git a/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c b/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c index e6eca4d66f6c..b2cc3d98e0f7 100644 --- a/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c +++ b/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c | |||
@@ -586,10 +586,12 @@ static int iwl_mvm_mac_ctxt_send_cmd(struct iwl_mvm *mvm, | |||
586 | */ | 586 | */ |
587 | static void iwl_mvm_mac_ctxt_cmd_fill_sta(struct iwl_mvm *mvm, | 587 | static void iwl_mvm_mac_ctxt_cmd_fill_sta(struct iwl_mvm *mvm, |
588 | struct ieee80211_vif *vif, | 588 | struct ieee80211_vif *vif, |
589 | struct iwl_mac_data_sta *ctxt_sta) | 589 | struct iwl_mac_data_sta *ctxt_sta, |
590 | bool force_assoc_off) | ||
590 | { | 591 | { |
591 | /* We need the dtim_period to set the MAC as associated */ | 592 | /* We need the dtim_period to set the MAC as associated */ |
592 | if (vif->bss_conf.assoc && vif->bss_conf.dtim_period) { | 593 | if (vif->bss_conf.assoc && vif->bss_conf.dtim_period && |
594 | !force_assoc_off) { | ||
593 | u32 dtim_offs; | 595 | u32 dtim_offs; |
594 | 596 | ||
595 | /* | 597 | /* |
@@ -659,7 +661,8 @@ static int iwl_mvm_mac_ctxt_cmd_station(struct iwl_mvm *mvm, | |||
659 | cmd.filter_flags &= ~cpu_to_le32(MAC_FILTER_IN_BEACON); | 661 | cmd.filter_flags &= ~cpu_to_le32(MAC_FILTER_IN_BEACON); |
660 | 662 | ||
661 | /* Fill the data specific for station mode */ | 663 | /* Fill the data specific for station mode */ |
662 | iwl_mvm_mac_ctxt_cmd_fill_sta(mvm, vif, &cmd.sta); | 664 | iwl_mvm_mac_ctxt_cmd_fill_sta(mvm, vif, &cmd.sta, |
665 | action == FW_CTXT_ACTION_ADD); | ||
663 | 666 | ||
664 | return iwl_mvm_mac_ctxt_send_cmd(mvm, &cmd); | 667 | return iwl_mvm_mac_ctxt_send_cmd(mvm, &cmd); |
665 | } | 668 | } |
@@ -677,7 +680,8 @@ static int iwl_mvm_mac_ctxt_cmd_p2p_client(struct iwl_mvm *mvm, | |||
677 | iwl_mvm_mac_ctxt_cmd_common(mvm, vif, &cmd, action); | 680 | iwl_mvm_mac_ctxt_cmd_common(mvm, vif, &cmd, action); |
678 | 681 | ||
679 | /* Fill the data specific for station mode */ | 682 | /* Fill the data specific for station mode */ |
680 | iwl_mvm_mac_ctxt_cmd_fill_sta(mvm, vif, &cmd.p2p_sta.sta); | 683 | iwl_mvm_mac_ctxt_cmd_fill_sta(mvm, vif, &cmd.p2p_sta.sta, |
684 | action == FW_CTXT_ACTION_ADD); | ||
681 | 685 | ||
682 | cmd.p2p_sta.ctwin = cpu_to_le32(noa->oppps_ctwindow & | 686 | cmd.p2p_sta.ctwin = cpu_to_le32(noa->oppps_ctwindow & |
683 | IEEE80211_P2P_OPPPS_CTWINDOW_MASK); | 687 | IEEE80211_P2P_OPPPS_CTWINDOW_MASK); |
diff --git a/drivers/net/wireless/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/iwlwifi/mvm/mac80211.c index dd158ec571fb..a5eb8c82f16a 100644 --- a/drivers/net/wireless/iwlwifi/mvm/mac80211.c +++ b/drivers/net/wireless/iwlwifi/mvm/mac80211.c | |||
@@ -701,6 +701,20 @@ static void iwl_mvm_configure_filter(struct ieee80211_hw *hw, | |||
701 | *total_flags = 0; | 701 | *total_flags = 0; |
702 | } | 702 | } |
703 | 703 | ||
704 | static int iwl_mvm_configure_mcast_filter(struct iwl_mvm *mvm, | ||
705 | struct ieee80211_vif *vif) | ||
706 | { | ||
707 | struct iwl_mcast_filter_cmd mcast_filter_cmd = { | ||
708 | .pass_all = 1, | ||
709 | }; | ||
710 | |||
711 | memcpy(mcast_filter_cmd.bssid, vif->bss_conf.bssid, ETH_ALEN); | ||
712 | |||
713 | return iwl_mvm_send_cmd_pdu(mvm, MCAST_FILTER_CMD, CMD_SYNC, | ||
714 | sizeof(mcast_filter_cmd), | ||
715 | &mcast_filter_cmd); | ||
716 | } | ||
717 | |||
704 | static void iwl_mvm_bss_info_changed_station(struct iwl_mvm *mvm, | 718 | static void iwl_mvm_bss_info_changed_station(struct iwl_mvm *mvm, |
705 | struct ieee80211_vif *vif, | 719 | struct ieee80211_vif *vif, |
706 | struct ieee80211_bss_conf *bss_conf, | 720 | struct ieee80211_bss_conf *bss_conf, |
@@ -722,6 +736,7 @@ static void iwl_mvm_bss_info_changed_station(struct iwl_mvm *mvm, | |||
722 | return; | 736 | return; |
723 | } | 737 | } |
724 | iwl_mvm_bt_coex_vif_assoc(mvm, vif); | 738 | iwl_mvm_bt_coex_vif_assoc(mvm, vif); |
739 | iwl_mvm_configure_mcast_filter(mvm, vif); | ||
725 | } else if (mvmvif->ap_sta_id != IWL_MVM_STATION_COUNT) { | 740 | } else if (mvmvif->ap_sta_id != IWL_MVM_STATION_COUNT) { |
726 | /* remove AP station now that the MAC is unassoc */ | 741 | /* remove AP station now that the MAC is unassoc */ |
727 | ret = iwl_mvm_rm_sta_id(mvm, vif, mvmvif->ap_sta_id); | 742 | ret = iwl_mvm_rm_sta_id(mvm, vif, mvmvif->ap_sta_id); |
@@ -931,7 +946,7 @@ static void iwl_mvm_mac_sta_notify(struct ieee80211_hw *hw, | |||
931 | 946 | ||
932 | switch (cmd) { | 947 | switch (cmd) { |
933 | case STA_NOTIFY_SLEEP: | 948 | case STA_NOTIFY_SLEEP: |
934 | if (atomic_read(&mvmsta->pending_frames) > 0) | 949 | if (atomic_read(&mvm->pending_frames[mvmsta->sta_id]) > 0) |
935 | ieee80211_sta_block_awake(hw, sta, true); | 950 | ieee80211_sta_block_awake(hw, sta, true); |
936 | /* | 951 | /* |
937 | * The fw updates the STA to be asleep. Tx packets on the Tx | 952 | * The fw updates the STA to be asleep. Tx packets on the Tx |
diff --git a/drivers/net/wireless/iwlwifi/mvm/mvm.h b/drivers/net/wireless/iwlwifi/mvm/mvm.h index 8269bc562951..9f46b23801bc 100644 --- a/drivers/net/wireless/iwlwifi/mvm/mvm.h +++ b/drivers/net/wireless/iwlwifi/mvm/mvm.h | |||
@@ -292,6 +292,7 @@ struct iwl_mvm { | |||
292 | struct ieee80211_sta __rcu *fw_id_to_mac_id[IWL_MVM_STATION_COUNT]; | 292 | struct ieee80211_sta __rcu *fw_id_to_mac_id[IWL_MVM_STATION_COUNT]; |
293 | struct work_struct sta_drained_wk; | 293 | struct work_struct sta_drained_wk; |
294 | unsigned long sta_drained[BITS_TO_LONGS(IWL_MVM_STATION_COUNT)]; | 294 | unsigned long sta_drained[BITS_TO_LONGS(IWL_MVM_STATION_COUNT)]; |
295 | atomic_t pending_frames[IWL_MVM_STATION_COUNT]; | ||
295 | 296 | ||
296 | /* configured by mac80211 */ | 297 | /* configured by mac80211 */ |
297 | u32 rts_threshold; | 298 | u32 rts_threshold; |
diff --git a/drivers/net/wireless/iwlwifi/mvm/ops.c b/drivers/net/wireless/iwlwifi/mvm/ops.c index fe031d304d1e..b29c31a41594 100644 --- a/drivers/net/wireless/iwlwifi/mvm/ops.c +++ b/drivers/net/wireless/iwlwifi/mvm/ops.c | |||
@@ -292,6 +292,7 @@ static const char *iwl_mvm_cmd_strings[REPLY_MAX] = { | |||
292 | CMD(BT_COEX_PROT_ENV), | 292 | CMD(BT_COEX_PROT_ENV), |
293 | CMD(BT_PROFILE_NOTIFICATION), | 293 | CMD(BT_PROFILE_NOTIFICATION), |
294 | CMD(BT_CONFIG), | 294 | CMD(BT_CONFIG), |
295 | CMD(MCAST_FILTER_CMD), | ||
295 | }; | 296 | }; |
296 | #undef CMD | 297 | #undef CMD |
297 | 298 | ||
diff --git a/drivers/net/wireless/iwlwifi/mvm/scan.c b/drivers/net/wireless/iwlwifi/mvm/scan.c index 2157b0f8ced5..2476e43799d5 100644 --- a/drivers/net/wireless/iwlwifi/mvm/scan.c +++ b/drivers/net/wireless/iwlwifi/mvm/scan.c | |||
@@ -298,6 +298,12 @@ int iwl_mvm_scan_request(struct iwl_mvm *mvm, | |||
298 | else | 298 | else |
299 | cmd->type = cpu_to_le32(SCAN_TYPE_FORCED); | 299 | cmd->type = cpu_to_le32(SCAN_TYPE_FORCED); |
300 | 300 | ||
301 | /* | ||
302 | * TODO: This is a WA due to a bug in the FW AUX framework that does not | ||
303 | * properly handle time events that fail to be scheduled | ||
304 | */ | ||
305 | cmd->type = cpu_to_le32(SCAN_TYPE_FORCED); | ||
306 | |||
301 | cmd->repeats = cpu_to_le32(1); | 307 | cmd->repeats = cpu_to_le32(1); |
302 | 308 | ||
303 | /* | 309 | /* |
diff --git a/drivers/net/wireless/iwlwifi/mvm/sta.c b/drivers/net/wireless/iwlwifi/mvm/sta.c index 0fd96e4da461..5c664ed54400 100644 --- a/drivers/net/wireless/iwlwifi/mvm/sta.c +++ b/drivers/net/wireless/iwlwifi/mvm/sta.c | |||
@@ -219,7 +219,7 @@ int iwl_mvm_add_sta(struct iwl_mvm *mvm, | |||
219 | mvm_sta->max_agg_bufsize = LINK_QUAL_AGG_FRAME_LIMIT_DEF; | 219 | mvm_sta->max_agg_bufsize = LINK_QUAL_AGG_FRAME_LIMIT_DEF; |
220 | 220 | ||
221 | /* HW restart, don't assume the memory has been zeroed */ | 221 | /* HW restart, don't assume the memory has been zeroed */ |
222 | atomic_set(&mvm_sta->pending_frames, 0); | 222 | atomic_set(&mvm->pending_frames[sta_id], 0); |
223 | mvm_sta->tid_disable_agg = 0; | 223 | mvm_sta->tid_disable_agg = 0; |
224 | mvm_sta->tfd_queue_msk = 0; | 224 | mvm_sta->tfd_queue_msk = 0; |
225 | for (i = 0; i < IEEE80211_NUM_ACS; i++) | 225 | for (i = 0; i < IEEE80211_NUM_ACS; i++) |
@@ -407,14 +407,21 @@ int iwl_mvm_rm_sta(struct iwl_mvm *mvm, | |||
407 | } | 407 | } |
408 | 408 | ||
409 | /* | 409 | /* |
410 | * Make sure that the tx response code sees the station as -EBUSY and | ||
411 | * calls the drain worker. | ||
412 | */ | ||
413 | spin_lock_bh(&mvm_sta->lock); | ||
414 | /* | ||
410 | * There are frames pending on the AC queues for this station. | 415 | * There are frames pending on the AC queues for this station. |
411 | * We need to wait until all the frames are drained... | 416 | * We need to wait until all the frames are drained... |
412 | */ | 417 | */ |
413 | if (atomic_read(&mvm_sta->pending_frames)) { | 418 | if (atomic_read(&mvm->pending_frames[mvm_sta->sta_id])) { |
414 | ret = iwl_mvm_drain_sta(mvm, mvm_sta, true); | ||
415 | rcu_assign_pointer(mvm->fw_id_to_mac_id[mvm_sta->sta_id], | 419 | rcu_assign_pointer(mvm->fw_id_to_mac_id[mvm_sta->sta_id], |
416 | ERR_PTR(-EBUSY)); | 420 | ERR_PTR(-EBUSY)); |
421 | spin_unlock_bh(&mvm_sta->lock); | ||
422 | ret = iwl_mvm_drain_sta(mvm, mvm_sta, true); | ||
417 | } else { | 423 | } else { |
424 | spin_unlock_bh(&mvm_sta->lock); | ||
418 | ret = iwl_mvm_rm_sta_common(mvm, mvm_sta->sta_id); | 425 | ret = iwl_mvm_rm_sta_common(mvm, mvm_sta->sta_id); |
419 | rcu_assign_pointer(mvm->fw_id_to_mac_id[mvm_sta->sta_id], NULL); | 426 | rcu_assign_pointer(mvm->fw_id_to_mac_id[mvm_sta->sta_id], NULL); |
420 | } | 427 | } |
diff --git a/drivers/net/wireless/iwlwifi/mvm/sta.h b/drivers/net/wireless/iwlwifi/mvm/sta.h index 12abd2d71835..a4ddce77aaae 100644 --- a/drivers/net/wireless/iwlwifi/mvm/sta.h +++ b/drivers/net/wireless/iwlwifi/mvm/sta.h | |||
@@ -274,7 +274,6 @@ struct iwl_mvm_tid_data { | |||
274 | * @bt_reduced_txpower: is reduced tx power enabled for this station | 274 | * @bt_reduced_txpower: is reduced tx power enabled for this station |
275 | * @lock: lock to protect the whole struct. Since %tid_data is access from Tx | 275 | * @lock: lock to protect the whole struct. Since %tid_data is access from Tx |
276 | * and from Tx response flow, it needs a spinlock. | 276 | * and from Tx response flow, it needs a spinlock. |
277 | * @pending_frames: number of frames for this STA on the shared Tx queues. | ||
278 | * @tid_data: per tid data. Look at %iwl_mvm_tid_data. | 277 | * @tid_data: per tid data. Look at %iwl_mvm_tid_data. |
279 | * | 278 | * |
280 | * When mac80211 creates a station it reserves some space (hw->sta_data_size) | 279 | * When mac80211 creates a station it reserves some space (hw->sta_data_size) |
@@ -290,7 +289,6 @@ struct iwl_mvm_sta { | |||
290 | u8 max_agg_bufsize; | 289 | u8 max_agg_bufsize; |
291 | bool bt_reduced_txpower; | 290 | bool bt_reduced_txpower; |
292 | spinlock_t lock; | 291 | spinlock_t lock; |
293 | atomic_t pending_frames; | ||
294 | struct iwl_mvm_tid_data tid_data[IWL_MAX_TID_COUNT]; | 292 | struct iwl_mvm_tid_data tid_data[IWL_MAX_TID_COUNT]; |
295 | struct iwl_lq_sta lq_sta; | 293 | struct iwl_lq_sta lq_sta; |
296 | struct ieee80211_vif *vif; | 294 | struct ieee80211_vif *vif; |
diff --git a/drivers/net/wireless/iwlwifi/mvm/tx.c b/drivers/net/wireless/iwlwifi/mvm/tx.c index 479074303bd7..f212f16502ff 100644 --- a/drivers/net/wireless/iwlwifi/mvm/tx.c +++ b/drivers/net/wireless/iwlwifi/mvm/tx.c | |||
@@ -416,9 +416,8 @@ int iwl_mvm_tx_skb(struct iwl_mvm *mvm, struct sk_buff *skb, | |||
416 | 416 | ||
417 | spin_unlock(&mvmsta->lock); | 417 | spin_unlock(&mvmsta->lock); |
418 | 418 | ||
419 | if (mvmsta->vif->type == NL80211_IFTYPE_AP && | 419 | if (txq_id < IWL_MVM_FIRST_AGG_QUEUE) |
420 | txq_id < IWL_MVM_FIRST_AGG_QUEUE) | 420 | atomic_inc(&mvm->pending_frames[mvmsta->sta_id]); |
421 | atomic_inc(&mvmsta->pending_frames); | ||
422 | 421 | ||
423 | return 0; | 422 | return 0; |
424 | 423 | ||
@@ -680,16 +679,41 @@ static void iwl_mvm_rx_tx_cmd_single(struct iwl_mvm *mvm, | |||
680 | /* | 679 | /* |
681 | * If the txq is not an AMPDU queue, there is no chance we freed | 680 | * If the txq is not an AMPDU queue, there is no chance we freed |
682 | * several skbs. Check that out... | 681 | * several skbs. Check that out... |
683 | * If there are no pending frames for this STA, notify mac80211 that | ||
684 | * this station can go to sleep in its STA table. | ||
685 | */ | 682 | */ |
686 | if (txq_id < IWL_MVM_FIRST_AGG_QUEUE && mvmsta && | 683 | if (txq_id < IWL_MVM_FIRST_AGG_QUEUE && !WARN_ON(skb_freed > 1) && |
687 | !WARN_ON(skb_freed > 1) && | 684 | atomic_sub_and_test(skb_freed, &mvm->pending_frames[sta_id])) { |
688 | mvmsta->vif->type == NL80211_IFTYPE_AP && | 685 | if (mvmsta) { |
689 | atomic_sub_and_test(skb_freed, &mvmsta->pending_frames)) { | 686 | /* |
690 | ieee80211_sta_block_awake(mvm->hw, sta, false); | 687 | * If there are no pending frames for this STA, notify |
691 | set_bit(sta_id, mvm->sta_drained); | 688 | * mac80211 that this station can go to sleep in its |
692 | schedule_work(&mvm->sta_drained_wk); | 689 | * STA table. |
690 | */ | ||
691 | if (mvmsta->vif->type == NL80211_IFTYPE_AP) | ||
692 | ieee80211_sta_block_awake(mvm->hw, sta, false); | ||
693 | /* | ||
694 | * We might very well have taken mvmsta pointer while | ||
695 | * the station was being removed. The remove flow might | ||
696 | * have seen a pending_frame (because we didn't take | ||
697 | * the lock) even if now the queues are drained. So make | ||
698 | * really sure now that this the station is not being | ||
699 | * removed. If it is, run the drain worker to remove it. | ||
700 | */ | ||
701 | spin_lock_bh(&mvmsta->lock); | ||
702 | sta = rcu_dereference(mvm->fw_id_to_mac_id[sta_id]); | ||
703 | if (IS_ERR_OR_NULL(sta)) { | ||
704 | /* | ||
705 | * Station disappeared in the meantime: | ||
706 | * so we are draining. | ||
707 | */ | ||
708 | set_bit(sta_id, mvm->sta_drained); | ||
709 | schedule_work(&mvm->sta_drained_wk); | ||
710 | } | ||
711 | spin_unlock_bh(&mvmsta->lock); | ||
712 | } else if (!mvmsta) { | ||
713 | /* Tx response without STA, so we are draining */ | ||
714 | set_bit(sta_id, mvm->sta_drained); | ||
715 | schedule_work(&mvm->sta_drained_wk); | ||
716 | } | ||
693 | } | 717 | } |
694 | 718 | ||
695 | rcu_read_unlock(); | 719 | rcu_read_unlock(); |
diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c index b878a32e7a98..cb34c7895f2a 100644 --- a/drivers/net/wireless/mac80211_hwsim.c +++ b/drivers/net/wireless/mac80211_hwsim.c | |||
@@ -1723,11 +1723,11 @@ static void mac80211_hwsim_free(void) | |||
1723 | class_destroy(hwsim_class); | 1723 | class_destroy(hwsim_class); |
1724 | } | 1724 | } |
1725 | 1725 | ||
1726 | 1726 | static struct platform_driver mac80211_hwsim_driver = { | |
1727 | static struct device_driver mac80211_hwsim_driver = { | 1727 | .driver = { |
1728 | .name = "mac80211_hwsim", | 1728 | .name = "mac80211_hwsim", |
1729 | .bus = &platform_bus_type, | 1729 | .owner = THIS_MODULE, |
1730 | .owner = THIS_MODULE, | 1730 | }, |
1731 | }; | 1731 | }; |
1732 | 1732 | ||
1733 | static const struct net_device_ops hwsim_netdev_ops = { | 1733 | static const struct net_device_ops hwsim_netdev_ops = { |
@@ -2219,7 +2219,7 @@ static int __init init_mac80211_hwsim(void) | |||
2219 | spin_lock_init(&hwsim_radio_lock); | 2219 | spin_lock_init(&hwsim_radio_lock); |
2220 | INIT_LIST_HEAD(&hwsim_radios); | 2220 | INIT_LIST_HEAD(&hwsim_radios); |
2221 | 2221 | ||
2222 | err = driver_register(&mac80211_hwsim_driver); | 2222 | err = platform_driver_register(&mac80211_hwsim_driver); |
2223 | if (err) | 2223 | if (err) |
2224 | return err; | 2224 | return err; |
2225 | 2225 | ||
@@ -2254,7 +2254,7 @@ static int __init init_mac80211_hwsim(void) | |||
2254 | err = -ENOMEM; | 2254 | err = -ENOMEM; |
2255 | goto failed_drvdata; | 2255 | goto failed_drvdata; |
2256 | } | 2256 | } |
2257 | data->dev->driver = &mac80211_hwsim_driver; | 2257 | data->dev->driver = &mac80211_hwsim_driver.driver; |
2258 | err = device_bind_driver(data->dev); | 2258 | err = device_bind_driver(data->dev); |
2259 | if (err != 0) { | 2259 | if (err != 0) { |
2260 | printk(KERN_DEBUG | 2260 | printk(KERN_DEBUG |
@@ -2564,7 +2564,7 @@ failed_drvdata: | |||
2564 | failed: | 2564 | failed: |
2565 | mac80211_hwsim_free(); | 2565 | mac80211_hwsim_free(); |
2566 | failed_unregister_driver: | 2566 | failed_unregister_driver: |
2567 | driver_unregister(&mac80211_hwsim_driver); | 2567 | platform_driver_unregister(&mac80211_hwsim_driver); |
2568 | return err; | 2568 | return err; |
2569 | } | 2569 | } |
2570 | module_init(init_mac80211_hwsim); | 2570 | module_init(init_mac80211_hwsim); |
@@ -2577,6 +2577,6 @@ static void __exit exit_mac80211_hwsim(void) | |||
2577 | 2577 | ||
2578 | mac80211_hwsim_free(); | 2578 | mac80211_hwsim_free(); |
2579 | unregister_netdev(hwsim_mon); | 2579 | unregister_netdev(hwsim_mon); |
2580 | driver_unregister(&mac80211_hwsim_driver); | 2580 | platform_driver_unregister(&mac80211_hwsim_driver); |
2581 | } | 2581 | } |
2582 | module_exit(exit_mac80211_hwsim); | 2582 | module_exit(exit_mac80211_hwsim); |
diff --git a/drivers/net/wireless/rtlwifi/rtl8188ee/trx.h b/drivers/net/wireless/rtlwifi/rtl8188ee/trx.h index d3a02e73f53a..21ca33a7c770 100644 --- a/drivers/net/wireless/rtlwifi/rtl8188ee/trx.h +++ b/drivers/net/wireless/rtlwifi/rtl8188ee/trx.h | |||
@@ -550,7 +550,7 @@ do { \ | |||
550 | rxmcs == DESC92C_RATE11M) | 550 | rxmcs == DESC92C_RATE11M) |
551 | 551 | ||
552 | struct phy_rx_agc_info_t { | 552 | struct phy_rx_agc_info_t { |
553 | #if __LITTLE_ENDIAN | 553 | #ifdef __LITTLE_ENDIAN |
554 | u8 gain:7, trsw:1; | 554 | u8 gain:7, trsw:1; |
555 | #else | 555 | #else |
556 | u8 trsw:1, gain:7; | 556 | u8 trsw:1, gain:7; |
@@ -574,7 +574,7 @@ struct phy_status_rpt { | |||
574 | u8 stream_target_csi[2]; | 574 | u8 stream_target_csi[2]; |
575 | u8 sig_evm; | 575 | u8 sig_evm; |
576 | u8 rsvd_3; | 576 | u8 rsvd_3; |
577 | #if __LITTLE_ENDIAN | 577 | #ifdef __LITTLE_ENDIAN |
578 | u8 antsel_rx_keep_2:1; /*ex_intf_flg:1;*/ | 578 | u8 antsel_rx_keep_2:1; /*ex_intf_flg:1;*/ |
579 | u8 sgi_en:1; | 579 | u8 sgi_en:1; |
580 | u8 rxsc:2; | 580 | u8 rxsc:2; |
diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c b/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c index 23d640a4debd..938b1e670b93 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c | |||
@@ -349,6 +349,7 @@ static struct usb_device_id rtl8192c_usb_ids[] = { | |||
349 | {RTL_USB_DEVICE(0x07aa, 0x0056, rtl92cu_hal_cfg)}, /*ATKK-Gemtek*/ | 349 | {RTL_USB_DEVICE(0x07aa, 0x0056, rtl92cu_hal_cfg)}, /*ATKK-Gemtek*/ |
350 | {RTL_USB_DEVICE(0x07b8, 0x8178, rtl92cu_hal_cfg)}, /*Funai -Abocom*/ | 350 | {RTL_USB_DEVICE(0x07b8, 0x8178, rtl92cu_hal_cfg)}, /*Funai -Abocom*/ |
351 | {RTL_USB_DEVICE(0x0846, 0x9021, rtl92cu_hal_cfg)}, /*Netgear-Sercomm*/ | 351 | {RTL_USB_DEVICE(0x0846, 0x9021, rtl92cu_hal_cfg)}, /*Netgear-Sercomm*/ |
352 | {RTL_USB_DEVICE(0x0846, 0xf001, rtl92cu_hal_cfg)}, /*On Netwrks N300MA*/ | ||
352 | {RTL_USB_DEVICE(0x0b05, 0x17ab, rtl92cu_hal_cfg)}, /*ASUS-Edimax*/ | 353 | {RTL_USB_DEVICE(0x0b05, 0x17ab, rtl92cu_hal_cfg)}, /*ASUS-Edimax*/ |
353 | {RTL_USB_DEVICE(0x0bda, 0x8186, rtl92cu_hal_cfg)}, /*Realtek 92CE-VAU*/ | 354 | {RTL_USB_DEVICE(0x0bda, 0x8186, rtl92cu_hal_cfg)}, /*Realtek 92CE-VAU*/ |
354 | {RTL_USB_DEVICE(0x0df6, 0x0061, rtl92cu_hal_cfg)}, /*Sitecom-Edimax*/ | 355 | {RTL_USB_DEVICE(0x0df6, 0x0061, rtl92cu_hal_cfg)}, /*Sitecom-Edimax*/ |
diff --git a/drivers/parisc/lba_pci.c b/drivers/parisc/lba_pci.c index 2ef7103270bb..1f05913ae677 100644 --- a/drivers/parisc/lba_pci.c +++ b/drivers/parisc/lba_pci.c | |||
@@ -668,7 +668,7 @@ lba_fixup_bus(struct pci_bus *bus) | |||
668 | BUG(); | 668 | BUG(); |
669 | } | 669 | } |
670 | 670 | ||
671 | if (ldev->hba.elmmio_space.start) { | 671 | if (ldev->hba.elmmio_space.flags) { |
672 | err = request_resource(&iomem_resource, | 672 | err = request_resource(&iomem_resource, |
673 | &(ldev->hba.elmmio_space)); | 673 | &(ldev->hba.elmmio_space)); |
674 | if (err < 0) { | 674 | if (err < 0) { |
@@ -993,7 +993,7 @@ lba_pat_resources(struct parisc_device *pa_dev, struct lba_device *lba_dev) | |||
993 | 993 | ||
994 | case PAT_LMMIO: | 994 | case PAT_LMMIO: |
995 | /* used to fix up pre-initialized MEM BARs */ | 995 | /* used to fix up pre-initialized MEM BARs */ |
996 | if (!lba_dev->hba.lmmio_space.start) { | 996 | if (!lba_dev->hba.lmmio_space.flags) { |
997 | sprintf(lba_dev->hba.lmmio_name, | 997 | sprintf(lba_dev->hba.lmmio_name, |
998 | "PCI%02x LMMIO", | 998 | "PCI%02x LMMIO", |
999 | (int)lba_dev->hba.bus_num.start); | 999 | (int)lba_dev->hba.bus_num.start); |
@@ -1001,7 +1001,7 @@ lba_pat_resources(struct parisc_device *pa_dev, struct lba_device *lba_dev) | |||
1001 | io->start; | 1001 | io->start; |
1002 | r = &lba_dev->hba.lmmio_space; | 1002 | r = &lba_dev->hba.lmmio_space; |
1003 | r->name = lba_dev->hba.lmmio_name; | 1003 | r->name = lba_dev->hba.lmmio_name; |
1004 | } else if (!lba_dev->hba.elmmio_space.start) { | 1004 | } else if (!lba_dev->hba.elmmio_space.flags) { |
1005 | sprintf(lba_dev->hba.elmmio_name, | 1005 | sprintf(lba_dev->hba.elmmio_name, |
1006 | "PCI%02x ELMMIO", | 1006 | "PCI%02x ELMMIO", |
1007 | (int)lba_dev->hba.bus_num.start); | 1007 | (int)lba_dev->hba.bus_num.start); |
@@ -1096,6 +1096,7 @@ lba_legacy_resources(struct parisc_device *pa_dev, struct lba_device *lba_dev) | |||
1096 | r->name = "LBA PCI Busses"; | 1096 | r->name = "LBA PCI Busses"; |
1097 | r->start = lba_num & 0xff; | 1097 | r->start = lba_num & 0xff; |
1098 | r->end = (lba_num>>8) & 0xff; | 1098 | r->end = (lba_num>>8) & 0xff; |
1099 | r->flags = IORESOURCE_BUS; | ||
1099 | 1100 | ||
1100 | /* Set up local PCI Bus resources - we don't need them for | 1101 | /* Set up local PCI Bus resources - we don't need them for |
1101 | ** Legacy boxes but it's nice to see in /proc/iomem. | 1102 | ** Legacy boxes but it's nice to see in /proc/iomem. |
@@ -1494,7 +1495,7 @@ lba_driver_probe(struct parisc_device *dev) | |||
1494 | 1495 | ||
1495 | pci_add_resource_offset(&resources, &lba_dev->hba.io_space, | 1496 | pci_add_resource_offset(&resources, &lba_dev->hba.io_space, |
1496 | HBA_PORT_BASE(lba_dev->hba.hba_num)); | 1497 | HBA_PORT_BASE(lba_dev->hba.hba_num)); |
1497 | if (lba_dev->hba.elmmio_space.start) | 1498 | if (lba_dev->hba.elmmio_space.flags) |
1498 | pci_add_resource_offset(&resources, &lba_dev->hba.elmmio_space, | 1499 | pci_add_resource_offset(&resources, &lba_dev->hba.elmmio_space, |
1499 | lba_dev->hba.lmmio_space_offset); | 1500 | lba_dev->hba.lmmio_space_offset); |
1500 | if (lba_dev->hba.lmmio_space.flags) | 1501 | if (lba_dev->hba.lmmio_space.flags) |
diff --git a/drivers/parisc/superio.c b/drivers/parisc/superio.c index ac6e8e7a02df..a042d065a0c7 100644 --- a/drivers/parisc/superio.c +++ b/drivers/parisc/superio.c | |||
@@ -494,15 +494,4 @@ static struct pci_driver superio_driver = { | |||
494 | .probe = superio_probe, | 494 | .probe = superio_probe, |
495 | }; | 495 | }; |
496 | 496 | ||
497 | static int __init superio_modinit(void) | 497 | module_pci_driver(superio_driver); |
498 | { | ||
499 | return pci_register_driver(&superio_driver); | ||
500 | } | ||
501 | |||
502 | static void __exit superio_exit(void) | ||
503 | { | ||
504 | pci_unregister_driver(&superio_driver); | ||
505 | } | ||
506 | |||
507 | module_init(superio_modinit); | ||
508 | module_exit(superio_exit); | ||
diff --git a/drivers/parport/Kconfig b/drivers/parport/Kconfig index 24e12d4d1769..a50576081b34 100644 --- a/drivers/parport/Kconfig +++ b/drivers/parport/Kconfig | |||
@@ -71,7 +71,7 @@ config PARPORT_PC_FIFO | |||
71 | 71 | ||
72 | config PARPORT_PC_SUPERIO | 72 | config PARPORT_PC_SUPERIO |
73 | bool "SuperIO chipset support" | 73 | bool "SuperIO chipset support" |
74 | depends on PARPORT_PC | 74 | depends on PARPORT_PC && !PARISC |
75 | help | 75 | help |
76 | Saying Y here enables some probes for Super-IO chipsets in order to | 76 | Saying Y here enables some probes for Super-IO chipsets in order to |
77 | find out things like base addresses, IRQ lines and DMA channels. It | 77 | find out things like base addresses, IRQ lines and DMA channels. It |
diff --git a/drivers/parport/parport_gsc.c b/drivers/parport/parport_gsc.c index a5251cb5fb0c..6e3a60c78873 100644 --- a/drivers/parport/parport_gsc.c +++ b/drivers/parport/parport_gsc.c | |||
@@ -234,7 +234,7 @@ static int parport_PS2_supported(struct parport *pb) | |||
234 | 234 | ||
235 | struct parport *parport_gsc_probe_port(unsigned long base, | 235 | struct parport *parport_gsc_probe_port(unsigned long base, |
236 | unsigned long base_hi, int irq, | 236 | unsigned long base_hi, int irq, |
237 | int dma, struct pci_dev *dev) | 237 | int dma, struct parisc_device *padev) |
238 | { | 238 | { |
239 | struct parport_gsc_private *priv; | 239 | struct parport_gsc_private *priv; |
240 | struct parport_operations *ops; | 240 | struct parport_operations *ops; |
@@ -258,7 +258,6 @@ struct parport *parport_gsc_probe_port(unsigned long base, | |||
258 | priv->ctr_writable = 0xff; | 258 | priv->ctr_writable = 0xff; |
259 | priv->dma_buf = 0; | 259 | priv->dma_buf = 0; |
260 | priv->dma_handle = 0; | 260 | priv->dma_handle = 0; |
261 | priv->dev = dev; | ||
262 | p->base = base; | 261 | p->base = base; |
263 | p->base_hi = base_hi; | 262 | p->base_hi = base_hi; |
264 | p->irq = irq; | 263 | p->irq = irq; |
@@ -282,6 +281,7 @@ struct parport *parport_gsc_probe_port(unsigned long base, | |||
282 | return NULL; | 281 | return NULL; |
283 | } | 282 | } |
284 | 283 | ||
284 | p->dev = &padev->dev; | ||
285 | p->base_hi = base_hi; | 285 | p->base_hi = base_hi; |
286 | p->modes = tmp.modes; | 286 | p->modes = tmp.modes; |
287 | p->size = (p->modes & PARPORT_MODE_EPP)?8:3; | 287 | p->size = (p->modes & PARPORT_MODE_EPP)?8:3; |
@@ -373,7 +373,7 @@ static int parport_init_chip(struct parisc_device *dev) | |||
373 | } | 373 | } |
374 | 374 | ||
375 | p = parport_gsc_probe_port(port, 0, dev->irq, | 375 | p = parport_gsc_probe_port(port, 0, dev->irq, |
376 | /* PARPORT_IRQ_NONE */ PARPORT_DMA_NONE, NULL); | 376 | /* PARPORT_IRQ_NONE */ PARPORT_DMA_NONE, dev); |
377 | if (p) | 377 | if (p) |
378 | parport_count++; | 378 | parport_count++; |
379 | dev_set_drvdata(&dev->dev, p); | 379 | dev_set_drvdata(&dev->dev, p); |
diff --git a/drivers/parport/parport_gsc.h b/drivers/parport/parport_gsc.h index fc9c37c54022..812214768d27 100644 --- a/drivers/parport/parport_gsc.h +++ b/drivers/parport/parport_gsc.h | |||
@@ -217,6 +217,6 @@ extern void parport_gsc_dec_use_count(void); | |||
217 | extern struct parport *parport_gsc_probe_port(unsigned long base, | 217 | extern struct parport *parport_gsc_probe_port(unsigned long base, |
218 | unsigned long base_hi, | 218 | unsigned long base_hi, |
219 | int irq, int dma, | 219 | int irq, int dma, |
220 | struct pci_dev *dev); | 220 | struct parisc_device *padev); |
221 | 221 | ||
222 | #endif /* __DRIVERS_PARPORT_PARPORT_GSC_H */ | 222 | #endif /* __DRIVERS_PARPORT_PARPORT_GSC_H */ |
diff --git a/drivers/pci/pcie/aer/aerdrv_core.c b/drivers/pci/pcie/aer/aerdrv_core.c index 8ec8b4f48560..0f4554e48cc5 100644 --- a/drivers/pci/pcie/aer/aerdrv_core.c +++ b/drivers/pci/pcie/aer/aerdrv_core.c | |||
@@ -580,6 +580,7 @@ struct aer_recover_entry | |||
580 | u8 devfn; | 580 | u8 devfn; |
581 | u16 domain; | 581 | u16 domain; |
582 | int severity; | 582 | int severity; |
583 | struct aer_capability_regs *regs; | ||
583 | }; | 584 | }; |
584 | 585 | ||
585 | static DEFINE_KFIFO(aer_recover_ring, struct aer_recover_entry, | 586 | static DEFINE_KFIFO(aer_recover_ring, struct aer_recover_entry, |
@@ -593,7 +594,7 @@ static DEFINE_SPINLOCK(aer_recover_ring_lock); | |||
593 | static DECLARE_WORK(aer_recover_work, aer_recover_work_func); | 594 | static DECLARE_WORK(aer_recover_work, aer_recover_work_func); |
594 | 595 | ||
595 | void aer_recover_queue(int domain, unsigned int bus, unsigned int devfn, | 596 | void aer_recover_queue(int domain, unsigned int bus, unsigned int devfn, |
596 | int severity) | 597 | int severity, struct aer_capability_regs *aer_regs) |
597 | { | 598 | { |
598 | unsigned long flags; | 599 | unsigned long flags; |
599 | struct aer_recover_entry entry = { | 600 | struct aer_recover_entry entry = { |
@@ -601,6 +602,7 @@ void aer_recover_queue(int domain, unsigned int bus, unsigned int devfn, | |||
601 | .devfn = devfn, | 602 | .devfn = devfn, |
602 | .domain = domain, | 603 | .domain = domain, |
603 | .severity = severity, | 604 | .severity = severity, |
605 | .regs = aer_regs, | ||
604 | }; | 606 | }; |
605 | 607 | ||
606 | spin_lock_irqsave(&aer_recover_ring_lock, flags); | 608 | spin_lock_irqsave(&aer_recover_ring_lock, flags); |
@@ -627,6 +629,7 @@ static void aer_recover_work_func(struct work_struct *work) | |||
627 | PCI_SLOT(entry.devfn), PCI_FUNC(entry.devfn)); | 629 | PCI_SLOT(entry.devfn), PCI_FUNC(entry.devfn)); |
628 | continue; | 630 | continue; |
629 | } | 631 | } |
632 | cper_print_aer(pdev, entry.severity, entry.regs); | ||
630 | do_recovery(pdev, entry.severity); | 633 | do_recovery(pdev, entry.severity); |
631 | pci_dev_put(pdev); | 634 | pci_dev_put(pdev); |
632 | } | 635 | } |
diff --git a/drivers/pci/pcie/aer/aerdrv_errprint.c b/drivers/pci/pcie/aer/aerdrv_errprint.c index 5ab14251839d..2c7c9f5f592c 100644 --- a/drivers/pci/pcie/aer/aerdrv_errprint.c +++ b/drivers/pci/pcie/aer/aerdrv_errprint.c | |||
@@ -220,7 +220,7 @@ int cper_severity_to_aer(int cper_severity) | |||
220 | } | 220 | } |
221 | EXPORT_SYMBOL_GPL(cper_severity_to_aer); | 221 | EXPORT_SYMBOL_GPL(cper_severity_to_aer); |
222 | 222 | ||
223 | void cper_print_aer(const char *prefix, struct pci_dev *dev, int cper_severity, | 223 | void cper_print_aer(struct pci_dev *dev, int cper_severity, |
224 | struct aer_capability_regs *aer) | 224 | struct aer_capability_regs *aer) |
225 | { | 225 | { |
226 | int aer_severity, layer, agent, status_strs_size, tlp_header_valid = 0; | 226 | int aer_severity, layer, agent, status_strs_size, tlp_header_valid = 0; |
@@ -244,7 +244,7 @@ void cper_print_aer(const char *prefix, struct pci_dev *dev, int cper_severity, | |||
244 | agent = AER_GET_AGENT(aer_severity, status); | 244 | agent = AER_GET_AGENT(aer_severity, status); |
245 | dev_err(&dev->dev, "aer_status: 0x%08x, aer_mask: 0x%08x\n", | 245 | dev_err(&dev->dev, "aer_status: 0x%08x, aer_mask: 0x%08x\n", |
246 | status, mask); | 246 | status, mask); |
247 | cper_print_bits(prefix, status, status_strs, status_strs_size); | 247 | cper_print_bits("", status, status_strs, status_strs_size); |
248 | dev_err(&dev->dev, "aer_layer=%s, aer_agent=%s\n", | 248 | dev_err(&dev->dev, "aer_layer=%s, aer_agent=%s\n", |
249 | aer_error_layer[layer], aer_agent_string[agent]); | 249 | aer_error_layer[layer], aer_agent_string[agent]); |
250 | if (aer_severity != AER_CORRECTABLE) | 250 | if (aer_severity != AER_CORRECTABLE) |
diff --git a/drivers/pinctrl/pinconf.c b/drivers/pinctrl/pinconf.c index c67c37e23dd7..694c3ace4520 100644 --- a/drivers/pinctrl/pinconf.c +++ b/drivers/pinctrl/pinconf.c | |||
@@ -610,7 +610,7 @@ static int pinconf_dbg_config_print(struct seq_file *s, void *d) | |||
610 | bool found = false; | 610 | bool found = false; |
611 | unsigned long config; | 611 | unsigned long config; |
612 | 612 | ||
613 | mutex_lock(&pctldev->mutex); | 613 | mutex_lock(&pinctrl_maps_mutex); |
614 | 614 | ||
615 | /* Parse the pinctrl map and look for the elected pin/state */ | 615 | /* Parse the pinctrl map and look for the elected pin/state */ |
616 | for_each_maps(maps_node, i, map) { | 616 | for_each_maps(maps_node, i, map) { |
@@ -659,7 +659,7 @@ static int pinconf_dbg_config_print(struct seq_file *s, void *d) | |||
659 | confops->pin_config_config_dbg_show(pctldev, s, config); | 659 | confops->pin_config_config_dbg_show(pctldev, s, config); |
660 | 660 | ||
661 | exit: | 661 | exit: |
662 | mutex_unlock(&pctldev->mutex); | 662 | mutex_unlock(&pinctrl_maps_mutex); |
663 | 663 | ||
664 | return 0; | 664 | return 0; |
665 | } | 665 | } |
diff --git a/drivers/pinctrl/pinctrl-coh901.c b/drivers/pinctrl/pinctrl-coh901.c index a67af419f531..d6b41747d687 100644 --- a/drivers/pinctrl/pinctrl-coh901.c +++ b/drivers/pinctrl/pinctrl-coh901.c | |||
@@ -830,7 +830,8 @@ static int __init u300_gpio_probe(struct platform_device *pdev) | |||
830 | return 0; | 830 | return 0; |
831 | 831 | ||
832 | err_no_range: | 832 | err_no_range: |
833 | err = gpiochip_remove(&gpio->chip); | 833 | if (gpiochip_remove(&gpio->chip)) |
834 | dev_err(&pdev->dev, "failed to remove gpio chip\n"); | ||
834 | err_no_chip: | 835 | err_no_chip: |
835 | err_no_domain: | 836 | err_no_domain: |
836 | err_no_port: | 837 | err_no_port: |
diff --git a/drivers/pinctrl/pinctrl-exynos.c b/drivers/pinctrl/pinctrl-exynos.c index ac742817ebce..2d76f66a2e0b 100644 --- a/drivers/pinctrl/pinctrl-exynos.c +++ b/drivers/pinctrl/pinctrl-exynos.c | |||
@@ -196,6 +196,12 @@ static irqreturn_t exynos_eint_gpio_irq(int irq, void *data) | |||
196 | return IRQ_HANDLED; | 196 | return IRQ_HANDLED; |
197 | } | 197 | } |
198 | 198 | ||
199 | struct exynos_eint_gpio_save { | ||
200 | u32 eint_con; | ||
201 | u32 eint_fltcon0; | ||
202 | u32 eint_fltcon1; | ||
203 | }; | ||
204 | |||
199 | /* | 205 | /* |
200 | * exynos_eint_gpio_init() - setup handling of external gpio interrupts. | 206 | * exynos_eint_gpio_init() - setup handling of external gpio interrupts. |
201 | * @d: driver data of samsung pinctrl driver. | 207 | * @d: driver data of samsung pinctrl driver. |
@@ -204,8 +210,8 @@ static int exynos_eint_gpio_init(struct samsung_pinctrl_drv_data *d) | |||
204 | { | 210 | { |
205 | struct samsung_pin_bank *bank; | 211 | struct samsung_pin_bank *bank; |
206 | struct device *dev = d->dev; | 212 | struct device *dev = d->dev; |
207 | unsigned int ret; | 213 | int ret; |
208 | unsigned int i; | 214 | int i; |
209 | 215 | ||
210 | if (!d->irq) { | 216 | if (!d->irq) { |
211 | dev_err(dev, "irq number not available\n"); | 217 | dev_err(dev, "irq number not available\n"); |
@@ -227,11 +233,29 @@ static int exynos_eint_gpio_init(struct samsung_pinctrl_drv_data *d) | |||
227 | bank->nr_pins, &exynos_gpio_irqd_ops, bank); | 233 | bank->nr_pins, &exynos_gpio_irqd_ops, bank); |
228 | if (!bank->irq_domain) { | 234 | if (!bank->irq_domain) { |
229 | dev_err(dev, "gpio irq domain add failed\n"); | 235 | dev_err(dev, "gpio irq domain add failed\n"); |
230 | return -ENXIO; | 236 | ret = -ENXIO; |
237 | goto err_domains; | ||
238 | } | ||
239 | |||
240 | bank->soc_priv = devm_kzalloc(d->dev, | ||
241 | sizeof(struct exynos_eint_gpio_save), GFP_KERNEL); | ||
242 | if (!bank->soc_priv) { | ||
243 | irq_domain_remove(bank->irq_domain); | ||
244 | ret = -ENOMEM; | ||
245 | goto err_domains; | ||
231 | } | 246 | } |
232 | } | 247 | } |
233 | 248 | ||
234 | return 0; | 249 | return 0; |
250 | |||
251 | err_domains: | ||
252 | for (--i, --bank; i >= 0; --i, --bank) { | ||
253 | if (bank->eint_type != EINT_TYPE_GPIO) | ||
254 | continue; | ||
255 | irq_domain_remove(bank->irq_domain); | ||
256 | } | ||
257 | |||
258 | return ret; | ||
235 | } | 259 | } |
236 | 260 | ||
237 | static void exynos_wkup_irq_unmask(struct irq_data *irqd) | 261 | static void exynos_wkup_irq_unmask(struct irq_data *irqd) |
@@ -326,6 +350,28 @@ static int exynos_wkup_irq_set_type(struct irq_data *irqd, unsigned int type) | |||
326 | return 0; | 350 | return 0; |
327 | } | 351 | } |
328 | 352 | ||
353 | static u32 exynos_eint_wake_mask = 0xffffffff; | ||
354 | |||
355 | u32 exynos_get_eint_wake_mask(void) | ||
356 | { | ||
357 | return exynos_eint_wake_mask; | ||
358 | } | ||
359 | |||
360 | static int exynos_wkup_irq_set_wake(struct irq_data *irqd, unsigned int on) | ||
361 | { | ||
362 | struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(irqd); | ||
363 | unsigned long bit = 1UL << (2 * bank->eint_offset + irqd->hwirq); | ||
364 | |||
365 | pr_info("wake %s for irq %d\n", on ? "enabled" : "disabled", irqd->irq); | ||
366 | |||
367 | if (!on) | ||
368 | exynos_eint_wake_mask |= bit; | ||
369 | else | ||
370 | exynos_eint_wake_mask &= ~bit; | ||
371 | |||
372 | return 0; | ||
373 | } | ||
374 | |||
329 | /* | 375 | /* |
330 | * irq_chip for wakeup interrupts | 376 | * irq_chip for wakeup interrupts |
331 | */ | 377 | */ |
@@ -335,6 +381,7 @@ static struct irq_chip exynos_wkup_irq_chip = { | |||
335 | .irq_mask = exynos_wkup_irq_mask, | 381 | .irq_mask = exynos_wkup_irq_mask, |
336 | .irq_ack = exynos_wkup_irq_ack, | 382 | .irq_ack = exynos_wkup_irq_ack, |
337 | .irq_set_type = exynos_wkup_irq_set_type, | 383 | .irq_set_type = exynos_wkup_irq_set_type, |
384 | .irq_set_wake = exynos_wkup_irq_set_wake, | ||
338 | }; | 385 | }; |
339 | 386 | ||
340 | /* interrupt handler for wakeup interrupts 0..15 */ | 387 | /* interrupt handler for wakeup interrupts 0..15 */ |
@@ -505,6 +552,72 @@ static int exynos_eint_wkup_init(struct samsung_pinctrl_drv_data *d) | |||
505 | return 0; | 552 | return 0; |
506 | } | 553 | } |
507 | 554 | ||
555 | static void exynos_pinctrl_suspend_bank( | ||
556 | struct samsung_pinctrl_drv_data *drvdata, | ||
557 | struct samsung_pin_bank *bank) | ||
558 | { | ||
559 | struct exynos_eint_gpio_save *save = bank->soc_priv; | ||
560 | void __iomem *regs = drvdata->virt_base; | ||
561 | |||
562 | save->eint_con = readl(regs + EXYNOS_GPIO_ECON_OFFSET | ||
563 | + bank->eint_offset); | ||
564 | save->eint_fltcon0 = readl(regs + EXYNOS_GPIO_EFLTCON_OFFSET | ||
565 | + 2 * bank->eint_offset); | ||
566 | save->eint_fltcon1 = readl(regs + EXYNOS_GPIO_EFLTCON_OFFSET | ||
567 | + 2 * bank->eint_offset + 4); | ||
568 | |||
569 | pr_debug("%s: save con %#010x\n", bank->name, save->eint_con); | ||
570 | pr_debug("%s: save fltcon0 %#010x\n", bank->name, save->eint_fltcon0); | ||
571 | pr_debug("%s: save fltcon1 %#010x\n", bank->name, save->eint_fltcon1); | ||
572 | } | ||
573 | |||
574 | static void exynos_pinctrl_suspend(struct samsung_pinctrl_drv_data *drvdata) | ||
575 | { | ||
576 | struct samsung_pin_ctrl *ctrl = drvdata->ctrl; | ||
577 | struct samsung_pin_bank *bank = ctrl->pin_banks; | ||
578 | int i; | ||
579 | |||
580 | for (i = 0; i < ctrl->nr_banks; ++i, ++bank) | ||
581 | if (bank->eint_type == EINT_TYPE_GPIO) | ||
582 | exynos_pinctrl_suspend_bank(drvdata, bank); | ||
583 | } | ||
584 | |||
585 | static void exynos_pinctrl_resume_bank( | ||
586 | struct samsung_pinctrl_drv_data *drvdata, | ||
587 | struct samsung_pin_bank *bank) | ||
588 | { | ||
589 | struct exynos_eint_gpio_save *save = bank->soc_priv; | ||
590 | void __iomem *regs = drvdata->virt_base; | ||
591 | |||
592 | pr_debug("%s: con %#010x => %#010x\n", bank->name, | ||
593 | readl(regs + EXYNOS_GPIO_ECON_OFFSET | ||
594 | + bank->eint_offset), save->eint_con); | ||
595 | pr_debug("%s: fltcon0 %#010x => %#010x\n", bank->name, | ||
596 | readl(regs + EXYNOS_GPIO_EFLTCON_OFFSET | ||
597 | + 2 * bank->eint_offset), save->eint_fltcon0); | ||
598 | pr_debug("%s: fltcon1 %#010x => %#010x\n", bank->name, | ||
599 | readl(regs + EXYNOS_GPIO_EFLTCON_OFFSET | ||
600 | + 2 * bank->eint_offset + 4), save->eint_fltcon1); | ||
601 | |||
602 | writel(save->eint_con, regs + EXYNOS_GPIO_ECON_OFFSET | ||
603 | + bank->eint_offset); | ||
604 | writel(save->eint_fltcon0, regs + EXYNOS_GPIO_EFLTCON_OFFSET | ||
605 | + 2 * bank->eint_offset); | ||
606 | writel(save->eint_fltcon1, regs + EXYNOS_GPIO_EFLTCON_OFFSET | ||
607 | + 2 * bank->eint_offset + 4); | ||
608 | } | ||
609 | |||
610 | static void exynos_pinctrl_resume(struct samsung_pinctrl_drv_data *drvdata) | ||
611 | { | ||
612 | struct samsung_pin_ctrl *ctrl = drvdata->ctrl; | ||
613 | struct samsung_pin_bank *bank = ctrl->pin_banks; | ||
614 | int i; | ||
615 | |||
616 | for (i = 0; i < ctrl->nr_banks; ++i, ++bank) | ||
617 | if (bank->eint_type == EINT_TYPE_GPIO) | ||
618 | exynos_pinctrl_resume_bank(drvdata, bank); | ||
619 | } | ||
620 | |||
508 | /* pin banks of exynos4210 pin-controller 0 */ | 621 | /* pin banks of exynos4210 pin-controller 0 */ |
509 | static struct samsung_pin_bank exynos4210_pin_banks0[] = { | 622 | static struct samsung_pin_bank exynos4210_pin_banks0[] = { |
510 | EXYNOS_PIN_BANK_EINTG(8, 0x000, "gpa0", 0x00), | 623 | EXYNOS_PIN_BANK_EINTG(8, 0x000, "gpa0", 0x00), |
@@ -568,6 +681,8 @@ struct samsung_pin_ctrl exynos4210_pin_ctrl[] = { | |||
568 | .geint_pend = EXYNOS_GPIO_EPEND_OFFSET, | 681 | .geint_pend = EXYNOS_GPIO_EPEND_OFFSET, |
569 | .svc = EXYNOS_SVC_OFFSET, | 682 | .svc = EXYNOS_SVC_OFFSET, |
570 | .eint_gpio_init = exynos_eint_gpio_init, | 683 | .eint_gpio_init = exynos_eint_gpio_init, |
684 | .suspend = exynos_pinctrl_suspend, | ||
685 | .resume = exynos_pinctrl_resume, | ||
571 | .label = "exynos4210-gpio-ctrl0", | 686 | .label = "exynos4210-gpio-ctrl0", |
572 | }, { | 687 | }, { |
573 | /* pin-controller instance 1 data */ | 688 | /* pin-controller instance 1 data */ |
@@ -582,6 +697,8 @@ struct samsung_pin_ctrl exynos4210_pin_ctrl[] = { | |||
582 | .svc = EXYNOS_SVC_OFFSET, | 697 | .svc = EXYNOS_SVC_OFFSET, |
583 | .eint_gpio_init = exynos_eint_gpio_init, | 698 | .eint_gpio_init = exynos_eint_gpio_init, |
584 | .eint_wkup_init = exynos_eint_wkup_init, | 699 | .eint_wkup_init = exynos_eint_wkup_init, |
700 | .suspend = exynos_pinctrl_suspend, | ||
701 | .resume = exynos_pinctrl_resume, | ||
585 | .label = "exynos4210-gpio-ctrl1", | 702 | .label = "exynos4210-gpio-ctrl1", |
586 | }, { | 703 | }, { |
587 | /* pin-controller instance 2 data */ | 704 | /* pin-controller instance 2 data */ |
@@ -663,6 +780,8 @@ struct samsung_pin_ctrl exynos4x12_pin_ctrl[] = { | |||
663 | .geint_pend = EXYNOS_GPIO_EPEND_OFFSET, | 780 | .geint_pend = EXYNOS_GPIO_EPEND_OFFSET, |
664 | .svc = EXYNOS_SVC_OFFSET, | 781 | .svc = EXYNOS_SVC_OFFSET, |
665 | .eint_gpio_init = exynos_eint_gpio_init, | 782 | .eint_gpio_init = exynos_eint_gpio_init, |
783 | .suspend = exynos_pinctrl_suspend, | ||
784 | .resume = exynos_pinctrl_resume, | ||
666 | .label = "exynos4x12-gpio-ctrl0", | 785 | .label = "exynos4x12-gpio-ctrl0", |
667 | }, { | 786 | }, { |
668 | /* pin-controller instance 1 data */ | 787 | /* pin-controller instance 1 data */ |
@@ -677,6 +796,8 @@ struct samsung_pin_ctrl exynos4x12_pin_ctrl[] = { | |||
677 | .svc = EXYNOS_SVC_OFFSET, | 796 | .svc = EXYNOS_SVC_OFFSET, |
678 | .eint_gpio_init = exynos_eint_gpio_init, | 797 | .eint_gpio_init = exynos_eint_gpio_init, |
679 | .eint_wkup_init = exynos_eint_wkup_init, | 798 | .eint_wkup_init = exynos_eint_wkup_init, |
799 | .suspend = exynos_pinctrl_suspend, | ||
800 | .resume = exynos_pinctrl_resume, | ||
680 | .label = "exynos4x12-gpio-ctrl1", | 801 | .label = "exynos4x12-gpio-ctrl1", |
681 | }, { | 802 | }, { |
682 | /* pin-controller instance 2 data */ | 803 | /* pin-controller instance 2 data */ |
@@ -687,6 +808,8 @@ struct samsung_pin_ctrl exynos4x12_pin_ctrl[] = { | |||
687 | .geint_pend = EXYNOS_GPIO_EPEND_OFFSET, | 808 | .geint_pend = EXYNOS_GPIO_EPEND_OFFSET, |
688 | .svc = EXYNOS_SVC_OFFSET, | 809 | .svc = EXYNOS_SVC_OFFSET, |
689 | .eint_gpio_init = exynos_eint_gpio_init, | 810 | .eint_gpio_init = exynos_eint_gpio_init, |
811 | .suspend = exynos_pinctrl_suspend, | ||
812 | .resume = exynos_pinctrl_resume, | ||
690 | .label = "exynos4x12-gpio-ctrl2", | 813 | .label = "exynos4x12-gpio-ctrl2", |
691 | }, { | 814 | }, { |
692 | /* pin-controller instance 3 data */ | 815 | /* pin-controller instance 3 data */ |
@@ -697,6 +820,8 @@ struct samsung_pin_ctrl exynos4x12_pin_ctrl[] = { | |||
697 | .geint_pend = EXYNOS_GPIO_EPEND_OFFSET, | 820 | .geint_pend = EXYNOS_GPIO_EPEND_OFFSET, |
698 | .svc = EXYNOS_SVC_OFFSET, | 821 | .svc = EXYNOS_SVC_OFFSET, |
699 | .eint_gpio_init = exynos_eint_gpio_init, | 822 | .eint_gpio_init = exynos_eint_gpio_init, |
823 | .suspend = exynos_pinctrl_suspend, | ||
824 | .resume = exynos_pinctrl_resume, | ||
700 | .label = "exynos4x12-gpio-ctrl3", | 825 | .label = "exynos4x12-gpio-ctrl3", |
701 | }, | 826 | }, |
702 | }; | 827 | }; |
@@ -775,6 +900,8 @@ struct samsung_pin_ctrl exynos5250_pin_ctrl[] = { | |||
775 | .svc = EXYNOS_SVC_OFFSET, | 900 | .svc = EXYNOS_SVC_OFFSET, |
776 | .eint_gpio_init = exynos_eint_gpio_init, | 901 | .eint_gpio_init = exynos_eint_gpio_init, |
777 | .eint_wkup_init = exynos_eint_wkup_init, | 902 | .eint_wkup_init = exynos_eint_wkup_init, |
903 | .suspend = exynos_pinctrl_suspend, | ||
904 | .resume = exynos_pinctrl_resume, | ||
778 | .label = "exynos5250-gpio-ctrl0", | 905 | .label = "exynos5250-gpio-ctrl0", |
779 | }, { | 906 | }, { |
780 | /* pin-controller instance 1 data */ | 907 | /* pin-controller instance 1 data */ |
@@ -785,6 +912,8 @@ struct samsung_pin_ctrl exynos5250_pin_ctrl[] = { | |||
785 | .geint_pend = EXYNOS_GPIO_EPEND_OFFSET, | 912 | .geint_pend = EXYNOS_GPIO_EPEND_OFFSET, |
786 | .svc = EXYNOS_SVC_OFFSET, | 913 | .svc = EXYNOS_SVC_OFFSET, |
787 | .eint_gpio_init = exynos_eint_gpio_init, | 914 | .eint_gpio_init = exynos_eint_gpio_init, |
915 | .suspend = exynos_pinctrl_suspend, | ||
916 | .resume = exynos_pinctrl_resume, | ||
788 | .label = "exynos5250-gpio-ctrl1", | 917 | .label = "exynos5250-gpio-ctrl1", |
789 | }, { | 918 | }, { |
790 | /* pin-controller instance 2 data */ | 919 | /* pin-controller instance 2 data */ |
@@ -795,6 +924,8 @@ struct samsung_pin_ctrl exynos5250_pin_ctrl[] = { | |||
795 | .geint_pend = EXYNOS_GPIO_EPEND_OFFSET, | 924 | .geint_pend = EXYNOS_GPIO_EPEND_OFFSET, |
796 | .svc = EXYNOS_SVC_OFFSET, | 925 | .svc = EXYNOS_SVC_OFFSET, |
797 | .eint_gpio_init = exynos_eint_gpio_init, | 926 | .eint_gpio_init = exynos_eint_gpio_init, |
927 | .suspend = exynos_pinctrl_suspend, | ||
928 | .resume = exynos_pinctrl_resume, | ||
798 | .label = "exynos5250-gpio-ctrl2", | 929 | .label = "exynos5250-gpio-ctrl2", |
799 | }, { | 930 | }, { |
800 | /* pin-controller instance 3 data */ | 931 | /* pin-controller instance 3 data */ |
@@ -805,6 +936,8 @@ struct samsung_pin_ctrl exynos5250_pin_ctrl[] = { | |||
805 | .geint_pend = EXYNOS_GPIO_EPEND_OFFSET, | 936 | .geint_pend = EXYNOS_GPIO_EPEND_OFFSET, |
806 | .svc = EXYNOS_SVC_OFFSET, | 937 | .svc = EXYNOS_SVC_OFFSET, |
807 | .eint_gpio_init = exynos_eint_gpio_init, | 938 | .eint_gpio_init = exynos_eint_gpio_init, |
939 | .suspend = exynos_pinctrl_suspend, | ||
940 | .resume = exynos_pinctrl_resume, | ||
808 | .label = "exynos5250-gpio-ctrl3", | 941 | .label = "exynos5250-gpio-ctrl3", |
809 | }, | 942 | }, |
810 | }; | 943 | }; |
diff --git a/drivers/pinctrl/pinctrl-exynos.h b/drivers/pinctrl/pinctrl-exynos.h index 9b1f77a5bf0f..3c91c357792f 100644 --- a/drivers/pinctrl/pinctrl-exynos.h +++ b/drivers/pinctrl/pinctrl-exynos.h | |||
@@ -19,6 +19,7 @@ | |||
19 | 19 | ||
20 | /* External GPIO and wakeup interrupt related definitions */ | 20 | /* External GPIO and wakeup interrupt related definitions */ |
21 | #define EXYNOS_GPIO_ECON_OFFSET 0x700 | 21 | #define EXYNOS_GPIO_ECON_OFFSET 0x700 |
22 | #define EXYNOS_GPIO_EFLTCON_OFFSET 0x800 | ||
22 | #define EXYNOS_GPIO_EMASK_OFFSET 0x900 | 23 | #define EXYNOS_GPIO_EMASK_OFFSET 0x900 |
23 | #define EXYNOS_GPIO_EPEND_OFFSET 0xA00 | 24 | #define EXYNOS_GPIO_EPEND_OFFSET 0xA00 |
24 | #define EXYNOS_WKUP_ECON_OFFSET 0xE00 | 25 | #define EXYNOS_WKUP_ECON_OFFSET 0xE00 |
diff --git a/drivers/pinctrl/pinctrl-samsung.c b/drivers/pinctrl/pinctrl-samsung.c index 055d0162098b..63ac22e89678 100644 --- a/drivers/pinctrl/pinctrl-samsung.c +++ b/drivers/pinctrl/pinctrl-samsung.c | |||
@@ -28,6 +28,7 @@ | |||
28 | #include <linux/gpio.h> | 28 | #include <linux/gpio.h> |
29 | #include <linux/irqdomain.h> | 29 | #include <linux/irqdomain.h> |
30 | #include <linux/spinlock.h> | 30 | #include <linux/spinlock.h> |
31 | #include <linux/syscore_ops.h> | ||
31 | 32 | ||
32 | #include "core.h" | 33 | #include "core.h" |
33 | #include "pinctrl-samsung.h" | 34 | #include "pinctrl-samsung.h" |
@@ -48,6 +49,9 @@ static struct pin_config { | |||
48 | { "samsung,pin-pud-pdn", PINCFG_TYPE_PUD_PDN }, | 49 | { "samsung,pin-pud-pdn", PINCFG_TYPE_PUD_PDN }, |
49 | }; | 50 | }; |
50 | 51 | ||
52 | /* Global list of devices (struct samsung_pinctrl_drv_data) */ | ||
53 | LIST_HEAD(drvdata_list); | ||
54 | |||
51 | static unsigned int pin_base; | 55 | static unsigned int pin_base; |
52 | 56 | ||
53 | static inline struct samsung_pin_bank *gc_to_pin_bank(struct gpio_chip *gc) | 57 | static inline struct samsung_pin_bank *gc_to_pin_bank(struct gpio_chip *gc) |
@@ -956,9 +960,151 @@ static int samsung_pinctrl_probe(struct platform_device *pdev) | |||
956 | ctrl->eint_wkup_init(drvdata); | 960 | ctrl->eint_wkup_init(drvdata); |
957 | 961 | ||
958 | platform_set_drvdata(pdev, drvdata); | 962 | platform_set_drvdata(pdev, drvdata); |
963 | |||
964 | /* Add to the global list */ | ||
965 | list_add_tail(&drvdata->node, &drvdata_list); | ||
966 | |||
959 | return 0; | 967 | return 0; |
960 | } | 968 | } |
961 | 969 | ||
970 | #ifdef CONFIG_PM | ||
971 | |||
972 | /** | ||
973 | * samsung_pinctrl_suspend_dev - save pinctrl state for suspend for a device | ||
974 | * | ||
975 | * Save data for all banks handled by this device. | ||
976 | */ | ||
977 | static void samsung_pinctrl_suspend_dev( | ||
978 | struct samsung_pinctrl_drv_data *drvdata) | ||
979 | { | ||
980 | struct samsung_pin_ctrl *ctrl = drvdata->ctrl; | ||
981 | void __iomem *virt_base = drvdata->virt_base; | ||
982 | int i; | ||
983 | |||
984 | for (i = 0; i < ctrl->nr_banks; i++) { | ||
985 | struct samsung_pin_bank *bank = &ctrl->pin_banks[i]; | ||
986 | void __iomem *reg = virt_base + bank->pctl_offset; | ||
987 | |||
988 | u8 *offs = bank->type->reg_offset; | ||
989 | u8 *widths = bank->type->fld_width; | ||
990 | enum pincfg_type type; | ||
991 | |||
992 | /* Registers without a powerdown config aren't lost */ | ||
993 | if (!widths[PINCFG_TYPE_CON_PDN]) | ||
994 | continue; | ||
995 | |||
996 | for (type = 0; type < PINCFG_TYPE_NUM; type++) | ||
997 | if (widths[type]) | ||
998 | bank->pm_save[type] = readl(reg + offs[type]); | ||
999 | |||
1000 | if (widths[PINCFG_TYPE_FUNC] * bank->nr_pins > 32) { | ||
1001 | /* Some banks have two config registers */ | ||
1002 | bank->pm_save[PINCFG_TYPE_NUM] = | ||
1003 | readl(reg + offs[PINCFG_TYPE_FUNC] + 4); | ||
1004 | pr_debug("Save %s @ %p (con %#010x %08x)\n", | ||
1005 | bank->name, reg, | ||
1006 | bank->pm_save[PINCFG_TYPE_FUNC], | ||
1007 | bank->pm_save[PINCFG_TYPE_NUM]); | ||
1008 | } else { | ||
1009 | pr_debug("Save %s @ %p (con %#010x)\n", bank->name, | ||
1010 | reg, bank->pm_save[PINCFG_TYPE_FUNC]); | ||
1011 | } | ||
1012 | } | ||
1013 | |||
1014 | if (ctrl->suspend) | ||
1015 | ctrl->suspend(drvdata); | ||
1016 | } | ||
1017 | |||
1018 | /** | ||
1019 | * samsung_pinctrl_resume_dev - restore pinctrl state from suspend for a device | ||
1020 | * | ||
1021 | * Restore one of the banks that was saved during suspend. | ||
1022 | * | ||
1023 | * We don't bother doing anything complicated to avoid glitching lines since | ||
1024 | * we're called before pad retention is turned off. | ||
1025 | */ | ||
1026 | static void samsung_pinctrl_resume_dev(struct samsung_pinctrl_drv_data *drvdata) | ||
1027 | { | ||
1028 | struct samsung_pin_ctrl *ctrl = drvdata->ctrl; | ||
1029 | void __iomem *virt_base = drvdata->virt_base; | ||
1030 | int i; | ||
1031 | |||
1032 | if (ctrl->resume) | ||
1033 | ctrl->resume(drvdata); | ||
1034 | |||
1035 | for (i = 0; i < ctrl->nr_banks; i++) { | ||
1036 | struct samsung_pin_bank *bank = &ctrl->pin_banks[i]; | ||
1037 | void __iomem *reg = virt_base + bank->pctl_offset; | ||
1038 | |||
1039 | u8 *offs = bank->type->reg_offset; | ||
1040 | u8 *widths = bank->type->fld_width; | ||
1041 | enum pincfg_type type; | ||
1042 | |||
1043 | /* Registers without a powerdown config aren't lost */ | ||
1044 | if (!widths[PINCFG_TYPE_CON_PDN]) | ||
1045 | continue; | ||
1046 | |||
1047 | if (widths[PINCFG_TYPE_FUNC] * bank->nr_pins > 32) { | ||
1048 | /* Some banks have two config registers */ | ||
1049 | pr_debug("%s @ %p (con %#010x %08x => %#010x %08x)\n", | ||
1050 | bank->name, reg, | ||
1051 | readl(reg + offs[PINCFG_TYPE_FUNC]), | ||
1052 | readl(reg + offs[PINCFG_TYPE_FUNC] + 4), | ||
1053 | bank->pm_save[PINCFG_TYPE_FUNC], | ||
1054 | bank->pm_save[PINCFG_TYPE_NUM]); | ||
1055 | writel(bank->pm_save[PINCFG_TYPE_NUM], | ||
1056 | reg + offs[PINCFG_TYPE_FUNC] + 4); | ||
1057 | } else { | ||
1058 | pr_debug("%s @ %p (con %#010x => %#010x)\n", bank->name, | ||
1059 | reg, readl(reg + offs[PINCFG_TYPE_FUNC]), | ||
1060 | bank->pm_save[PINCFG_TYPE_FUNC]); | ||
1061 | } | ||
1062 | for (type = 0; type < PINCFG_TYPE_NUM; type++) | ||
1063 | if (widths[type]) | ||
1064 | writel(bank->pm_save[type], reg + offs[type]); | ||
1065 | } | ||
1066 | } | ||
1067 | |||
1068 | /** | ||
1069 | * samsung_pinctrl_suspend - save pinctrl state for suspend | ||
1070 | * | ||
1071 | * Save data for all banks across all devices. | ||
1072 | */ | ||
1073 | static int samsung_pinctrl_suspend(void) | ||
1074 | { | ||
1075 | struct samsung_pinctrl_drv_data *drvdata; | ||
1076 | |||
1077 | list_for_each_entry(drvdata, &drvdata_list, node) { | ||
1078 | samsung_pinctrl_suspend_dev(drvdata); | ||
1079 | } | ||
1080 | |||
1081 | return 0; | ||
1082 | } | ||
1083 | |||
1084 | /** | ||
1085 | * samsung_pinctrl_resume - restore pinctrl state for suspend | ||
1086 | * | ||
1087 | * Restore data for all banks across all devices. | ||
1088 | */ | ||
1089 | static void samsung_pinctrl_resume(void) | ||
1090 | { | ||
1091 | struct samsung_pinctrl_drv_data *drvdata; | ||
1092 | |||
1093 | list_for_each_entry_reverse(drvdata, &drvdata_list, node) { | ||
1094 | samsung_pinctrl_resume_dev(drvdata); | ||
1095 | } | ||
1096 | } | ||
1097 | |||
1098 | #else | ||
1099 | #define samsung_pinctrl_suspend NULL | ||
1100 | #define samsung_pinctrl_resume NULL | ||
1101 | #endif | ||
1102 | |||
1103 | static struct syscore_ops samsung_pinctrl_syscore_ops = { | ||
1104 | .suspend = samsung_pinctrl_suspend, | ||
1105 | .resume = samsung_pinctrl_resume, | ||
1106 | }; | ||
1107 | |||
962 | static const struct of_device_id samsung_pinctrl_dt_match[] = { | 1108 | static const struct of_device_id samsung_pinctrl_dt_match[] = { |
963 | #ifdef CONFIG_PINCTRL_EXYNOS | 1109 | #ifdef CONFIG_PINCTRL_EXYNOS |
964 | { .compatible = "samsung,exynos4210-pinctrl", | 1110 | { .compatible = "samsung,exynos4210-pinctrl", |
@@ -987,6 +1133,14 @@ static struct platform_driver samsung_pinctrl_driver = { | |||
987 | 1133 | ||
988 | static int __init samsung_pinctrl_drv_register(void) | 1134 | static int __init samsung_pinctrl_drv_register(void) |
989 | { | 1135 | { |
1136 | /* | ||
1137 | * Register syscore ops for save/restore of registers across suspend. | ||
1138 | * It's important to ensure that this driver is running at an earlier | ||
1139 | * initcall level than any arch-specific init calls that install syscore | ||
1140 | * ops that turn off pad retention (like exynos_pm_resume). | ||
1141 | */ | ||
1142 | register_syscore_ops(&samsung_pinctrl_syscore_ops); | ||
1143 | |||
990 | return platform_driver_register(&samsung_pinctrl_driver); | 1144 | return platform_driver_register(&samsung_pinctrl_driver); |
991 | } | 1145 | } |
992 | postcore_initcall(samsung_pinctrl_drv_register); | 1146 | postcore_initcall(samsung_pinctrl_drv_register); |
diff --git a/drivers/pinctrl/pinctrl-samsung.h b/drivers/pinctrl/pinctrl-samsung.h index 7c7f9ebcd05b..26d3519240c9 100644 --- a/drivers/pinctrl/pinctrl-samsung.h +++ b/drivers/pinctrl/pinctrl-samsung.h | |||
@@ -127,6 +127,7 @@ struct samsung_pin_bank_type { | |||
127 | * @gpio_chip: GPIO chip of the bank. | 127 | * @gpio_chip: GPIO chip of the bank. |
128 | * @grange: linux gpio pin range supported by this bank. | 128 | * @grange: linux gpio pin range supported by this bank. |
129 | * @slock: spinlock protecting bank registers | 129 | * @slock: spinlock protecting bank registers |
130 | * @pm_save: saved register values during suspend | ||
130 | */ | 131 | */ |
131 | struct samsung_pin_bank { | 132 | struct samsung_pin_bank { |
132 | struct samsung_pin_bank_type *type; | 133 | struct samsung_pin_bank_type *type; |
@@ -138,12 +139,15 @@ struct samsung_pin_bank { | |||
138 | u32 eint_mask; | 139 | u32 eint_mask; |
139 | u32 eint_offset; | 140 | u32 eint_offset; |
140 | char *name; | 141 | char *name; |
142 | void *soc_priv; | ||
141 | struct device_node *of_node; | 143 | struct device_node *of_node; |
142 | struct samsung_pinctrl_drv_data *drvdata; | 144 | struct samsung_pinctrl_drv_data *drvdata; |
143 | struct irq_domain *irq_domain; | 145 | struct irq_domain *irq_domain; |
144 | struct gpio_chip gpio_chip; | 146 | struct gpio_chip gpio_chip; |
145 | struct pinctrl_gpio_range grange; | 147 | struct pinctrl_gpio_range grange; |
146 | spinlock_t slock; | 148 | spinlock_t slock; |
149 | |||
150 | u32 pm_save[PINCFG_TYPE_NUM + 1]; /* +1 to handle double CON registers*/ | ||
147 | }; | 151 | }; |
148 | 152 | ||
149 | /** | 153 | /** |
@@ -184,11 +188,15 @@ struct samsung_pin_ctrl { | |||
184 | 188 | ||
185 | int (*eint_gpio_init)(struct samsung_pinctrl_drv_data *); | 189 | int (*eint_gpio_init)(struct samsung_pinctrl_drv_data *); |
186 | int (*eint_wkup_init)(struct samsung_pinctrl_drv_data *); | 190 | int (*eint_wkup_init)(struct samsung_pinctrl_drv_data *); |
191 | void (*suspend)(struct samsung_pinctrl_drv_data *); | ||
192 | void (*resume)(struct samsung_pinctrl_drv_data *); | ||
193 | |||
187 | char *label; | 194 | char *label; |
188 | }; | 195 | }; |
189 | 196 | ||
190 | /** | 197 | /** |
191 | * struct samsung_pinctrl_drv_data: wrapper for holding driver data together. | 198 | * struct samsung_pinctrl_drv_data: wrapper for holding driver data together. |
199 | * @node: global list node | ||
192 | * @virt_base: register base address of the controller. | 200 | * @virt_base: register base address of the controller. |
193 | * @dev: device instance representing the controller. | 201 | * @dev: device instance representing the controller. |
194 | * @irq: interrpt number used by the controller to notify gpio interrupts. | 202 | * @irq: interrpt number used by the controller to notify gpio interrupts. |
@@ -201,6 +209,7 @@ struct samsung_pin_ctrl { | |||
201 | * @nr_function: number of such pin functions. | 209 | * @nr_function: number of such pin functions. |
202 | */ | 210 | */ |
203 | struct samsung_pinctrl_drv_data { | 211 | struct samsung_pinctrl_drv_data { |
212 | struct list_head node; | ||
204 | void __iomem *virt_base; | 213 | void __iomem *virt_base; |
205 | struct device *dev; | 214 | struct device *dev; |
206 | int irq; | 215 | int irq; |
diff --git a/drivers/pinctrl/pinctrl-sunxi.c b/drivers/pinctrl/pinctrl-sunxi.c index c52fc2c08732..b7d8c890514c 100644 --- a/drivers/pinctrl/pinctrl-sunxi.c +++ b/drivers/pinctrl/pinctrl-sunxi.c | |||
@@ -1990,8 +1990,10 @@ static int sunxi_pinctrl_probe(struct platform_device *pdev) | |||
1990 | } | 1990 | } |
1991 | 1991 | ||
1992 | clk = devm_clk_get(&pdev->dev, NULL); | 1992 | clk = devm_clk_get(&pdev->dev, NULL); |
1993 | if (IS_ERR(clk)) | 1993 | if (IS_ERR(clk)) { |
1994 | ret = PTR_ERR(clk); | ||
1994 | goto gpiochip_error; | 1995 | goto gpiochip_error; |
1996 | } | ||
1995 | 1997 | ||
1996 | clk_prepare_enable(clk); | 1998 | clk_prepare_enable(clk); |
1997 | 1999 | ||
@@ -2000,7 +2002,8 @@ static int sunxi_pinctrl_probe(struct platform_device *pdev) | |||
2000 | return 0; | 2002 | return 0; |
2001 | 2003 | ||
2002 | gpiochip_error: | 2004 | gpiochip_error: |
2003 | ret = gpiochip_remove(pctl->chip); | 2005 | if (gpiochip_remove(pctl->chip)) |
2006 | dev_err(&pdev->dev, "failed to remove gpio chip\n"); | ||
2004 | pinctrl_error: | 2007 | pinctrl_error: |
2005 | pinctrl_unregister(pctl->pctl_dev); | 2008 | pinctrl_unregister(pctl->pctl_dev); |
2006 | return ret; | 2009 | return ret; |
diff --git a/drivers/pinctrl/vt8500/pinctrl-wmt.c b/drivers/pinctrl/vt8500/pinctrl-wmt.c index ab63104e8dc9..70d986e04afb 100644 --- a/drivers/pinctrl/vt8500/pinctrl-wmt.c +++ b/drivers/pinctrl/vt8500/pinctrl-wmt.c | |||
@@ -609,8 +609,7 @@ int wmt_pinctrl_probe(struct platform_device *pdev, | |||
609 | return 0; | 609 | return 0; |
610 | 610 | ||
611 | fail_range: | 611 | fail_range: |
612 | err = gpiochip_remove(&data->gpio_chip); | 612 | if (gpiochip_remove(&data->gpio_chip)) |
613 | if (err) | ||
614 | dev_err(&pdev->dev, "failed to remove gpio chip\n"); | 613 | dev_err(&pdev->dev, "failed to remove gpio chip\n"); |
615 | fail_gpio: | 614 | fail_gpio: |
616 | pinctrl_unregister(data->pctl_dev); | 615 | pinctrl_unregister(data->pctl_dev); |
diff --git a/drivers/power/Kconfig b/drivers/power/Kconfig index 0d0b5d7d19d0..7b8979c63f48 100644 --- a/drivers/power/Kconfig +++ b/drivers/power/Kconfig | |||
@@ -152,6 +152,7 @@ config BATTERY_SBS | |||
152 | 152 | ||
153 | config BATTERY_BQ27x00 | 153 | config BATTERY_BQ27x00 |
154 | tristate "BQ27x00 battery driver" | 154 | tristate "BQ27x00 battery driver" |
155 | depends on I2C || I2C=n | ||
155 | help | 156 | help |
156 | Say Y here to enable support for batteries with BQ27x00 (I2C/HDQ) chips. | 157 | Say Y here to enable support for batteries with BQ27x00 (I2C/HDQ) chips. |
157 | 158 | ||
@@ -284,6 +285,7 @@ config CHARGER_LP8788 | |||
284 | tristate "TI LP8788 charger driver" | 285 | tristate "TI LP8788 charger driver" |
285 | depends on MFD_LP8788 | 286 | depends on MFD_LP8788 |
286 | depends on LP8788_ADC | 287 | depends on LP8788_ADC |
288 | depends on IIO | ||
287 | help | 289 | help |
288 | Say Y to enable support for the LP8788 linear charger. | 290 | Say Y to enable support for the LP8788 linear charger. |
289 | 291 | ||
diff --git a/drivers/power/pm2301_charger.c b/drivers/power/pm2301_charger.c index a44175139bbf..fef56e2041b3 100644 --- a/drivers/power/pm2301_charger.c +++ b/drivers/power/pm2301_charger.c | |||
@@ -1269,5 +1269,5 @@ module_exit(pm2xxx_charger_exit); | |||
1269 | 1269 | ||
1270 | MODULE_LICENSE("GPL v2"); | 1270 | MODULE_LICENSE("GPL v2"); |
1271 | MODULE_AUTHOR("Rajkumar kasirajan, Olivier Launay"); | 1271 | MODULE_AUTHOR("Rajkumar kasirajan, Olivier Launay"); |
1272 | MODULE_ALIAS("platform:pm2xxx-charger"); | 1272 | MODULE_ALIAS("i2c:pm2xxx-charger"); |
1273 | MODULE_DESCRIPTION("PM2xxx charger management driver"); | 1273 | MODULE_DESCRIPTION("PM2xxx charger management driver"); |
diff --git a/drivers/power/wm831x_backup.c b/drivers/power/wm831x_backup.c index 58cbb009b74f..56fb509f4be0 100644 --- a/drivers/power/wm831x_backup.c +++ b/drivers/power/wm831x_backup.c | |||
@@ -207,7 +207,6 @@ static int wm831x_backup_remove(struct platform_device *pdev) | |||
207 | struct wm831x_backup *devdata = platform_get_drvdata(pdev); | 207 | struct wm831x_backup *devdata = platform_get_drvdata(pdev); |
208 | 208 | ||
209 | power_supply_unregister(&devdata->backup); | 209 | power_supply_unregister(&devdata->backup); |
210 | kfree(devdata->backup.name); | ||
211 | 210 | ||
212 | return 0; | 211 | return 0; |
213 | } | 212 | } |
diff --git a/drivers/rapidio/Kconfig b/drivers/rapidio/Kconfig index 6194d35ebb97..5ab056494bbe 100644 --- a/drivers/rapidio/Kconfig +++ b/drivers/rapidio/Kconfig | |||
@@ -47,4 +47,24 @@ config RAPIDIO_DEBUG | |||
47 | 47 | ||
48 | If you are unsure about this, say N here. | 48 | If you are unsure about this, say N here. |
49 | 49 | ||
50 | choice | ||
51 | prompt "Enumeration method" | ||
52 | depends on RAPIDIO | ||
53 | default RAPIDIO_ENUM_BASIC | ||
54 | help | ||
55 | There are different enumeration and discovery mechanisms offered | ||
56 | for RapidIO subsystem. You may select single built-in method or | ||
57 | or any number of methods to be built as modules. | ||
58 | Selecting a built-in method disables use of loadable methods. | ||
59 | |||
60 | If unsure, select Basic built-in. | ||
61 | |||
62 | config RAPIDIO_ENUM_BASIC | ||
63 | tristate "Basic" | ||
64 | help | ||
65 | This option includes basic RapidIO fabric enumeration and discovery | ||
66 | mechanism similar to one described in RapidIO specification Annex 1. | ||
67 | |||
68 | endchoice | ||
69 | |||
50 | source "drivers/rapidio/switches/Kconfig" | 70 | source "drivers/rapidio/switches/Kconfig" |
diff --git a/drivers/rapidio/Makefile b/drivers/rapidio/Makefile index ec3fb8121004..3036702ffe8b 100644 --- a/drivers/rapidio/Makefile +++ b/drivers/rapidio/Makefile | |||
@@ -1,7 +1,8 @@ | |||
1 | # | 1 | # |
2 | # Makefile for RapidIO interconnect services | 2 | # Makefile for RapidIO interconnect services |
3 | # | 3 | # |
4 | obj-y += rio.o rio-access.o rio-driver.o rio-scan.o rio-sysfs.o | 4 | obj-y += rio.o rio-access.o rio-driver.o rio-sysfs.o |
5 | obj-$(CONFIG_RAPIDIO_ENUM_BASIC) += rio-scan.o | ||
5 | 6 | ||
6 | obj-$(CONFIG_RAPIDIO) += switches/ | 7 | obj-$(CONFIG_RAPIDIO) += switches/ |
7 | obj-$(CONFIG_RAPIDIO) += devices/ | 8 | obj-$(CONFIG_RAPIDIO) += devices/ |
diff --git a/drivers/rapidio/devices/tsi721.c b/drivers/rapidio/devices/tsi721.c index 6faba406b6e9..a8b2c23a7ef4 100644 --- a/drivers/rapidio/devices/tsi721.c +++ b/drivers/rapidio/devices/tsi721.c | |||
@@ -471,6 +471,10 @@ static irqreturn_t tsi721_irqhandler(int irq, void *ptr) | |||
471 | u32 intval; | 471 | u32 intval; |
472 | u32 ch_inte; | 472 | u32 ch_inte; |
473 | 473 | ||
474 | /* For MSI mode disable all device-level interrupts */ | ||
475 | if (priv->flags & TSI721_USING_MSI) | ||
476 | iowrite32(0, priv->regs + TSI721_DEV_INTE); | ||
477 | |||
474 | dev_int = ioread32(priv->regs + TSI721_DEV_INT); | 478 | dev_int = ioread32(priv->regs + TSI721_DEV_INT); |
475 | if (!dev_int) | 479 | if (!dev_int) |
476 | return IRQ_NONE; | 480 | return IRQ_NONE; |
@@ -560,6 +564,14 @@ static irqreturn_t tsi721_irqhandler(int irq, void *ptr) | |||
560 | } | 564 | } |
561 | } | 565 | } |
562 | #endif | 566 | #endif |
567 | |||
568 | /* For MSI mode re-enable device-level interrupts */ | ||
569 | if (priv->flags & TSI721_USING_MSI) { | ||
570 | dev_int = TSI721_DEV_INT_SR2PC_CH | TSI721_DEV_INT_SRIO | | ||
571 | TSI721_DEV_INT_SMSG_CH | TSI721_DEV_INT_BDMA_CH; | ||
572 | iowrite32(dev_int, priv->regs + TSI721_DEV_INTE); | ||
573 | } | ||
574 | |||
563 | return IRQ_HANDLED; | 575 | return IRQ_HANDLED; |
564 | } | 576 | } |
565 | 577 | ||
diff --git a/drivers/rapidio/rio-driver.c b/drivers/rapidio/rio-driver.c index 0f4a53bdaa3c..a0c875563d76 100644 --- a/drivers/rapidio/rio-driver.c +++ b/drivers/rapidio/rio-driver.c | |||
@@ -164,6 +164,13 @@ void rio_unregister_driver(struct rio_driver *rdrv) | |||
164 | driver_unregister(&rdrv->driver); | 164 | driver_unregister(&rdrv->driver); |
165 | } | 165 | } |
166 | 166 | ||
167 | void rio_attach_device(struct rio_dev *rdev) | ||
168 | { | ||
169 | rdev->dev.bus = &rio_bus_type; | ||
170 | rdev->dev.parent = &rio_bus; | ||
171 | } | ||
172 | EXPORT_SYMBOL_GPL(rio_attach_device); | ||
173 | |||
167 | /** | 174 | /** |
168 | * rio_match_bus - Tell if a RIO device structure has a matching RIO driver device id structure | 175 | * rio_match_bus - Tell if a RIO device structure has a matching RIO driver device id structure |
169 | * @dev: the standard device structure to match against | 176 | * @dev: the standard device structure to match against |
@@ -200,6 +207,7 @@ struct bus_type rio_bus_type = { | |||
200 | .name = "rapidio", | 207 | .name = "rapidio", |
201 | .match = rio_match_bus, | 208 | .match = rio_match_bus, |
202 | .dev_attrs = rio_dev_attrs, | 209 | .dev_attrs = rio_dev_attrs, |
210 | .bus_attrs = rio_bus_attrs, | ||
203 | .probe = rio_device_probe, | 211 | .probe = rio_device_probe, |
204 | .remove = rio_device_remove, | 212 | .remove = rio_device_remove, |
205 | }; | 213 | }; |
diff --git a/drivers/rapidio/rio-scan.c b/drivers/rapidio/rio-scan.c index a965acd3c0e4..4c15dbf81087 100644 --- a/drivers/rapidio/rio-scan.c +++ b/drivers/rapidio/rio-scan.c | |||
@@ -37,12 +37,8 @@ | |||
37 | 37 | ||
38 | #include "rio.h" | 38 | #include "rio.h" |
39 | 39 | ||
40 | LIST_HEAD(rio_devices); | ||
41 | |||
42 | static void rio_init_em(struct rio_dev *rdev); | 40 | static void rio_init_em(struct rio_dev *rdev); |
43 | 41 | ||
44 | DEFINE_SPINLOCK(rio_global_list_lock); | ||
45 | |||
46 | static int next_destid = 0; | 42 | static int next_destid = 0; |
47 | static int next_comptag = 1; | 43 | static int next_comptag = 1; |
48 | 44 | ||
@@ -327,127 +323,6 @@ static int rio_is_switch(struct rio_dev *rdev) | |||
327 | } | 323 | } |
328 | 324 | ||
329 | /** | 325 | /** |
330 | * rio_switch_init - Sets switch operations for a particular vendor switch | ||
331 | * @rdev: RIO device | ||
332 | * @do_enum: Enumeration/Discovery mode flag | ||
333 | * | ||
334 | * Searches the RIO switch ops table for known switch types. If the vid | ||
335 | * and did match a switch table entry, then call switch initialization | ||
336 | * routine to setup switch-specific routines. | ||
337 | */ | ||
338 | static void rio_switch_init(struct rio_dev *rdev, int do_enum) | ||
339 | { | ||
340 | struct rio_switch_ops *cur = __start_rio_switch_ops; | ||
341 | struct rio_switch_ops *end = __end_rio_switch_ops; | ||
342 | |||
343 | while (cur < end) { | ||
344 | if ((cur->vid == rdev->vid) && (cur->did == rdev->did)) { | ||
345 | pr_debug("RIO: calling init routine for %s\n", | ||
346 | rio_name(rdev)); | ||
347 | cur->init_hook(rdev, do_enum); | ||
348 | break; | ||
349 | } | ||
350 | cur++; | ||
351 | } | ||
352 | |||
353 | if ((cur >= end) && (rdev->pef & RIO_PEF_STD_RT)) { | ||
354 | pr_debug("RIO: adding STD routing ops for %s\n", | ||
355 | rio_name(rdev)); | ||
356 | rdev->rswitch->add_entry = rio_std_route_add_entry; | ||
357 | rdev->rswitch->get_entry = rio_std_route_get_entry; | ||
358 | rdev->rswitch->clr_table = rio_std_route_clr_table; | ||
359 | } | ||
360 | |||
361 | if (!rdev->rswitch->add_entry || !rdev->rswitch->get_entry) | ||
362 | printk(KERN_ERR "RIO: missing routing ops for %s\n", | ||
363 | rio_name(rdev)); | ||
364 | } | ||
365 | |||
366 | /** | ||
367 | * rio_add_device- Adds a RIO device to the device model | ||
368 | * @rdev: RIO device | ||
369 | * | ||
370 | * Adds the RIO device to the global device list and adds the RIO | ||
371 | * device to the RIO device list. Creates the generic sysfs nodes | ||
372 | * for an RIO device. | ||
373 | */ | ||
374 | static int rio_add_device(struct rio_dev *rdev) | ||
375 | { | ||
376 | int err; | ||
377 | |||
378 | err = device_add(&rdev->dev); | ||
379 | if (err) | ||
380 | return err; | ||
381 | |||
382 | spin_lock(&rio_global_list_lock); | ||
383 | list_add_tail(&rdev->global_list, &rio_devices); | ||
384 | spin_unlock(&rio_global_list_lock); | ||
385 | |||
386 | rio_create_sysfs_dev_files(rdev); | ||
387 | |||
388 | return 0; | ||
389 | } | ||
390 | |||
391 | /** | ||
392 | * rio_enable_rx_tx_port - enable input receiver and output transmitter of | ||
393 | * given port | ||
394 | * @port: Master port associated with the RIO network | ||
395 | * @local: local=1 select local port otherwise a far device is reached | ||
396 | * @destid: Destination ID of the device to check host bit | ||
397 | * @hopcount: Number of hops to reach the target | ||
398 | * @port_num: Port (-number on switch) to enable on a far end device | ||
399 | * | ||
400 | * Returns 0 or 1 from on General Control Command and Status Register | ||
401 | * (EXT_PTR+0x3C) | ||
402 | */ | ||
403 | inline int rio_enable_rx_tx_port(struct rio_mport *port, | ||
404 | int local, u16 destid, | ||
405 | u8 hopcount, u8 port_num) { | ||
406 | #ifdef CONFIG_RAPIDIO_ENABLE_RX_TX_PORTS | ||
407 | u32 regval; | ||
408 | u32 ext_ftr_ptr; | ||
409 | |||
410 | /* | ||
411 | * enable rx input tx output port | ||
412 | */ | ||
413 | pr_debug("rio_enable_rx_tx_port(local = %d, destid = %d, hopcount = " | ||
414 | "%d, port_num = %d)\n", local, destid, hopcount, port_num); | ||
415 | |||
416 | ext_ftr_ptr = rio_mport_get_physefb(port, local, destid, hopcount); | ||
417 | |||
418 | if (local) { | ||
419 | rio_local_read_config_32(port, ext_ftr_ptr + | ||
420 | RIO_PORT_N_CTL_CSR(0), | ||
421 | ®val); | ||
422 | } else { | ||
423 | if (rio_mport_read_config_32(port, destid, hopcount, | ||
424 | ext_ftr_ptr + RIO_PORT_N_CTL_CSR(port_num), ®val) < 0) | ||
425 | return -EIO; | ||
426 | } | ||
427 | |||
428 | if (regval & RIO_PORT_N_CTL_P_TYP_SER) { | ||
429 | /* serial */ | ||
430 | regval = regval | RIO_PORT_N_CTL_EN_RX_SER | ||
431 | | RIO_PORT_N_CTL_EN_TX_SER; | ||
432 | } else { | ||
433 | /* parallel */ | ||
434 | regval = regval | RIO_PORT_N_CTL_EN_RX_PAR | ||
435 | | RIO_PORT_N_CTL_EN_TX_PAR; | ||
436 | } | ||
437 | |||
438 | if (local) { | ||
439 | rio_local_write_config_32(port, ext_ftr_ptr + | ||
440 | RIO_PORT_N_CTL_CSR(0), regval); | ||
441 | } else { | ||
442 | if (rio_mport_write_config_32(port, destid, hopcount, | ||
443 | ext_ftr_ptr + RIO_PORT_N_CTL_CSR(port_num), regval) < 0) | ||
444 | return -EIO; | ||
445 | } | ||
446 | #endif | ||
447 | return 0; | ||
448 | } | ||
449 | |||
450 | /** | ||
451 | * rio_setup_device- Allocates and sets up a RIO device | 326 | * rio_setup_device- Allocates and sets up a RIO device |
452 | * @net: RIO network | 327 | * @net: RIO network |
453 | * @port: Master port to send transactions | 328 | * @port: Master port to send transactions |
@@ -587,8 +462,7 @@ static struct rio_dev *rio_setup_device(struct rio_net *net, | |||
587 | rdev->destid); | 462 | rdev->destid); |
588 | } | 463 | } |
589 | 464 | ||
590 | rdev->dev.bus = &rio_bus_type; | 465 | rio_attach_device(rdev); |
591 | rdev->dev.parent = &rio_bus; | ||
592 | 466 | ||
593 | device_initialize(&rdev->dev); | 467 | device_initialize(&rdev->dev); |
594 | rdev->dev.release = rio_release_dev; | 468 | rdev->dev.release = rio_release_dev; |
@@ -1260,19 +1134,30 @@ static void rio_pw_enable(struct rio_mport *port, int enable) | |||
1260 | /** | 1134 | /** |
1261 | * rio_enum_mport- Start enumeration through a master port | 1135 | * rio_enum_mport- Start enumeration through a master port |
1262 | * @mport: Master port to send transactions | 1136 | * @mport: Master port to send transactions |
1137 | * @flags: Enumeration control flags | ||
1263 | * | 1138 | * |
1264 | * Starts the enumeration process. If somebody has enumerated our | 1139 | * Starts the enumeration process. If somebody has enumerated our |
1265 | * master port device, then give up. If not and we have an active | 1140 | * master port device, then give up. If not and we have an active |
1266 | * link, then start recursive peer enumeration. Returns %0 if | 1141 | * link, then start recursive peer enumeration. Returns %0 if |
1267 | * enumeration succeeds or %-EBUSY if enumeration fails. | 1142 | * enumeration succeeds or %-EBUSY if enumeration fails. |
1268 | */ | 1143 | */ |
1269 | int rio_enum_mport(struct rio_mport *mport) | 1144 | int rio_enum_mport(struct rio_mport *mport, u32 flags) |
1270 | { | 1145 | { |
1271 | struct rio_net *net = NULL; | 1146 | struct rio_net *net = NULL; |
1272 | int rc = 0; | 1147 | int rc = 0; |
1273 | 1148 | ||
1274 | printk(KERN_INFO "RIO: enumerate master port %d, %s\n", mport->id, | 1149 | printk(KERN_INFO "RIO: enumerate master port %d, %s\n", mport->id, |
1275 | mport->name); | 1150 | mport->name); |
1151 | |||
1152 | /* | ||
1153 | * To avoid multiple start requests (repeat enumeration is not supported | ||
1154 | * by this method) check if enumeration/discovery was performed for this | ||
1155 | * mport: if mport was added into the list of mports for a net exit | ||
1156 | * with error. | ||
1157 | */ | ||
1158 | if (mport->nnode.next || mport->nnode.prev) | ||
1159 | return -EBUSY; | ||
1160 | |||
1276 | /* If somebody else enumerated our master port device, bail. */ | 1161 | /* If somebody else enumerated our master port device, bail. */ |
1277 | if (rio_enum_host(mport) < 0) { | 1162 | if (rio_enum_host(mport) < 0) { |
1278 | printk(KERN_INFO | 1163 | printk(KERN_INFO |
@@ -1362,14 +1247,16 @@ static void rio_build_route_tables(struct rio_net *net) | |||
1362 | /** | 1247 | /** |
1363 | * rio_disc_mport- Start discovery through a master port | 1248 | * rio_disc_mport- Start discovery through a master port |
1364 | * @mport: Master port to send transactions | 1249 | * @mport: Master port to send transactions |
1250 | * @flags: discovery control flags | ||
1365 | * | 1251 | * |
1366 | * Starts the discovery process. If we have an active link, | 1252 | * Starts the discovery process. If we have an active link, |
1367 | * then wait for the signal that enumeration is complete. | 1253 | * then wait for the signal that enumeration is complete (if wait |
1254 | * is allowed). | ||
1368 | * When enumeration completion is signaled, start recursive | 1255 | * When enumeration completion is signaled, start recursive |
1369 | * peer discovery. Returns %0 if discovery succeeds or %-EBUSY | 1256 | * peer discovery. Returns %0 if discovery succeeds or %-EBUSY |
1370 | * on failure. | 1257 | * on failure. |
1371 | */ | 1258 | */ |
1372 | int rio_disc_mport(struct rio_mport *mport) | 1259 | int rio_disc_mport(struct rio_mport *mport, u32 flags) |
1373 | { | 1260 | { |
1374 | struct rio_net *net = NULL; | 1261 | struct rio_net *net = NULL; |
1375 | unsigned long to_end; | 1262 | unsigned long to_end; |
@@ -1379,6 +1266,11 @@ int rio_disc_mport(struct rio_mport *mport) | |||
1379 | 1266 | ||
1380 | /* If master port has an active link, allocate net and discover peers */ | 1267 | /* If master port has an active link, allocate net and discover peers */ |
1381 | if (rio_mport_is_active(mport)) { | 1268 | if (rio_mport_is_active(mport)) { |
1269 | if (rio_enum_complete(mport)) | ||
1270 | goto enum_done; | ||
1271 | else if (flags & RIO_SCAN_ENUM_NO_WAIT) | ||
1272 | return -EAGAIN; | ||
1273 | |||
1382 | pr_debug("RIO: wait for enumeration to complete...\n"); | 1274 | pr_debug("RIO: wait for enumeration to complete...\n"); |
1383 | 1275 | ||
1384 | to_end = jiffies + CONFIG_RAPIDIO_DISC_TIMEOUT * HZ; | 1276 | to_end = jiffies + CONFIG_RAPIDIO_DISC_TIMEOUT * HZ; |
@@ -1421,3 +1313,41 @@ enum_done: | |||
1421 | bail: | 1313 | bail: |
1422 | return -EBUSY; | 1314 | return -EBUSY; |
1423 | } | 1315 | } |
1316 | |||
1317 | static struct rio_scan rio_scan_ops = { | ||
1318 | .enumerate = rio_enum_mport, | ||
1319 | .discover = rio_disc_mport, | ||
1320 | }; | ||
1321 | |||
1322 | static bool scan; | ||
1323 | module_param(scan, bool, 0); | ||
1324 | MODULE_PARM_DESC(scan, "Start RapidIO network enumeration/discovery " | ||
1325 | "(default = 0)"); | ||
1326 | |||
1327 | /** | ||
1328 | * rio_basic_attach: | ||
1329 | * | ||
1330 | * When this enumeration/discovery method is loaded as a module this function | ||
1331 | * registers its specific enumeration and discover routines for all available | ||
1332 | * RapidIO mport devices. The "scan" command line parameter controls ability of | ||
1333 | * the module to start RapidIO enumeration/discovery automatically. | ||
1334 | * | ||
1335 | * Returns 0 for success or -EIO if unable to register itself. | ||
1336 | * | ||
1337 | * This enumeration/discovery method cannot be unloaded and therefore does not | ||
1338 | * provide a matching cleanup_module routine. | ||
1339 | */ | ||
1340 | |||
1341 | static int __init rio_basic_attach(void) | ||
1342 | { | ||
1343 | if (rio_register_scan(RIO_MPORT_ANY, &rio_scan_ops)) | ||
1344 | return -EIO; | ||
1345 | if (scan) | ||
1346 | rio_init_mports(); | ||
1347 | return 0; | ||
1348 | } | ||
1349 | |||
1350 | late_initcall(rio_basic_attach); | ||
1351 | |||
1352 | MODULE_DESCRIPTION("Basic RapidIO enumeration/discovery"); | ||
1353 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/rapidio/rio-sysfs.c b/drivers/rapidio/rio-sysfs.c index 4dbe360989be..66d4acd5e18f 100644 --- a/drivers/rapidio/rio-sysfs.c +++ b/drivers/rapidio/rio-sysfs.c | |||
@@ -285,3 +285,48 @@ void rio_remove_sysfs_dev_files(struct rio_dev *rdev) | |||
285 | rdev->rswitch->sw_sysfs(rdev, RIO_SW_SYSFS_REMOVE); | 285 | rdev->rswitch->sw_sysfs(rdev, RIO_SW_SYSFS_REMOVE); |
286 | } | 286 | } |
287 | } | 287 | } |
288 | |||
289 | static ssize_t bus_scan_store(struct bus_type *bus, const char *buf, | ||
290 | size_t count) | ||
291 | { | ||
292 | long val; | ||
293 | struct rio_mport *port = NULL; | ||
294 | int rc; | ||
295 | |||
296 | if (kstrtol(buf, 0, &val) < 0) | ||
297 | return -EINVAL; | ||
298 | |||
299 | if (val == RIO_MPORT_ANY) { | ||
300 | rc = rio_init_mports(); | ||
301 | goto exit; | ||
302 | } | ||
303 | |||
304 | if (val < 0 || val >= RIO_MAX_MPORTS) | ||
305 | return -EINVAL; | ||
306 | |||
307 | port = rio_find_mport((int)val); | ||
308 | |||
309 | if (!port) { | ||
310 | pr_debug("RIO: %s: mport_%d not available\n", | ||
311 | __func__, (int)val); | ||
312 | return -EINVAL; | ||
313 | } | ||
314 | |||
315 | if (!port->nscan) | ||
316 | return -EINVAL; | ||
317 | |||
318 | if (port->host_deviceid >= 0) | ||
319 | rc = port->nscan->enumerate(port, 0); | ||
320 | else | ||
321 | rc = port->nscan->discover(port, RIO_SCAN_ENUM_NO_WAIT); | ||
322 | exit: | ||
323 | if (!rc) | ||
324 | rc = count; | ||
325 | |||
326 | return rc; | ||
327 | } | ||
328 | |||
329 | struct bus_attribute rio_bus_attrs[] = { | ||
330 | __ATTR(scan, (S_IWUSR|S_IWGRP), NULL, bus_scan_store), | ||
331 | __ATTR_NULL | ||
332 | }; | ||
diff --git a/drivers/rapidio/rio.c b/drivers/rapidio/rio.c index d553b5d13722..cb1c08996fbb 100644 --- a/drivers/rapidio/rio.c +++ b/drivers/rapidio/rio.c | |||
@@ -31,7 +31,11 @@ | |||
31 | 31 | ||
32 | #include "rio.h" | 32 | #include "rio.h" |
33 | 33 | ||
34 | static LIST_HEAD(rio_devices); | ||
35 | static DEFINE_SPINLOCK(rio_global_list_lock); | ||
36 | |||
34 | static LIST_HEAD(rio_mports); | 37 | static LIST_HEAD(rio_mports); |
38 | static DEFINE_MUTEX(rio_mport_list_lock); | ||
35 | static unsigned char next_portid; | 39 | static unsigned char next_portid; |
36 | static DEFINE_SPINLOCK(rio_mmap_lock); | 40 | static DEFINE_SPINLOCK(rio_mmap_lock); |
37 | 41 | ||
@@ -53,6 +57,32 @@ u16 rio_local_get_device_id(struct rio_mport *port) | |||
53 | } | 57 | } |
54 | 58 | ||
55 | /** | 59 | /** |
60 | * rio_add_device- Adds a RIO device to the device model | ||
61 | * @rdev: RIO device | ||
62 | * | ||
63 | * Adds the RIO device to the global device list and adds the RIO | ||
64 | * device to the RIO device list. Creates the generic sysfs nodes | ||
65 | * for an RIO device. | ||
66 | */ | ||
67 | int rio_add_device(struct rio_dev *rdev) | ||
68 | { | ||
69 | int err; | ||
70 | |||
71 | err = device_add(&rdev->dev); | ||
72 | if (err) | ||
73 | return err; | ||
74 | |||
75 | spin_lock(&rio_global_list_lock); | ||
76 | list_add_tail(&rdev->global_list, &rio_devices); | ||
77 | spin_unlock(&rio_global_list_lock); | ||
78 | |||
79 | rio_create_sysfs_dev_files(rdev); | ||
80 | |||
81 | return 0; | ||
82 | } | ||
83 | EXPORT_SYMBOL_GPL(rio_add_device); | ||
84 | |||
85 | /** | ||
56 | * rio_request_inb_mbox - request inbound mailbox service | 86 | * rio_request_inb_mbox - request inbound mailbox service |
57 | * @mport: RIO master port from which to allocate the mailbox resource | 87 | * @mport: RIO master port from which to allocate the mailbox resource |
58 | * @dev_id: Device specific pointer to pass on event | 88 | * @dev_id: Device specific pointer to pass on event |
@@ -489,6 +519,7 @@ rio_mport_get_physefb(struct rio_mport *port, int local, | |||
489 | 519 | ||
490 | return ext_ftr_ptr; | 520 | return ext_ftr_ptr; |
491 | } | 521 | } |
522 | EXPORT_SYMBOL_GPL(rio_mport_get_physefb); | ||
492 | 523 | ||
493 | /** | 524 | /** |
494 | * rio_get_comptag - Begin or continue searching for a RIO device by component tag | 525 | * rio_get_comptag - Begin or continue searching for a RIO device by component tag |
@@ -521,6 +552,7 @@ exit: | |||
521 | spin_unlock(&rio_global_list_lock); | 552 | spin_unlock(&rio_global_list_lock); |
522 | return rdev; | 553 | return rdev; |
523 | } | 554 | } |
555 | EXPORT_SYMBOL_GPL(rio_get_comptag); | ||
524 | 556 | ||
525 | /** | 557 | /** |
526 | * rio_set_port_lockout - Sets/clears LOCKOUT bit (RIO EM 1.3) for a switch port. | 558 | * rio_set_port_lockout - Sets/clears LOCKOUT bit (RIO EM 1.3) for a switch port. |
@@ -545,6 +577,107 @@ int rio_set_port_lockout(struct rio_dev *rdev, u32 pnum, int lock) | |||
545 | regval); | 577 | regval); |
546 | return 0; | 578 | return 0; |
547 | } | 579 | } |
580 | EXPORT_SYMBOL_GPL(rio_set_port_lockout); | ||
581 | |||
582 | /** | ||
583 | * rio_switch_init - Sets switch operations for a particular vendor switch | ||
584 | * @rdev: RIO device | ||
585 | * @do_enum: Enumeration/Discovery mode flag | ||
586 | * | ||
587 | * Searches the RIO switch ops table for known switch types. If the vid | ||
588 | * and did match a switch table entry, then call switch initialization | ||
589 | * routine to setup switch-specific routines. | ||
590 | */ | ||
591 | void rio_switch_init(struct rio_dev *rdev, int do_enum) | ||
592 | { | ||
593 | struct rio_switch_ops *cur = __start_rio_switch_ops; | ||
594 | struct rio_switch_ops *end = __end_rio_switch_ops; | ||
595 | |||
596 | while (cur < end) { | ||
597 | if ((cur->vid == rdev->vid) && (cur->did == rdev->did)) { | ||
598 | pr_debug("RIO: calling init routine for %s\n", | ||
599 | rio_name(rdev)); | ||
600 | cur->init_hook(rdev, do_enum); | ||
601 | break; | ||
602 | } | ||
603 | cur++; | ||
604 | } | ||
605 | |||
606 | if ((cur >= end) && (rdev->pef & RIO_PEF_STD_RT)) { | ||
607 | pr_debug("RIO: adding STD routing ops for %s\n", | ||
608 | rio_name(rdev)); | ||
609 | rdev->rswitch->add_entry = rio_std_route_add_entry; | ||
610 | rdev->rswitch->get_entry = rio_std_route_get_entry; | ||
611 | rdev->rswitch->clr_table = rio_std_route_clr_table; | ||
612 | } | ||
613 | |||
614 | if (!rdev->rswitch->add_entry || !rdev->rswitch->get_entry) | ||
615 | printk(KERN_ERR "RIO: missing routing ops for %s\n", | ||
616 | rio_name(rdev)); | ||
617 | } | ||
618 | EXPORT_SYMBOL_GPL(rio_switch_init); | ||
619 | |||
620 | /** | ||
621 | * rio_enable_rx_tx_port - enable input receiver and output transmitter of | ||
622 | * given port | ||
623 | * @port: Master port associated with the RIO network | ||
624 | * @local: local=1 select local port otherwise a far device is reached | ||
625 | * @destid: Destination ID of the device to check host bit | ||
626 | * @hopcount: Number of hops to reach the target | ||
627 | * @port_num: Port (-number on switch) to enable on a far end device | ||
628 | * | ||
629 | * Returns 0 or 1 from on General Control Command and Status Register | ||
630 | * (EXT_PTR+0x3C) | ||
631 | */ | ||
632 | int rio_enable_rx_tx_port(struct rio_mport *port, | ||
633 | int local, u16 destid, | ||
634 | u8 hopcount, u8 port_num) | ||
635 | { | ||
636 | #ifdef CONFIG_RAPIDIO_ENABLE_RX_TX_PORTS | ||
637 | u32 regval; | ||
638 | u32 ext_ftr_ptr; | ||
639 | |||
640 | /* | ||
641 | * enable rx input tx output port | ||
642 | */ | ||
643 | pr_debug("rio_enable_rx_tx_port(local = %d, destid = %d, hopcount = " | ||
644 | "%d, port_num = %d)\n", local, destid, hopcount, port_num); | ||
645 | |||
646 | ext_ftr_ptr = rio_mport_get_physefb(port, local, destid, hopcount); | ||
647 | |||
648 | if (local) { | ||
649 | rio_local_read_config_32(port, ext_ftr_ptr + | ||
650 | RIO_PORT_N_CTL_CSR(0), | ||
651 | ®val); | ||
652 | } else { | ||
653 | if (rio_mport_read_config_32(port, destid, hopcount, | ||
654 | ext_ftr_ptr + RIO_PORT_N_CTL_CSR(port_num), ®val) < 0) | ||
655 | return -EIO; | ||
656 | } | ||
657 | |||
658 | if (regval & RIO_PORT_N_CTL_P_TYP_SER) { | ||
659 | /* serial */ | ||
660 | regval = regval | RIO_PORT_N_CTL_EN_RX_SER | ||
661 | | RIO_PORT_N_CTL_EN_TX_SER; | ||
662 | } else { | ||
663 | /* parallel */ | ||
664 | regval = regval | RIO_PORT_N_CTL_EN_RX_PAR | ||
665 | | RIO_PORT_N_CTL_EN_TX_PAR; | ||
666 | } | ||
667 | |||
668 | if (local) { | ||
669 | rio_local_write_config_32(port, ext_ftr_ptr + | ||
670 | RIO_PORT_N_CTL_CSR(0), regval); | ||
671 | } else { | ||
672 | if (rio_mport_write_config_32(port, destid, hopcount, | ||
673 | ext_ftr_ptr + RIO_PORT_N_CTL_CSR(port_num), regval) < 0) | ||
674 | return -EIO; | ||
675 | } | ||
676 | #endif | ||
677 | return 0; | ||
678 | } | ||
679 | EXPORT_SYMBOL_GPL(rio_enable_rx_tx_port); | ||
680 | |||
548 | 681 | ||
549 | /** | 682 | /** |
550 | * rio_chk_dev_route - Validate route to the specified device. | 683 | * rio_chk_dev_route - Validate route to the specified device. |
@@ -610,6 +743,7 @@ rio_mport_chk_dev_access(struct rio_mport *mport, u16 destid, u8 hopcount) | |||
610 | 743 | ||
611 | return 0; | 744 | return 0; |
612 | } | 745 | } |
746 | EXPORT_SYMBOL_GPL(rio_mport_chk_dev_access); | ||
613 | 747 | ||
614 | /** | 748 | /** |
615 | * rio_chk_dev_access - Validate access to the specified device. | 749 | * rio_chk_dev_access - Validate access to the specified device. |
@@ -941,6 +1075,7 @@ rio_mport_get_efb(struct rio_mport *port, int local, u16 destid, | |||
941 | return RIO_GET_BLOCK_ID(reg_val); | 1075 | return RIO_GET_BLOCK_ID(reg_val); |
942 | } | 1076 | } |
943 | } | 1077 | } |
1078 | EXPORT_SYMBOL_GPL(rio_mport_get_efb); | ||
944 | 1079 | ||
945 | /** | 1080 | /** |
946 | * rio_mport_get_feature - query for devices' extended features | 1081 | * rio_mport_get_feature - query for devices' extended features |
@@ -997,6 +1132,7 @@ rio_mport_get_feature(struct rio_mport * port, int local, u16 destid, | |||
997 | 1132 | ||
998 | return 0; | 1133 | return 0; |
999 | } | 1134 | } |
1135 | EXPORT_SYMBOL_GPL(rio_mport_get_feature); | ||
1000 | 1136 | ||
1001 | /** | 1137 | /** |
1002 | * rio_get_asm - Begin or continue searching for a RIO device by vid/did/asm_vid/asm_did | 1138 | * rio_get_asm - Begin or continue searching for a RIO device by vid/did/asm_vid/asm_did |
@@ -1246,6 +1382,95 @@ EXPORT_SYMBOL_GPL(rio_dma_prep_slave_sg); | |||
1246 | 1382 | ||
1247 | #endif /* CONFIG_RAPIDIO_DMA_ENGINE */ | 1383 | #endif /* CONFIG_RAPIDIO_DMA_ENGINE */ |
1248 | 1384 | ||
1385 | /** | ||
1386 | * rio_find_mport - find RIO mport by its ID | ||
1387 | * @mport_id: number (ID) of mport device | ||
1388 | * | ||
1389 | * Given a RIO mport number, the desired mport is located | ||
1390 | * in the global list of mports. If the mport is found, a pointer to its | ||
1391 | * data structure is returned. If no mport is found, %NULL is returned. | ||
1392 | */ | ||
1393 | struct rio_mport *rio_find_mport(int mport_id) | ||
1394 | { | ||
1395 | struct rio_mport *port; | ||
1396 | |||
1397 | mutex_lock(&rio_mport_list_lock); | ||
1398 | list_for_each_entry(port, &rio_mports, node) { | ||
1399 | if (port->id == mport_id) | ||
1400 | goto found; | ||
1401 | } | ||
1402 | port = NULL; | ||
1403 | found: | ||
1404 | mutex_unlock(&rio_mport_list_lock); | ||
1405 | |||
1406 | return port; | ||
1407 | } | ||
1408 | |||
1409 | /** | ||
1410 | * rio_register_scan - enumeration/discovery method registration interface | ||
1411 | * @mport_id: mport device ID for which fabric scan routine has to be set | ||
1412 | * (RIO_MPORT_ANY = set for all available mports) | ||
1413 | * @scan_ops: enumeration/discovery control structure | ||
1414 | * | ||
1415 | * Assigns enumeration or discovery method to the specified mport device (or all | ||
1416 | * available mports if RIO_MPORT_ANY is specified). | ||
1417 | * Returns error if the mport already has an enumerator attached to it. | ||
1418 | * In case of RIO_MPORT_ANY ignores ports with valid scan routines and returns | ||
1419 | * an error if was unable to find at least one available mport. | ||
1420 | */ | ||
1421 | int rio_register_scan(int mport_id, struct rio_scan *scan_ops) | ||
1422 | { | ||
1423 | struct rio_mport *port; | ||
1424 | int rc = -EBUSY; | ||
1425 | |||
1426 | mutex_lock(&rio_mport_list_lock); | ||
1427 | list_for_each_entry(port, &rio_mports, node) { | ||
1428 | if (port->id == mport_id || mport_id == RIO_MPORT_ANY) { | ||
1429 | if (port->nscan && mport_id == RIO_MPORT_ANY) | ||
1430 | continue; | ||
1431 | else if (port->nscan) | ||
1432 | break; | ||
1433 | |||
1434 | port->nscan = scan_ops; | ||
1435 | rc = 0; | ||
1436 | |||
1437 | if (mport_id != RIO_MPORT_ANY) | ||
1438 | break; | ||
1439 | } | ||
1440 | } | ||
1441 | mutex_unlock(&rio_mport_list_lock); | ||
1442 | |||
1443 | return rc; | ||
1444 | } | ||
1445 | EXPORT_SYMBOL_GPL(rio_register_scan); | ||
1446 | |||
1447 | /** | ||
1448 | * rio_unregister_scan - removes enumeration/discovery method from mport | ||
1449 | * @mport_id: mport device ID for which fabric scan routine has to be | ||
1450 | * unregistered (RIO_MPORT_ANY = set for all available mports) | ||
1451 | * | ||
1452 | * Removes enumeration or discovery method assigned to the specified mport | ||
1453 | * device (or all available mports if RIO_MPORT_ANY is specified). | ||
1454 | */ | ||
1455 | int rio_unregister_scan(int mport_id) | ||
1456 | { | ||
1457 | struct rio_mport *port; | ||
1458 | |||
1459 | mutex_lock(&rio_mport_list_lock); | ||
1460 | list_for_each_entry(port, &rio_mports, node) { | ||
1461 | if (port->id == mport_id || mport_id == RIO_MPORT_ANY) { | ||
1462 | if (port->nscan) | ||
1463 | port->nscan = NULL; | ||
1464 | if (mport_id != RIO_MPORT_ANY) | ||
1465 | break; | ||
1466 | } | ||
1467 | } | ||
1468 | mutex_unlock(&rio_mport_list_lock); | ||
1469 | |||
1470 | return 0; | ||
1471 | } | ||
1472 | EXPORT_SYMBOL_GPL(rio_unregister_scan); | ||
1473 | |||
1249 | static void rio_fixup_device(struct rio_dev *dev) | 1474 | static void rio_fixup_device(struct rio_dev *dev) |
1250 | { | 1475 | { |
1251 | } | 1476 | } |
@@ -1274,7 +1499,7 @@ static void disc_work_handler(struct work_struct *_work) | |||
1274 | work = container_of(_work, struct rio_disc_work, work); | 1499 | work = container_of(_work, struct rio_disc_work, work); |
1275 | pr_debug("RIO: discovery work for mport %d %s\n", | 1500 | pr_debug("RIO: discovery work for mport %d %s\n", |
1276 | work->mport->id, work->mport->name); | 1501 | work->mport->id, work->mport->name); |
1277 | rio_disc_mport(work->mport); | 1502 | work->mport->nscan->discover(work->mport, 0); |
1278 | } | 1503 | } |
1279 | 1504 | ||
1280 | int rio_init_mports(void) | 1505 | int rio_init_mports(void) |
@@ -1290,12 +1515,15 @@ int rio_init_mports(void) | |||
1290 | * First, run enumerations and check if we need to perform discovery | 1515 | * First, run enumerations and check if we need to perform discovery |
1291 | * on any of the registered mports. | 1516 | * on any of the registered mports. |
1292 | */ | 1517 | */ |
1518 | mutex_lock(&rio_mport_list_lock); | ||
1293 | list_for_each_entry(port, &rio_mports, node) { | 1519 | list_for_each_entry(port, &rio_mports, node) { |
1294 | if (port->host_deviceid >= 0) | 1520 | if (port->host_deviceid >= 0) { |
1295 | rio_enum_mport(port); | 1521 | if (port->nscan) |
1296 | else | 1522 | port->nscan->enumerate(port, 0); |
1523 | } else | ||
1297 | n++; | 1524 | n++; |
1298 | } | 1525 | } |
1526 | mutex_unlock(&rio_mport_list_lock); | ||
1299 | 1527 | ||
1300 | if (!n) | 1528 | if (!n) |
1301 | goto no_disc; | 1529 | goto no_disc; |
@@ -1322,14 +1550,16 @@ int rio_init_mports(void) | |||
1322 | } | 1550 | } |
1323 | 1551 | ||
1324 | n = 0; | 1552 | n = 0; |
1553 | mutex_lock(&rio_mport_list_lock); | ||
1325 | list_for_each_entry(port, &rio_mports, node) { | 1554 | list_for_each_entry(port, &rio_mports, node) { |
1326 | if (port->host_deviceid < 0) { | 1555 | if (port->host_deviceid < 0 && port->nscan) { |
1327 | work[n].mport = port; | 1556 | work[n].mport = port; |
1328 | INIT_WORK(&work[n].work, disc_work_handler); | 1557 | INIT_WORK(&work[n].work, disc_work_handler); |
1329 | queue_work(rio_wq, &work[n].work); | 1558 | queue_work(rio_wq, &work[n].work); |
1330 | n++; | 1559 | n++; |
1331 | } | 1560 | } |
1332 | } | 1561 | } |
1562 | mutex_unlock(&rio_mport_list_lock); | ||
1333 | 1563 | ||
1334 | flush_workqueue(rio_wq); | 1564 | flush_workqueue(rio_wq); |
1335 | pr_debug("RIO: destroy discovery workqueue\n"); | 1565 | pr_debug("RIO: destroy discovery workqueue\n"); |
@@ -1342,8 +1572,6 @@ no_disc: | |||
1342 | return 0; | 1572 | return 0; |
1343 | } | 1573 | } |
1344 | 1574 | ||
1345 | device_initcall_sync(rio_init_mports); | ||
1346 | |||
1347 | static int hdids[RIO_MAX_MPORTS + 1]; | 1575 | static int hdids[RIO_MAX_MPORTS + 1]; |
1348 | 1576 | ||
1349 | static int rio_get_hdid(int index) | 1577 | static int rio_get_hdid(int index) |
@@ -1371,7 +1599,10 @@ int rio_register_mport(struct rio_mport *port) | |||
1371 | 1599 | ||
1372 | port->id = next_portid++; | 1600 | port->id = next_portid++; |
1373 | port->host_deviceid = rio_get_hdid(port->id); | 1601 | port->host_deviceid = rio_get_hdid(port->id); |
1602 | port->nscan = NULL; | ||
1603 | mutex_lock(&rio_mport_list_lock); | ||
1374 | list_add_tail(&port->node, &rio_mports); | 1604 | list_add_tail(&port->node, &rio_mports); |
1605 | mutex_unlock(&rio_mport_list_lock); | ||
1375 | return 0; | 1606 | return 0; |
1376 | } | 1607 | } |
1377 | 1608 | ||
@@ -1386,3 +1617,4 @@ EXPORT_SYMBOL_GPL(rio_request_inb_mbox); | |||
1386 | EXPORT_SYMBOL_GPL(rio_release_inb_mbox); | 1617 | EXPORT_SYMBOL_GPL(rio_release_inb_mbox); |
1387 | EXPORT_SYMBOL_GPL(rio_request_outb_mbox); | 1618 | EXPORT_SYMBOL_GPL(rio_request_outb_mbox); |
1388 | EXPORT_SYMBOL_GPL(rio_release_outb_mbox); | 1619 | EXPORT_SYMBOL_GPL(rio_release_outb_mbox); |
1620 | EXPORT_SYMBOL_GPL(rio_init_mports); | ||
diff --git a/drivers/rapidio/rio.h b/drivers/rapidio/rio.h index b1af414f15e6..c14f864dea5c 100644 --- a/drivers/rapidio/rio.h +++ b/drivers/rapidio/rio.h | |||
@@ -15,6 +15,7 @@ | |||
15 | #include <linux/rio.h> | 15 | #include <linux/rio.h> |
16 | 16 | ||
17 | #define RIO_MAX_CHK_RETRY 3 | 17 | #define RIO_MAX_CHK_RETRY 3 |
18 | #define RIO_MPORT_ANY (-1) | ||
18 | 19 | ||
19 | /* Functions internal to the RIO core code */ | 20 | /* Functions internal to the RIO core code */ |
20 | 21 | ||
@@ -27,8 +28,6 @@ extern u32 rio_mport_get_efb(struct rio_mport *port, int local, u16 destid, | |||
27 | extern int rio_mport_chk_dev_access(struct rio_mport *mport, u16 destid, | 28 | extern int rio_mport_chk_dev_access(struct rio_mport *mport, u16 destid, |
28 | u8 hopcount); | 29 | u8 hopcount); |
29 | extern int rio_create_sysfs_dev_files(struct rio_dev *rdev); | 30 | extern int rio_create_sysfs_dev_files(struct rio_dev *rdev); |
30 | extern int rio_enum_mport(struct rio_mport *mport); | ||
31 | extern int rio_disc_mport(struct rio_mport *mport); | ||
32 | extern int rio_std_route_add_entry(struct rio_mport *mport, u16 destid, | 31 | extern int rio_std_route_add_entry(struct rio_mport *mport, u16 destid, |
33 | u8 hopcount, u16 table, u16 route_destid, | 32 | u8 hopcount, u16 table, u16 route_destid, |
34 | u8 route_port); | 33 | u8 route_port); |
@@ -39,10 +38,18 @@ extern int rio_std_route_clr_table(struct rio_mport *mport, u16 destid, | |||
39 | u8 hopcount, u16 table); | 38 | u8 hopcount, u16 table); |
40 | extern int rio_set_port_lockout(struct rio_dev *rdev, u32 pnum, int lock); | 39 | extern int rio_set_port_lockout(struct rio_dev *rdev, u32 pnum, int lock); |
41 | extern struct rio_dev *rio_get_comptag(u32 comp_tag, struct rio_dev *from); | 40 | extern struct rio_dev *rio_get_comptag(u32 comp_tag, struct rio_dev *from); |
41 | extern int rio_add_device(struct rio_dev *rdev); | ||
42 | extern void rio_switch_init(struct rio_dev *rdev, int do_enum); | ||
43 | extern int rio_enable_rx_tx_port(struct rio_mport *port, int local, u16 destid, | ||
44 | u8 hopcount, u8 port_num); | ||
45 | extern int rio_register_scan(int mport_id, struct rio_scan *scan_ops); | ||
46 | extern int rio_unregister_scan(int mport_id); | ||
47 | extern void rio_attach_device(struct rio_dev *rdev); | ||
48 | extern struct rio_mport *rio_find_mport(int mport_id); | ||
42 | 49 | ||
43 | /* Structures internal to the RIO core code */ | 50 | /* Structures internal to the RIO core code */ |
44 | extern struct device_attribute rio_dev_attrs[]; | 51 | extern struct device_attribute rio_dev_attrs[]; |
45 | extern spinlock_t rio_global_list_lock; | 52 | extern struct bus_attribute rio_bus_attrs[]; |
46 | 53 | ||
47 | extern struct rio_switch_ops __start_rio_switch_ops[]; | 54 | extern struct rio_switch_ops __start_rio_switch_ops[]; |
48 | extern struct rio_switch_ops __end_rio_switch_ops[]; | 55 | extern struct rio_switch_ops __end_rio_switch_ops[]; |
diff --git a/drivers/rtc/rtc-max8998.c b/drivers/rtc/rtc-max8998.c index 48b6612fae7f..d5af7baa48b5 100644 --- a/drivers/rtc/rtc-max8998.c +++ b/drivers/rtc/rtc-max8998.c | |||
@@ -285,7 +285,7 @@ static int max8998_rtc_probe(struct platform_device *pdev) | |||
285 | info->irq, ret); | 285 | info->irq, ret); |
286 | 286 | ||
287 | dev_info(&pdev->dev, "RTC CHIP NAME: %s\n", pdev->id_entry->name); | 287 | dev_info(&pdev->dev, "RTC CHIP NAME: %s\n", pdev->id_entry->name); |
288 | if (pdata->rtc_delay) { | 288 | if (pdata && pdata->rtc_delay) { |
289 | info->lp3974_bug_workaround = true; | 289 | info->lp3974_bug_workaround = true; |
290 | dev_warn(&pdev->dev, "LP3974 with RTC REGERR option." | 290 | dev_warn(&pdev->dev, "LP3974 with RTC REGERR option." |
291 | " RTC updates will be extremely slow.\n"); | 291 | " RTC updates will be extremely slow.\n"); |
diff --git a/drivers/rtc/rtc-pl031.c b/drivers/rtc/rtc-pl031.c index 8900ea784817..0f0609b1aa2c 100644 --- a/drivers/rtc/rtc-pl031.c +++ b/drivers/rtc/rtc-pl031.c | |||
@@ -306,7 +306,7 @@ static int pl031_remove(struct amba_device *adev) | |||
306 | struct pl031_local *ldata = dev_get_drvdata(&adev->dev); | 306 | struct pl031_local *ldata = dev_get_drvdata(&adev->dev); |
307 | 307 | ||
308 | amba_set_drvdata(adev, NULL); | 308 | amba_set_drvdata(adev, NULL); |
309 | free_irq(adev->irq[0], ldata->rtc); | 309 | free_irq(adev->irq[0], ldata); |
310 | rtc_device_unregister(ldata->rtc); | 310 | rtc_device_unregister(ldata->rtc); |
311 | iounmap(ldata->base); | 311 | iounmap(ldata->base); |
312 | kfree(ldata); | 312 | kfree(ldata); |
diff --git a/drivers/scsi/qla2xxx/tcm_qla2xxx.c b/drivers/scsi/qla2xxx/tcm_qla2xxx.c index d182c96e17ea..7a3870f385f6 100644 --- a/drivers/scsi/qla2xxx/tcm_qla2xxx.c +++ b/drivers/scsi/qla2xxx/tcm_qla2xxx.c | |||
@@ -1370,7 +1370,7 @@ static void tcm_qla2xxx_free_session(struct qla_tgt_sess *sess) | |||
1370 | dump_stack(); | 1370 | dump_stack(); |
1371 | return; | 1371 | return; |
1372 | } | 1372 | } |
1373 | target_wait_for_sess_cmds(se_sess, 0); | 1373 | target_wait_for_sess_cmds(se_sess); |
1374 | 1374 | ||
1375 | transport_deregister_session_configfs(sess->se_sess); | 1375 | transport_deregister_session_configfs(sess->se_sess); |
1376 | transport_deregister_session(sess->se_sess); | 1376 | transport_deregister_session(sess->se_sess); |
diff --git a/drivers/scsi/scsi_proc.c b/drivers/scsi/scsi_proc.c index db66357211ed..86f0c5d5c116 100644 --- a/drivers/scsi/scsi_proc.c +++ b/drivers/scsi/scsi_proc.c | |||
@@ -84,6 +84,7 @@ static int proc_scsi_host_open(struct inode *inode, struct file *file) | |||
84 | 84 | ||
85 | static const struct file_operations proc_scsi_fops = { | 85 | static const struct file_operations proc_scsi_fops = { |
86 | .open = proc_scsi_host_open, | 86 | .open = proc_scsi_host_open, |
87 | .release = single_release, | ||
87 | .read = seq_read, | 88 | .read = seq_read, |
88 | .llseek = seq_lseek, | 89 | .llseek = seq_lseek, |
89 | .write = proc_scsi_host_write | 90 | .write = proc_scsi_host_write |
diff --git a/drivers/target/iscsi/iscsi_target.c b/drivers/target/iscsi/iscsi_target.c index 262ef1f23b38..d7705e5824fb 100644 --- a/drivers/target/iscsi/iscsi_target.c +++ b/drivers/target/iscsi/iscsi_target.c | |||
@@ -651,7 +651,7 @@ static int iscsit_add_reject( | |||
651 | cmd->buf_ptr = kmemdup(buf, ISCSI_HDR_LEN, GFP_KERNEL); | 651 | cmd->buf_ptr = kmemdup(buf, ISCSI_HDR_LEN, GFP_KERNEL); |
652 | if (!cmd->buf_ptr) { | 652 | if (!cmd->buf_ptr) { |
653 | pr_err("Unable to allocate memory for cmd->buf_ptr\n"); | 653 | pr_err("Unable to allocate memory for cmd->buf_ptr\n"); |
654 | iscsit_release_cmd(cmd); | 654 | iscsit_free_cmd(cmd, false); |
655 | return -1; | 655 | return -1; |
656 | } | 656 | } |
657 | 657 | ||
@@ -697,7 +697,7 @@ int iscsit_add_reject_from_cmd( | |||
697 | cmd->buf_ptr = kmemdup(buf, ISCSI_HDR_LEN, GFP_KERNEL); | 697 | cmd->buf_ptr = kmemdup(buf, ISCSI_HDR_LEN, GFP_KERNEL); |
698 | if (!cmd->buf_ptr) { | 698 | if (!cmd->buf_ptr) { |
699 | pr_err("Unable to allocate memory for cmd->buf_ptr\n"); | 699 | pr_err("Unable to allocate memory for cmd->buf_ptr\n"); |
700 | iscsit_release_cmd(cmd); | 700 | iscsit_free_cmd(cmd, false); |
701 | return -1; | 701 | return -1; |
702 | } | 702 | } |
703 | 703 | ||
@@ -1743,7 +1743,7 @@ int iscsit_handle_nop_out(struct iscsi_conn *conn, struct iscsi_cmd *cmd, | |||
1743 | return 0; | 1743 | return 0; |
1744 | out: | 1744 | out: |
1745 | if (cmd) | 1745 | if (cmd) |
1746 | iscsit_release_cmd(cmd); | 1746 | iscsit_free_cmd(cmd, false); |
1747 | ping_out: | 1747 | ping_out: |
1748 | kfree(ping_data); | 1748 | kfree(ping_data); |
1749 | return ret; | 1749 | return ret; |
@@ -2251,7 +2251,7 @@ iscsit_handle_logout_cmd(struct iscsi_conn *conn, struct iscsi_cmd *cmd, | |||
2251 | if (conn->conn_state != TARG_CONN_STATE_LOGGED_IN) { | 2251 | if (conn->conn_state != TARG_CONN_STATE_LOGGED_IN) { |
2252 | pr_err("Received logout request on connection that" | 2252 | pr_err("Received logout request on connection that" |
2253 | " is not in logged in state, ignoring request.\n"); | 2253 | " is not in logged in state, ignoring request.\n"); |
2254 | iscsit_release_cmd(cmd); | 2254 | iscsit_free_cmd(cmd, false); |
2255 | return 0; | 2255 | return 0; |
2256 | } | 2256 | } |
2257 | 2257 | ||
@@ -3665,7 +3665,7 @@ iscsit_immediate_queue(struct iscsi_conn *conn, struct iscsi_cmd *cmd, int state | |||
3665 | list_del(&cmd->i_conn_node); | 3665 | list_del(&cmd->i_conn_node); |
3666 | spin_unlock_bh(&conn->cmd_lock); | 3666 | spin_unlock_bh(&conn->cmd_lock); |
3667 | 3667 | ||
3668 | iscsit_free_cmd(cmd); | 3668 | iscsit_free_cmd(cmd, false); |
3669 | break; | 3669 | break; |
3670 | case ISTATE_SEND_NOPIN_WANT_RESPONSE: | 3670 | case ISTATE_SEND_NOPIN_WANT_RESPONSE: |
3671 | iscsit_mod_nopin_response_timer(conn); | 3671 | iscsit_mod_nopin_response_timer(conn); |
@@ -4122,7 +4122,7 @@ static void iscsit_release_commands_from_conn(struct iscsi_conn *conn) | |||
4122 | 4122 | ||
4123 | iscsit_increment_maxcmdsn(cmd, sess); | 4123 | iscsit_increment_maxcmdsn(cmd, sess); |
4124 | 4124 | ||
4125 | iscsit_free_cmd(cmd); | 4125 | iscsit_free_cmd(cmd, true); |
4126 | 4126 | ||
4127 | spin_lock_bh(&conn->cmd_lock); | 4127 | spin_lock_bh(&conn->cmd_lock); |
4128 | } | 4128 | } |
diff --git a/drivers/target/iscsi/iscsi_target_erl2.c b/drivers/target/iscsi/iscsi_target_erl2.c index ba6091bf93fc..45a5afd5ea13 100644 --- a/drivers/target/iscsi/iscsi_target_erl2.c +++ b/drivers/target/iscsi/iscsi_target_erl2.c | |||
@@ -143,7 +143,7 @@ void iscsit_free_connection_recovery_entires(struct iscsi_session *sess) | |||
143 | list_del(&cmd->i_conn_node); | 143 | list_del(&cmd->i_conn_node); |
144 | cmd->conn = NULL; | 144 | cmd->conn = NULL; |
145 | spin_unlock(&cr->conn_recovery_cmd_lock); | 145 | spin_unlock(&cr->conn_recovery_cmd_lock); |
146 | iscsit_free_cmd(cmd); | 146 | iscsit_free_cmd(cmd, true); |
147 | spin_lock(&cr->conn_recovery_cmd_lock); | 147 | spin_lock(&cr->conn_recovery_cmd_lock); |
148 | } | 148 | } |
149 | spin_unlock(&cr->conn_recovery_cmd_lock); | 149 | spin_unlock(&cr->conn_recovery_cmd_lock); |
@@ -165,7 +165,7 @@ void iscsit_free_connection_recovery_entires(struct iscsi_session *sess) | |||
165 | list_del(&cmd->i_conn_node); | 165 | list_del(&cmd->i_conn_node); |
166 | cmd->conn = NULL; | 166 | cmd->conn = NULL; |
167 | spin_unlock(&cr->conn_recovery_cmd_lock); | 167 | spin_unlock(&cr->conn_recovery_cmd_lock); |
168 | iscsit_free_cmd(cmd); | 168 | iscsit_free_cmd(cmd, true); |
169 | spin_lock(&cr->conn_recovery_cmd_lock); | 169 | spin_lock(&cr->conn_recovery_cmd_lock); |
170 | } | 170 | } |
171 | spin_unlock(&cr->conn_recovery_cmd_lock); | 171 | spin_unlock(&cr->conn_recovery_cmd_lock); |
@@ -248,7 +248,7 @@ void iscsit_discard_cr_cmds_by_expstatsn( | |||
248 | iscsit_remove_cmd_from_connection_recovery(cmd, sess); | 248 | iscsit_remove_cmd_from_connection_recovery(cmd, sess); |
249 | 249 | ||
250 | spin_unlock(&cr->conn_recovery_cmd_lock); | 250 | spin_unlock(&cr->conn_recovery_cmd_lock); |
251 | iscsit_free_cmd(cmd); | 251 | iscsit_free_cmd(cmd, true); |
252 | spin_lock(&cr->conn_recovery_cmd_lock); | 252 | spin_lock(&cr->conn_recovery_cmd_lock); |
253 | } | 253 | } |
254 | spin_unlock(&cr->conn_recovery_cmd_lock); | 254 | spin_unlock(&cr->conn_recovery_cmd_lock); |
@@ -302,7 +302,7 @@ int iscsit_discard_unacknowledged_ooo_cmdsns_for_conn(struct iscsi_conn *conn) | |||
302 | list_del(&cmd->i_conn_node); | 302 | list_del(&cmd->i_conn_node); |
303 | 303 | ||
304 | spin_unlock_bh(&conn->cmd_lock); | 304 | spin_unlock_bh(&conn->cmd_lock); |
305 | iscsit_free_cmd(cmd); | 305 | iscsit_free_cmd(cmd, true); |
306 | spin_lock_bh(&conn->cmd_lock); | 306 | spin_lock_bh(&conn->cmd_lock); |
307 | } | 307 | } |
308 | spin_unlock_bh(&conn->cmd_lock); | 308 | spin_unlock_bh(&conn->cmd_lock); |
@@ -355,7 +355,7 @@ int iscsit_prepare_cmds_for_realligance(struct iscsi_conn *conn) | |||
355 | 355 | ||
356 | list_del(&cmd->i_conn_node); | 356 | list_del(&cmd->i_conn_node); |
357 | spin_unlock_bh(&conn->cmd_lock); | 357 | spin_unlock_bh(&conn->cmd_lock); |
358 | iscsit_free_cmd(cmd); | 358 | iscsit_free_cmd(cmd, true); |
359 | spin_lock_bh(&conn->cmd_lock); | 359 | spin_lock_bh(&conn->cmd_lock); |
360 | continue; | 360 | continue; |
361 | } | 361 | } |
@@ -375,7 +375,7 @@ int iscsit_prepare_cmds_for_realligance(struct iscsi_conn *conn) | |||
375 | iscsi_sna_gte(cmd->cmd_sn, conn->sess->exp_cmd_sn)) { | 375 | iscsi_sna_gte(cmd->cmd_sn, conn->sess->exp_cmd_sn)) { |
376 | list_del(&cmd->i_conn_node); | 376 | list_del(&cmd->i_conn_node); |
377 | spin_unlock_bh(&conn->cmd_lock); | 377 | spin_unlock_bh(&conn->cmd_lock); |
378 | iscsit_free_cmd(cmd); | 378 | iscsit_free_cmd(cmd, true); |
379 | spin_lock_bh(&conn->cmd_lock); | 379 | spin_lock_bh(&conn->cmd_lock); |
380 | continue; | 380 | continue; |
381 | } | 381 | } |
diff --git a/drivers/target/iscsi/iscsi_target_parameters.c b/drivers/target/iscsi/iscsi_target_parameters.c index c2185fc31136..e38222191a33 100644 --- a/drivers/target/iscsi/iscsi_target_parameters.c +++ b/drivers/target/iscsi/iscsi_target_parameters.c | |||
@@ -758,9 +758,9 @@ static int iscsi_add_notunderstood_response( | |||
758 | } | 758 | } |
759 | INIT_LIST_HEAD(&extra_response->er_list); | 759 | INIT_LIST_HEAD(&extra_response->er_list); |
760 | 760 | ||
761 | strncpy(extra_response->key, key, strlen(key) + 1); | 761 | strlcpy(extra_response->key, key, sizeof(extra_response->key)); |
762 | strncpy(extra_response->value, NOTUNDERSTOOD, | 762 | strlcpy(extra_response->value, NOTUNDERSTOOD, |
763 | strlen(NOTUNDERSTOOD) + 1); | 763 | sizeof(extra_response->value)); |
764 | 764 | ||
765 | list_add_tail(&extra_response->er_list, | 765 | list_add_tail(&extra_response->er_list, |
766 | ¶m_list->extra_response_list); | 766 | ¶m_list->extra_response_list); |
@@ -1629,8 +1629,6 @@ int iscsi_decode_text_input( | |||
1629 | 1629 | ||
1630 | if (phase & PHASE_SECURITY) { | 1630 | if (phase & PHASE_SECURITY) { |
1631 | if (iscsi_check_for_auth_key(key) > 0) { | 1631 | if (iscsi_check_for_auth_key(key) > 0) { |
1632 | char *tmpptr = key + strlen(key); | ||
1633 | *tmpptr = '='; | ||
1634 | kfree(tmpbuf); | 1632 | kfree(tmpbuf); |
1635 | return 1; | 1633 | return 1; |
1636 | } | 1634 | } |
diff --git a/drivers/target/iscsi/iscsi_target_parameters.h b/drivers/target/iscsi/iscsi_target_parameters.h index 915b06798505..a47046a752aa 100644 --- a/drivers/target/iscsi/iscsi_target_parameters.h +++ b/drivers/target/iscsi/iscsi_target_parameters.h | |||
@@ -1,8 +1,10 @@ | |||
1 | #ifndef ISCSI_PARAMETERS_H | 1 | #ifndef ISCSI_PARAMETERS_H |
2 | #define ISCSI_PARAMETERS_H | 2 | #define ISCSI_PARAMETERS_H |
3 | 3 | ||
4 | #include <scsi/iscsi_proto.h> | ||
5 | |||
4 | struct iscsi_extra_response { | 6 | struct iscsi_extra_response { |
5 | char key[64]; | 7 | char key[KEY_MAXLEN]; |
6 | char value[32]; | 8 | char value[32]; |
7 | struct list_head er_list; | 9 | struct list_head er_list; |
8 | } ____cacheline_aligned; | 10 | } ____cacheline_aligned; |
diff --git a/drivers/target/iscsi/iscsi_target_util.c b/drivers/target/iscsi/iscsi_target_util.c index 2cc6c9a3ffb8..08a3bacef0c5 100644 --- a/drivers/target/iscsi/iscsi_target_util.c +++ b/drivers/target/iscsi/iscsi_target_util.c | |||
@@ -676,40 +676,56 @@ void iscsit_free_queue_reqs_for_conn(struct iscsi_conn *conn) | |||
676 | 676 | ||
677 | void iscsit_release_cmd(struct iscsi_cmd *cmd) | 677 | void iscsit_release_cmd(struct iscsi_cmd *cmd) |
678 | { | 678 | { |
679 | struct iscsi_conn *conn = cmd->conn; | ||
680 | |||
681 | iscsit_free_r2ts_from_list(cmd); | ||
682 | iscsit_free_all_datain_reqs(cmd); | ||
683 | |||
684 | kfree(cmd->buf_ptr); | 679 | kfree(cmd->buf_ptr); |
685 | kfree(cmd->pdu_list); | 680 | kfree(cmd->pdu_list); |
686 | kfree(cmd->seq_list); | 681 | kfree(cmd->seq_list); |
687 | kfree(cmd->tmr_req); | 682 | kfree(cmd->tmr_req); |
688 | kfree(cmd->iov_data); | 683 | kfree(cmd->iov_data); |
689 | 684 | ||
690 | if (conn) { | 685 | kmem_cache_free(lio_cmd_cache, cmd); |
686 | } | ||
687 | |||
688 | static void __iscsit_free_cmd(struct iscsi_cmd *cmd, bool scsi_cmd, | ||
689 | bool check_queues) | ||
690 | { | ||
691 | struct iscsi_conn *conn = cmd->conn; | ||
692 | |||
693 | if (scsi_cmd) { | ||
694 | if (cmd->data_direction == DMA_TO_DEVICE) { | ||
695 | iscsit_stop_dataout_timer(cmd); | ||
696 | iscsit_free_r2ts_from_list(cmd); | ||
697 | } | ||
698 | if (cmd->data_direction == DMA_FROM_DEVICE) | ||
699 | iscsit_free_all_datain_reqs(cmd); | ||
700 | } | ||
701 | |||
702 | if (conn && check_queues) { | ||
691 | iscsit_remove_cmd_from_immediate_queue(cmd, conn); | 703 | iscsit_remove_cmd_from_immediate_queue(cmd, conn); |
692 | iscsit_remove_cmd_from_response_queue(cmd, conn); | 704 | iscsit_remove_cmd_from_response_queue(cmd, conn); |
693 | } | 705 | } |
694 | |||
695 | kmem_cache_free(lio_cmd_cache, cmd); | ||
696 | } | 706 | } |
697 | 707 | ||
698 | void iscsit_free_cmd(struct iscsi_cmd *cmd) | 708 | void iscsit_free_cmd(struct iscsi_cmd *cmd, bool shutdown) |
699 | { | 709 | { |
710 | struct se_cmd *se_cmd = NULL; | ||
711 | int rc; | ||
700 | /* | 712 | /* |
701 | * Determine if a struct se_cmd is associated with | 713 | * Determine if a struct se_cmd is associated with |
702 | * this struct iscsi_cmd. | 714 | * this struct iscsi_cmd. |
703 | */ | 715 | */ |
704 | switch (cmd->iscsi_opcode) { | 716 | switch (cmd->iscsi_opcode) { |
705 | case ISCSI_OP_SCSI_CMD: | 717 | case ISCSI_OP_SCSI_CMD: |
706 | if (cmd->data_direction == DMA_TO_DEVICE) | 718 | se_cmd = &cmd->se_cmd; |
707 | iscsit_stop_dataout_timer(cmd); | 719 | __iscsit_free_cmd(cmd, true, shutdown); |
708 | /* | 720 | /* |
709 | * Fallthrough | 721 | * Fallthrough |
710 | */ | 722 | */ |
711 | case ISCSI_OP_SCSI_TMFUNC: | 723 | case ISCSI_OP_SCSI_TMFUNC: |
712 | transport_generic_free_cmd(&cmd->se_cmd, 1); | 724 | rc = transport_generic_free_cmd(&cmd->se_cmd, 1); |
725 | if (!rc && shutdown && se_cmd && se_cmd->se_sess) { | ||
726 | __iscsit_free_cmd(cmd, true, shutdown); | ||
727 | target_put_sess_cmd(se_cmd->se_sess, se_cmd); | ||
728 | } | ||
713 | break; | 729 | break; |
714 | case ISCSI_OP_REJECT: | 730 | case ISCSI_OP_REJECT: |
715 | /* | 731 | /* |
@@ -718,11 +734,19 @@ void iscsit_free_cmd(struct iscsi_cmd *cmd) | |||
718 | * associated cmd->se_cmd needs to be released. | 734 | * associated cmd->se_cmd needs to be released. |
719 | */ | 735 | */ |
720 | if (cmd->se_cmd.se_tfo != NULL) { | 736 | if (cmd->se_cmd.se_tfo != NULL) { |
721 | transport_generic_free_cmd(&cmd->se_cmd, 1); | 737 | se_cmd = &cmd->se_cmd; |
738 | __iscsit_free_cmd(cmd, true, shutdown); | ||
739 | |||
740 | rc = transport_generic_free_cmd(&cmd->se_cmd, 1); | ||
741 | if (!rc && shutdown && se_cmd->se_sess) { | ||
742 | __iscsit_free_cmd(cmd, true, shutdown); | ||
743 | target_put_sess_cmd(se_cmd->se_sess, se_cmd); | ||
744 | } | ||
722 | break; | 745 | break; |
723 | } | 746 | } |
724 | /* Fall-through */ | 747 | /* Fall-through */ |
725 | default: | 748 | default: |
749 | __iscsit_free_cmd(cmd, false, shutdown); | ||
726 | cmd->release_cmd(cmd); | 750 | cmd->release_cmd(cmd); |
727 | break; | 751 | break; |
728 | } | 752 | } |
diff --git a/drivers/target/iscsi/iscsi_target_util.h b/drivers/target/iscsi/iscsi_target_util.h index 4f8e01a47081..a4422659d049 100644 --- a/drivers/target/iscsi/iscsi_target_util.h +++ b/drivers/target/iscsi/iscsi_target_util.h | |||
@@ -29,7 +29,7 @@ extern void iscsit_remove_cmd_from_tx_queues(struct iscsi_cmd *, struct iscsi_co | |||
29 | extern bool iscsit_conn_all_queues_empty(struct iscsi_conn *); | 29 | extern bool iscsit_conn_all_queues_empty(struct iscsi_conn *); |
30 | extern void iscsit_free_queue_reqs_for_conn(struct iscsi_conn *); | 30 | extern void iscsit_free_queue_reqs_for_conn(struct iscsi_conn *); |
31 | extern void iscsit_release_cmd(struct iscsi_cmd *); | 31 | extern void iscsit_release_cmd(struct iscsi_cmd *); |
32 | extern void iscsit_free_cmd(struct iscsi_cmd *); | 32 | extern void iscsit_free_cmd(struct iscsi_cmd *, bool); |
33 | extern int iscsit_check_session_usage_count(struct iscsi_session *); | 33 | extern int iscsit_check_session_usage_count(struct iscsi_session *); |
34 | extern void iscsit_dec_session_usage_count(struct iscsi_session *); | 34 | extern void iscsit_dec_session_usage_count(struct iscsi_session *); |
35 | extern void iscsit_inc_session_usage_count(struct iscsi_session *); | 35 | extern void iscsit_inc_session_usage_count(struct iscsi_session *); |
diff --git a/drivers/target/target_core_file.c b/drivers/target/target_core_file.c index 1b1d544e927a..b11890d85120 100644 --- a/drivers/target/target_core_file.c +++ b/drivers/target/target_core_file.c | |||
@@ -153,6 +153,7 @@ static int fd_configure_device(struct se_device *dev) | |||
153 | struct request_queue *q = bdev_get_queue(inode->i_bdev); | 153 | struct request_queue *q = bdev_get_queue(inode->i_bdev); |
154 | unsigned long long dev_size; | 154 | unsigned long long dev_size; |
155 | 155 | ||
156 | fd_dev->fd_block_size = bdev_logical_block_size(inode->i_bdev); | ||
156 | /* | 157 | /* |
157 | * Determine the number of bytes from i_size_read() minus | 158 | * Determine the number of bytes from i_size_read() minus |
158 | * one (1) logical sector from underlying struct block_device | 159 | * one (1) logical sector from underlying struct block_device |
@@ -199,6 +200,7 @@ static int fd_configure_device(struct se_device *dev) | |||
199 | goto fail; | 200 | goto fail; |
200 | } | 201 | } |
201 | 202 | ||
203 | fd_dev->fd_block_size = FD_BLOCKSIZE; | ||
202 | /* | 204 | /* |
203 | * Limit UNMAP emulation to 8k Number of LBAs (NoLB) | 205 | * Limit UNMAP emulation to 8k Number of LBAs (NoLB) |
204 | */ | 206 | */ |
@@ -217,9 +219,7 @@ static int fd_configure_device(struct se_device *dev) | |||
217 | dev->dev_attrib.max_write_same_len = 0x1000; | 219 | dev->dev_attrib.max_write_same_len = 0x1000; |
218 | } | 220 | } |
219 | 221 | ||
220 | fd_dev->fd_block_size = dev->dev_attrib.hw_block_size; | 222 | dev->dev_attrib.hw_block_size = fd_dev->fd_block_size; |
221 | |||
222 | dev->dev_attrib.hw_block_size = FD_BLOCKSIZE; | ||
223 | dev->dev_attrib.hw_max_sectors = FD_MAX_SECTORS; | 223 | dev->dev_attrib.hw_max_sectors = FD_MAX_SECTORS; |
224 | dev->dev_attrib.hw_queue_depth = FD_MAX_DEVICE_QUEUE_DEPTH; | 224 | dev->dev_attrib.hw_queue_depth = FD_MAX_DEVICE_QUEUE_DEPTH; |
225 | 225 | ||
@@ -694,11 +694,12 @@ static sector_t fd_get_blocks(struct se_device *dev) | |||
694 | * to handle underlying block_device resize operations. | 694 | * to handle underlying block_device resize operations. |
695 | */ | 695 | */ |
696 | if (S_ISBLK(i->i_mode)) | 696 | if (S_ISBLK(i->i_mode)) |
697 | dev_size = (i_size_read(i) - fd_dev->fd_block_size); | 697 | dev_size = i_size_read(i); |
698 | else | 698 | else |
699 | dev_size = fd_dev->fd_dev_size; | 699 | dev_size = fd_dev->fd_dev_size; |
700 | 700 | ||
701 | return div_u64(dev_size, dev->dev_attrib.block_size); | 701 | return div_u64(dev_size - dev->dev_attrib.block_size, |
702 | dev->dev_attrib.block_size); | ||
702 | } | 703 | } |
703 | 704 | ||
704 | static struct sbc_ops fd_sbc_ops = { | 705 | static struct sbc_ops fd_sbc_ops = { |
diff --git a/drivers/target/target_core_transport.c b/drivers/target/target_core_transport.c index 4a793362309d..21e315874a54 100644 --- a/drivers/target/target_core_transport.c +++ b/drivers/target/target_core_transport.c | |||
@@ -65,7 +65,7 @@ static void transport_complete_task_attr(struct se_cmd *cmd); | |||
65 | static void transport_handle_queue_full(struct se_cmd *cmd, | 65 | static void transport_handle_queue_full(struct se_cmd *cmd, |
66 | struct se_device *dev); | 66 | struct se_device *dev); |
67 | static int transport_generic_get_mem(struct se_cmd *cmd); | 67 | static int transport_generic_get_mem(struct se_cmd *cmd); |
68 | static void transport_put_cmd(struct se_cmd *cmd); | 68 | static int transport_put_cmd(struct se_cmd *cmd); |
69 | static void target_complete_ok_work(struct work_struct *work); | 69 | static void target_complete_ok_work(struct work_struct *work); |
70 | 70 | ||
71 | int init_se_kmem_caches(void) | 71 | int init_se_kmem_caches(void) |
@@ -221,6 +221,7 @@ struct se_session *transport_init_session(void) | |||
221 | INIT_LIST_HEAD(&se_sess->sess_list); | 221 | INIT_LIST_HEAD(&se_sess->sess_list); |
222 | INIT_LIST_HEAD(&se_sess->sess_acl_list); | 222 | INIT_LIST_HEAD(&se_sess->sess_acl_list); |
223 | INIT_LIST_HEAD(&se_sess->sess_cmd_list); | 223 | INIT_LIST_HEAD(&se_sess->sess_cmd_list); |
224 | INIT_LIST_HEAD(&se_sess->sess_wait_list); | ||
224 | spin_lock_init(&se_sess->sess_cmd_lock); | 225 | spin_lock_init(&se_sess->sess_cmd_lock); |
225 | kref_init(&se_sess->sess_kref); | 226 | kref_init(&se_sess->sess_kref); |
226 | 227 | ||
@@ -1943,7 +1944,7 @@ static inline void transport_free_pages(struct se_cmd *cmd) | |||
1943 | * This routine unconditionally frees a command, and reference counting | 1944 | * This routine unconditionally frees a command, and reference counting |
1944 | * or list removal must be done in the caller. | 1945 | * or list removal must be done in the caller. |
1945 | */ | 1946 | */ |
1946 | static void transport_release_cmd(struct se_cmd *cmd) | 1947 | static int transport_release_cmd(struct se_cmd *cmd) |
1947 | { | 1948 | { |
1948 | BUG_ON(!cmd->se_tfo); | 1949 | BUG_ON(!cmd->se_tfo); |
1949 | 1950 | ||
@@ -1955,11 +1956,11 @@ static void transport_release_cmd(struct se_cmd *cmd) | |||
1955 | * If this cmd has been setup with target_get_sess_cmd(), drop | 1956 | * If this cmd has been setup with target_get_sess_cmd(), drop |
1956 | * the kref and call ->release_cmd() in kref callback. | 1957 | * the kref and call ->release_cmd() in kref callback. |
1957 | */ | 1958 | */ |
1958 | if (cmd->check_release != 0) { | 1959 | if (cmd->check_release != 0) |
1959 | target_put_sess_cmd(cmd->se_sess, cmd); | 1960 | return target_put_sess_cmd(cmd->se_sess, cmd); |
1960 | return; | 1961 | |
1961 | } | ||
1962 | cmd->se_tfo->release_cmd(cmd); | 1962 | cmd->se_tfo->release_cmd(cmd); |
1963 | return 1; | ||
1963 | } | 1964 | } |
1964 | 1965 | ||
1965 | /** | 1966 | /** |
@@ -1968,7 +1969,7 @@ static void transport_release_cmd(struct se_cmd *cmd) | |||
1968 | * | 1969 | * |
1969 | * This routine releases our reference to the command and frees it if possible. | 1970 | * This routine releases our reference to the command and frees it if possible. |
1970 | */ | 1971 | */ |
1971 | static void transport_put_cmd(struct se_cmd *cmd) | 1972 | static int transport_put_cmd(struct se_cmd *cmd) |
1972 | { | 1973 | { |
1973 | unsigned long flags; | 1974 | unsigned long flags; |
1974 | 1975 | ||
@@ -1976,7 +1977,7 @@ static void transport_put_cmd(struct se_cmd *cmd) | |||
1976 | if (atomic_read(&cmd->t_fe_count) && | 1977 | if (atomic_read(&cmd->t_fe_count) && |
1977 | !atomic_dec_and_test(&cmd->t_fe_count)) { | 1978 | !atomic_dec_and_test(&cmd->t_fe_count)) { |
1978 | spin_unlock_irqrestore(&cmd->t_state_lock, flags); | 1979 | spin_unlock_irqrestore(&cmd->t_state_lock, flags); |
1979 | return; | 1980 | return 0; |
1980 | } | 1981 | } |
1981 | 1982 | ||
1982 | if (cmd->transport_state & CMD_T_DEV_ACTIVE) { | 1983 | if (cmd->transport_state & CMD_T_DEV_ACTIVE) { |
@@ -1986,8 +1987,7 @@ static void transport_put_cmd(struct se_cmd *cmd) | |||
1986 | spin_unlock_irqrestore(&cmd->t_state_lock, flags); | 1987 | spin_unlock_irqrestore(&cmd->t_state_lock, flags); |
1987 | 1988 | ||
1988 | transport_free_pages(cmd); | 1989 | transport_free_pages(cmd); |
1989 | transport_release_cmd(cmd); | 1990 | return transport_release_cmd(cmd); |
1990 | return; | ||
1991 | } | 1991 | } |
1992 | 1992 | ||
1993 | void *transport_kmap_data_sg(struct se_cmd *cmd) | 1993 | void *transport_kmap_data_sg(struct se_cmd *cmd) |
@@ -2152,13 +2152,15 @@ static void transport_write_pending_qf(struct se_cmd *cmd) | |||
2152 | } | 2152 | } |
2153 | } | 2153 | } |
2154 | 2154 | ||
2155 | void transport_generic_free_cmd(struct se_cmd *cmd, int wait_for_tasks) | 2155 | int transport_generic_free_cmd(struct se_cmd *cmd, int wait_for_tasks) |
2156 | { | 2156 | { |
2157 | int ret = 0; | ||
2158 | |||
2157 | if (!(cmd->se_cmd_flags & SCF_SE_LUN_CMD)) { | 2159 | if (!(cmd->se_cmd_flags & SCF_SE_LUN_CMD)) { |
2158 | if (wait_for_tasks && (cmd->se_cmd_flags & SCF_SCSI_TMR_CDB)) | 2160 | if (wait_for_tasks && (cmd->se_cmd_flags & SCF_SCSI_TMR_CDB)) |
2159 | transport_wait_for_tasks(cmd); | 2161 | transport_wait_for_tasks(cmd); |
2160 | 2162 | ||
2161 | transport_release_cmd(cmd); | 2163 | ret = transport_release_cmd(cmd); |
2162 | } else { | 2164 | } else { |
2163 | if (wait_for_tasks) | 2165 | if (wait_for_tasks) |
2164 | transport_wait_for_tasks(cmd); | 2166 | transport_wait_for_tasks(cmd); |
@@ -2166,8 +2168,9 @@ void transport_generic_free_cmd(struct se_cmd *cmd, int wait_for_tasks) | |||
2166 | if (cmd->se_lun) | 2168 | if (cmd->se_lun) |
2167 | transport_lun_remove_cmd(cmd); | 2169 | transport_lun_remove_cmd(cmd); |
2168 | 2170 | ||
2169 | transport_put_cmd(cmd); | 2171 | ret = transport_put_cmd(cmd); |
2170 | } | 2172 | } |
2173 | return ret; | ||
2171 | } | 2174 | } |
2172 | EXPORT_SYMBOL(transport_generic_free_cmd); | 2175 | EXPORT_SYMBOL(transport_generic_free_cmd); |
2173 | 2176 | ||
@@ -2250,11 +2253,14 @@ void target_sess_cmd_list_set_waiting(struct se_session *se_sess) | |||
2250 | unsigned long flags; | 2253 | unsigned long flags; |
2251 | 2254 | ||
2252 | spin_lock_irqsave(&se_sess->sess_cmd_lock, flags); | 2255 | spin_lock_irqsave(&se_sess->sess_cmd_lock, flags); |
2253 | 2256 | if (se_sess->sess_tearing_down) { | |
2254 | WARN_ON(se_sess->sess_tearing_down); | 2257 | spin_unlock_irqrestore(&se_sess->sess_cmd_lock, flags); |
2258 | return; | ||
2259 | } | ||
2255 | se_sess->sess_tearing_down = 1; | 2260 | se_sess->sess_tearing_down = 1; |
2261 | list_splice_init(&se_sess->sess_cmd_list, &se_sess->sess_wait_list); | ||
2256 | 2262 | ||
2257 | list_for_each_entry(se_cmd, &se_sess->sess_cmd_list, se_cmd_list) | 2263 | list_for_each_entry(se_cmd, &se_sess->sess_wait_list, se_cmd_list) |
2258 | se_cmd->cmd_wait_set = 1; | 2264 | se_cmd->cmd_wait_set = 1; |
2259 | 2265 | ||
2260 | spin_unlock_irqrestore(&se_sess->sess_cmd_lock, flags); | 2266 | spin_unlock_irqrestore(&se_sess->sess_cmd_lock, flags); |
@@ -2263,44 +2269,32 @@ EXPORT_SYMBOL(target_sess_cmd_list_set_waiting); | |||
2263 | 2269 | ||
2264 | /* target_wait_for_sess_cmds - Wait for outstanding descriptors | 2270 | /* target_wait_for_sess_cmds - Wait for outstanding descriptors |
2265 | * @se_sess: session to wait for active I/O | 2271 | * @se_sess: session to wait for active I/O |
2266 | * @wait_for_tasks: Make extra transport_wait_for_tasks call | ||
2267 | */ | 2272 | */ |
2268 | void target_wait_for_sess_cmds( | 2273 | void target_wait_for_sess_cmds(struct se_session *se_sess) |
2269 | struct se_session *se_sess, | ||
2270 | int wait_for_tasks) | ||
2271 | { | 2274 | { |
2272 | struct se_cmd *se_cmd, *tmp_cmd; | 2275 | struct se_cmd *se_cmd, *tmp_cmd; |
2273 | bool rc = false; | 2276 | unsigned long flags; |
2274 | 2277 | ||
2275 | list_for_each_entry_safe(se_cmd, tmp_cmd, | 2278 | list_for_each_entry_safe(se_cmd, tmp_cmd, |
2276 | &se_sess->sess_cmd_list, se_cmd_list) { | 2279 | &se_sess->sess_wait_list, se_cmd_list) { |
2277 | list_del(&se_cmd->se_cmd_list); | 2280 | list_del(&se_cmd->se_cmd_list); |
2278 | 2281 | ||
2279 | pr_debug("Waiting for se_cmd: %p t_state: %d, fabric state:" | 2282 | pr_debug("Waiting for se_cmd: %p t_state: %d, fabric state:" |
2280 | " %d\n", se_cmd, se_cmd->t_state, | 2283 | " %d\n", se_cmd, se_cmd->t_state, |
2281 | se_cmd->se_tfo->get_cmd_state(se_cmd)); | 2284 | se_cmd->se_tfo->get_cmd_state(se_cmd)); |
2282 | 2285 | ||
2283 | if (wait_for_tasks) { | 2286 | wait_for_completion(&se_cmd->cmd_wait_comp); |
2284 | pr_debug("Calling transport_wait_for_tasks se_cmd: %p t_state: %d," | 2287 | pr_debug("After cmd_wait_comp: se_cmd: %p t_state: %d" |
2285 | " fabric state: %d\n", se_cmd, se_cmd->t_state, | 2288 | " fabric state: %d\n", se_cmd, se_cmd->t_state, |
2286 | se_cmd->se_tfo->get_cmd_state(se_cmd)); | 2289 | se_cmd->se_tfo->get_cmd_state(se_cmd)); |
2287 | |||
2288 | rc = transport_wait_for_tasks(se_cmd); | ||
2289 | |||
2290 | pr_debug("After transport_wait_for_tasks se_cmd: %p t_state: %d," | ||
2291 | " fabric state: %d\n", se_cmd, se_cmd->t_state, | ||
2292 | se_cmd->se_tfo->get_cmd_state(se_cmd)); | ||
2293 | } | ||
2294 | |||
2295 | if (!rc) { | ||
2296 | wait_for_completion(&se_cmd->cmd_wait_comp); | ||
2297 | pr_debug("After cmd_wait_comp: se_cmd: %p t_state: %d" | ||
2298 | " fabric state: %d\n", se_cmd, se_cmd->t_state, | ||
2299 | se_cmd->se_tfo->get_cmd_state(se_cmd)); | ||
2300 | } | ||
2301 | 2290 | ||
2302 | se_cmd->se_tfo->release_cmd(se_cmd); | 2291 | se_cmd->se_tfo->release_cmd(se_cmd); |
2303 | } | 2292 | } |
2293 | |||
2294 | spin_lock_irqsave(&se_sess->sess_cmd_lock, flags); | ||
2295 | WARN_ON(!list_empty(&se_sess->sess_cmd_list)); | ||
2296 | spin_unlock_irqrestore(&se_sess->sess_cmd_lock, flags); | ||
2297 | |||
2304 | } | 2298 | } |
2305 | EXPORT_SYMBOL(target_wait_for_sess_cmds); | 2299 | EXPORT_SYMBOL(target_wait_for_sess_cmds); |
2306 | 2300 | ||
diff --git a/drivers/tty/serial/omap-serial.c b/drivers/tty/serial/omap-serial.c index 30d4f7a783cd..f0b9f6b52b32 100644 --- a/drivers/tty/serial/omap-serial.c +++ b/drivers/tty/serial/omap-serial.c | |||
@@ -202,26 +202,6 @@ static int serial_omap_get_context_loss_count(struct uart_omap_port *up) | |||
202 | return pdata->get_context_loss_count(up->dev); | 202 | return pdata->get_context_loss_count(up->dev); |
203 | } | 203 | } |
204 | 204 | ||
205 | static void serial_omap_set_forceidle(struct uart_omap_port *up) | ||
206 | { | ||
207 | struct omap_uart_port_info *pdata = up->dev->platform_data; | ||
208 | |||
209 | if (!pdata || !pdata->set_forceidle) | ||
210 | return; | ||
211 | |||
212 | pdata->set_forceidle(up->dev); | ||
213 | } | ||
214 | |||
215 | static void serial_omap_set_noidle(struct uart_omap_port *up) | ||
216 | { | ||
217 | struct omap_uart_port_info *pdata = up->dev->platform_data; | ||
218 | |||
219 | if (!pdata || !pdata->set_noidle) | ||
220 | return; | ||
221 | |||
222 | pdata->set_noidle(up->dev); | ||
223 | } | ||
224 | |||
225 | static void serial_omap_enable_wakeup(struct uart_omap_port *up, bool enable) | 205 | static void serial_omap_enable_wakeup(struct uart_omap_port *up, bool enable) |
226 | { | 206 | { |
227 | struct omap_uart_port_info *pdata = up->dev->platform_data; | 207 | struct omap_uart_port_info *pdata = up->dev->platform_data; |
@@ -298,8 +278,6 @@ static void serial_omap_stop_tx(struct uart_port *port) | |||
298 | serial_out(up, UART_IER, up->ier); | 278 | serial_out(up, UART_IER, up->ier); |
299 | } | 279 | } |
300 | 280 | ||
301 | serial_omap_set_forceidle(up); | ||
302 | |||
303 | pm_runtime_mark_last_busy(up->dev); | 281 | pm_runtime_mark_last_busy(up->dev); |
304 | pm_runtime_put_autosuspend(up->dev); | 282 | pm_runtime_put_autosuspend(up->dev); |
305 | } | 283 | } |
@@ -364,7 +342,6 @@ static void serial_omap_start_tx(struct uart_port *port) | |||
364 | 342 | ||
365 | pm_runtime_get_sync(up->dev); | 343 | pm_runtime_get_sync(up->dev); |
366 | serial_omap_enable_ier_thri(up); | 344 | serial_omap_enable_ier_thri(up); |
367 | serial_omap_set_noidle(up); | ||
368 | pm_runtime_mark_last_busy(up->dev); | 345 | pm_runtime_mark_last_busy(up->dev); |
369 | pm_runtime_put_autosuspend(up->dev); | 346 | pm_runtime_put_autosuspend(up->dev); |
370 | } | 347 | } |
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig index d71d60f94fc1..2e937bdace6f 100644 --- a/drivers/video/Kconfig +++ b/drivers/video/Kconfig | |||
@@ -2199,7 +2199,7 @@ config FB_XILINX | |||
2199 | 2199 | ||
2200 | config FB_GOLDFISH | 2200 | config FB_GOLDFISH |
2201 | tristate "Goldfish Framebuffer" | 2201 | tristate "Goldfish Framebuffer" |
2202 | depends on FB | 2202 | depends on FB && HAS_DMA |
2203 | select FB_CFB_FILLRECT | 2203 | select FB_CFB_FILLRECT |
2204 | select FB_CFB_COPYAREA | 2204 | select FB_CFB_COPYAREA |
2205 | select FB_CFB_IMAGEBLIT | 2205 | select FB_CFB_IMAGEBLIT |
@@ -2453,6 +2453,23 @@ config FB_HYPERV | |||
2453 | help | 2453 | help |
2454 | This framebuffer driver supports Microsoft Hyper-V Synthetic Video. | 2454 | This framebuffer driver supports Microsoft Hyper-V Synthetic Video. |
2455 | 2455 | ||
2456 | config FB_SIMPLE | ||
2457 | bool "Simple framebuffer support" | ||
2458 | depends on (FB = y) && OF | ||
2459 | select FB_CFB_FILLRECT | ||
2460 | select FB_CFB_COPYAREA | ||
2461 | select FB_CFB_IMAGEBLIT | ||
2462 | help | ||
2463 | Say Y if you want support for a simple frame-buffer. | ||
2464 | |||
2465 | This driver assumes that the display hardware has been initialized | ||
2466 | before the kernel boots, and the kernel will simply render to the | ||
2467 | pre-allocated frame buffer surface. | ||
2468 | |||
2469 | Configuration re: surface address, size, and format must be provided | ||
2470 | through device tree, or potentially plain old platform data in the | ||
2471 | future. | ||
2472 | |||
2456 | source "drivers/video/omap/Kconfig" | 2473 | source "drivers/video/omap/Kconfig" |
2457 | source "drivers/video/omap2/Kconfig" | 2474 | source "drivers/video/omap2/Kconfig" |
2458 | source "drivers/video/exynos/Kconfig" | 2475 | source "drivers/video/exynos/Kconfig" |
diff --git a/drivers/video/Makefile b/drivers/video/Makefile index 7234e4a959e8..e8bae8dd4804 100644 --- a/drivers/video/Makefile +++ b/drivers/video/Makefile | |||
@@ -166,6 +166,7 @@ obj-$(CONFIG_FB_MX3) += mx3fb.o | |||
166 | obj-$(CONFIG_FB_DA8XX) += da8xx-fb.o | 166 | obj-$(CONFIG_FB_DA8XX) += da8xx-fb.o |
167 | obj-$(CONFIG_FB_MXS) += mxsfb.o | 167 | obj-$(CONFIG_FB_MXS) += mxsfb.o |
168 | obj-$(CONFIG_FB_SSD1307) += ssd1307fb.o | 168 | obj-$(CONFIG_FB_SSD1307) += ssd1307fb.o |
169 | obj-$(CONFIG_FB_SIMPLE) += simplefb.o | ||
169 | 170 | ||
170 | # the test framebuffer is last | 171 | # the test framebuffer is last |
171 | obj-$(CONFIG_FB_VIRTUAL) += vfb.o | 172 | obj-$(CONFIG_FB_VIRTUAL) += vfb.o |
diff --git a/drivers/video/atmel_lcdfb.c b/drivers/video/atmel_lcdfb.c index 540909de6247..effdb373b8db 100644 --- a/drivers/video/atmel_lcdfb.c +++ b/drivers/video/atmel_lcdfb.c | |||
@@ -223,8 +223,14 @@ static void init_backlight(struct atmel_lcdfb_info *sinfo) | |||
223 | 223 | ||
224 | static void exit_backlight(struct atmel_lcdfb_info *sinfo) | 224 | static void exit_backlight(struct atmel_lcdfb_info *sinfo) |
225 | { | 225 | { |
226 | if (sinfo->backlight) | 226 | if (!sinfo->backlight) |
227 | backlight_device_unregister(sinfo->backlight); | 227 | return; |
228 | |||
229 | if (sinfo->backlight->ops) { | ||
230 | sinfo->backlight->props.power = FB_BLANK_POWERDOWN; | ||
231 | sinfo->backlight->ops->update_status(sinfo->backlight); | ||
232 | } | ||
233 | backlight_device_unregister(sinfo->backlight); | ||
228 | } | 234 | } |
229 | 235 | ||
230 | #else | 236 | #else |
@@ -461,8 +467,11 @@ static int atmel_lcdfb_check_var(struct fb_var_screeninfo *var, | |||
461 | if (info->fix.smem_len) { | 467 | if (info->fix.smem_len) { |
462 | unsigned int smem_len = (var->xres_virtual * var->yres_virtual | 468 | unsigned int smem_len = (var->xres_virtual * var->yres_virtual |
463 | * ((var->bits_per_pixel + 7) / 8)); | 469 | * ((var->bits_per_pixel + 7) / 8)); |
464 | if (smem_len > info->fix.smem_len) | 470 | if (smem_len > info->fix.smem_len) { |
471 | dev_err(dev, "Frame buffer is too small (%u) for screen size (need at least %u)\n", | ||
472 | info->fix.smem_len, smem_len); | ||
465 | return -EINVAL; | 473 | return -EINVAL; |
474 | } | ||
466 | } | 475 | } |
467 | 476 | ||
468 | /* Saturate vertical and horizontal timings at maximum values */ | 477 | /* Saturate vertical and horizontal timings at maximum values */ |
diff --git a/drivers/video/omap2/dss/core.c b/drivers/video/omap2/dss/core.c index 60cc6fee6548..c9c2252e3719 100644 --- a/drivers/video/omap2/dss/core.c +++ b/drivers/video/omap2/dss/core.c | |||
@@ -53,6 +53,8 @@ static char *def_disp_name; | |||
53 | module_param_named(def_disp, def_disp_name, charp, 0); | 53 | module_param_named(def_disp, def_disp_name, charp, 0); |
54 | MODULE_PARM_DESC(def_disp, "default display name"); | 54 | MODULE_PARM_DESC(def_disp, "default display name"); |
55 | 55 | ||
56 | static bool dss_initialized; | ||
57 | |||
56 | const char *omapdss_get_default_display_name(void) | 58 | const char *omapdss_get_default_display_name(void) |
57 | { | 59 | { |
58 | return core.default_display_name; | 60 | return core.default_display_name; |
@@ -66,6 +68,12 @@ enum omapdss_version omapdss_get_version(void) | |||
66 | } | 68 | } |
67 | EXPORT_SYMBOL(omapdss_get_version); | 69 | EXPORT_SYMBOL(omapdss_get_version); |
68 | 70 | ||
71 | bool omapdss_is_initialized(void) | ||
72 | { | ||
73 | return dss_initialized; | ||
74 | } | ||
75 | EXPORT_SYMBOL(omapdss_is_initialized); | ||
76 | |||
69 | struct platform_device *dss_get_core_pdev(void) | 77 | struct platform_device *dss_get_core_pdev(void) |
70 | { | 78 | { |
71 | return core.pdev; | 79 | return core.pdev; |
@@ -603,6 +611,8 @@ static int __init omap_dss_init(void) | |||
603 | return r; | 611 | return r; |
604 | } | 612 | } |
605 | 613 | ||
614 | dss_initialized = true; | ||
615 | |||
606 | return 0; | 616 | return 0; |
607 | } | 617 | } |
608 | 618 | ||
@@ -633,7 +643,15 @@ static int __init omap_dss_init(void) | |||
633 | 643 | ||
634 | static int __init omap_dss_init2(void) | 644 | static int __init omap_dss_init2(void) |
635 | { | 645 | { |
636 | return omap_dss_register_drivers(); | 646 | int r; |
647 | |||
648 | r = omap_dss_register_drivers(); | ||
649 | if (r) | ||
650 | return r; | ||
651 | |||
652 | dss_initialized = true; | ||
653 | |||
654 | return 0; | ||
637 | } | 655 | } |
638 | 656 | ||
639 | core_initcall(omap_dss_init); | 657 | core_initcall(omap_dss_init); |
diff --git a/drivers/video/omap2/omapfb/omapfb-main.c b/drivers/video/omap2/omapfb/omapfb-main.c index c84bb8a4d0c4..856917b33616 100644 --- a/drivers/video/omap2/omapfb/omapfb-main.c +++ b/drivers/video/omap2/omapfb/omapfb-main.c | |||
@@ -2416,6 +2416,9 @@ static int omapfb_probe(struct platform_device *pdev) | |||
2416 | 2416 | ||
2417 | DBG("omapfb_probe\n"); | 2417 | DBG("omapfb_probe\n"); |
2418 | 2418 | ||
2419 | if (omapdss_is_initialized() == false) | ||
2420 | return -EPROBE_DEFER; | ||
2421 | |||
2419 | if (pdev->num_resources != 0) { | 2422 | if (pdev->num_resources != 0) { |
2420 | dev_err(&pdev->dev, "probed for an unknown device\n"); | 2423 | dev_err(&pdev->dev, "probed for an unknown device\n"); |
2421 | r = -ENODEV; | 2424 | r = -ENODEV; |
diff --git a/drivers/video/ps3fb.c b/drivers/video/ps3fb.c index d9f08c653d62..dbfe2c18a434 100644 --- a/drivers/video/ps3fb.c +++ b/drivers/video/ps3fb.c | |||
@@ -710,7 +710,7 @@ static int ps3fb_mmap(struct fb_info *info, struct vm_area_struct *vma) | |||
710 | r = vm_iomap_memory(vma, info->fix.smem_start, info->fix.smem_len); | 710 | r = vm_iomap_memory(vma, info->fix.smem_start, info->fix.smem_len); |
711 | 711 | ||
712 | dev_dbg(info->device, "ps3fb: mmap framebuffer P(%lx)->V(%lx)\n", | 712 | dev_dbg(info->device, "ps3fb: mmap framebuffer P(%lx)->V(%lx)\n", |
713 | info->fix.smem_start + vma->vm_pgoff << PAGE_SHIFT, | 713 | info->fix.smem_start + (vma->vm_pgoff << PAGE_SHIFT), |
714 | vma->vm_start); | 714 | vma->vm_start); |
715 | 715 | ||
716 | return r; | 716 | return r; |
diff --git a/drivers/video/simplefb.c b/drivers/video/simplefb.c new file mode 100644 index 000000000000..e2e9e3e61b72 --- /dev/null +++ b/drivers/video/simplefb.c | |||
@@ -0,0 +1,234 @@ | |||
1 | /* | ||
2 | * Simplest possible simple frame-buffer driver, as a platform device | ||
3 | * | ||
4 | * Copyright (c) 2013, Stephen Warren | ||
5 | * | ||
6 | * Based on q40fb.c, which was: | ||
7 | * Copyright (C) 2001 Richard Zidlicky <rz@linux-m68k.org> | ||
8 | * | ||
9 | * Also based on offb.c, which was: | ||
10 | * Copyright (C) 1997 Geert Uytterhoeven | ||
11 | * Copyright (C) 1996 Paul Mackerras | ||
12 | * | ||
13 | * This program is free software; you can redistribute it and/or modify it | ||
14 | * under the terms and conditions of the GNU General Public License, | ||
15 | * version 2, as published by the Free Software Foundation. | ||
16 | * | ||
17 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
18 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
19 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
20 | * more details. | ||
21 | */ | ||
22 | |||
23 | #include <linux/errno.h> | ||
24 | #include <linux/fb.h> | ||
25 | #include <linux/io.h> | ||
26 | #include <linux/module.h> | ||
27 | #include <linux/platform_device.h> | ||
28 | |||
29 | static struct fb_fix_screeninfo simplefb_fix = { | ||
30 | .id = "simple", | ||
31 | .type = FB_TYPE_PACKED_PIXELS, | ||
32 | .visual = FB_VISUAL_TRUECOLOR, | ||
33 | .accel = FB_ACCEL_NONE, | ||
34 | }; | ||
35 | |||
36 | static struct fb_var_screeninfo simplefb_var = { | ||
37 | .height = -1, | ||
38 | .width = -1, | ||
39 | .activate = FB_ACTIVATE_NOW, | ||
40 | .vmode = FB_VMODE_NONINTERLACED, | ||
41 | }; | ||
42 | |||
43 | static int simplefb_setcolreg(u_int regno, u_int red, u_int green, u_int blue, | ||
44 | u_int transp, struct fb_info *info) | ||
45 | { | ||
46 | u32 *pal = info->pseudo_palette; | ||
47 | u32 cr = red >> (16 - info->var.red.length); | ||
48 | u32 cg = green >> (16 - info->var.green.length); | ||
49 | u32 cb = blue >> (16 - info->var.blue.length); | ||
50 | u32 value; | ||
51 | |||
52 | if (regno >= 16) | ||
53 | return -EINVAL; | ||
54 | |||
55 | value = (cr << info->var.red.offset) | | ||
56 | (cg << info->var.green.offset) | | ||
57 | (cb << info->var.blue.offset); | ||
58 | if (info->var.transp.length > 0) { | ||
59 | u32 mask = (1 << info->var.transp.length) - 1; | ||
60 | mask <<= info->var.transp.offset; | ||
61 | value |= mask; | ||
62 | } | ||
63 | pal[regno] = value; | ||
64 | |||
65 | return 0; | ||
66 | } | ||
67 | |||
68 | static struct fb_ops simplefb_ops = { | ||
69 | .owner = THIS_MODULE, | ||
70 | .fb_setcolreg = simplefb_setcolreg, | ||
71 | .fb_fillrect = cfb_fillrect, | ||
72 | .fb_copyarea = cfb_copyarea, | ||
73 | .fb_imageblit = cfb_imageblit, | ||
74 | }; | ||
75 | |||
76 | struct simplefb_format { | ||
77 | const char *name; | ||
78 | u32 bits_per_pixel; | ||
79 | struct fb_bitfield red; | ||
80 | struct fb_bitfield green; | ||
81 | struct fb_bitfield blue; | ||
82 | struct fb_bitfield transp; | ||
83 | }; | ||
84 | |||
85 | static struct simplefb_format simplefb_formats[] = { | ||
86 | { "r5g6b5", 16, {11, 5}, {5, 6}, {0, 5}, {0, 0} }, | ||
87 | }; | ||
88 | |||
89 | struct simplefb_params { | ||
90 | u32 width; | ||
91 | u32 height; | ||
92 | u32 stride; | ||
93 | struct simplefb_format *format; | ||
94 | }; | ||
95 | |||
96 | static int simplefb_parse_dt(struct platform_device *pdev, | ||
97 | struct simplefb_params *params) | ||
98 | { | ||
99 | struct device_node *np = pdev->dev.of_node; | ||
100 | int ret; | ||
101 | const char *format; | ||
102 | int i; | ||
103 | |||
104 | ret = of_property_read_u32(np, "width", ¶ms->width); | ||
105 | if (ret) { | ||
106 | dev_err(&pdev->dev, "Can't parse width property\n"); | ||
107 | return ret; | ||
108 | } | ||
109 | |||
110 | ret = of_property_read_u32(np, "height", ¶ms->height); | ||
111 | if (ret) { | ||
112 | dev_err(&pdev->dev, "Can't parse height property\n"); | ||
113 | return ret; | ||
114 | } | ||
115 | |||
116 | ret = of_property_read_u32(np, "stride", ¶ms->stride); | ||
117 | if (ret) { | ||
118 | dev_err(&pdev->dev, "Can't parse stride property\n"); | ||
119 | return ret; | ||
120 | } | ||
121 | |||
122 | ret = of_property_read_string(np, "format", &format); | ||
123 | if (ret) { | ||
124 | dev_err(&pdev->dev, "Can't parse format property\n"); | ||
125 | return ret; | ||
126 | } | ||
127 | params->format = NULL; | ||
128 | for (i = 0; i < ARRAY_SIZE(simplefb_formats); i++) { | ||
129 | if (strcmp(format, simplefb_formats[i].name)) | ||
130 | continue; | ||
131 | params->format = &simplefb_formats[i]; | ||
132 | break; | ||
133 | } | ||
134 | if (!params->format) { | ||
135 | dev_err(&pdev->dev, "Invalid format value\n"); | ||
136 | return -EINVAL; | ||
137 | } | ||
138 | |||
139 | return 0; | ||
140 | } | ||
141 | |||
142 | static int simplefb_probe(struct platform_device *pdev) | ||
143 | { | ||
144 | int ret; | ||
145 | struct simplefb_params params; | ||
146 | struct fb_info *info; | ||
147 | struct resource *mem; | ||
148 | |||
149 | if (fb_get_options("simplefb", NULL)) | ||
150 | return -ENODEV; | ||
151 | |||
152 | ret = simplefb_parse_dt(pdev, ¶ms); | ||
153 | if (ret) | ||
154 | return ret; | ||
155 | |||
156 | mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
157 | if (!mem) { | ||
158 | dev_err(&pdev->dev, "No memory resource\n"); | ||
159 | return -EINVAL; | ||
160 | } | ||
161 | |||
162 | info = framebuffer_alloc(sizeof(u32) * 16, &pdev->dev); | ||
163 | if (!info) | ||
164 | return -ENOMEM; | ||
165 | platform_set_drvdata(pdev, info); | ||
166 | |||
167 | info->fix = simplefb_fix; | ||
168 | info->fix.smem_start = mem->start; | ||
169 | info->fix.smem_len = resource_size(mem); | ||
170 | info->fix.line_length = params.stride; | ||
171 | |||
172 | info->var = simplefb_var; | ||
173 | info->var.xres = params.width; | ||
174 | info->var.yres = params.height; | ||
175 | info->var.xres_virtual = params.width; | ||
176 | info->var.yres_virtual = params.height; | ||
177 | info->var.bits_per_pixel = params.format->bits_per_pixel; | ||
178 | info->var.red = params.format->red; | ||
179 | info->var.green = params.format->green; | ||
180 | info->var.blue = params.format->blue; | ||
181 | info->var.transp = params.format->transp; | ||
182 | |||
183 | info->fbops = &simplefb_ops; | ||
184 | info->flags = FBINFO_DEFAULT; | ||
185 | info->screen_base = devm_ioremap(&pdev->dev, info->fix.smem_start, | ||
186 | info->fix.smem_len); | ||
187 | if (!info->screen_base) { | ||
188 | framebuffer_release(info); | ||
189 | return -ENODEV; | ||
190 | } | ||
191 | info->pseudo_palette = (void *)(info + 1); | ||
192 | |||
193 | ret = register_framebuffer(info); | ||
194 | if (ret < 0) { | ||
195 | dev_err(&pdev->dev, "Unable to register simplefb: %d\n", ret); | ||
196 | framebuffer_release(info); | ||
197 | return ret; | ||
198 | } | ||
199 | |||
200 | dev_info(&pdev->dev, "fb%d: simplefb registered!\n", info->node); | ||
201 | |||
202 | return 0; | ||
203 | } | ||
204 | |||
205 | static int simplefb_remove(struct platform_device *pdev) | ||
206 | { | ||
207 | struct fb_info *info = platform_get_drvdata(pdev); | ||
208 | |||
209 | unregister_framebuffer(info); | ||
210 | framebuffer_release(info); | ||
211 | |||
212 | return 0; | ||
213 | } | ||
214 | |||
215 | static const struct of_device_id simplefb_of_match[] = { | ||
216 | { .compatible = "simple-framebuffer", }, | ||
217 | { }, | ||
218 | }; | ||
219 | MODULE_DEVICE_TABLE(of, simplefb_of_match); | ||
220 | |||
221 | static struct platform_driver simplefb_driver = { | ||
222 | .driver = { | ||
223 | .name = "simple-framebuffer", | ||
224 | .owner = THIS_MODULE, | ||
225 | .of_match_table = simplefb_of_match, | ||
226 | }, | ||
227 | .probe = simplefb_probe, | ||
228 | .remove = simplefb_remove, | ||
229 | }; | ||
230 | module_platform_driver(simplefb_driver); | ||
231 | |||
232 | MODULE_AUTHOR("Stephen Warren <swarren@wwwdotorg.org>"); | ||
233 | MODULE_DESCRIPTION("Simple framebuffer driver"); | ||
234 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/xen/tmem.c b/drivers/xen/tmem.c index 18e8bd8fa947..cc072c66c766 100644 --- a/drivers/xen/tmem.c +++ b/drivers/xen/tmem.c | |||
@@ -41,6 +41,8 @@ module_param(selfballooning, bool, S_IRUGO); | |||
41 | #ifdef CONFIG_FRONTSWAP | 41 | #ifdef CONFIG_FRONTSWAP |
42 | static bool frontswap __read_mostly = true; | 42 | static bool frontswap __read_mostly = true; |
43 | module_param(frontswap, bool, S_IRUGO); | 43 | module_param(frontswap, bool, S_IRUGO); |
44 | #else /* CONFIG_FRONTSWAP */ | ||
45 | #define frontswap (0) | ||
44 | #endif /* CONFIG_FRONTSWAP */ | 46 | #endif /* CONFIG_FRONTSWAP */ |
45 | 47 | ||
46 | #ifdef CONFIG_XEN_SELFBALLOONING | 48 | #ifdef CONFIG_XEN_SELFBALLOONING |
diff --git a/drivers/xen/xen-pciback/pci_stub.c b/drivers/xen/xen-pciback/pci_stub.c index a2278ba7fb27..4e8ba38aa0c9 100644 --- a/drivers/xen/xen-pciback/pci_stub.c +++ b/drivers/xen/xen-pciback/pci_stub.c | |||
@@ -106,7 +106,7 @@ static void pcistub_device_release(struct kref *kref) | |||
106 | else | 106 | else |
107 | pci_restore_state(dev); | 107 | pci_restore_state(dev); |
108 | 108 | ||
109 | if (pci_find_capability(dev, PCI_CAP_ID_MSIX)) { | 109 | if (dev->msix_cap) { |
110 | struct physdev_pci_device ppdev = { | 110 | struct physdev_pci_device ppdev = { |
111 | .seg = pci_domain_nr(dev->bus), | 111 | .seg = pci_domain_nr(dev->bus), |
112 | .bus = dev->bus->number, | 112 | .bus = dev->bus->number, |
@@ -371,7 +371,7 @@ static int pcistub_init_device(struct pci_dev *dev) | |||
371 | if (err) | 371 | if (err) |
372 | goto config_release; | 372 | goto config_release; |
373 | 373 | ||
374 | if (pci_find_capability(dev, PCI_CAP_ID_MSIX)) { | 374 | if (dev->msix_cap) { |
375 | struct physdev_pci_device ppdev = { | 375 | struct physdev_pci_device ppdev = { |
376 | .seg = pci_domain_nr(dev->bus), | 376 | .seg = pci_domain_nr(dev->bus), |
377 | .bus = dev->bus->number, | 377 | .bus = dev->bus->number, |
diff --git a/drivers/xen/xenbus/xenbus_client.c b/drivers/xen/xenbus/xenbus_client.c index 61786be9138b..ec097d6f964d 100644 --- a/drivers/xen/xenbus/xenbus_client.c +++ b/drivers/xen/xenbus/xenbus_client.c | |||
@@ -534,7 +534,7 @@ static int xenbus_map_ring_valloc_hvm(struct xenbus_device *dev, | |||
534 | 534 | ||
535 | err = xenbus_map_ring(dev, gnt_ref, &node->handle, addr); | 535 | err = xenbus_map_ring(dev, gnt_ref, &node->handle, addr); |
536 | if (err) | 536 | if (err) |
537 | goto out_err; | 537 | goto out_err_free_ballooned_pages; |
538 | 538 | ||
539 | spin_lock(&xenbus_valloc_lock); | 539 | spin_lock(&xenbus_valloc_lock); |
540 | list_add(&node->next, &xenbus_valloc_pages); | 540 | list_add(&node->next, &xenbus_valloc_pages); |
@@ -543,8 +543,9 @@ static int xenbus_map_ring_valloc_hvm(struct xenbus_device *dev, | |||
543 | *vaddr = addr; | 543 | *vaddr = addr; |
544 | return 0; | 544 | return 0; |
545 | 545 | ||
546 | out_err: | 546 | out_err_free_ballooned_pages: |
547 | free_xenballooned_pages(1, &node->page); | 547 | free_xenballooned_pages(1, &node->page); |
548 | out_err: | ||
548 | kfree(node); | 549 | kfree(node); |
549 | return err; | 550 | return err; |
550 | } | 551 | } |
diff --git a/drivers/xen/xenbus/xenbus_comms.h b/drivers/xen/xenbus/xenbus_comms.h index c8abd3b8a6c4..e74f9c1fbd80 100644 --- a/drivers/xen/xenbus/xenbus_comms.h +++ b/drivers/xen/xenbus/xenbus_comms.h | |||
@@ -45,6 +45,7 @@ int xb_wait_for_data_to_read(void); | |||
45 | int xs_input_avail(void); | 45 | int xs_input_avail(void); |
46 | extern struct xenstore_domain_interface *xen_store_interface; | 46 | extern struct xenstore_domain_interface *xen_store_interface; |
47 | extern int xen_store_evtchn; | 47 | extern int xen_store_evtchn; |
48 | extern enum xenstore_init xen_store_domain_type; | ||
48 | 49 | ||
49 | extern const struct file_operations xen_xenbus_fops; | 50 | extern const struct file_operations xen_xenbus_fops; |
50 | 51 | ||
diff --git a/drivers/xen/xenbus/xenbus_probe.c b/drivers/xen/xenbus/xenbus_probe.c index 3325884c693f..56cfaaa9d006 100644 --- a/drivers/xen/xenbus/xenbus_probe.c +++ b/drivers/xen/xenbus/xenbus_probe.c | |||
@@ -69,6 +69,9 @@ EXPORT_SYMBOL_GPL(xen_store_evtchn); | |||
69 | struct xenstore_domain_interface *xen_store_interface; | 69 | struct xenstore_domain_interface *xen_store_interface; |
70 | EXPORT_SYMBOL_GPL(xen_store_interface); | 70 | EXPORT_SYMBOL_GPL(xen_store_interface); |
71 | 71 | ||
72 | enum xenstore_init xen_store_domain_type; | ||
73 | EXPORT_SYMBOL_GPL(xen_store_domain_type); | ||
74 | |||
72 | static unsigned long xen_store_mfn; | 75 | static unsigned long xen_store_mfn; |
73 | 76 | ||
74 | static BLOCKING_NOTIFIER_HEAD(xenstore_chain); | 77 | static BLOCKING_NOTIFIER_HEAD(xenstore_chain); |
@@ -719,17 +722,11 @@ static int __init xenstored_local_init(void) | |||
719 | return err; | 722 | return err; |
720 | } | 723 | } |
721 | 724 | ||
722 | enum xenstore_init { | ||
723 | UNKNOWN, | ||
724 | PV, | ||
725 | HVM, | ||
726 | LOCAL, | ||
727 | }; | ||
728 | static int __init xenbus_init(void) | 725 | static int __init xenbus_init(void) |
729 | { | 726 | { |
730 | int err = 0; | 727 | int err = 0; |
731 | enum xenstore_init usage = UNKNOWN; | ||
732 | uint64_t v = 0; | 728 | uint64_t v = 0; |
729 | xen_store_domain_type = XS_UNKNOWN; | ||
733 | 730 | ||
734 | if (!xen_domain()) | 731 | if (!xen_domain()) |
735 | return -ENODEV; | 732 | return -ENODEV; |
@@ -737,29 +734,29 @@ static int __init xenbus_init(void) | |||
737 | xenbus_ring_ops_init(); | 734 | xenbus_ring_ops_init(); |
738 | 735 | ||
739 | if (xen_pv_domain()) | 736 | if (xen_pv_domain()) |
740 | usage = PV; | 737 | xen_store_domain_type = XS_PV; |
741 | if (xen_hvm_domain()) | 738 | if (xen_hvm_domain()) |
742 | usage = HVM; | 739 | xen_store_domain_type = XS_HVM; |
743 | if (xen_hvm_domain() && xen_initial_domain()) | 740 | if (xen_hvm_domain() && xen_initial_domain()) |
744 | usage = LOCAL; | 741 | xen_store_domain_type = XS_LOCAL; |
745 | if (xen_pv_domain() && !xen_start_info->store_evtchn) | 742 | if (xen_pv_domain() && !xen_start_info->store_evtchn) |
746 | usage = LOCAL; | 743 | xen_store_domain_type = XS_LOCAL; |
747 | if (xen_pv_domain() && xen_start_info->store_evtchn) | 744 | if (xen_pv_domain() && xen_start_info->store_evtchn) |
748 | xenstored_ready = 1; | 745 | xenstored_ready = 1; |
749 | 746 | ||
750 | switch (usage) { | 747 | switch (xen_store_domain_type) { |
751 | case LOCAL: | 748 | case XS_LOCAL: |
752 | err = xenstored_local_init(); | 749 | err = xenstored_local_init(); |
753 | if (err) | 750 | if (err) |
754 | goto out_error; | 751 | goto out_error; |
755 | xen_store_interface = mfn_to_virt(xen_store_mfn); | 752 | xen_store_interface = mfn_to_virt(xen_store_mfn); |
756 | break; | 753 | break; |
757 | case PV: | 754 | case XS_PV: |
758 | xen_store_evtchn = xen_start_info->store_evtchn; | 755 | xen_store_evtchn = xen_start_info->store_evtchn; |
759 | xen_store_mfn = xen_start_info->store_mfn; | 756 | xen_store_mfn = xen_start_info->store_mfn; |
760 | xen_store_interface = mfn_to_virt(xen_store_mfn); | 757 | xen_store_interface = mfn_to_virt(xen_store_mfn); |
761 | break; | 758 | break; |
762 | case HVM: | 759 | case XS_HVM: |
763 | err = hvm_get_parameter(HVM_PARAM_STORE_EVTCHN, &v); | 760 | err = hvm_get_parameter(HVM_PARAM_STORE_EVTCHN, &v); |
764 | if (err) | 761 | if (err) |
765 | goto out_error; | 762 | goto out_error; |
diff --git a/drivers/xen/xenbus/xenbus_probe.h b/drivers/xen/xenbus/xenbus_probe.h index bb4f92ed8730..146f857a36f8 100644 --- a/drivers/xen/xenbus/xenbus_probe.h +++ b/drivers/xen/xenbus/xenbus_probe.h | |||
@@ -47,6 +47,13 @@ struct xen_bus_type { | |||
47 | struct bus_type bus; | 47 | struct bus_type bus; |
48 | }; | 48 | }; |
49 | 49 | ||
50 | enum xenstore_init { | ||
51 | XS_UNKNOWN, | ||
52 | XS_PV, | ||
53 | XS_HVM, | ||
54 | XS_LOCAL, | ||
55 | }; | ||
56 | |||
50 | extern struct device_attribute xenbus_dev_attrs[]; | 57 | extern struct device_attribute xenbus_dev_attrs[]; |
51 | 58 | ||
52 | extern int xenbus_match(struct device *_dev, struct device_driver *_drv); | 59 | extern int xenbus_match(struct device *_dev, struct device_driver *_drv); |
diff --git a/drivers/xen/xenbus/xenbus_probe_frontend.c b/drivers/xen/xenbus/xenbus_probe_frontend.c index 3159a37d966d..a7e25073de19 100644 --- a/drivers/xen/xenbus/xenbus_probe_frontend.c +++ b/drivers/xen/xenbus/xenbus_probe_frontend.c | |||
@@ -29,6 +29,8 @@ | |||
29 | #include "xenbus_probe.h" | 29 | #include "xenbus_probe.h" |
30 | 30 | ||
31 | 31 | ||
32 | static struct workqueue_struct *xenbus_frontend_wq; | ||
33 | |||
32 | /* device/<type>/<id> => <type>-<id> */ | 34 | /* device/<type>/<id> => <type>-<id> */ |
33 | static int frontend_bus_id(char bus_id[XEN_BUS_ID_SIZE], const char *nodename) | 35 | static int frontend_bus_id(char bus_id[XEN_BUS_ID_SIZE], const char *nodename) |
34 | { | 36 | { |
@@ -89,9 +91,40 @@ static void backend_changed(struct xenbus_watch *watch, | |||
89 | xenbus_otherend_changed(watch, vec, len, 1); | 91 | xenbus_otherend_changed(watch, vec, len, 1); |
90 | } | 92 | } |
91 | 93 | ||
94 | static void xenbus_frontend_delayed_resume(struct work_struct *w) | ||
95 | { | ||
96 | struct xenbus_device *xdev = container_of(w, struct xenbus_device, work); | ||
97 | |||
98 | xenbus_dev_resume(&xdev->dev); | ||
99 | } | ||
100 | |||
101 | static int xenbus_frontend_dev_resume(struct device *dev) | ||
102 | { | ||
103 | /* | ||
104 | * If xenstored is running in this domain, we cannot access the backend | ||
105 | * state at the moment, so we need to defer xenbus_dev_resume | ||
106 | */ | ||
107 | if (xen_store_domain_type == XS_LOCAL) { | ||
108 | struct xenbus_device *xdev = to_xenbus_device(dev); | ||
109 | |||
110 | if (!xenbus_frontend_wq) { | ||
111 | pr_err("%s: no workqueue to process delayed resume\n", | ||
112 | xdev->nodename); | ||
113 | return -EFAULT; | ||
114 | } | ||
115 | |||
116 | INIT_WORK(&xdev->work, xenbus_frontend_delayed_resume); | ||
117 | queue_work(xenbus_frontend_wq, &xdev->work); | ||
118 | |||
119 | return 0; | ||
120 | } | ||
121 | |||
122 | return xenbus_dev_resume(dev); | ||
123 | } | ||
124 | |||
92 | static const struct dev_pm_ops xenbus_pm_ops = { | 125 | static const struct dev_pm_ops xenbus_pm_ops = { |
93 | .suspend = xenbus_dev_suspend, | 126 | .suspend = xenbus_dev_suspend, |
94 | .resume = xenbus_dev_resume, | 127 | .resume = xenbus_frontend_dev_resume, |
95 | .freeze = xenbus_dev_suspend, | 128 | .freeze = xenbus_dev_suspend, |
96 | .thaw = xenbus_dev_cancel, | 129 | .thaw = xenbus_dev_cancel, |
97 | .restore = xenbus_dev_resume, | 130 | .restore = xenbus_dev_resume, |
@@ -440,6 +473,8 @@ static int __init xenbus_probe_frontend_init(void) | |||
440 | 473 | ||
441 | register_xenstore_notifier(&xenstore_notifier); | 474 | register_xenstore_notifier(&xenstore_notifier); |
442 | 475 | ||
476 | xenbus_frontend_wq = create_workqueue("xenbus_frontend"); | ||
477 | |||
443 | return 0; | 478 | return 0; |
444 | } | 479 | } |
445 | subsys_initcall(xenbus_probe_frontend_init); | 480 | subsys_initcall(xenbus_probe_frontend_init); |