Message ID | 20200614215726.v1.11.I9313ecf187a225877256809220ada492a47f4340@changeid |
---|---|
State | Accepted |
Commit | dba7ee419d9d8c433f35f693f7d145de71d715c5 |
Headers | show |
Series | x86: Programmatic generation of ACPI tables (Part C) | expand |
Hi Simon, -----"Simon Glass" <sjg at chromium.org> schrieb: ----- > Betreff: [PATCH v1 11/43] acpi: mmc: Generate ACPI info for the PCI SD Card > > 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 at 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(-) Reviewed-by: Wolfgang Wallner <wolfgang.wallner at br-automation.com>
Hi Simon, On Mon, Jun 15, 2020 at 11:57 AM Simon Glass <sjg at 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 at 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
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; + 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[] = {
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 at 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(-)