
Hi Simon,
On Mon, Jun 15, 2020 at 11:57 AM Simon Glass sjg@chromium.org wrote:
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 sjg@chromium.org
Changes in v1:
- Capitalise ACPI_OPS_PTR
configs/sandbox_defconfig | 2 + drivers/mmc/pci_mmc.c | 78 ++++++++++++++++++++++++++++++++++++++- 2 files changed, 79 insertions(+), 1 deletion(-)
diff --git a/configs/sandbox_defconfig b/configs/sandbox_defconfig index 982075c568..cb6b4b0ee7 100644 --- a/configs/sandbox_defconfig +++ b/configs/sandbox_defconfig @@ -143,7 +143,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..0c45e1b893 100644 --- a/drivers/mmc/pci_mmc.c +++ b/drivers/mmc/pci_mmc.c @@ -7,10 +7,15 @@ #include <common.h> #include <dm.h> #include <errno.h> +#include <log.h> #include <malloc.h> #include <mapmem.h> #include <sdhci.h> -#include <asm/pci.h> +#include <acpi/acpigen.h> +#include <acpi/acpi_device.h> +#include <acpi/acpi_dp.h> +#include <asm-generic/gpio.h> +#include <dm/acpi.h>
struct pci_mmc_plat { struct mmc_config cfg; @@ -20,6 +25,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 +50,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 +66,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;
The above are all hardcoded. Is there is way to figure out these from DT GPIO properties?
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[] = {
Regards, Bin