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
					
				|  | @ -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…
	
		Reference in New Issue