From patchwork Mon Jan 27 05:05:52 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Glass X-Patchwork-Id: 240195 List-Id: U-Boot discussion From: sjg at chromium.org (Simon Glass) Date: Sun, 26 Jan 2020 22:05:52 -0700 Subject: [PATCH 045/108] acpi: mmc: Generate ACPI info for the PCI SD Card In-Reply-To: <20200127050655.170614-1-sjg@chromium.org> References: <20200127050655.170614-1-sjg@chromium.org> Message-ID: <20200126220508.45.I9313ecf187a225877256809220ada492a47f4340@changeid> Write required information into the SSDT to describe the SD card card-detect pin. Since the required GPIO properties are not present in the device-tree binding, set them manually for now. Signed-off-by: Simon Glass --- configs/sandbox_defconfig | 2 ++ drivers/mmc/pci_mmc.c | 76 ++++++++++++++++++++++++++++++++++++++- 2 files changed, 77 insertions(+), 1 deletion(-) diff --git a/configs/sandbox_defconfig b/configs/sandbox_defconfig index 858ad04b10..83a42cfddf 100644 --- a/configs/sandbox_defconfig +++ b/configs/sandbox_defconfig @@ -137,7 +137,9 @@ CONFIG_P2SB=y CONFIG_PWRSEQ=y CONFIG_SPL_PWRSEQ=y CONFIG_I2C_EEPROM=y +CONFIG_MMC_PCI=y CONFIG_MMC_SANDBOX=y +CONFIG_MMC_SDHCI=y CONFIG_MTD=y CONFIG_SPI_FLASH_SANDBOX=y CONFIG_SPI_FLASH_ATMEL=y diff --git a/drivers/mmc/pci_mmc.c b/drivers/mmc/pci_mmc.c index 404264a697..b4705e45a1 100644 --- a/drivers/mmc/pci_mmc.c +++ b/drivers/mmc/pci_mmc.c @@ -5,12 +5,15 @@ */ #include +#include +#include #include #include #include #include #include -#include +#include +#include struct pci_mmc_plat { struct mmc_config cfg; @@ -20,6 +23,7 @@ struct pci_mmc_plat { struct pci_mmc_priv { struct sdhci_host host; void *base; + struct gpio_desc cd_gpio; }; static int pci_mmc_probe(struct udevice *dev) @@ -44,6 +48,15 @@ static int pci_mmc_probe(struct udevice *dev) return sdhci_probe(dev); } +static int pci_mmc_ofdata_to_platdata(struct udevice *dev) +{ + struct pci_mmc_priv *priv = dev_get_priv(dev); + + gpio_request_by_name(dev, "cd-gpios", 0, &priv->cd_gpio, GPIOD_IS_IN); + + return 0; +} + static int pci_mmc_bind(struct udevice *dev) { struct pci_mmc_plat *plat = dev_get_platdata(dev); @@ -51,14 +64,75 @@ static int pci_mmc_bind(struct udevice *dev) return sdhci_bind(dev, &plat->mmc, &plat->cfg); } +static int pci_mmc_acpi_fill_ssdt(const struct udevice *dev, + struct acpi_ctx *ctx) +{ + struct pci_mmc_priv *priv = dev_get_priv(dev); + char path[ACPI_PATH_MAX]; + struct acpi_gpio gpio; + struct acpi_dp *dp; + int ret; + + if (!dev_of_valid(dev)) + return 0; + + ret = gpio_get_acpi(&priv->cd_gpio, &gpio); + if (ret) + return log_msg_ret("gpio", ret); + gpio.type = ACPI_GPIO_TYPE_INTERRUPT; + gpio.pull = ACPI_GPIO_PULL_NONE; + gpio.irq.mode = ACPI_IRQ_EDGE_TRIGGERED; + gpio.irq.polarity = ACPI_IRQ_ACTIVE_BOTH; + gpio.irq.shared = ACPI_IRQ_SHARED; + gpio.irq.wake = ACPI_IRQ_WAKE; + gpio.interrupt_debounce_timeout = 10000; /* 100ms */ + + /* Use device path as the Scope for the SSDT */ + ret = acpi_device_path(dev, path, sizeof(path)); + if (ret) + return log_msg_ret("path", ret); + acpigen_write_scope(ctx, path); + acpigen_write_name(ctx, "_CRS"); + + /* Write GpioInt() as default (if set) or custom from devicetree */ + acpigen_write_resourcetemplate_header(ctx); + acpi_device_write_gpio(ctx, &gpio); + acpigen_write_resourcetemplate_footer(ctx); + + /* Bind the cd-gpio name to the GpioInt() resource */ + dp = acpi_dp_new_table("_DSD"); + if (!dp) + return -ENOMEM; + acpi_dp_add_gpio(dp, "cd-gpio", path, 0, 0, 1); + ret = acpi_dp_write(ctx, dp); + if (ret) + return log_msg_ret("cd", ret); + + acpigen_pop_len(ctx); + + return 0; +} + +struct acpi_ops pci_mmc_acpi_ops = { + .fill_ssdt = pci_mmc_acpi_fill_ssdt, +}; + +static const struct udevice_id pci_mmc_match[] = { + { .compatible = "intel,apl-sd" }, + { } +}; + U_BOOT_DRIVER(pci_mmc) = { .name = "pci_mmc", .id = UCLASS_MMC, + .of_match = pci_mmc_match, .bind = pci_mmc_bind, + .ofdata_to_platdata = pci_mmc_ofdata_to_platdata, .probe = pci_mmc_probe, .ops = &sdhci_ops, .priv_auto_alloc_size = sizeof(struct pci_mmc_priv), .platdata_auto_alloc_size = sizeof(struct pci_mmc_plat), + acpi_ops_ptr(&pci_mmc_acpi_ops) }; static struct pci_device_id mmc_supported[] = {