aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2017-07-14 16:10:06 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2017-07-14 16:10:06 -0400
commit907afe5923b4f89b3c377e8ce3b495124321659c (patch)
tree52863c208a4a0bb1d19e53c834edaef58da41a2d
parent0a264b6db702e0e9bdf8b037c61c951f87785bfc (diff)
parent9c284c41c0886f09e75c323a16278b6d353b0b4a (diff)
Merge tag 'mmc-v4.13-2' of git://git.kernel.org/pub/scm/linux/kernel/git/ulfh/mmc
Pull MMC fixes from Ulf Hansson: "Here are a couple of mmc fixes intended for v4.13 rc1. MMC core: - Restore some behaviour of MMC_IOC_MULTI_CMD commands - Fix using un-initialized variable in mmc_blk_issue_drv_op() - Fix mmc block queue cleanup MMC host: - sdhci-acpi: Workaround conflict with PCI wifi on GPD Win handheld - tmio-mmc: Fix bad pointer math" * tag 'mmc-v4.13-2' of git://git.kernel.org/pub/scm/linux/kernel/git/ulfh/mmc: mmc: tmio-mmc: fix bad pointer math mmc: block: Prevent new req entering queue after its cleanup mmc: block: Let MMC_IOC_MULTI_CMD return zero again for zero entries mmc: block: Initialize ret in mmc_blk_issue_drv_op() for MMC_DRV_OP_IOCTL mmc: sdhci-acpi: Workaround conflict with PCI wifi on GPD Win handheld
-rw-r--r--drivers/mmc/core/block.c6
-rw-r--r--drivers/mmc/host/sdhci-acpi.c70
-rw-r--r--drivers/mmc/host/tmio_mmc_core.c19
3 files changed, 78 insertions, 17 deletions
diff --git a/drivers/mmc/core/block.c b/drivers/mmc/core/block.c
index 0cfac2d39107..8ac59dc80f23 100644
--- a/drivers/mmc/core/block.c
+++ b/drivers/mmc/core/block.c
@@ -637,6 +637,9 @@ static int mmc_blk_ioctl_multi_cmd(struct block_device *bdev,
637 sizeof(num_of_cmds))) 637 sizeof(num_of_cmds)))
638 return -EFAULT; 638 return -EFAULT;
639 639
640 if (!num_of_cmds)
641 return 0;
642
640 if (num_of_cmds > MMC_IOC_MAX_CMDS) 643 if (num_of_cmds > MMC_IOC_MAX_CMDS)
641 return -EINVAL; 644 return -EINVAL;
642 645
@@ -1182,7 +1185,7 @@ static void mmc_blk_issue_drv_op(struct mmc_queue *mq, struct request *req)
1182 1185
1183 switch (mq_rq->drv_op) { 1186 switch (mq_rq->drv_op) {
1184 case MMC_DRV_OP_IOCTL: 1187 case MMC_DRV_OP_IOCTL:
1185 for (i = 0; i < mq_rq->ioc_count; i++) { 1188 for (i = 0, ret = 0; i < mq_rq->ioc_count; i++) {
1186 ret = __mmc_blk_ioctl_cmd(card, md, mq_rq->idata[i]); 1189 ret = __mmc_blk_ioctl_cmd(card, md, mq_rq->idata[i]);
1187 if (ret) 1190 if (ret)
1188 break; 1191 break;
@@ -2167,6 +2170,7 @@ static void mmc_blk_remove_req(struct mmc_blk_data *md)
2167 * from being accepted. 2170 * from being accepted.
2168 */ 2171 */
2169 card = md->queue.card; 2172 card = md->queue.card;
2173 blk_set_queue_dying(md->queue.queue);
2170 mmc_cleanup_queue(&md->queue); 2174 mmc_cleanup_queue(&md->queue);
2171 if (md->disk->flags & GENHD_FL_UP) { 2175 if (md->disk->flags & GENHD_FL_UP) {
2172 device_remove_file(disk_to_dev(md->disk), &md->force_ro); 2176 device_remove_file(disk_to_dev(md->disk), &md->force_ro);
diff --git a/drivers/mmc/host/sdhci-acpi.c b/drivers/mmc/host/sdhci-acpi.c
index cf66a3db71b8..ac678e9fb19a 100644
--- a/drivers/mmc/host/sdhci-acpi.c
+++ b/drivers/mmc/host/sdhci-acpi.c
@@ -45,6 +45,7 @@
45#include <asm/cpu_device_id.h> 45#include <asm/cpu_device_id.h>
46#include <asm/intel-family.h> 46#include <asm/intel-family.h>
47#include <asm/iosf_mbi.h> 47#include <asm/iosf_mbi.h>
48#include <linux/pci.h>
48#endif 49#endif
49 50
50#include "sdhci.h" 51#include "sdhci.h"
@@ -134,6 +135,16 @@ static bool sdhci_acpi_byt(void)
134 return x86_match_cpu(byt); 135 return x86_match_cpu(byt);
135} 136}
136 137
138static bool sdhci_acpi_cht(void)
139{
140 static const struct x86_cpu_id cht[] = {
141 { X86_VENDOR_INTEL, 6, INTEL_FAM6_ATOM_AIRMONT },
142 {}
143 };
144
145 return x86_match_cpu(cht);
146}
147
137#define BYT_IOSF_SCCEP 0x63 148#define BYT_IOSF_SCCEP 0x63
138#define BYT_IOSF_OCP_NETCTRL0 0x1078 149#define BYT_IOSF_OCP_NETCTRL0 0x1078
139#define BYT_IOSF_OCP_TIMEOUT_BASE GENMASK(10, 8) 150#define BYT_IOSF_OCP_TIMEOUT_BASE GENMASK(10, 8)
@@ -178,6 +189,45 @@ static bool sdhci_acpi_byt_defer(struct device *dev)
178 return false; 189 return false;
179} 190}
180 191
192static bool sdhci_acpi_cht_pci_wifi(unsigned int vendor, unsigned int device,
193 unsigned int slot, unsigned int parent_slot)
194{
195 struct pci_dev *dev, *parent, *from = NULL;
196
197 while (1) {
198 dev = pci_get_device(vendor, device, from);
199 pci_dev_put(from);
200 if (!dev)
201 break;
202 parent = pci_upstream_bridge(dev);
203 if (ACPI_COMPANION(&dev->dev) && PCI_SLOT(dev->devfn) == slot &&
204 parent && PCI_SLOT(parent->devfn) == parent_slot &&
205 !pci_upstream_bridge(parent)) {
206 pci_dev_put(dev);
207 return true;
208 }
209 from = dev;
210 }
211
212 return false;
213}
214
215/*
216 * GPDwin uses PCI wifi which conflicts with SDIO's use of
217 * acpi_device_fix_up_power() on child device nodes. Identifying GPDwin is
218 * problematic, but since SDIO is only used for wifi, the presence of the PCI
219 * wifi card in the expected slot with an ACPI companion node, is used to
220 * indicate that acpi_device_fix_up_power() should be avoided.
221 */
222static inline bool sdhci_acpi_no_fixup_child_power(const char *hid,
223 const char *uid)
224{
225 return sdhci_acpi_cht() &&
226 !strcmp(hid, "80860F14") &&
227 !strcmp(uid, "2") &&
228 sdhci_acpi_cht_pci_wifi(0x14e4, 0x43ec, 0, 28);
229}
230
181#else 231#else
182 232
183static inline void sdhci_acpi_byt_setting(struct device *dev) 233static inline void sdhci_acpi_byt_setting(struct device *dev)
@@ -189,6 +239,12 @@ static inline bool sdhci_acpi_byt_defer(struct device *dev)
189 return false; 239 return false;
190} 240}
191 241
242static inline bool sdhci_acpi_no_fixup_child_power(const char *hid,
243 const char *uid)
244{
245 return false;
246}
247
192#endif 248#endif
193 249
194static int bxt_get_cd(struct mmc_host *mmc) 250static int bxt_get_cd(struct mmc_host *mmc)
@@ -389,18 +445,20 @@ static int sdhci_acpi_probe(struct platform_device *pdev)
389 if (acpi_bus_get_device(handle, &device)) 445 if (acpi_bus_get_device(handle, &device))
390 return -ENODEV; 446 return -ENODEV;
391 447
448 hid = acpi_device_hid(device);
449 uid = device->pnp.unique_id;
450
392 /* Power on the SDHCI controller and its children */ 451 /* Power on the SDHCI controller and its children */
393 acpi_device_fix_up_power(device); 452 acpi_device_fix_up_power(device);
394 list_for_each_entry(child, &device->children, node) 453 if (!sdhci_acpi_no_fixup_child_power(hid, uid)) {
395 if (child->status.present && child->status.enabled) 454 list_for_each_entry(child, &device->children, node)
396 acpi_device_fix_up_power(child); 455 if (child->status.present && child->status.enabled)
456 acpi_device_fix_up_power(child);
457 }
397 458
398 if (sdhci_acpi_byt_defer(dev)) 459 if (sdhci_acpi_byt_defer(dev))
399 return -EPROBE_DEFER; 460 return -EPROBE_DEFER;
400 461
401 hid = acpi_device_hid(device);
402 uid = device->pnp.unique_id;
403
404 iomem = platform_get_resource(pdev, IORESOURCE_MEM, 0); 462 iomem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
405 if (!iomem) 463 if (!iomem)
406 return -ENOMEM; 464 return -ENOMEM;
diff --git a/drivers/mmc/host/tmio_mmc_core.c b/drivers/mmc/host/tmio_mmc_core.c
index 82b80d42f7ae..88a94355ac90 100644
--- a/drivers/mmc/host/tmio_mmc_core.c
+++ b/drivers/mmc/host/tmio_mmc_core.c
@@ -409,30 +409,29 @@ static void tmio_mmc_transfer_data(struct tmio_mmc_host *host,
409 * Transfer the data 409 * Transfer the data
410 */ 410 */
411 if (host->pdata->flags & TMIO_MMC_32BIT_DATA_PORT) { 411 if (host->pdata->flags & TMIO_MMC_32BIT_DATA_PORT) {
412 u8 data[4] = { }; 412 u32 data = 0;
413 u32 *buf32 = (u32 *)buf;
413 414
414 if (is_read) 415 if (is_read)
415 sd_ctrl_read32_rep(host, CTL_SD_DATA_PORT, (u32 *)buf, 416 sd_ctrl_read32_rep(host, CTL_SD_DATA_PORT, buf32,
416 count >> 2); 417 count >> 2);
417 else 418 else
418 sd_ctrl_write32_rep(host, CTL_SD_DATA_PORT, (u32 *)buf, 419 sd_ctrl_write32_rep(host, CTL_SD_DATA_PORT, buf32,
419 count >> 2); 420 count >> 2);
420 421
421 /* if count was multiple of 4 */ 422 /* if count was multiple of 4 */
422 if (!(count & 0x3)) 423 if (!(count & 0x3))
423 return; 424 return;
424 425
425 buf8 = (u8 *)(buf + (count >> 2)); 426 buf32 += count >> 2;
426 count %= 4; 427 count %= 4;
427 428
428 if (is_read) { 429 if (is_read) {
429 sd_ctrl_read32_rep(host, CTL_SD_DATA_PORT, 430 sd_ctrl_read32_rep(host, CTL_SD_DATA_PORT, &data, 1);
430 (u32 *)data, 1); 431 memcpy(buf32, &data, count);
431 memcpy(buf8, data, count);
432 } else { 432 } else {
433 memcpy(data, buf8, count); 433 memcpy(&data, buf32, count);
434 sd_ctrl_write32_rep(host, CTL_SD_DATA_PORT, 434 sd_ctrl_write32_rep(host, CTL_SD_DATA_PORT, &data, 1);
435 (u32 *)data, 1);
436 } 435 }
437 436
438 return; 437 return;