[bhnd] Add support for matching on chip identifiers.

This is used by the upcoming SPROM code to match on chipsets
that require special handling of muxed SPROM pins.

Submitted by:	Landon Fuller <landonf@landonf.org>
Differential Revision:	https://reviews.freebsd.org/D6195
This commit is contained in:
Adrian Chadd 2016-05-08 18:30:08 +00:00
parent a73ac06d93
commit f74f1a68d5
2 changed files with 130 additions and 4 deletions

View File

@ -232,6 +232,65 @@ struct bhnd_core_match {
.unit = -1 \
}
/** A chipset match descriptor. */
struct bhnd_chip_match {
/** Select fields to be matched */
uint8_t
match_id:1,
match_rev:1,
match_pkg:1,
match_flags_unused:5;
uint16_t chip_id; /**< required chip id */
struct bhnd_hwrev_match chip_rev; /**< matching chip revisions */
uint8_t chip_pkg; /**< required package */
};
#define BHND_CHIP_MATCH_ANY \
{ .match_id = 0, .match_rev = 0, .match_pkg = 0 }
#define BHND_CHIP_MATCH_IS_ANY(_m) \
((_m)->match_id == 0 && (_m)->match_rev == 0 && (_m)->match_pkg == 0)
/** Set the required chip ID within a bhnd_chip_match instance */
#define BHND_CHIP_ID(_cid) \
.match_id = 1, .chip_id = BHND_CHIPID_BCM ## _cid
/** Set the required revision range within a bhnd_chip_match instance */
#define BHND_CHIP_REV(_rev) \
.match_rev = 1, .chip_rev = BHND_ ## _rev
/** Set the required package ID within a bhnd_chip_match instance */
#define BHND_CHIP_PKG(_pkg) \
.match_pkg = 1, .chip_pkg = BHND_PKGID_BCM ## _pkg
/** Set the required chip and package ID within a bhnd_chip_match instance */
#define BHND_CHIP_IP(_cid, _pkg) \
BHND_CHIP_ID(_cid), BHND_CHIP_PKG(_pkg)
/** Set the required chip ID, package ID, and revision within a bhnd_chip_match
* instance */
#define BHND_CHIP_IPR(_cid, _pkg, _rev) \
BHND_CHIP_ID(_cid), BHND_CHIP_PKG(_pkg), BHND_CHIP_REV(_rev)
/** Set the required chip ID and revision within a bhnd_chip_match
* instance */
#define BHND_CHIP_IR(_cid, _rev) \
BHND_CHIP_ID(_cid), BHND_CHIP_REV(_rev)
/**
* Chipset quirk table descriptor.
*/
struct bhnd_chip_quirk {
const struct bhnd_chip_match chip; /**< chip match descriptor */
uint32_t quirks; /**< quirk flags */
};
#define BHND_CHIP_QUIRK_END { BHND_CHIP_MATCH_ANY, 0 }
#define BHND_CHIP_QUIRK_IS_END(_q) \
(BHND_CHIP_MATCH_IS_ANY(&(_q)->chip) && (_q)->quirks == 0)
/**
* Device quirk table descriptor.
*/
@ -297,9 +356,16 @@ bool bhnd_core_matches(
const struct bhnd_core_info *core,
const struct bhnd_core_match *desc);
bool bhnd_chip_matches(
const struct bhnd_chipid *chipid,
const struct bhnd_chip_match *desc);
bool bhnd_hwrev_matches(uint16_t hwrev,
const struct bhnd_hwrev_match *desc);
uint32_t bhnd_chip_quirks(device_t dev,
const struct bhnd_chip_quirk *table);
bool bhnd_device_matches(device_t dev,
const struct bhnd_core_match *desc);
@ -388,6 +454,17 @@ bhnd_is_hw_disabled(device_t dev) {
return (BHND_BUS_IS_HW_DISABLED(device_get_parent(dev), dev));
}
/**
* Return the BHND chip identification info for the bhnd bus.
*
* @param dev A bhnd bus child device.
*/
static inline const struct bhnd_chipid *
bhnd_get_chipid(device_t dev) {
return (BHND_BUS_GET_CHIPID(device_get_parent(dev), dev));
};
/**
* Allocate a resource from a device's parent bhnd(4) bus.
*

View File

@ -415,10 +415,6 @@ bhnd_core_matches(const struct bhnd_core_info *core,
if (!bhnd_hwrev_matches(core->hwrev, &desc->hwrev))
return (false);
if (desc->hwrev.end != BHND_HWREV_INVALID &&
desc->hwrev.end < core->hwrev)
return (false);
if (desc->class != BHND_DEVCLASS_INVALID &&
desc->class != bhnd_core_class(core))
@ -427,6 +423,32 @@ bhnd_core_matches(const struct bhnd_core_info *core,
return true;
}
/**
* Return true if the @p chip matches @p desc.
*
* @param chip A bhnd chip identifier.
* @param desc A match descriptor to compare against @p chip.
*
* @retval true if @p chip matches @p match
* @retval false if @p chip does not match @p match.
*/
bool
bhnd_chip_matches(const struct bhnd_chipid *chip,
const struct bhnd_chip_match *desc)
{
if (desc->match_id && chip->chip_id != desc->chip_id)
return (false);
if (desc->match_pkg && chip->chip_pkg != desc->chip_pkg)
return (false);
if (desc->match_rev &&
!bhnd_hwrev_matches(chip->chip_rev, &desc->chip_rev))
return (false);
return (true);
}
/**
* Return true if the @p hwrev matches @p desc.
*
@ -513,6 +535,33 @@ bhnd_device_lookup(device_t dev, const struct bhnd_device *table,
return (NULL);
}
/**
* Scan @p table for all quirk flags applicable to @p dev's chip identifier
* (as returned by bhnd_get_chipid).
*
* @param dev A bhnd device.
* @param table The chip quirk table to search.
*
* @return returns all matching quirk flags.
*/
uint32_t
bhnd_chip_quirks(device_t dev, const struct bhnd_chip_quirk *table)
{
const struct bhnd_chipid *cid;
const struct bhnd_chip_quirk *qent;
uint32_t quirks;
cid = bhnd_get_chipid(dev);
quirks = 0;
for (qent = table; !BHND_CHIP_QUIRK_IS_END(qent); qent++) {
if (bhnd_chip_matches(cid, &qent->chip))
quirks |= qent->quirks;
}
return (quirks);
}
/**
* Scan @p table for all quirk flags applicable to @p dev.
*