diff options
Diffstat (limited to 'drivers/mmc/core/quirks.h')
| -rw-r--r-- | drivers/mmc/core/quirks.h | 64 | 
1 files changed, 47 insertions, 17 deletions
| diff --git a/drivers/mmc/core/quirks.h b/drivers/mmc/core/quirks.h index d68e6e513a4f..20f568727277 100644 --- a/drivers/mmc/core/quirks.h +++ b/drivers/mmc/core/quirks.h @@ -10,6 +10,7 @@   *   */ +#include <linux/of.h>  #include <linux/mmc/sdio_ids.h>  #include "card.h" @@ -145,6 +146,25 @@ static const struct mmc_fixup __maybe_unused sdio_fixup_methods[] = {  	END_FIXUP  }; +static const struct mmc_fixup __maybe_unused sdio_card_init_methods[] = { +	SDIO_FIXUP_COMPATIBLE("ti,wl1251", wl1251_quirk, 0), + +	END_FIXUP +}; + +static inline bool mmc_fixup_of_compatible_match(struct mmc_card *card, +						 const char *compatible) +{ +	struct device_node *np; + +	for_each_child_of_node(mmc_dev(card->host)->of_node, np) { +		if (of_device_is_compatible(np, compatible)) +			return true; +	} + +	return false; +} +  static inline void mmc_fixup_device(struct mmc_card *card,  				    const struct mmc_fixup *table)  { @@ -152,22 +172,32 @@ static inline void mmc_fixup_device(struct mmc_card *card,  	u64 rev = cid_rev_card(card);  	for (f = table; f->vendor_fixup; f++) { -		if ((f->manfid == CID_MANFID_ANY || -		     f->manfid == card->cid.manfid) && -		    (f->oemid == CID_OEMID_ANY || -		     f->oemid == card->cid.oemid) && -		    (f->name == CID_NAME_ANY || -		     !strncmp(f->name, card->cid.prod_name, -			      sizeof(card->cid.prod_name))) && -		    (f->cis_vendor == card->cis.vendor || -		     f->cis_vendor == (u16) SDIO_ANY_ID) && -		    (f->cis_device == card->cis.device || -		     f->cis_device == (u16) SDIO_ANY_ID) && -		    (f->ext_csd_rev == EXT_CSD_REV_ANY || -		     f->ext_csd_rev == card->ext_csd.rev) && -		    rev >= f->rev_start && rev <= f->rev_end) { -			dev_dbg(&card->dev, "calling %ps\n", f->vendor_fixup); -			f->vendor_fixup(card, f->data); -		} +		if (f->manfid != CID_MANFID_ANY && +		    f->manfid != card->cid.manfid) +			continue; +		if (f->oemid != CID_OEMID_ANY && +		    f->oemid != card->cid.oemid) +			continue; +		if (f->name != CID_NAME_ANY && +		    strncmp(f->name, card->cid.prod_name, +			    sizeof(card->cid.prod_name))) +			continue; +		if (f->cis_vendor != (u16)SDIO_ANY_ID && +		    f->cis_vendor != card->cis.vendor) +			continue; +		if (f->cis_device != (u16)SDIO_ANY_ID && +		    f->cis_device != card->cis.device) +			continue; +		if (f->ext_csd_rev != EXT_CSD_REV_ANY && +		    f->ext_csd_rev != card->ext_csd.rev) +			continue; +		if (rev < f->rev_start || rev > f->rev_end) +			continue; +		if (f->of_compatible && +		    !mmc_fixup_of_compatible_match(card, f->of_compatible)) +			continue; + +		dev_dbg(&card->dev, "calling %ps\n", f->vendor_fixup); +		f->vendor_fixup(card, f->data);  	}  } |