Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 32bcbf8b authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull ARM SoC driver updates from Olof Johansson:
 "This contains platform-related driver updates for ARM and ARM64.

  Highlights:

   - ARM SCMI (System Control & Management Interface) driver cleanups

   - Hisilicon support for LPC bus w/ ACPI

   - Reset driver updates for several platforms: Uniphier,

   - Rockchip power domain bindings and hardware descriptions for
     several SoCs.

   - Tegra memory controller reset improvements"

* tag 'armsoc-drivers' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc: (59 commits)
  ARM: tegra: fix compile-testing PCI host driver
  soc: rockchip: power-domain: add power domain support for px30
  dt-bindings: power: add binding for px30 power domains
  dt-bindings: power: add PX30 SoCs header for power-domain
  soc: rockchip: power-domain: add power domain support for rk3228
  dt-bindings: power: add binding for rk3228 power domains
  dt-bindings: power: add RK3228 SoCs header for power-domain
  soc: rockchip: power-domain: add power domain support for rk3128
  dt-bindings: power: add binding for rk3128 power domains
  dt-bindings: power: add RK3128 SoCs header for power-domain
  soc: rockchip: power-domain: add power domain support for rk3036
  dt-bindings: power: add binding for rk3036 power domains
  dt-bindings: power: add RK3036 SoCs header for power-domain
  dt-bindings: memory: tegra: Remove Tegra114 SATA and AFI reset definitions
  memory: tegra: Remove Tegra114 SATA and AFI reset definitions
  memory: tegra: Register SMMU after MC driver became ready
  soc: mediatek: remove unneeded semicolon
  soc: mediatek: add a fixed wait for SRAM stable
  soc: mediatek: introduce a CAPS flag for scp_domain_data
  soc: mediatek: reuse regmap_read_poll_timeout helpers
  ...
parents 721afaa2 32561354
Loading
Loading
Loading
Loading
+4 −16
Original line number Diff line number Diff line
@@ -15,23 +15,13 @@ Required Properties:
Optional Properties:
- label: Human readable string with domain name. Will be visible in userspace
	to let user to distinguish between multiple domains in SoC.
- clocks: List of clock handles. The parent clocks of the input clocks to the
	devices in this power domain are set to oscclk before power gating
	and restored back after powering on a domain. This is required for
	all domains which are powered on and off and not required for unused
	domains.
- clock-names: The following clocks can be specified:
	- oscclk: Oscillator clock.
	- clkN: Input clocks to the devices in this power domain. These clocks
		will be reparented to oscclk before switching power domain off.
		Their original parent will be brought back after turning on
		the domain. Maximum of 4 clocks (N = 0 to 3) are supported.
	- asbN: Clocks required by asynchronous bridges (ASB) present in
		the power domain. These clock should be enabled during power
		domain on/off operations.
- power-domains: phandle pointing to the parent power domain, for more details
		 see Documentation/devicetree/bindings/power/power_domain.txt

Deprecated Properties:
- clocks
- clock-names

Node of a device using power domains must have a power-domains property
defined with a phandle to respective power domain.

@@ -47,8 +37,6 @@ Example:
	mfc_pd: power-domain@10044060 {
		compatible = "samsung,exynos4210-pd";
		reg = <0x10044060 0x20>;
		clocks = <&clock CLK_FIN_PLL>, <&clock CLK_MOUT_USER_ACLK333>;
		clock-names = "oscclk", "clk0";
		#power-domain-cells = <0>;
		label = "MFC";
	};
+12 −0
Original line number Diff line number Diff line
@@ -5,6 +5,10 @@ powered up/down by software based on different application scenes to save power.

Required properties for power domain controller:
- compatible: Should be one of the following.
	"rockchip,px30-power-controller" - for PX30 SoCs.
	"rockchip,rk3036-power-controller" - for RK3036 SoCs.
	"rockchip,rk3128-power-controller" - for RK3128 SoCs.
	"rockchip,rk3228-power-controller" - for RK3228 SoCs.
	"rockchip,rk3288-power-controller" - for RK3288 SoCs.
	"rockchip,rk3328-power-controller" - for RK3328 SoCs.
	"rockchip,rk3366-power-controller" - for RK3366 SoCs.
@@ -17,6 +21,10 @@ Required properties for power domain controller:

Required properties for power domain sub nodes:
- reg: index of the power domain, should use macros in:
	"include/dt-bindings/power/px30-power.h" - for PX30 type power domain.
	"include/dt-bindings/power/rk3036-power.h" - for RK3036 type power domain.
	"include/dt-bindings/power/rk3128-power.h" - for RK3128 type power domain.
	"include/dt-bindings/power/rk3228-power.h" - for RK3228 type power domain.
	"include/dt-bindings/power/rk3288-power.h" - for RK3288 type power domain.
	"include/dt-bindings/power/rk3328-power.h" - for RK3328 type power domain.
	"include/dt-bindings/power/rk3366-power.h" - for RK3366 type power domain.
@@ -93,6 +101,10 @@ Node of a device using power domains must have a power-domains property,
containing a phandle to the power device node and an index specifying which
power domain to use.
The index should use macros in:
	"include/dt-bindings/power/px30-power.h" - for px30 type power domain.
	"include/dt-bindings/power/rk3036-power.h" - for rk3036 type power domain.
	"include/dt-bindings/power/rk3128-power.h" - for rk3128 type power domain.
	"include/dt-bindings/power/rk3128-power.h" - for rk3228 type power domain.
	"include/dt-bindings/power/rk3288-power.h" - for rk3288 type power domain.
	"include/dt-bindings/power/rk3328-power.h" - for rk3328 type power domain.
	"include/dt-bindings/power/rk3366-power.h" - for rk3366 type power domain.
+0 −1
Original line number Diff line number Diff line
@@ -33,7 +33,6 @@ config HISILICON_LPC
	bool "Support for ISA I/O space on HiSilicon Hip06/7"
	depends on ARM64 && (ARCH_HISI || COMPILE_TEST)
	select INDIRECT_PIO
	select MFD_CORE if ACPI
	help
	  Driver to enable I/O access to devices attached to the Low Pin
	  Count bus on the HiSilicon Hip06/7 SoC.
+0 −2
Original line number Diff line number Diff line
@@ -371,8 +371,6 @@ asmlinkage void __naked cci_enable_port_for_self(void)
	[sizeof_struct_cpu_port] "i" (sizeof(struct cpu_port)),
	[sizeof_struct_ace_port] "i" (sizeof(struct cci_ace_port)),
	[offsetof_port_phys] "i" (offsetof(struct cci_ace_port, phys)) );

	unreachable();
}

/**
+97 −62
Original line number Diff line number Diff line
@@ -11,12 +11,12 @@
#include <linux/delay.h>
#include <linux/io.h>
#include <linux/logic_pio.h>
#include <linux/mfd/core.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/of_platform.h>
#include <linux/pci.h>
#include <linux/serial_8250.h>
#include <linux/slab.h>

#define DRV_NAME "hisi-lpc"
@@ -341,15 +341,6 @@ static const struct logic_pio_host_ops hisi_lpc_ops = {
};

#ifdef CONFIG_ACPI
#define MFD_CHILD_NAME_PREFIX DRV_NAME"-"
#define MFD_CHILD_NAME_LEN (ACPI_ID_LEN + sizeof(MFD_CHILD_NAME_PREFIX) - 1)

struct hisi_lpc_mfd_cell {
	struct mfd_cell_acpi_match acpi_match;
	char name[MFD_CHILD_NAME_LEN];
	char pnpid[ACPI_ID_LEN];
};

static int hisi_lpc_acpi_xlat_io_res(struct acpi_device *adev,
				     struct acpi_device *host,
				     struct resource *res)
@@ -368,7 +359,7 @@ static int hisi_lpc_acpi_xlat_io_res(struct acpi_device *adev,
}

/*
 * hisi_lpc_acpi_set_io_res - set the resources for a child's MFD
 * hisi_lpc_acpi_set_io_res - set the resources for a child
 * @child: the device node to be updated the I/O resource
 * @hostdev: the device node associated with host controller
 * @res: double pointer to be set to the address of translated resources
@@ -452,78 +443,122 @@ static int hisi_lpc_acpi_set_io_res(struct device *child,
	return 0;
}

static int hisi_lpc_acpi_remove_subdev(struct device *dev, void *unused)
{
	platform_device_unregister(to_platform_device(dev));
	return 0;
}

struct hisi_lpc_acpi_cell {
	const char *hid;
	const char *name;
	void *pdata;
	size_t pdata_size;
};

/*
 * hisi_lpc_acpi_probe - probe children for ACPI FW
 * @hostdev: LPC host device pointer
 *
 * Returns 0 when successful, and a negative value for failure.
 *
 * Scan all child devices and create a per-device MFD with
 * logical PIO translated IO resources.
 * Create a platform device per child, fixing up the resources
 * from bus addresses to Logical PIO addresses.
 *
 */
static int hisi_lpc_acpi_probe(struct device *hostdev)
{
	struct acpi_device *adev = ACPI_COMPANION(hostdev);
	struct hisi_lpc_mfd_cell *hisi_lpc_mfd_cells;
	struct mfd_cell *mfd_cells;
	struct acpi_device *child;
	int size, ret, count = 0, cell_num = 0;

	list_for_each_entry(child, &adev->children, node)
		cell_num++;

	/* allocate the mfd cell and companion ACPI info, one per child */
	size = sizeof(*mfd_cells) + sizeof(*hisi_lpc_mfd_cells);
	mfd_cells = devm_kcalloc(hostdev, cell_num, size, GFP_KERNEL);
	if (!mfd_cells)
		return -ENOMEM;
	int ret;

	hisi_lpc_mfd_cells = (struct hisi_lpc_mfd_cell *)&mfd_cells[cell_num];
	/* Only consider the children of the host */
	list_for_each_entry(child, &adev->children, node) {
		struct mfd_cell *mfd_cell = &mfd_cells[count];
		struct hisi_lpc_mfd_cell *hisi_lpc_mfd_cell =
					&hisi_lpc_mfd_cells[count];
		struct mfd_cell_acpi_match *acpi_match =
					&hisi_lpc_mfd_cell->acpi_match;
		char *name = hisi_lpc_mfd_cell[count].name;
		char *pnpid = hisi_lpc_mfd_cell[count].pnpid;
		struct mfd_cell_acpi_match match = {
			.pnpid = pnpid,
		};
		const char *hid = acpi_device_hid(child);
		const struct hisi_lpc_acpi_cell *cell;
		struct platform_device *pdev;
		const struct resource *res;
		bool found = false;
		int num_res;

		ret = hisi_lpc_acpi_set_io_res(&child->dev, &adev->dev, &res,
					       &num_res);
		if (ret) {
			dev_warn(hostdev, "set resource fail (%d)\n", ret);
			goto fail;
		}

		/*
		 * For any instances of this host controller (Hip06 and Hip07
		 * are the only chipsets), we would not have multiple slaves
		 * with the same HID. And in any system we would have just one
		 * controller active. So don't worrry about MFD name clashes.
		 */
		snprintf(name, MFD_CHILD_NAME_LEN, MFD_CHILD_NAME_PREFIX"%s",
			 acpi_device_hid(child));
		snprintf(pnpid, ACPI_ID_LEN, "%s", acpi_device_hid(child));
		cell = (struct hisi_lpc_acpi_cell []){
			/* ipmi */
			{
				.hid = "IPI0001",
				.name = "hisi-lpc-ipmi",
			},
			/* 8250-compatible uart */
			{
				.hid = "HISI1031",
				.name = "serial8250",
				.pdata = (struct plat_serial8250_port []) {
					{
						.iobase = res->start,
						.uartclk = 1843200,
						.iotype = UPIO_PORT,
						.flags = UPF_BOOT_AUTOCONF,
					},
					{}
				},
				.pdata_size = 2 *
					sizeof(struct plat_serial8250_port),
			},
			{}
		};

		memcpy(acpi_match, &match, sizeof(*acpi_match));
		mfd_cell->name = name;
		mfd_cell->acpi_match = acpi_match;
		for (; cell && cell->name; cell++) {
			if (!strcmp(cell->hid, hid)) {
				found = true;
				break;
			}
		}

		ret = hisi_lpc_acpi_set_io_res(&child->dev, &adev->dev,
					       &mfd_cell->resources,
					       &mfd_cell->num_resources);
		if (ret) {
			dev_warn(&child->dev, "set resource fail (%d)\n", ret);
			return ret;
		if (!found) {
			dev_warn(hostdev,
				 "could not find cell for child device (%s)\n",
				 hid);
			ret = -ENODEV;
			goto fail;
		}
		count++;

		pdev = platform_device_alloc(cell->name, PLATFORM_DEVID_AUTO);
		if (!pdev) {
			ret = -ENOMEM;
			goto fail;
		}

	ret = mfd_add_devices(hostdev, PLATFORM_DEVID_NONE,
			      mfd_cells, cell_num, NULL, 0, NULL);
	if (ret) {
		dev_err(hostdev, "failed to add mfd cells (%d)\n", ret);
		return ret;
		pdev->dev.parent = hostdev;
		ACPI_COMPANION_SET(&pdev->dev, child);

		ret = platform_device_add_resources(pdev, res, num_res);
		if (ret)
			goto fail;

		ret = platform_device_add_data(pdev, cell->pdata,
					       cell->pdata_size);
		if (ret)
			goto fail;

		ret = platform_device_add(pdev);
		if (ret)
			goto fail;

		acpi_device_set_enumerated(child);
	}

	return 0;

fail:
	device_for_each_child(hostdev, NULL,
			      hisi_lpc_acpi_remove_subdev);
	return ret;
}

static const struct acpi_device_id hisi_lpc_acpi_match[] = {
Loading