mirror of
https://github.com/u-boot/u-boot.git
synced 2025-04-23 13:56:20 +00:00
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@chromium.org> Reviewed-by: Wolfgang Wallner <wolfgang.wallner@br-automation.com> Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
This commit is contained in:
parent
d7d631df2d
commit
dba7ee419d
2 changed files with 79 additions and 1 deletions
|
@ -149,7 +149,9 @@ CONFIG_P2SB=y
|
||||||
CONFIG_PWRSEQ=y
|
CONFIG_PWRSEQ=y
|
||||||
CONFIG_SPL_PWRSEQ=y
|
CONFIG_SPL_PWRSEQ=y
|
||||||
CONFIG_I2C_EEPROM=y
|
CONFIG_I2C_EEPROM=y
|
||||||
|
CONFIG_MMC_PCI=y
|
||||||
CONFIG_MMC_SANDBOX=y
|
CONFIG_MMC_SANDBOX=y
|
||||||
|
CONFIG_MMC_SDHCI=y
|
||||||
CONFIG_MTD=y
|
CONFIG_MTD=y
|
||||||
CONFIG_SPI_FLASH_SANDBOX=y
|
CONFIG_SPI_FLASH_SANDBOX=y
|
||||||
CONFIG_SPI_FLASH_ATMEL=y
|
CONFIG_SPI_FLASH_ATMEL=y
|
||||||
|
|
|
@ -7,10 +7,15 @@
|
||||||
#include <common.h>
|
#include <common.h>
|
||||||
#include <dm.h>
|
#include <dm.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
#include <log.h>
|
||||||
#include <malloc.h>
|
#include <malloc.h>
|
||||||
#include <mapmem.h>
|
#include <mapmem.h>
|
||||||
#include <sdhci.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 pci_mmc_plat {
|
||||||
struct mmc_config cfg;
|
struct mmc_config cfg;
|
||||||
|
@ -20,6 +25,7 @@ struct pci_mmc_plat {
|
||||||
struct pci_mmc_priv {
|
struct pci_mmc_priv {
|
||||||
struct sdhci_host host;
|
struct sdhci_host host;
|
||||||
void *base;
|
void *base;
|
||||||
|
struct gpio_desc cd_gpio;
|
||||||
};
|
};
|
||||||
|
|
||||||
static int pci_mmc_probe(struct udevice *dev)
|
static int pci_mmc_probe(struct udevice *dev)
|
||||||
|
@ -44,6 +50,15 @@ static int pci_mmc_probe(struct udevice *dev)
|
||||||
return sdhci_probe(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)
|
static int pci_mmc_bind(struct udevice *dev)
|
||||||
{
|
{
|
||||||
struct pci_mmc_plat *plat = dev_get_platdata(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);
|
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) = {
|
U_BOOT_DRIVER(pci_mmc) = {
|
||||||
.name = "pci_mmc",
|
.name = "pci_mmc",
|
||||||
.id = UCLASS_MMC,
|
.id = UCLASS_MMC,
|
||||||
|
.of_match = pci_mmc_match,
|
||||||
.bind = pci_mmc_bind,
|
.bind = pci_mmc_bind,
|
||||||
|
.ofdata_to_platdata = pci_mmc_ofdata_to_platdata,
|
||||||
.probe = pci_mmc_probe,
|
.probe = pci_mmc_probe,
|
||||||
.ops = &sdhci_ops,
|
.ops = &sdhci_ops,
|
||||||
.priv_auto_alloc_size = sizeof(struct pci_mmc_priv),
|
.priv_auto_alloc_size = sizeof(struct pci_mmc_priv),
|
||||||
.platdata_auto_alloc_size = sizeof(struct pci_mmc_plat),
|
.platdata_auto_alloc_size = sizeof(struct pci_mmc_plat),
|
||||||
|
ACPI_OPS_PTR(&pci_mmc_acpi_ops)
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct pci_device_id mmc_supported[] = {
|
static struct pci_device_id mmc_supported[] = {
|
||||||
|
|
Loading…
Add table
Reference in a new issue