diff options
| -rw-r--r-- | drivers/bus/Kconfig | 1 | ||||
| -rw-r--r-- | drivers/bus/hisi_lpc.c | 72 |
2 files changed, 8 insertions, 65 deletions
diff --git a/drivers/bus/Kconfig b/drivers/bus/Kconfig index 6dc177bf4c42..d1c0b60e9326 100644 --- a/drivers/bus/Kconfig +++ b/drivers/bus/Kconfig | |||
| @@ -33,7 +33,6 @@ config HISILICON_LPC | |||
| 33 | bool "Support for ISA I/O space on HiSilicon Hip06/7" | 33 | bool "Support for ISA I/O space on HiSilicon Hip06/7" |
| 34 | depends on ARM64 && (ARCH_HISI || COMPILE_TEST) | 34 | depends on ARM64 && (ARCH_HISI || COMPILE_TEST) |
| 35 | select INDIRECT_PIO | 35 | select INDIRECT_PIO |
| 36 | select MFD_CORE if ACPI | ||
| 37 | help | 36 | help |
| 38 | Driver to enable I/O access to devices attached to the Low Pin | 37 | Driver to enable I/O access to devices attached to the Low Pin |
| 39 | Count bus on the HiSilicon Hip06/7 SoC. | 38 | Count bus on the HiSilicon Hip06/7 SoC. |
diff --git a/drivers/bus/hisi_lpc.c b/drivers/bus/hisi_lpc.c index 2d4611e4c339..252a6a401a42 100644 --- a/drivers/bus/hisi_lpc.c +++ b/drivers/bus/hisi_lpc.c | |||
| @@ -11,7 +11,6 @@ | |||
| 11 | #include <linux/delay.h> | 11 | #include <linux/delay.h> |
| 12 | #include <linux/io.h> | 12 | #include <linux/io.h> |
| 13 | #include <linux/logic_pio.h> | 13 | #include <linux/logic_pio.h> |
| 14 | #include <linux/mfd/core.h> | ||
| 15 | #include <linux/module.h> | 14 | #include <linux/module.h> |
| 16 | #include <linux/of.h> | 15 | #include <linux/of.h> |
| 17 | #include <linux/of_address.h> | 16 | #include <linux/of_address.h> |
| @@ -341,15 +340,6 @@ static const struct logic_pio_host_ops hisi_lpc_ops = { | |||
| 341 | }; | 340 | }; |
| 342 | 341 | ||
| 343 | #ifdef CONFIG_ACPI | 342 | #ifdef CONFIG_ACPI |
| 344 | #define MFD_CHILD_NAME_PREFIX DRV_NAME"-" | ||
| 345 | #define MFD_CHILD_NAME_LEN (ACPI_ID_LEN + sizeof(MFD_CHILD_NAME_PREFIX) - 1) | ||
| 346 | |||
| 347 | struct hisi_lpc_mfd_cell { | ||
| 348 | struct mfd_cell_acpi_match acpi_match; | ||
| 349 | char name[MFD_CHILD_NAME_LEN]; | ||
| 350 | char pnpid[ACPI_ID_LEN]; | ||
| 351 | }; | ||
| 352 | |||
| 353 | static int hisi_lpc_acpi_xlat_io_res(struct acpi_device *adev, | 343 | static int hisi_lpc_acpi_xlat_io_res(struct acpi_device *adev, |
| 354 | struct acpi_device *host, | 344 | struct acpi_device *host, |
| 355 | struct resource *res) | 345 | struct resource *res) |
| @@ -368,7 +358,7 @@ static int hisi_lpc_acpi_xlat_io_res(struct acpi_device *adev, | |||
| 368 | } | 358 | } |
| 369 | 359 | ||
| 370 | /* | 360 | /* |
| 371 | * hisi_lpc_acpi_set_io_res - set the resources for a child's MFD | 361 | * hisi_lpc_acpi_set_io_res - set the resources for a child |
| 372 | * @child: the device node to be updated the I/O resource | 362 | * @child: the device node to be updated the I/O resource |
| 373 | * @hostdev: the device node associated with host controller | 363 | * @hostdev: the device node associated with host controller |
| 374 | * @res: double pointer to be set to the address of translated resources | 364 | * @res: double pointer to be set to the address of translated resources |
| @@ -458,69 +448,23 @@ static int hisi_lpc_acpi_set_io_res(struct device *child, | |||
| 458 | * | 448 | * |
| 459 | * Returns 0 when successful, and a negative value for failure. | 449 | * Returns 0 when successful, and a negative value for failure. |
| 460 | * | 450 | * |
| 461 | * Scan all child devices and create a per-device MFD with | ||
| 462 | * logical PIO translated IO resources. | ||
| 463 | */ | 451 | */ |
| 464 | static int hisi_lpc_acpi_probe(struct device *hostdev) | 452 | static int hisi_lpc_acpi_probe(struct device *hostdev) |
| 465 | { | 453 | { |
| 466 | struct acpi_device *adev = ACPI_COMPANION(hostdev); | 454 | struct acpi_device *adev = ACPI_COMPANION(hostdev); |
| 467 | struct hisi_lpc_mfd_cell *hisi_lpc_mfd_cells; | ||
| 468 | struct mfd_cell *mfd_cells; | ||
| 469 | struct acpi_device *child; | 455 | struct acpi_device *child; |
| 470 | int size, ret, count = 0, cell_num = 0; | 456 | int ret; |
| 471 | |||
| 472 | list_for_each_entry(child, &adev->children, node) | ||
| 473 | cell_num++; | ||
| 474 | |||
| 475 | /* allocate the mfd cell and companion ACPI info, one per child */ | ||
| 476 | size = sizeof(*mfd_cells) + sizeof(*hisi_lpc_mfd_cells); | ||
| 477 | mfd_cells = devm_kcalloc(hostdev, cell_num, size, GFP_KERNEL); | ||
| 478 | if (!mfd_cells) | ||
| 479 | return -ENOMEM; | ||
| 480 | 457 | ||
| 481 | hisi_lpc_mfd_cells = (struct hisi_lpc_mfd_cell *)&mfd_cells[cell_num]; | ||
| 482 | /* Only consider the children of the host */ | 458 | /* Only consider the children of the host */ |
| 483 | list_for_each_entry(child, &adev->children, node) { | 459 | list_for_each_entry(child, &adev->children, node) { |
| 484 | struct mfd_cell *mfd_cell = &mfd_cells[count]; | 460 | const struct resource *res; |
| 485 | struct hisi_lpc_mfd_cell *hisi_lpc_mfd_cell = | 461 | int num_res; |
| 486 | &hisi_lpc_mfd_cells[count]; | 462 | |
| 487 | struct mfd_cell_acpi_match *acpi_match = | 463 | ret = hisi_lpc_acpi_set_io_res(&child->dev, &adev->dev, &res, |
| 488 | &hisi_lpc_mfd_cell->acpi_match; | 464 | &num_res); |
| 489 | char *name = hisi_lpc_mfd_cell[count].name; | ||
| 490 | char *pnpid = hisi_lpc_mfd_cell[count].pnpid; | ||
| 491 | struct mfd_cell_acpi_match match = { | ||
| 492 | .pnpid = pnpid, | ||
| 493 | }; | ||
| 494 | |||
| 495 | /* | ||
| 496 | * For any instances of this host controller (Hip06 and Hip07 | ||
| 497 | * are the only chipsets), we would not have multiple slaves | ||
| 498 | * with the same HID. And in any system we would have just one | ||
| 499 | * controller active. So don't worrry about MFD name clashes. | ||
| 500 | */ | ||
| 501 | snprintf(name, MFD_CHILD_NAME_LEN, MFD_CHILD_NAME_PREFIX"%s", | ||
| 502 | acpi_device_hid(child)); | ||
| 503 | snprintf(pnpid, ACPI_ID_LEN, "%s", acpi_device_hid(child)); | ||
| 504 | |||
| 505 | memcpy(acpi_match, &match, sizeof(*acpi_match)); | ||
| 506 | mfd_cell->name = name; | ||
| 507 | mfd_cell->acpi_match = acpi_match; | ||
| 508 | |||
| 509 | ret = hisi_lpc_acpi_set_io_res(&child->dev, &adev->dev, | ||
| 510 | &mfd_cell->resources, | ||
| 511 | &mfd_cell->num_resources); | ||
| 512 | if (ret) { | 465 | if (ret) { |
| 513 | dev_warn(&child->dev, "set resource fail (%d)\n", ret); | 466 | dev_warn(hostdev, "set resource fail (%d)\n", ret); |
| 514 | return ret; | ||
| 515 | } | 467 | } |
| 516 | count++; | ||
| 517 | } | ||
| 518 | |||
| 519 | ret = mfd_add_devices(hostdev, PLATFORM_DEVID_NONE, | ||
| 520 | mfd_cells, cell_num, NULL, 0, NULL); | ||
| 521 | if (ret) { | ||
| 522 | dev_err(hostdev, "failed to add mfd cells (%d)\n", ret); | ||
| 523 | return ret; | ||
| 524 | } | 468 | } |
| 525 | 469 | ||
| 526 | return 0; | 470 | return 0; |
