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:
Andrei Emeltchenko 2022-11-17 15:35:09 +02:00 committed by Anas Nashif
commit a42ab2729f
5 changed files with 27 additions and 30 deletions

View file

@ -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, \

View file

@ -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:

View file

@ -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>;

View file

@ -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>;

View file

@ -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);