cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

sdio.c (15915B)


      1/*
      2 * Sonics Silicon Backplane
      3 * SDIO-Hostbus related functions
      4 *
      5 * Copyright 2009 Albert Herranz <albert_herranz@yahoo.es>
      6 *
      7 * Based on drivers/ssb/pcmcia.c
      8 * Copyright 2006 Johannes Berg <johannes@sipsolutions.net>
      9 * Copyright 2007-2008 Michael Buesch <m@bues.ch>
     10 *
     11 * Licensed under the GNU/GPL. See COPYING for details.
     12 *
     13 */
     14
     15#include "ssb_private.h"
     16
     17#include <linux/ssb/ssb.h>
     18#include <linux/delay.h>
     19#include <linux/io.h>
     20#include <linux/etherdevice.h>
     21#include <linux/mmc/sdio_func.h>
     22
     23/* Define the following to 1 to enable a printk on each coreswitch. */
     24#define SSB_VERBOSE_SDIOCORESWITCH_DEBUG		0
     25
     26
     27/* Hardware invariants CIS tuples */
     28#define SSB_SDIO_CIS			0x80
     29#define  SSB_SDIO_CIS_SROMREV		0x00
     30#define  SSB_SDIO_CIS_ID		0x01
     31#define  SSB_SDIO_CIS_BOARDREV		0x02
     32#define  SSB_SDIO_CIS_PA		0x03
     33#define   SSB_SDIO_CIS_PA_PA0B0_LO	0
     34#define   SSB_SDIO_CIS_PA_PA0B0_HI	1
     35#define   SSB_SDIO_CIS_PA_PA0B1_LO	2
     36#define   SSB_SDIO_CIS_PA_PA0B1_HI	3
     37#define   SSB_SDIO_CIS_PA_PA0B2_LO	4
     38#define   SSB_SDIO_CIS_PA_PA0B2_HI	5
     39#define   SSB_SDIO_CIS_PA_ITSSI		6
     40#define   SSB_SDIO_CIS_PA_MAXPOW	7
     41#define  SSB_SDIO_CIS_OEMNAME		0x04
     42#define  SSB_SDIO_CIS_CCODE		0x05
     43#define  SSB_SDIO_CIS_ANTENNA		0x06
     44#define  SSB_SDIO_CIS_ANTGAIN		0x07
     45#define  SSB_SDIO_CIS_BFLAGS		0x08
     46#define  SSB_SDIO_CIS_LEDS		0x09
     47
     48#define CISTPL_FUNCE_LAN_NODE_ID        0x04	/* same as in PCMCIA */
     49
     50
     51/*
     52 * Function 1 miscellaneous registers.
     53 *
     54 * Definitions match src/include/sbsdio.h from the
     55 * Android Open Source Project
     56 * http://android.git.kernel.org/?p=platform/system/wlan/broadcom.git
     57 *
     58 */
     59#define SBSDIO_FUNC1_SBADDRLOW	0x1000a	/* SB Address window Low (b15) */
     60#define SBSDIO_FUNC1_SBADDRMID	0x1000b	/* SB Address window Mid (b23-b16) */
     61#define SBSDIO_FUNC1_SBADDRHIGH	0x1000c	/* SB Address window High (b24-b31) */
     62
     63/* valid bits in SBSDIO_FUNC1_SBADDRxxx regs */
     64#define SBSDIO_SBADDRLOW_MASK	0x80	/* Valid address bits in SBADDRLOW */
     65#define SBSDIO_SBADDRMID_MASK	0xff	/* Valid address bits in SBADDRMID */
     66#define SBSDIO_SBADDRHIGH_MASK	0xff	/* Valid address bits in SBADDRHIGH */
     67
     68#define SBSDIO_SB_OFT_ADDR_MASK	0x7FFF	/* sb offset addr is <= 15 bits, 32k */
     69
     70/* REVISIT: this flag doesn't seem to matter */
     71#define SBSDIO_SB_ACCESS_2_4B_FLAG	0x8000	/* forces 32-bit SB access */
     72
     73
     74/*
     75 * Address map within the SDIO function address space (128K).
     76 *
     77 *   Start   End     Description
     78 *   ------- ------- ------------------------------------------
     79 *   0x00000 0x0ffff selected backplane address window (64K)
     80 *   0x10000 0x1ffff backplane control registers (max 64K)
     81 *
     82 * The current address window is configured by writing to registers
     83 * SBADDRLOW, SBADDRMID and SBADDRHIGH.
     84 *
     85 * In order to access the contents of a 32-bit Silicon Backplane address
     86 * the backplane address window must be first loaded with the highest
     87 * 16 bits of the target address. Then, an access must be done to the
     88 * SDIO function address space using the lower 15 bits of the address.
     89 * Bit 15 of the address must be set when doing 32 bit accesses.
     90 *
     91 * 10987654321098765432109876543210
     92 * WWWWWWWWWWWWWWWWW                 SB Address Window
     93 *                 OOOOOOOOOOOOOOOO  Offset within SB Address Window
     94 *                 a                 32-bit access flag
     95 */
     96
     97
     98/*
     99 * SSB I/O via SDIO.
    100 *
    101 * NOTE: SDIO address @addr is 17 bits long (SDIO address space is 128K).
    102 */
    103
    104static inline struct device *ssb_sdio_dev(struct ssb_bus *bus)
    105{
    106	return &bus->host_sdio->dev;
    107}
    108
    109/* host claimed */
    110static int ssb_sdio_writeb(struct ssb_bus *bus, unsigned int addr, u8 val)
    111{
    112	int error = 0;
    113
    114	sdio_writeb(bus->host_sdio, val, addr, &error);
    115	if (unlikely(error)) {
    116		dev_dbg(ssb_sdio_dev(bus), "%08X <- %02x, error %d\n",
    117			addr, val, error);
    118	}
    119
    120	return error;
    121}
    122
    123#if 0
    124static u8 ssb_sdio_readb(struct ssb_bus *bus, unsigned int addr)
    125{
    126	u8 val;
    127	int error = 0;
    128
    129	val = sdio_readb(bus->host_sdio, addr, &error);
    130	if (unlikely(error)) {
    131		dev_dbg(ssb_sdio_dev(bus), "%08X -> %02x, error %d\n",
    132			addr, val, error);
    133	}
    134
    135	return val;
    136}
    137#endif
    138
    139/* host claimed */
    140static int ssb_sdio_set_sbaddr_window(struct ssb_bus *bus, u32 address)
    141{
    142	int error;
    143
    144	error = ssb_sdio_writeb(bus, SBSDIO_FUNC1_SBADDRLOW,
    145				(address >> 8) & SBSDIO_SBADDRLOW_MASK);
    146	if (error)
    147		goto out;
    148	error = ssb_sdio_writeb(bus, SBSDIO_FUNC1_SBADDRMID,
    149				(address >> 16) & SBSDIO_SBADDRMID_MASK);
    150	if (error)
    151		goto out;
    152	error = ssb_sdio_writeb(bus, SBSDIO_FUNC1_SBADDRHIGH,
    153				(address >> 24) & SBSDIO_SBADDRHIGH_MASK);
    154	if (error)
    155		goto out;
    156	bus->sdio_sbaddr = address;
    157out:
    158	if (error) {
    159		dev_dbg(ssb_sdio_dev(bus), "failed to set address window"
    160			" to 0x%08x, error %d\n", address, error);
    161	}
    162
    163	return error;
    164}
    165
    166/* for enumeration use only */
    167u32 ssb_sdio_scan_read32(struct ssb_bus *bus, u16 offset)
    168{
    169	u32 val;
    170	int error;
    171
    172	sdio_claim_host(bus->host_sdio);
    173	val = sdio_readl(bus->host_sdio, offset, &error);
    174	sdio_release_host(bus->host_sdio);
    175	if (unlikely(error)) {
    176		dev_dbg(ssb_sdio_dev(bus), "%04X:%04X > %08x, error %d\n",
    177			bus->sdio_sbaddr >> 16, offset, val, error);
    178	}
    179
    180	return val;
    181}
    182
    183/* for enumeration use only */
    184int ssb_sdio_scan_switch_coreidx(struct ssb_bus *bus, u8 coreidx)
    185{
    186	u32 sbaddr;
    187	int error;
    188
    189	sbaddr = (coreidx * SSB_CORE_SIZE) + SSB_ENUM_BASE;
    190	sdio_claim_host(bus->host_sdio);
    191	error = ssb_sdio_set_sbaddr_window(bus, sbaddr);
    192	sdio_release_host(bus->host_sdio);
    193	if (error) {
    194		dev_err(ssb_sdio_dev(bus), "failed to switch to core %u,"
    195			" error %d\n", coreidx, error);
    196		goto out;
    197	}
    198out:
    199	return error;
    200}
    201
    202/* host must be already claimed */
    203static int ssb_sdio_switch_core(struct ssb_bus *bus, struct ssb_device *dev)
    204{
    205	u8 coreidx = dev->core_index;
    206	u32 sbaddr;
    207	int error = 0;
    208
    209	sbaddr = (coreidx * SSB_CORE_SIZE) + SSB_ENUM_BASE;
    210	if (unlikely(bus->sdio_sbaddr != sbaddr)) {
    211#if SSB_VERBOSE_SDIOCORESWITCH_DEBUG
    212		dev_info(ssb_sdio_dev(bus),
    213			   "switching to %s core, index %d\n",
    214			   ssb_core_name(dev->id.coreid), coreidx);
    215#endif
    216		error = ssb_sdio_set_sbaddr_window(bus, sbaddr);
    217		if (error) {
    218			dev_dbg(ssb_sdio_dev(bus), "failed to switch to"
    219				" core %u, error %d\n", coreidx, error);
    220			goto out;
    221		}
    222		bus->mapped_device = dev;
    223	}
    224
    225out:
    226	return error;
    227}
    228
    229static u8 ssb_sdio_read8(struct ssb_device *dev, u16 offset)
    230{
    231	struct ssb_bus *bus = dev->bus;
    232	u8 val = 0xff;
    233	int error = 0;
    234
    235	sdio_claim_host(bus->host_sdio);
    236	if (unlikely(ssb_sdio_switch_core(bus, dev)))
    237		goto out;
    238	offset |= bus->sdio_sbaddr & 0xffff;
    239	offset &= SBSDIO_SB_OFT_ADDR_MASK;
    240	val = sdio_readb(bus->host_sdio, offset, &error);
    241	if (error) {
    242		dev_dbg(ssb_sdio_dev(bus), "%04X:%04X > %02x, error %d\n",
    243			bus->sdio_sbaddr >> 16, offset, val, error);
    244	}
    245out:
    246	sdio_release_host(bus->host_sdio);
    247
    248	return val;
    249}
    250
    251static u16 ssb_sdio_read16(struct ssb_device *dev, u16 offset)
    252{
    253	struct ssb_bus *bus = dev->bus;
    254	u16 val = 0xffff;
    255	int error = 0;
    256
    257	sdio_claim_host(bus->host_sdio);
    258	if (unlikely(ssb_sdio_switch_core(bus, dev)))
    259		goto out;
    260	offset |= bus->sdio_sbaddr & 0xffff;
    261	offset &= SBSDIO_SB_OFT_ADDR_MASK;
    262	val = sdio_readw(bus->host_sdio, offset, &error);
    263	if (error) {
    264		dev_dbg(ssb_sdio_dev(bus), "%04X:%04X > %04x, error %d\n",
    265			bus->sdio_sbaddr >> 16, offset, val, error);
    266	}
    267out:
    268	sdio_release_host(bus->host_sdio);
    269
    270	return val;
    271}
    272
    273static u32 ssb_sdio_read32(struct ssb_device *dev, u16 offset)
    274{
    275	struct ssb_bus *bus = dev->bus;
    276	u32 val = 0xffffffff;
    277	int error = 0;
    278
    279	sdio_claim_host(bus->host_sdio);
    280	if (unlikely(ssb_sdio_switch_core(bus, dev)))
    281		goto out;
    282	offset |= bus->sdio_sbaddr & 0xffff;
    283	offset &= SBSDIO_SB_OFT_ADDR_MASK;
    284	offset |= SBSDIO_SB_ACCESS_2_4B_FLAG;	/* 32 bit data access */
    285	val = sdio_readl(bus->host_sdio, offset, &error);
    286	if (error) {
    287		dev_dbg(ssb_sdio_dev(bus), "%04X:%04X > %08x, error %d\n",
    288			bus->sdio_sbaddr >> 16, offset, val, error);
    289	}
    290out:
    291	sdio_release_host(bus->host_sdio);
    292
    293	return val;
    294}
    295
    296#ifdef CONFIG_SSB_BLOCKIO
    297static void ssb_sdio_block_read(struct ssb_device *dev, void *buffer,
    298				  size_t count, u16 offset, u8 reg_width)
    299{
    300	size_t saved_count = count;
    301	struct ssb_bus *bus = dev->bus;
    302	int error = 0;
    303
    304	sdio_claim_host(bus->host_sdio);
    305	if (unlikely(ssb_sdio_switch_core(bus, dev))) {
    306		error = -EIO;
    307		memset(buffer, 0xff, count);
    308		goto err_out;
    309	}
    310	offset |= bus->sdio_sbaddr & 0xffff;
    311	offset &= SBSDIO_SB_OFT_ADDR_MASK;
    312
    313	switch (reg_width) {
    314	case sizeof(u8): {
    315		error = sdio_readsb(bus->host_sdio, buffer, offset, count);
    316		break;
    317	}
    318	case sizeof(u16): {
    319		WARN_ON(count & 1);
    320		error = sdio_readsb(bus->host_sdio, buffer, offset, count);
    321		break;
    322	}
    323	case sizeof(u32): {
    324		WARN_ON(count & 3);
    325		offset |= SBSDIO_SB_ACCESS_2_4B_FLAG;	/* 32 bit data access */
    326		error = sdio_readsb(bus->host_sdio, buffer, offset, count);
    327		break;
    328	}
    329	default:
    330		WARN_ON(1);
    331	}
    332	if (!error)
    333		goto out;
    334
    335err_out:
    336	dev_dbg(ssb_sdio_dev(bus), "%04X:%04X (width=%u, len=%zu), error %d\n",
    337		bus->sdio_sbaddr >> 16, offset, reg_width, saved_count, error);
    338out:
    339	sdio_release_host(bus->host_sdio);
    340}
    341#endif /* CONFIG_SSB_BLOCKIO */
    342
    343static void ssb_sdio_write8(struct ssb_device *dev, u16 offset, u8 val)
    344{
    345	struct ssb_bus *bus = dev->bus;
    346	int error = 0;
    347
    348	sdio_claim_host(bus->host_sdio);
    349	if (unlikely(ssb_sdio_switch_core(bus, dev)))
    350		goto out;
    351	offset |= bus->sdio_sbaddr & 0xffff;
    352	offset &= SBSDIO_SB_OFT_ADDR_MASK;
    353	sdio_writeb(bus->host_sdio, val, offset, &error);
    354	if (error) {
    355		dev_dbg(ssb_sdio_dev(bus), "%04X:%04X < %02x, error %d\n",
    356			bus->sdio_sbaddr >> 16, offset, val, error);
    357	}
    358out:
    359	sdio_release_host(bus->host_sdio);
    360}
    361
    362static void ssb_sdio_write16(struct ssb_device *dev, u16 offset, u16 val)
    363{
    364	struct ssb_bus *bus = dev->bus;
    365	int error = 0;
    366
    367	sdio_claim_host(bus->host_sdio);
    368	if (unlikely(ssb_sdio_switch_core(bus, dev)))
    369		goto out;
    370	offset |= bus->sdio_sbaddr & 0xffff;
    371	offset &= SBSDIO_SB_OFT_ADDR_MASK;
    372	sdio_writew(bus->host_sdio, val, offset, &error);
    373	if (error) {
    374		dev_dbg(ssb_sdio_dev(bus), "%04X:%04X < %04x, error %d\n",
    375			bus->sdio_sbaddr >> 16, offset, val, error);
    376	}
    377out:
    378	sdio_release_host(bus->host_sdio);
    379}
    380
    381static void ssb_sdio_write32(struct ssb_device *dev, u16 offset, u32 val)
    382{
    383	struct ssb_bus *bus = dev->bus;
    384	int error = 0;
    385
    386	sdio_claim_host(bus->host_sdio);
    387	if (unlikely(ssb_sdio_switch_core(bus, dev)))
    388		goto out;
    389	offset |= bus->sdio_sbaddr & 0xffff;
    390	offset &= SBSDIO_SB_OFT_ADDR_MASK;
    391	offset |= SBSDIO_SB_ACCESS_2_4B_FLAG;	/* 32 bit data access */
    392	sdio_writel(bus->host_sdio, val, offset, &error);
    393	if (error) {
    394		dev_dbg(ssb_sdio_dev(bus), "%04X:%04X < %08x, error %d\n",
    395			bus->sdio_sbaddr >> 16, offset, val, error);
    396	}
    397	if (bus->quirks & SSB_QUIRK_SDIO_READ_AFTER_WRITE32)
    398		sdio_readl(bus->host_sdio, 0, &error);
    399out:
    400	sdio_release_host(bus->host_sdio);
    401}
    402
    403#ifdef CONFIG_SSB_BLOCKIO
    404static void ssb_sdio_block_write(struct ssb_device *dev, const void *buffer,
    405				   size_t count, u16 offset, u8 reg_width)
    406{
    407	size_t saved_count = count;
    408	struct ssb_bus *bus = dev->bus;
    409	int error = 0;
    410
    411	sdio_claim_host(bus->host_sdio);
    412	if (unlikely(ssb_sdio_switch_core(bus, dev))) {
    413		error = -EIO;
    414		goto err_out;
    415	}
    416	offset |= bus->sdio_sbaddr & 0xffff;
    417	offset &= SBSDIO_SB_OFT_ADDR_MASK;
    418
    419	switch (reg_width) {
    420	case sizeof(u8):
    421		error = sdio_writesb(bus->host_sdio, offset,
    422				     (void *)buffer, count);
    423		break;
    424	case sizeof(u16):
    425		WARN_ON(count & 1);
    426		error = sdio_writesb(bus->host_sdio, offset,
    427				     (void *)buffer, count);
    428		break;
    429	case sizeof(u32):
    430		WARN_ON(count & 3);
    431		offset |= SBSDIO_SB_ACCESS_2_4B_FLAG;	/* 32 bit data access */
    432		error = sdio_writesb(bus->host_sdio, offset,
    433				     (void *)buffer, count);
    434		break;
    435	default:
    436		WARN_ON(1);
    437	}
    438	if (!error)
    439		goto out;
    440
    441err_out:
    442	dev_dbg(ssb_sdio_dev(bus), "%04X:%04X (width=%u, len=%zu), error %d\n",
    443		bus->sdio_sbaddr >> 16, offset, reg_width, saved_count, error);
    444out:
    445	sdio_release_host(bus->host_sdio);
    446}
    447
    448#endif /* CONFIG_SSB_BLOCKIO */
    449
    450/* Not "static", as it's used in main.c */
    451const struct ssb_bus_ops ssb_sdio_ops = {
    452	.read8		= ssb_sdio_read8,
    453	.read16		= ssb_sdio_read16,
    454	.read32		= ssb_sdio_read32,
    455	.write8		= ssb_sdio_write8,
    456	.write16	= ssb_sdio_write16,
    457	.write32	= ssb_sdio_write32,
    458#ifdef CONFIG_SSB_BLOCKIO
    459	.block_read	= ssb_sdio_block_read,
    460	.block_write	= ssb_sdio_block_write,
    461#endif
    462};
    463
    464#define GOTO_ERROR_ON(condition, description) do {	\
    465	if (unlikely(condition)) {			\
    466		error_description = description;	\
    467		goto error;				\
    468	}						\
    469  } while (0)
    470
    471int ssb_sdio_get_invariants(struct ssb_bus *bus,
    472			    struct ssb_init_invariants *iv)
    473{
    474	struct ssb_sprom *sprom = &iv->sprom;
    475	struct ssb_boardinfo *bi = &iv->boardinfo;
    476	const char *error_description = "none";
    477	struct sdio_func_tuple *tuple;
    478	void *mac;
    479
    480	memset(sprom, 0xFF, sizeof(*sprom));
    481	sprom->boardflags_lo = 0;
    482	sprom->boardflags_hi = 0;
    483
    484	tuple = bus->host_sdio->tuples;
    485	while (tuple) {
    486		switch (tuple->code) {
    487		case 0x22: /* extended function */
    488			switch (tuple->data[0]) {
    489			case CISTPL_FUNCE_LAN_NODE_ID:
    490				GOTO_ERROR_ON((tuple->size != 7) &&
    491					      (tuple->data[1] != 6),
    492					      "mac tpl size");
    493				/* fetch the MAC address. */
    494				mac = tuple->data + 2;
    495				memcpy(sprom->il0mac, mac, ETH_ALEN);
    496				memcpy(sprom->et1mac, mac, ETH_ALEN);
    497				break;
    498			default:
    499				break;
    500			}
    501			break;
    502		case 0x80: /* vendor specific tuple */
    503			switch (tuple->data[0]) {
    504			case SSB_SDIO_CIS_SROMREV:
    505				GOTO_ERROR_ON(tuple->size != 2,
    506					      "sromrev tpl size");
    507				sprom->revision = tuple->data[1];
    508				break;
    509			case SSB_SDIO_CIS_ID:
    510				GOTO_ERROR_ON((tuple->size != 5) &&
    511					      (tuple->size != 7),
    512					      "id tpl size");
    513				bi->vendor = tuple->data[1] |
    514					     (tuple->data[2]<<8);
    515				break;
    516			case SSB_SDIO_CIS_BOARDREV:
    517				GOTO_ERROR_ON(tuple->size != 2,
    518					      "boardrev tpl size");
    519				sprom->board_rev = tuple->data[1];
    520				break;
    521			case SSB_SDIO_CIS_PA:
    522				GOTO_ERROR_ON((tuple->size != 9) &&
    523					      (tuple->size != 10),
    524					      "pa tpl size");
    525				sprom->pa0b0 = tuple->data[1] |
    526					 ((u16)tuple->data[2] << 8);
    527				sprom->pa0b1 = tuple->data[3] |
    528					 ((u16)tuple->data[4] << 8);
    529				sprom->pa0b2 = tuple->data[5] |
    530					 ((u16)tuple->data[6] << 8);
    531				sprom->itssi_a = tuple->data[7];
    532				sprom->itssi_bg = tuple->data[7];
    533				sprom->maxpwr_a = tuple->data[8];
    534				sprom->maxpwr_bg = tuple->data[8];
    535				break;
    536			case SSB_SDIO_CIS_OEMNAME:
    537				/* Not present */
    538				break;
    539			case SSB_SDIO_CIS_CCODE:
    540				GOTO_ERROR_ON(tuple->size != 2,
    541					      "ccode tpl size");
    542				sprom->country_code = tuple->data[1];
    543				break;
    544			case SSB_SDIO_CIS_ANTENNA:
    545				GOTO_ERROR_ON(tuple->size != 2,
    546					      "ant tpl size");
    547				sprom->ant_available_a = tuple->data[1];
    548				sprom->ant_available_bg = tuple->data[1];
    549				break;
    550			case SSB_SDIO_CIS_ANTGAIN:
    551				GOTO_ERROR_ON(tuple->size != 2,
    552					      "antg tpl size");
    553				sprom->antenna_gain.a0 = tuple->data[1];
    554				sprom->antenna_gain.a1 = tuple->data[1];
    555				sprom->antenna_gain.a2 = tuple->data[1];
    556				sprom->antenna_gain.a3 = tuple->data[1];
    557				break;
    558			case SSB_SDIO_CIS_BFLAGS:
    559				GOTO_ERROR_ON((tuple->size != 3) &&
    560					      (tuple->size != 5),
    561					      "bfl tpl size");
    562				sprom->boardflags_lo = tuple->data[1] |
    563						 ((u16)tuple->data[2] << 8);
    564				break;
    565			case SSB_SDIO_CIS_LEDS:
    566				GOTO_ERROR_ON(tuple->size != 5,
    567					      "leds tpl size");
    568				sprom->gpio0 = tuple->data[1];
    569				sprom->gpio1 = tuple->data[2];
    570				sprom->gpio2 = tuple->data[3];
    571				sprom->gpio3 = tuple->data[4];
    572				break;
    573			default:
    574				break;
    575			}
    576			break;
    577		default:
    578			break;
    579		}
    580		tuple = tuple->next;
    581	}
    582
    583	return 0;
    584error:
    585	dev_err(ssb_sdio_dev(bus), "failed to fetch device invariants: %s\n",
    586		error_description);
    587	return -ENODEV;
    588}
    589
    590void ssb_sdio_exit(struct ssb_bus *bus)
    591{
    592	if (bus->bustype != SSB_BUSTYPE_SDIO)
    593		return;
    594	/* Nothing to do here. */
    595}
    596
    597int ssb_sdio_init(struct ssb_bus *bus)
    598{
    599	if (bus->bustype != SSB_BUSTYPE_SDIO)
    600		return 0;
    601
    602	bus->sdio_sbaddr = ~0;
    603
    604	return 0;
    605}