smbus: Convert to use runtime BDF lookup
Convert PCH SMBus driver, tests and samples to use new dynamic BDF lookup. Signed-off-by: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
This commit is contained in:
parent
14923f4131
commit
a42ab2729f
5 changed files with 27 additions and 30 deletions
|
@ -37,10 +37,7 @@ LOG_MODULE_REGISTER(intel_pch, CONFIG_SMBUS_LOG_LEVEL);
|
||||||
struct pch_config {
|
struct pch_config {
|
||||||
/* IRQ configuration function */
|
/* IRQ configuration function */
|
||||||
void (*config_func)(const struct device *dev);
|
void (*config_func)(const struct device *dev);
|
||||||
/* PCIE BDF got from DTS */
|
struct pcie_dev *pcie;
|
||||||
pcie_bdf_t pcie_bdf;
|
|
||||||
/* PCIE ID got from DTS */
|
|
||||||
pcie_id_t pcie_id;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -245,19 +242,19 @@ static int pch_smbus_init(const struct device *dev)
|
||||||
struct pcie_bar mbar;
|
struct pcie_bar mbar;
|
||||||
uint32_t val;
|
uint32_t val;
|
||||||
|
|
||||||
if (!pcie_probe(config->pcie_bdf, config->pcie_id)) {
|
if (config->pcie->bdf == PCIE_BDF_NONE) {
|
||||||
LOG_ERR("Cannot probe PCI device");
|
LOG_ERR("Cannot probe PCI device");
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
}
|
}
|
||||||
|
|
||||||
val = pcie_conf_read(config->pcie_bdf, PCIE_CONF_CMDSTAT);
|
val = pcie_conf_read(config->pcie->bdf, PCIE_CONF_CMDSTAT);
|
||||||
if (val & PCIE_CONF_CMDSTAT_INTERRUPT) {
|
if (val & PCIE_CONF_CMDSTAT_INTERRUPT) {
|
||||||
LOG_WRN("Pending interrupt, continuing");
|
LOG_WRN("Pending interrupt, continuing");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (IS_ENABLED(CONFIG_SMBUS_INTEL_PCH_ACCESS_MMIO)) {
|
if (IS_ENABLED(CONFIG_SMBUS_INTEL_PCH_ACCESS_MMIO)) {
|
||||||
pcie_probe_mbar(config->pcie_bdf, 0, &mbar);
|
pcie_probe_mbar(config->pcie->bdf, 0, &mbar);
|
||||||
pcie_set_cmd(config->pcie_bdf, PCIE_CONF_CMDSTAT_MEM, true);
|
pcie_set_cmd(config->pcie->bdf, PCIE_CONF_CMDSTAT_MEM, true);
|
||||||
|
|
||||||
device_map(DEVICE_MMIO_RAM_PTR(dev), mbar.phys_addr, mbar.size,
|
device_map(DEVICE_MMIO_RAM_PTR(dev), mbar.phys_addr, mbar.size,
|
||||||
K_MEM_CACHE_NONE);
|
K_MEM_CACHE_NONE);
|
||||||
|
@ -265,8 +262,8 @@ static int pch_smbus_init(const struct device *dev)
|
||||||
LOG_DBG("Mapped 0x%lx size 0x%lx to 0x%lx",
|
LOG_DBG("Mapped 0x%lx size 0x%lx to 0x%lx",
|
||||||
mbar.phys_addr, mbar.size, DEVICE_MMIO_GET(dev));
|
mbar.phys_addr, mbar.size, DEVICE_MMIO_GET(dev));
|
||||||
} else {
|
} else {
|
||||||
pcie_set_cmd(config->pcie_bdf, PCIE_CONF_CMDSTAT_IO, true);
|
pcie_set_cmd(config->pcie->bdf, PCIE_CONF_CMDSTAT_IO, true);
|
||||||
val = pcie_conf_read(config->pcie_bdf, PCIE_CONF_BAR4);
|
val = pcie_conf_read(config->pcie->bdf, PCIE_CONF_BAR4);
|
||||||
if (!PCIE_CONF_BAR_IO(val)) {
|
if (!PCIE_CONF_BAR_IO(val)) {
|
||||||
LOG_ERR("Cannot read IO BAR");
|
LOG_ERR("Cannot read IO BAR");
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
@ -277,7 +274,7 @@ static int pch_smbus_init(const struct device *dev)
|
||||||
LOG_DBG("Using I/O address 0x%x", data->sba);
|
LOG_DBG("Using I/O address 0x%x", data->sba);
|
||||||
}
|
}
|
||||||
|
|
||||||
val = pcie_conf_read(config->pcie_bdf, PCH_SMBUS_HCFG);
|
val = pcie_conf_read(config->pcie->bdf, PCH_SMBUS_HCFG);
|
||||||
if ((val & PCH_SMBUS_HCFG_HST_EN) == 0) {
|
if ((val & PCH_SMBUS_HCFG_HST_EN) == 0) {
|
||||||
LOG_ERR("SMBus Host Controller is disabled");
|
LOG_ERR("SMBus Host Controller is disabled");
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
@ -933,7 +930,7 @@ static void smbus_isr(const struct device *dev)
|
||||||
uint32_t sts;
|
uint32_t sts;
|
||||||
uint8_t status;
|
uint8_t status;
|
||||||
|
|
||||||
sts = pcie_conf_read(config->pcie_bdf, PCIE_CONF_CMDSTAT);
|
sts = pcie_conf_read(config->pcie->bdf, PCIE_CONF_CMDSTAT);
|
||||||
if (!(sts & PCIE_CONF_CMDSTAT_INTERRUPT)) {
|
if (!(sts & PCIE_CONF_CMDSTAT_INTERRUPT)) {
|
||||||
LOG_ERR("Not our interrupt");
|
LOG_ERR("Not our interrupt");
|
||||||
return;
|
return;
|
||||||
|
@ -993,12 +990,6 @@ static void smbus_isr(const struct device *dev)
|
||||||
|
|
||||||
/* Device macro initialization / DTS hackery */
|
/* Device macro initialization / DTS hackery */
|
||||||
|
|
||||||
/* PCI BDF is hacked into REG_ADDR */
|
|
||||||
#define DT_INST_PCIE_BDF(n) DT_INST_REG_ADDR(n)
|
|
||||||
|
|
||||||
/* PCI ID is hacked into REG_SIZE */
|
|
||||||
#define DT_INST_PCIE_ID(n) DT_INST_REG_SIZE(n)
|
|
||||||
|
|
||||||
#define SMBUS_PCH_IRQ_FLAGS_SENSE0(n) 0
|
#define SMBUS_PCH_IRQ_FLAGS_SENSE0(n) 0
|
||||||
#define SMBUS_PCH_IRQ_FLAGS_SENSE1(n) DT_INST_IRQ(n, sense)
|
#define SMBUS_PCH_IRQ_FLAGS_SENSE1(n) DT_INST_IRQ(n, sense)
|
||||||
#define SMBUS_PCH_IRQ_FLAGS(n) \
|
#define SMBUS_PCH_IRQ_FLAGS(n) \
|
||||||
|
@ -1009,33 +1000,33 @@ static void smbus_isr(const struct device *dev)
|
||||||
"SMBus PCIe requires dynamic interrupts"); \
|
"SMBus PCIe requires dynamic interrupts"); \
|
||||||
static void pch_config_##n(const struct device *dev) \
|
static void pch_config_##n(const struct device *dev) \
|
||||||
{ \
|
{ \
|
||||||
ARG_UNUSED(dev); \
|
const struct pch_config * const config = dev->config; \
|
||||||
unsigned int irq; \
|
unsigned int irq; \
|
||||||
if (DT_INST_IRQN(n) == PCIE_IRQ_DETECT) { \
|
if (DT_INST_IRQN(n) == PCIE_IRQ_DETECT) { \
|
||||||
irq = pcie_alloc_irq(DT_INST_PCIE_BDF(n)); \
|
irq = pcie_alloc_irq(config->pcie->bdf); \
|
||||||
if (irq == PCIE_CONF_INTR_IRQ_NONE) { \
|
if (irq == PCIE_CONF_INTR_IRQ_NONE) { \
|
||||||
return; \
|
return; \
|
||||||
} \
|
} \
|
||||||
} else { \
|
} else { \
|
||||||
irq = DT_INST_IRQN(n); \
|
irq = DT_INST_IRQN(n); \
|
||||||
pcie_conf_write(DT_INST_PCIE_BDF(n), \
|
pcie_conf_write(config->pcie->bdf, \
|
||||||
PCIE_CONF_INTR, irq); \
|
PCIE_CONF_INTR, irq); \
|
||||||
} \
|
} \
|
||||||
pcie_connect_dynamic_irq(DT_INST_PCIE_BDF(n), irq, \
|
pcie_connect_dynamic_irq(config->pcie->bdf, irq, \
|
||||||
DT_INST_IRQ(n, priority), \
|
DT_INST_IRQ(n, priority), \
|
||||||
(void (*)(const void *))smbus_isr, \
|
(void (*)(const void *))smbus_isr, \
|
||||||
DEVICE_DT_INST_GET(n), \
|
DEVICE_DT_INST_GET(n), \
|
||||||
SMBUS_PCH_IRQ_FLAGS(n)); \
|
SMBUS_PCH_IRQ_FLAGS(n)); \
|
||||||
pcie_irq_enable(DT_INST_PCIE_BDF(n), irq); \
|
pcie_irq_enable(config->pcie->bdf, irq); \
|
||||||
LOG_DBG("Configure irq %d", irq); \
|
LOG_DBG("Configure irq %d", irq); \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define SMBUS_DEVICE_INIT(n) \
|
#define SMBUS_DEVICE_INIT(n) \
|
||||||
|
DEVICE_PCIE_INST_DECLARE(n); \
|
||||||
static void pch_config_##n(const struct device *dev); \
|
static void pch_config_##n(const struct device *dev); \
|
||||||
static const struct pch_config pch_config_data_##n = { \
|
static const struct pch_config pch_config_data_##n = { \
|
||||||
|
DEVICE_PCIE_INST_INIT(n, pcie), \
|
||||||
.config_func = pch_config_##n, \
|
.config_func = pch_config_##n, \
|
||||||
.pcie_bdf = DT_INST_PCIE_BDF(n), \
|
|
||||||
.pcie_id = DT_INST_PCIE_ID(n), \
|
|
||||||
}; \
|
}; \
|
||||||
static struct pch_data smbus_##n##_data; \
|
static struct pch_data smbus_##n##_data; \
|
||||||
SMBUS_DEVICE_DT_INST_DEFINE(n, pch_smbus_init, NULL, \
|
SMBUS_DEVICE_DT_INST_DEFINE(n, pch_smbus_init, NULL, \
|
||||||
|
|
|
@ -5,7 +5,7 @@ description: Intel Platform Controller Hub SMBus node
|
||||||
|
|
||||||
compatible: "intel,pch-smbus"
|
compatible: "intel,pch-smbus"
|
||||||
|
|
||||||
include: smbus-controller.yaml
|
include: [smbus-controller.yaml, pcie-device.yaml]
|
||||||
|
|
||||||
properties:
|
properties:
|
||||||
interrupts:
|
interrupts:
|
||||||
|
|
|
@ -189,11 +189,12 @@
|
||||||
current-speed = <115200>;
|
current-speed = <115200>;
|
||||||
};
|
};
|
||||||
|
|
||||||
smbus0: smbus@fc00 {
|
smbus0: smbus0 {
|
||||||
compatible = "intel,pch-smbus";
|
compatible = "intel,pch-smbus";
|
||||||
#address-cells = <1>;
|
#address-cells = <1>;
|
||||||
#size-cells = <0>;
|
#size-cells = <0>;
|
||||||
reg = <PCIE_BDF(0,0x1f,4) PCIE_ID(0x8086,0x4b23)>;
|
vendor-id = <0x8086>;
|
||||||
|
device-id = <0x4b23>;
|
||||||
interrupts = <16 IRQ_TYPE_LOWEST_LEVEL_LOW 3>;
|
interrupts = <16 IRQ_TYPE_LOWEST_LEVEL_LOW 3>;
|
||||||
interrupt-parent = <&intc>;
|
interrupt-parent = <&intc>;
|
||||||
|
|
||||||
|
|
|
@ -41,11 +41,12 @@
|
||||||
compatible = "intel,pcie";
|
compatible = "intel,pcie";
|
||||||
ranges;
|
ranges;
|
||||||
|
|
||||||
smbus0: smbus@fc00 {
|
smbus0: smbus0 {
|
||||||
compatible = "intel,pch-smbus";
|
compatible = "intel,pch-smbus";
|
||||||
#address-cells = <1>;
|
#address-cells = <1>;
|
||||||
#size-cells = <0>;
|
#size-cells = <0>;
|
||||||
reg = <PCIE_BDF(0,0x1f,4) PCIE_ID(0x8086,0x7a23)>;
|
vendor-id = <0x8086>;
|
||||||
|
device-id = <0x7a23>;
|
||||||
interrupts = <18 IRQ_TYPE_LOWEST_LEVEL_LOW 3>;
|
interrupts = <18 IRQ_TYPE_LOWEST_LEVEL_LOW 3>;
|
||||||
interrupt-parent = <&intc>;
|
interrupt-parent = <&intc>;
|
||||||
|
|
||||||
|
|
|
@ -93,9 +93,13 @@ static void config_function(const struct device *dev)
|
||||||
TC_PRINT("Emulator device configuration\n");
|
TC_PRINT("Emulator device configuration\n");
|
||||||
}
|
}
|
||||||
static struct pch_data smbus_data;
|
static struct pch_data smbus_data;
|
||||||
|
/* Zero initialized, dummy device does not care about pcie ids */
|
||||||
|
static struct pcie_dev pcie_params;
|
||||||
static struct pch_config pch_config_data = {
|
static struct pch_config pch_config_data = {
|
||||||
.config_func = config_function,
|
.config_func = config_function,
|
||||||
|
.pcie = &pcie_params,
|
||||||
};
|
};
|
||||||
|
|
||||||
DEVICE_DEFINE(dummy_driver, SMBUS_EMUL, &pch_smbus_init,
|
DEVICE_DEFINE(dummy_driver, SMBUS_EMUL, &pch_smbus_init,
|
||||||
NULL, &smbus_data, &pch_config_data, APPLICATION,
|
NULL, &smbus_data, &pch_config_data, APPLICATION,
|
||||||
CONFIG_KERNEL_INIT_PRIORITY_DEFAULT, &funcs);
|
CONFIG_KERNEL_INIT_PRIORITY_DEFAULT, &funcs);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue