Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 84c46a53 authored by Pierre Ossman's avatar Pierre Ossman
Browse files

sdhci: support JMicron JMB38x chips



The JMicron JMB38x chip doesn't support transfers that aren't 32-bit
aligned (both size and start address). It also doesn't like switching
between PIO and DMA mode, so it needs to be reset after each request.

Signed-off-by: default avatarPierre Ossman <drzeus@drzeus.cx>
parent c9fddbc4
Loading
Loading
Loading
Loading
+18 −1
Original line number Diff line number Diff line
@@ -7,6 +7,10 @@
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or (at
 * your option) any later version.
 *
 * Thanks to the following companies for their support:
 *
 *     - JMicron (hardware and technical support)
 */

#include <linux/delay.h>
@@ -47,6 +51,8 @@ static unsigned int debug_quirks = 0;
#define SDHCI_QUIRK_32BIT_DMA_ADDR			(1<<6)
/* Controller can only DMA chunk sizes that are a multiple of 32 bits */
#define SDHCI_QUIRK_32BIT_DMA_SIZE			(1<<7)
/* Controller needs to be reset after each request to stay stable */
#define SDHCI_QUIRK_RESET_AFTER_REQUEST			(1<<8)

static const struct pci_device_id pci_ids[] __devinitdata = {
	{
@@ -111,6 +117,16 @@ static const struct pci_device_id pci_ids[] __devinitdata = {
				  SDHCI_QUIRK_RESET_CMD_DATA_ON_IOS,
	},

	{
		.vendor         = PCI_VENDOR_ID_JMICRON,
		.device         = PCI_DEVICE_ID_JMICRON_JMB38X_SD,
		.subvendor      = PCI_ANY_ID,
		.subdevice      = PCI_ANY_ID,
		.driver_data    = SDHCI_QUIRK_32BIT_DMA_ADDR |
				  SDHCI_QUIRK_32BIT_DMA_SIZE |
				  SDHCI_QUIRK_RESET_AFTER_REQUEST,
	},

	{	/* Generic SD host controller */
		PCI_DEVICE_CLASS((PCI_CLASS_SYSTEM_SDHCI << 8), 0xFFFF00)
	},
@@ -922,7 +938,8 @@ static void sdhci_tasklet_finish(unsigned long param)
	 */
	if (mrq->cmd->error ||
		(mrq->data && (mrq->data->error ||
		(mrq->data->stop && mrq->data->stop->error)))) {
		(mrq->data->stop && mrq->data->stop->error))) ||
		(host->chip->quirks & SDHCI_QUIRK_RESET_AFTER_REQUEST)) {

		/* Some controllers need this kick or reset won't work here */
		if (host->chip->quirks & SDHCI_QUIRK_CLOCK_BEFORE_RESET) {
+1 −0
Original line number Diff line number Diff line
@@ -2148,6 +2148,7 @@
#define PCI_DEVICE_ID_JMICRON_JMB365	0x2365
#define PCI_DEVICE_ID_JMICRON_JMB366	0x2366
#define PCI_DEVICE_ID_JMICRON_JMB368	0x2368
#define PCI_DEVICE_ID_JMICRON_JMB38X_SD	0x2381

#define PCI_VENDOR_ID_KORENIX		0x1982
#define PCI_DEVICE_ID_KORENIX_JETCARDF0	0x1600