Skip to contentSkip to conversation

ARM: tegra: Add PCIe device tree support

PATCH New Thierry Reding 8 participants 46 messages Mar 8, 2012 – Mar 20, 2012

Subsystems (10)
lore
Share & tools
lore
#0 lore raw

cover ARM: tegra: Add PCIe device tree support

This patch series adds support for device tree based probing of the PCIe controller found on Tegra SoCs.

Patches 1 and 2 have already been posted by Grant and Mark respectively but I've included them here for reference. Both patches are dependencies for the subsequent patches.

Patches 3, 4 and 5 add support for obtaining the regulators required to power the PCIe controller from the device tree. Patches 6 and 7 are required to make some common PCI functions available after the init phase because the deferred probing will postpone the probing of the PCIe controller driver until that point.

Patches 8 and 9 make the PCIe controller code available as a driver and add the corresponding platform devices to the boards that enable PCIe (Harmony and TrimSlice). Patch 10 adds MSI support and patch 11 finally adds a device tree binding with documentation.

The code in patch 10 (MSI support) is based on the Vibrante kernel and I wasn't able to get a proper Signed-off-by or even copyright information. Perhaps somebody at NVIDIA can find out?

Thierry

Grant Likely (1):
drivercore: Add driver probe deferral mechanism

Mark Brown (1):
regulator: Support driver probe deferral

Thierry Reding (9):
regulator: fixed: Support driver probe deferral
regulator: tps6586x: fix typo in debug message
tps6586x: Add device-tree support
PCI: Keep pci_fixup_irqs() around after init
ARM: pci: Keep pci_common_init() around after init
ARM: tegra: Move tegra_pcie_xclk_clamp() to PMC
ARM: tegra: Rewrite PCIe support as a driver
ARM: tegra: pcie: Add MSI support
ARM: tegra: pcie: Add device tree support

 .../devicetree/bindings/pci/tegra-pcie.txt         |   23 +
 .../devicetree/bindings/regulator/tps6586x.txt     |   98 +++
 arch/arm/boot/dts/tegra20.dtsi                     |    8 +
 arch/arm/kernel/bios32.c                           |    4 +-
 arch/arm/mach-tegra/Kconfig                        |    1 +
 arch/arm/mach-tegra/board-harmony-pcie.c           |   38 +-
 arch/arm/mach-tegra/board-harmony.c                |    1 +
 arch/arm/mach-tegra/board-harmony.h                |    1 +
 arch/arm/mach-tegra/board-trimslice.c              |   16 +-
 arch/arm/mach-tegra/board.h                        |   11 +-
 arch/arm/mach-tegra/devices.c                      |   32 +
 arch/arm/mach-tegra/devices.h                      |    1 +
 arch/arm/mach-tegra/include/mach/iomap.h           |    6 +
 arch/arm/mach-tegra/include/mach/irqs.h            |    5 +-
 arch/arm/mach-tegra/pcie.c                         |  895 +++++++++++++++-----
 arch/arm/mach-tegra/pmc.c                          |   16 +
 arch/arm/mach-tegra/pmc.h                          |    1 +
 drivers/base/base.h                                |    1 +
 drivers/base/core.c                                |    2 +
 drivers/base/dd.c                                  |  138 ++-
 drivers/mfd/tps6586x.c                             |   66 ++
 drivers/pci/setup-irq.c                            |    4 +-
 drivers/regulator/core.c                           |    4 +-
 drivers/regulator/fixed.c                          |   14 +-
 drivers/regulator/tps6586x-regulator.c             |    4 +-
 include/linux/device.h                             |    5 +
 include/linux/errno.h                              |    1 +
 include/linux/mfd/tps6586x.h                       |    1 +
 28 files changed, 1136 insertions(+), 261 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/pci/tegra-pcie.txt
 create mode 100644 Documentation/devicetree/bindings/regulator/tps6586x.txt
Signature · 1 line
1.7.9.3
#1 lore raw

PATCH 1/11 drivercore: Add driver probe deferral mechanism

From: Grant Likely <[email protected]>

Allow drivers to report at probe time that they cannot get all the resources required by the device, and should be retried at a later time.

This should completely solve the problem of getting devices initialized in the right order. Right now this is mostly handled by mucking about with initcall ordering which is a complete hack, and doesn't even remotely handle the case where device drivers are in modules. This approach completely sidesteps the issues by allowing driver registration to occur in any order, and any driver can request to be retried after a few more other drivers get probed.

v4: - Integrate Manjunath's addition of a separate workqueue
- Change -EAGAIN to -EPROBE_DEFER for drivers to trigger deferral
- Update comment blocks to reflect how the code really works
v3: - Hold off workqueue scheduling until late_initcall so that the bulk
of driver probes are complete before we start retrying deferred devices.
- Tested with simple use cases. Still needs more testing though. Using it to get rid of the gpio early_initcall madness, or to replace the ASoC internal probe deferral code would be ideal.
v2: - added locking so it should no longer be utterly broken in that regard
- remove device from deferred list at device_del time.
- Still completely untested with any real use case, but has been boot tested.

[Cc list stripped in order not to get on people's nerves]
---
 drivers/base/base.h    |    1 +
 drivers/base/core.c    |    2 +
 drivers/base/dd.c      |  138 +++++++++++++++++++++++++++++++++++++++++++++++-
 include/linux/device.h |    5 ++
 include/linux/errno.h  |    1 +
 5 files changed, 146 insertions(+), 1 deletion(-)
drivers/base/base.h +1 -0
index b858dfd..2c13dea 100644
@@ -105,6 +105,7 @@ extern void bus_remove_driver(struct device_driver *drv);
 
 extern void driver_detach(struct device_driver *drv);
 extern int driver_probe_device(struct device_driver *drv, struct device *dev);
+extern void driver_deferred_probe_del(struct device *dev);
 static inline int driver_match_device(struct device_driver *drv,
 				      struct device *dev)
 {
drivers/base/core.c +2 -0
index 0841a36..946094f 100644
@@ -649,6 +649,7 @@ void device_initialize(struct device *dev)
 {
 	dev->kobj.kset = devices_kset;
 	kobject_init(&dev->kobj, &device_ktype);
+	INIT_LIST_HEAD(&dev->deferred_probe);
 	INIT_LIST_HEAD(&dev->dma_pools);
 	mutex_init(&dev->mutex);
 	lockdep_set_novalidate_class(&dev->mutex);
@@ -1193,6 +1194,7 @@ void device_del(struct device *dev)
 	device_remove_file(dev, &uevent_attr);
 	device_remove_attrs(dev);
 	bus_remove_device(dev);
+	driver_deferred_probe_del(dev);
 
 	/*
 	 * Some platform devices are driven without driver attached
drivers/base/dd.c +137 -1

156 lines not on this page · raw message

include/linux/device.h +5 -0
index f62e216..22d6938 100644
@@ -585,6 +585,10 @@ struct device_dma_parameters {
  * @mutex:	Mutex to synchronize calls to its driver.
  * @bus:	Type of bus device is on.
  * @driver:	Which driver has allocated this
+ * @deferred_probe: entry in deferred_probe_list which is used to retry the
+ * 		binding of drivers which were unable to get all the resources
+ * 		needed by the device; typically because it depends on another
+ * 		driver getting probed first.
  * @platform_data: Platform data specific to the device.
  * 		Example: For devices on custom boards, as typical of embedded
  * 		and SOC based hardware, Linux often uses platform_data to point
@@ -644,6 +648,7 @@ struct device {
 	struct bus_type	*bus;		/* type of bus device is on */
 	struct device_driver *driver;	/* which driver has allocated this
 					   device */
+	struct list_head	deferred_probe;
 	void		*platform_data;	/* Platform specific data, device
 					   core doesn't touch it */
 	struct dev_pm_info	power;
include/linux/errno.h +1 -0
index 4668583..2d09bfa 100644
@@ -16,6 +16,7 @@
 #define ERESTARTNOHAND	514	/* restart if no handler.. */
 #define ENOIOCTLCMD	515	/* No ioctl command */
 #define ERESTART_RESTARTBLOCK 516 /* restart by calling sys_restart_syscall */
+#define EPROBE_DEFER	517	/* Driver requests probe retry */
 
 /* Defined for the NFSv3 protocol */
 #define EBADHANDLE	521	/* Illegal NFS file handle */
Signature · 1 line
1.7.9.3
#2 lore raw

PATCH 1/11 drivercore: Add driver probe deferral mechanism

Quoted 28 lines · Thierry Reding

From: Grant Likely<[email protected]>

Allow drivers to report at probe time that they cannot get all the resources required by the device, and should be retried at a later time.

This should completely solve the problem of getting devices initialized in the right order. Right now this is mostly handled by mucking about with initcall ordering which is a complete hack, and doesn't even remotely handle the case where device drivers are in modules. This approach completely sidesteps the issues by allowing driver registration to occur in any order, and any driver can request to be retried after a few more other drivers get probed.

v4: - Integrate Manjunath's addition of a separate workqueue
- Change -EAGAIN to -EPROBE_DEFER for drivers to trigger deferral
- Update comment blocks to reflect how the code really works
v3: - Hold off workqueue scheduling until late_initcall so that the bulk
of driver probes are complete before we start retrying deferred devices.
- Tested with simple use cases. Still needs more testing though. Using it to get rid of the gpio early_initcall madness, or to replace the ASoC internal probe deferral code would be ideal.
v2: - added locking so it should no longer be utterly broken in that regard
- remove device from deferred list at device_del time.
- Still completely untested with any real use case, but has been boot tested.

[Cc list stripped in order not to get on people's nerves]
Quoted 7 lines
---
  drivers/base/base.h    |    1 +
  drivers/base/core.c    |    2 +
  drivers/base/dd.c      |  138 +++++++++++++++++++++++++++++++++++++++++++++++-
  include/linux/device.h |    5 ++
  include/linux/errno.h  |    1 +
  5 files changed, 146 insertions(+), 1 deletion(-)

Is this patch going to be included in v3.4 ? I can see it's in -next, but not sure where I could check if its really queued for v3.4. It would be nice to have it in v3.4, I've got already one more client of this deferred probe infrastructure.

--

Thanks,
Sylwester

#3 lore raw

PATCH 1/11 drivercore: Add driver probe deferral mechanism

Quoted 37 lines · Sylwester Nawrocki
Quoted 28 lines · Thierry Reding

From: Grant Likely<[email protected]>

Allow drivers to report at probe time that they cannot get all the resources required by the device, and should be retried at a later time.

This should completely solve the problem of getting devices initialized in the right order. Right now this is mostly handled by mucking about with initcall ordering which is a complete hack, and doesn't even remotely handle the case where device drivers are in modules. This approach completely sidesteps the issues by allowing driver registration to occur in any order, and any driver can request to be retried after a few more other drivers get probed.

v4: - Integrate Manjunath's addition of a separate workqueue
- Change -EAGAIN to -EPROBE_DEFER for drivers to trigger deferral
- Update comment blocks to reflect how the code really works
v3: - Hold off workqueue scheduling until late_initcall so that the bulk
of driver probes are complete before we start retrying deferred devices.
- Tested with simple use cases. Still needs more testing though. Using it to get rid of the gpio early_initcall madness, or to replace the ASoC internal probe deferral code would be ideal.
v2: - added locking so it should no longer be utterly broken in that regard
- remove device from deferred list at device_del time.
- Still completely untested with any real use case, but has been boot tested.

[Cc list stripped in order not to get on people's nerves]
Quoted 7 lines
---
  drivers/base/base.h    |    1 +
  drivers/base/core.c    |    2 +
  drivers/base/dd.c      |  138 +++++++++++++++++++++++++++++++++++++++++++++++-
  include/linux/device.h |    5 ++
  include/linux/errno.h  |    1 +
  5 files changed, 146 insertions(+), 1 deletion(-)
Quoted 4 lines

Is this patch going to be included in v3.4 ? I can see it's in -next, but not sure where I could check if its really queued for v3.4. It would be nice to have it in v3.4, I've got already one more client of this deferred probe infrastructure.

Greg has sent it on to Linus for merging, so yes.

g.

#4 lore raw

PATCH 2/11 regulator: Support driver probe deferral

In reply to Thierry Reding

From: Mark Brown <[email protected]>

If we fail to locate a requested regulator return -EPROBE_DEFER. If drivers pass this error code through to their caller (which they really should) then this will ensure that the probe is retried later when further devices become available.

[G,Manjunath Kondaiah removed in order not to bother him]
---
 drivers/regulator/core.c |    4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/regulator/core.c +2 -2
index 5a6b8ba..8a4b0a8 100644
@@ -1198,7 +1198,7 @@ static struct regulator *_regulator_get(struct device *dev, const char *id,
 {
 	struct regulator_dev *rdev;
 	struct regulator_map *map;
-	struct regulator *regulator = ERR_PTR(-ENODEV);
+	struct regulator *regulator = ERR_PTR(-EPROBE_DEFER);
 	const char *devname = NULL;
 	int ret;
 
@@ -2926,7 +2926,7 @@ struct regulator_dev *regulator_register(struct regulator_desc *regulator_desc,
 
 		if (!r) {
 			dev_err(dev, "Failed to find supply %s\n", supply);
-			ret = -ENODEV;
+			ret = -EPROBE_DEFER;
 			goto scrub;
 		}
 
Signature · 1 line
1.7.9.3
#5 lore raw

PATCH 3/11 regulator: fixed: Support driver probe deferral

In reply to Thierry Reding

If the specified GPIO is not found, return -EPROBE_DEFER. This will cause the driver to be probed again later when the required GPIO may have become available.

---
 drivers/regulator/fixed.c |   14 +++++++++++---
 1 file changed, 11 insertions(+), 3 deletions(-)
drivers/regulator/fixed.c +11 -3
index 40f3803..35cec44 100644
@@ -58,12 +58,19 @@ of_get_fixed_voltage_config(struct device *dev)
 	struct device_node *np = dev->of_node;
 	const __be32 *delay;
 	struct regulator_init_data *init_data;
+	int gpio;
+
+	gpio = of_get_named_gpio(np, "gpio", 0);
+	if (gpio < 0)
+		return ERR_PTR(-EPROBE_DEFER);
 
 	config = devm_kzalloc(dev, sizeof(struct fixed_voltage_config),
 								 GFP_KERNEL);
 	if (!config)
 		return NULL;
 
+	config->gpio = gpio;
+
 	config->init_data = of_get_regulator_init_data(dev, dev->of_node);
 	if (!config->init_data)
 		return NULL;
@@ -83,7 +90,6 @@ of_get_fixed_voltage_config(struct device *dev)
 	if (init_data->constraints.boot_on)
 		config->enabled_at_boot = true;
 
-	config->gpio = of_get_named_gpio(np, "gpio", 0);
 	delay = of_get_property(np, "startup-delay-us", NULL);
 	if (delay)
 		config->startup_delay = be32_to_cpu(*delay);
@@ -168,9 +174,11 @@ static int __devinit reg_fixed_voltage_probe(struct platform_device *pdev)
 	struct fixed_voltage_data *drvdata;
 	int ret;
 
-	if (pdev->dev.of_node)
+	if (pdev->dev.of_node) {
 		config = of_get_fixed_voltage_config(&pdev->dev);
-	else
+		if (IS_ERR(config))
+			return PTR_ERR(config);
+	} else
 		config = pdev->dev.platform_data;
 
 	if (!config)
Signature · 1 line
1.7.9.3
#6 lore raw

PATCH 3/11 regulator: fixed: Support driver probe deferral

Quoted 3 lines · Thierry Reding

If the specified GPIO is not found, return -EPROBE_DEFER. This will cause the driver to be probed again later when the required GPIO may have become available.

Might be worth pushing this into gpiolib? It seems like wanting to
defer if a GPIO is not found will be the overwhelmingly common case
given that the GPIO numbers need to be explicitly specified.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20120311/ee0f2383/attachment-0001.sig>

#7 lore raw

PATCH 4/11 regulator: tps6586x: fix typo in debug message

In reply to Thierry Reding
---
 drivers/regulator/tps6586x-regulator.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/regulator/tps6586x-regulator.c +1 -1
index c75fb20..29b615c 100644
@@ -383,7 +383,7 @@ static int __devinit tps6586x_regulator_probe(struct platform_device *pdev)
 	int id = pdev->id;
 	int err;
 
-	dev_dbg(&pdev->dev, "Probing reulator %d\n", id);
+	dev_dbg(&pdev->dev, "Probing regulator %d\n", id);
 
 	ri = find_regulator_info(id);
 	if (ri == NULL) {
Signature · 1 line
1.7.9.3
#9 lore raw

PATCH 5/11 tps6586x: Add device-tree support

In reply to Thierry Reding
---
 .../devicetree/bindings/regulator/tps6586x.txt     |   98 ++++++++++++++++++++
 drivers/mfd/tps6586x.c                             |   66 +++++++++++++
 drivers/regulator/tps6586x-regulator.c             |    2 +-
 include/linux/mfd/tps6586x.h                       |    1 +
 4 files changed, 166 insertions(+), 1 deletion(-)
 create mode 100644 Documentation/devicetree/bindings/regulator/tps6586x.txt
Documentation/devicetree/bindings/regulator/tps6586x.txt new file +98 -0
new file mode 100644
index 0000000..e8d2888
@@ -0,0 +1,98 @@
+TPS6586x family of regulators
+
+Required properties:
+- compatible: "ti,tps6586x"
+- reg: I2C slave address
+- interrupts: the interrupt outputs of the controller
+- #gpio-cells: number of cells to describe a GPIO
+- gpio-controller: mark the device as a GPIO controller
+- regulators: list of regulators provided by this controller, must be in the
+  following order:
+    SM0, SM1, SM2, LDO0, LDO1, LDO2, LDO3, LDO4, LDO5, LDO6, LDO7, LDO8, LDO9
+
+Each regulator is defined using the standard binding for regulators.
+
+Example:
+
+	pmu: tps6586x at 34 {
+		compatible = "ti,tps6586x";
+		reg = <0x34>;
+		interrupts = <0 88 0x4>;
+
+		#gpio-cells = <2>;
+		gpio-controller;
+
+		regulators {
+			sm0_reg: sm0 {
+				regulator-min-microvolt = < 725000>;
+				regulator-max-microvolt = <1500000>;
+				regulator-boot-on;
+				regulator-always-on;
+			};
+
+			sm1_reg: sm1 {
+				regulator-min-microvolt = < 725000>;
+				regulator-max-microvolt = <1500000>;
+				regulator-boot-on;
+				regulator-always-on;
+			};
+
+			sm2_reg: sm2 {
+				regulator-min-microvolt = <3000000>;
+				regulator-max-microvolt = <4550000>;
+				regulator-boot-on;
+				regulator-always-on;
+			};
+
+			ldo0_reg: ldo0 {
+				regulator-name = "PCIE CLK";
+				regulator-min-microvolt = <3300000>;
+				regulator-max-microvolt = <3300000>;
+			};
+
+			ldo1_reg: ldo1 {
+				regulator-min-microvolt = < 725000>;
+				regulator-max-microvolt = <1500000>;
+			};
+
+			ldo2_reg: ldo2 {
+				regulator-min-microvolt = < 725000>;
+				regulator-max-microvolt = <1500000>;
+			};
+
+			ldo3_reg: ldo3 {
+				regulator-min-microvolt = <1250000>;
+				regulator-max-microvolt = <3300000>;
+			};
+
+			ldo4_reg: ldo4 {
+				regulator-min-microvolt = <1700000>;
+				regulator-max-microvolt = <2475000>;
+			};
+
+			ldo5_reg: ldo5 {
+				regulator-min-microvolt = <1250000>;
+				regulator-max-microvolt = <3300000>;
+			};
+
+			ldo6_reg: ldo6 {
+				regulator-min-microvolt = <1250000>;
+				regulator-max-microvolt = <3300000>;
+			};
+
+			ldo7_reg: ldo7 {
+				regulator-min-microvolt = <1250000>;
+				regulator-max-microvolt = <3300000>;
+			};
+
+			ldo8_reg: ldo8 {
+				regulator-min-microvolt = <1250000>;
+				regulator-max-microvolt = <3300000>;
+			};
+
+			ldo9_reg: ldo9 {
+				regulator-min-microvolt = <1250000>;
+				regulator-max-microvolt = <3300000>;
+			};
+		};
+	};
drivers/mfd/tps6586x.c +66 -0

96 lines not on this page · raw message

drivers/regulator/tps6586x-regulator.c +1 -1
index 29b615c..f10a735 100644
@@ -396,7 +396,7 @@ static int __devinit tps6586x_regulator_probe(struct platform_device *pdev)
 		return err;
 
 	rdev = regulator_register(&ri->desc, &pdev->dev,
-				  pdev->dev.platform_data, ri, NULL);
+				  pdev->dev.platform_data, ri, pdev->dev.of_node);
 	if (IS_ERR(rdev)) {
 		dev_err(&pdev->dev, "failed to register regulator %s\n",
 				ri->desc.name);
include/linux/mfd/tps6586x.h +1 -0
index b19176e..f350fd0 100644
@@ -68,6 +68,7 @@ struct tps6586x_subdev_info {
 	int		id;
 	const char	*name;
 	void		*platform_data;
+	struct device_node *of_node;
 };
 
 struct tps6586x_platform_data {
Signature · 1 line
1.7.9.3
#10 lore raw

PATCH 5/11 tps6586x: Add device-tree support

Documentation/devicetree/bindings/regulator/tps6586x.txt line 11

Quoted 4 lines · Thierry Reding
+- gpio-controller: mark the device as a GPIO controller
+- regulators: list of regulators provided by this controller, must be in the
Documentation/devicetree/bindings/regulator/tps6586x.txt new file +2 -0
+  following order:
+    SM0, SM1, SM2, LDO0, LDO1, LDO2, LDO3, LDO4, LDO5, LDO6, LDO7, LDO8, LDO9

This ordering requirement is fairly sad, if there are unused regulators they still need to be listed even though...

Documentation/devicetree/bindings/regulator/tps6586x.txt line 33

Quoted 8 lines
Documentation/devicetree/bindings/regulator/tps6586x.txt new file +8 -0
+			sm0_reg: sm0 {
+				regulator-min-microvolt = < 725000>;
+				regulator-max-microvolt = <1500000>;
+				regulator-boot-on;
+				regulator-always-on;
+			};
+
+			sm1_reg: sm1 {

...they all seem to be explicitly named in the device tree so presumably there's enough information in there for the driver to pick any set of regulators in any order. This would be much nicer to use.

Otherwise this looks good.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20120308/3239a330/attachment.sig>

#11 lore raw

PATCH 5/11 tps6586x: Add device-tree support

Quoted 10 lines · Mark Brown

Documentation/devicetree/bindings/regulator/tps6586x.txt line 11

Quoted 4 lines · Thierry Reding
+- gpio-controller: mark the device as a GPIO controller
+- regulators: list of regulators provided by this controller, must be in the
Documentation/devicetree/bindings/regulator/tps6586x.txt new file +2 -0
+  following order:
+    SM0, SM1, SM2, LDO0, LDO1, LDO2, LDO3, LDO4, LDO5, LDO6, LDO7, LDO8, LDO9

This ordering requirement is fairly sad, if there are unused regulators they still need to be listed even though...

Quoted 12 lines

Documentation/devicetree/bindings/regulator/tps6586x.txt line 33

Quoted 8 lines
Documentation/devicetree/bindings/regulator/tps6586x.txt new file +8 -0
+			sm0_reg: sm0 {
+				regulator-min-microvolt = < 725000>;
+				regulator-max-microvolt = <1500000>;
+				regulator-boot-on;
+				regulator-always-on;
+			};
+
+			sm1_reg: sm1 {

...they all seem to be explicitly named in the device tree so presumably there's enough information in there for the driver to pick any set of regulators in any order. This would be much nicer to use.

I don't like it much either. The only reason that requirement exists is because it makes the assignment of the regulator ID (as defined in the include/linux/mfd/tps6586x.h header) very trivial. Would it be better to look up the ID based on the node name (sm0 --> TPS6586X_ID_SM_0, ...)?

Then the only requirement would be that the names match.

Thierry
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 198 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20120308/eacd48fa/attachment.sig>

#12 lore raw

PATCH 5/11 tps6586x: Add device-tree support

Quoted 6 lines · Thierry Reding
Quoted 3 lines · Mark Brown

...they all seem to be explicitly named in the device tree so presumably there's enough information in there for the driver to pick any set of regulators in any order. This would be much nicer to use.

Quoted 6 lines

I don't like it much either. The only reason that requirement exists is because it makes the assignment of the regulator ID (as defined in the include/linux/mfd/tps6586x.h header) very trivial. Would it be better to look up the ID based on the node name (sm0 --> TPS6586X_ID_SM_0, ...)?

Then the only requirement would be that the names match.

Yes, that's going to be more code but much nicer for users.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20120308/f2f4032e/attachment.sig>

#13 lore raw

PATCH 5/11 tps6586x: Add device-tree support

Quoted 7 lines · Mark Brown
Quoted 5 lines · Thierry Reding
Quoted 3 lines · Mark Brown

...they all seem to be explicitly named in the device tree so presumably there's enough information in there for the driver to pick any set of regulators in any order. This would be much nicer to use.

Quoted 8 lines
Quoted 6 lines

I don't like it much either. The only reason that requirement exists is because it makes the assignment of the regulator ID (as defined in the include/linux/mfd/tps6586x.h header) very trivial. Would it be better to look up the ID based on the node name (sm0 --> TPS6586X_ID_SM_0, ...)?

Then the only requirement would be that the names match.

Yes, that's going to be more code but much nicer for users.

Okay, I'll add that for the next round.

Thierry
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 198 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20120308/6cfa72be/attachment.sig>

#14 lore raw

PATCH 5/11 tps6586x: Add device-tree support

In reply to Thierry Reding
Quoted 10 lines · Thierry Reding
Quoted 9 lines · Mark Brown

Documentation/devicetree/bindings/regulator/tps6586x.txt line 11

Quoted 4 lines · Thierry Reding
+- gpio-controller: mark the device as a GPIO controller
+- regulators: list of regulators provided by this controller, must be in the
Documentation/devicetree/bindings/regulator/tps6586x.txt new file +2 -0
+  following order:
+    SM0, SM1, SM2, LDO0, LDO1, LDO2, LDO3, LDO4, LDO5, LDO6, LDO7, LDO8, LDO9

This ordering requirement is fairly sad, if there are unused regulators they still need to be listed even though...

It's worse than that; the DT provides absolutely no guarantees about the ordering of either child nodes or properties.

Quoted 14 lines
Quoted 13 lines

Documentation/devicetree/bindings/regulator/tps6586x.txt line 33

Quoted 9 lines
Documentation/devicetree/bindings/regulator/tps6586x.txt new file +8 -0
+			sm0_reg: sm0 {
+				regulator-min-microvolt = < 725000>;
+				regulator-max-microvolt = <1500000>;
+				regulator-boot-on;
+				regulator-always-on;
+			};
+
+			sm1_reg: sm1 {

...they all seem to be explicitly named in the device tree so presumably there's enough information in there for the driver to pick any set of regulators in any order. This would be much nicer to use.

Quoted 6 lines

I don't like it much either. The only reason that requirement exists is because it makes the assignment of the regulator ID (as defined in the include/linux/mfd/tps6586x.h header) very trivial. Would it be better to look up the ID based on the node name (sm0 --> TPS6586X_ID_SM_0, ...)?

Then the only requirement would be that the names match.

Yes, please look up id via name. Alternately you can give each child node a 'reg' property and put #address-cells = <1>; #size-cells = <0>; in the parent (assuming the regulator number is a documented attribute of the hardware and not just a convenient linux construct).

g.

#15 lore raw

PATCH 5/11 tps6586x: Add device-tree support

Quoted 11 lines · Grant Likely
Quoted 10 lines · Thierry Reding
Quoted 3 lines · Mark Brown

...they all seem to be explicitly named in the device tree so presumably there's enough information in there for the driver to pick any set of regulators in any order. This would be much nicer to use.

I don't like it much either. The only reason that requirement exists is because it makes the assignment of the regulator ID (as defined in the include/linux/mfd/tps6586x.h header) very trivial. Would it be better to look up the ID based on the node name (sm0 --> TPS6586X_ID_SM_0, ...)?

Quoted 6 lines
Quoted 1 line

Then the only requirement would be that the names match.

Yes, please look up id via name. Alternately you can give each child node a 'reg' property and put #address-cells = <1>; #size-cells = <0>; in the parent (assuming the regulator number is a documented attribute of the hardware and not just a convenient linux construct).

I'll go with the lookup via name then because as far as I can tell the datasheet doesn't list any specific ordering of the regulators.

Thierry
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 198 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20120309/61b3ddc2/attachment-0001.sig>

#16 lore raw

PATCH 6/11 PCI: Keep pci_fixup_irqs() around after init

In reply to Thierry Reding
---
 drivers/pci/setup-irq.c |    4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/pci/setup-irq.c +2 -2
index eb219a1..270ae7b 100644
@@ -18,7 +18,7 @@
 #include <linux/cache.h>
 
 
-static void __init
+static void
 pdev_fixup_irq(struct pci_dev *dev,
 	       u8 (*swizzle)(struct pci_dev *, u8 *),
 	       int (*map_irq)(const struct pci_dev *, u8, u8))
@@ -54,7 +54,7 @@ pdev_fixup_irq(struct pci_dev *dev,
 	pcibios_update_irq(dev, irq);
 }
 
-void __init
+void
 pci_fixup_irqs(u8 (*swizzle)(struct pci_dev *, u8 *),
 	       int (*map_irq)(const struct pci_dev *, u8, u8))
 {
Signature · 1 line
1.7.9.3
maintainer
#17 lore raw

PATCH 6/11 PCI: Keep pci_fixup_irqs() around after init

Quoted 19 lines · Thierry Reding

---
?drivers/pci/setup-irq.c | ? ?4 ++--
?1 file changed, 2 insertions(+), 2 deletions(-)

drivers/pci/setup-irq.c +0 -0
index eb219a1..270ae7b 100644
@@ -18,7 +18,7 @@

?#include <linux/cache.h>

drivers/pci/setup-irq.c +1 -1
-static void __init
+static void

?pdev_fixup_irq(struct pci_dev *dev,
? ? ? ? ? ? ? u8 (*swizzle)(struct pci_dev *, u8 *), ? ? ? ? ? ? ? int (*map_irq)(const struct pci_dev *, u8, u8))

drivers/pci/setup-irq.c pdev_fixup_irq(struct pci_dev *dev, · line 60

Quoted 8 lines
drivers/pci/setup-irq.c +1 -1
@@ -54,7 +54,7 @@ pdev_fixup_irq(struct pci_dev *dev,
 ? ? ? ?pcibios_update_irq(dev, irq);
 ?}
 
-void __init
+void
 ?pci_fixup_irqs(u8 (*swizzle)(struct pci_dev *, u8 *),
 ? ? ? ? ? ? ? int (*map_irq)(const struct pci_dev *, u8, u8))
 ?{
        struct pci_dev *dev = NULL;
        for_each_pci_dev(dev)
                pdev_fixup_irq(dev, swizzle, map_irq);
}

Hmm, your patch looks OK as far as it goes, but the implementation of pci_fixup_irqs() as a call-once-at-boot-time thing with a loop through all the PCI devices we've found so far looks completely broken with regard to hotplug.

Who does the swizzle for devices hot-added after boot?

Bjorn

#18 lore raw

PATCH 6/11 PCI: Keep pci_fixup_irqs() around after init

Quoted 6 lines · Bjorn Helgaas

Hmm, your patch looks OK as far as it goes, but the implementation of pci_fixup_irqs() as a call-once-at-boot-time thing with a loop through all the PCI devices we've found so far looks completely broken with regard to hotplug.

Who does the swizzle for devices hot-added after boot?

Perhaps I should have mentioned this in the commit message, but the patch isn't actually used in a hotplug scenario. In fact, the code is still run once at boot time, only very late. Grant's deferred probing allows the PCIe controller driver to postpone initialization until all the devices that it depends on (regulators) have been probed. This has the side-effect that the probing actually takes place *after* code and data annotated with __init have already been freed.

Thierry
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 198 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20120308/e3caaac8/attachment.sig>

maintainer
#19 lore raw

PATCH 6/11 PCI: Keep pci_fixup_irqs() around after init

Quoted 8 lines · Thierry Reding
Quoted 6 lines · Bjorn Helgaas

Hmm, your patch looks OK as far as it goes, but the implementation of pci_fixup_irqs() as a call-once-at-boot-time thing with a loop through all the PCI devices we've found so far looks completely broken with regard to hotplug.

Who does the swizzle for devices hot-added after boot?

Quoted 7 lines

Perhaps I should have mentioned this in the commit message, but the patch isn't actually used in a hotplug scenario. In fact, the code is still run once at boot time, only very late. Grant's deferred probing allows the PCIe controller driver to postpone initialization until all the devices that it depends on (regulators) have been probed. This has the side-effect that the probing actually takes place *after* code and data annotated with __init have already been freed.

Oh, I know *you're* not using the hotplug scenario. I'm just thinking that the PCi core looks a little broken in that scenario.

I think your patch is fine; it's just that I think the PCI core needs a little more attention in this area.

Bjorn

#20 lore raw

PATCH 7/11 ARM: pci: Keep pci_common_init() around after init

In reply to Thierry Reding
---
 arch/arm/kernel/bios32.c |    4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
arch/arm/kernel/bios32.c +2 -2
index be5d3b2..c88dcf5 100644
@@ -411,7 +411,7 @@ static int pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
 	return irq;
 }
 
-static void __init pcibios_init_hw(struct hw_pci *hw)
+static void pcibios_init_hw(struct hw_pci *hw)
 {
 	struct pci_sys_data *sys = NULL;
 	int ret;
@@ -457,7 +457,7 @@ static void __init pcibios_init_hw(struct hw_pci *hw)
 	}
 }
 
-void __init pci_common_init(struct hw_pci *hw)
+void pci_common_init(struct hw_pci *hw)
 {
 	struct pci_sys_data *sys;
 
Signature · 1 line
1.7.9.3
#21 lore raw

PATCH 8/11 ARM: tegra: Move tegra_pcie_xclk_clamp() to PMC

In reply to Thierry Reding

The PMC code already accesses the PMC registers so it makes sense to move this function there as well. While at it, rename the function to tegra_pmc_pcie_xclk_clamp() for consistency.

---
 arch/arm/mach-tegra/pcie.c |   30 ++++--------------------------
 arch/arm/mach-tegra/pmc.c  |   16 ++++++++++++++++
 arch/arm/mach-tegra/pmc.h  |    1 +
 3 files changed, 21 insertions(+), 26 deletions(-)
arch/arm/mach-tegra/pcie.c +4 -26
index 7313059..7704af7a 100644
@@ -42,6 +42,7 @@
 #include <mach/powergate.h>
 
 #include "board.h"
+#include "pmc.h"
 
 /* register definitions */
 #define AFI_OFFSET	0x3800
@@ -145,17 +146,6 @@
 #define  PADS_PLL_CTL_TXCLKREF_DIV10		(0 << 20)
 #define  PADS_PLL_CTL_TXCLKREF_DIV5		(1 << 20)
 
-/* PMC access is required for PCIE xclk (un)clamping */
-#define PMC_SCRATCH42		0x144
-#define PMC_SCRATCH42_PCX_CLAMP	(1 << 0)
-
-static void __iomem *reg_pmc_base = IO_ADDRESS(TEGRA_PMC_BASE);
-
-#define pmc_writel(value, reg) \
-	__raw_writel(value, reg_pmc_base + (reg))
-#define pmc_readl(reg) \
-	__raw_readl(reg_pmc_base + (reg))
-
 /*
  * Tegra2 defines 1GB in the AXI address map for PCIe.
  *
@@ -680,18 +670,6 @@ static int tegra_pcie_enable_controller(void)
 	return;
 }
 
-static void tegra_pcie_xclk_clamp(bool clamp)
-{
-	u32 reg;
-
-	reg = pmc_readl(PMC_SCRATCH42) & ~PMC_SCRATCH42_PCX_CLAMP;
-
-	if (clamp)
-		reg |= PMC_SCRATCH42_PCX_CLAMP;
-
-	pmc_writel(reg, PMC_SCRATCH42);
-}
-
 static void tegra_pcie_power_off(void)
 {
 	tegra_periph_reset_assert(tegra_pcie.pcie_xclk);
@@ -699,7 +677,7 @@ static void tegra_pcie_power_off(void)
 	tegra_periph_reset_assert(tegra_pcie.pex_clk);
 
 	tegra_powergate_power_off(TEGRA_POWERGATE_PCIE);
-	tegra_pcie_xclk_clamp(true);
+	tegra_pmc_pcie_xclk_clamp(true);
 }
 
 static int tegra_pcie_power_regate(void)
@@ -708,7 +686,7 @@ static int tegra_pcie_power_regate(void)
 
 	tegra_pcie_power_off();
 
-	tegra_pcie_xclk_clamp(true);
+	tegra_pmc_pcie_xclk_clamp(true);
 
 	tegra_periph_reset_assert(tegra_pcie.pcie_xclk);
 	tegra_periph_reset_assert(tegra_pcie.afi_clk);
@@ -722,7 +700,7 @@ static int tegra_pcie_power_regate(void)
 
 	tegra_periph_reset_deassert(tegra_pcie.afi_clk);
 
-	tegra_pcie_xclk_clamp(false);
+	tegra_pmc_pcie_xclk_clamp(false);
 
 	clk_enable(tegra_pcie.afi_clk);
 	clk_enable(tegra_pcie.pex_clk);
arch/arm/mach-tegra/pmc.c +16 -0
index 7af6a54..399dc3a 100644
@@ -24,6 +24,10 @@
 #define PMC_CTRL		0x0
 #define PMC_CTRL_INTR_LOW	(1 << 17)
 
+/* PMC access is required for PCIE xclk (un)clamping */
+#define PMC_SCRATCH42		0x144
+#define PMC_SCRATCH42_PCX_CLAMP	(1 << 0)
+
 static inline u32 tegra_pmc_readl(u32 reg)
 {
 	return readl(IO_ADDRESS(TEGRA_PMC_BASE + reg));
@@ -74,3 +78,15 @@ void __init tegra_pmc_init(void)
 		val &= ~PMC_CTRL_INTR_LOW;
 	tegra_pmc_writel(val, PMC_CTRL);
 }
+
+void tegra_pmc_pcie_xclk_clamp(bool clamp)
+{
+	u32 reg;
+
+	reg = tegra_pmc_readl(PMC_SCRATCH42) & ~PMC_SCRATCH42_PCX_CLAMP;
+
+	if (clamp)
+		reg |= PMC_SCRATCH42_PCX_CLAMP;
+
+	tegra_pmc_writel(reg, PMC_SCRATCH42);
+}
arch/arm/mach-tegra/pmc.h +1 -0
index 8995ee4..2631c9a 100644
@@ -19,5 +19,6 @@
 #define __MACH_TEGRA_PMC_H
 
 void tegra_pmc_init(void);
+void tegra_pmc_pcie_xclk_clamp(bool clamp);
 
 #endif
Signature · 1 line
1.7.9.3
#23 lore raw

PATCH 9/11 ARM: tegra: Rewrite PCIe support as a driver

In reply to Thierry Reding
---
 arch/arm/mach-tegra/board-harmony-pcie.c |   38 ++-
 arch/arm/mach-tegra/board-harmony.c      |    1 +
 arch/arm/mach-tegra/board-harmony.h      |    1 +
 arch/arm/mach-tegra/board-trimslice.c    |   16 +-
 arch/arm/mach-tegra/board.h              |   11 +-
 arch/arm/mach-tegra/devices.c            |   25 ++
 arch/arm/mach-tegra/devices.h            |    1 +
 arch/arm/mach-tegra/include/mach/iomap.h |    6 +
 arch/arm/mach-tegra/pcie.c               |  509 ++++++++++++++++++------------
 9 files changed, 386 insertions(+), 222 deletions(-)
arch/arm/mach-tegra/board-harmony-pcie.c +24 -14
index 33c4fed..e624a9c 100644
@@ -23,18 +23,15 @@
 #include <asm/mach-types.h>
 
 #include "board.h"
+#include "devices.h"
 #include "board-harmony.h"
 
 #ifdef CONFIG_TEGRA_PCI
-
-static int __init harmony_pcie_init(void)
+static int tegra_pcie_init(struct platform_device *pdev)
 {
 	struct regulator *regulator = NULL;
 	int err;
 
-	if (!machine_is_harmony())
-		return 0;
-
 	err = gpio_request(TEGRA_GPIO_EN_VDD_1V05_GPIO, "EN_VDD_1V05");
 	if (err)
 		return err;
@@ -47,22 +44,35 @@ static int __init harmony_pcie_init(void)
 
 	regulator_enable(regulator);
 
-	err = tegra_pcie_init(true, true);
-	if (err)
-		goto err_pcie;
-
 	return 0;
 
-err_pcie:
-	regulator_disable(regulator);
-	regulator_put(regulator);
 err_reg:
 	gpio_free(TEGRA_GPIO_EN_VDD_1V05_GPIO);
 
 	return err;
 }
 
-/* PCI should be initialized after I2C, mfd and regulators */
-subsys_initcall_sync(harmony_pcie_init);
+static struct tegra_pcie_pdata tegra_pcie_pdata = {
+	.init = tegra_pcie_init,
+	.enable_ports = {
+		[0] = true,
+		[1] = true,
+	},
+};
+
+int __init harmony_pcie_init(void)
+{
+	if (!machine_is_harmony())
+		return 0;
+
+	tegra_pcie_device.dev.platform_data = &tegra_pcie_pdata;
+	platform_device_register(&tegra_pcie_device);
 
+	return 0;
+}
+#else
+int __init harmony_pcie_init(void)
+{
+	return 0;
+}
 #endif
arch/arm/mach-tegra/board-harmony.c +1 -0
index c00aadb..ca20680 100644
@@ -180,6 +180,7 @@ static void __init tegra_harmony_init(void)
 	platform_add_devices(harmony_devices, ARRAY_SIZE(harmony_devices));
 	harmony_i2c_init();
 	harmony_regulator_init();
+	harmony_pcie_init();
 }
 
 MACHINE_START(HARMONY, "harmony")
arch/arm/mach-tegra/board-harmony.h +1 -0
index 139d96c..afa68e2 100644
@@ -37,5 +37,6 @@
 
 void harmony_pinmux_init(void);
 int harmony_regulator_init(void);
+int harmony_pcie_init(void);
 
 #endif
arch/arm/mach-tegra/board-trimslice.c +13 -3
index cd52820..9bc414a 100644
@@ -147,14 +147,23 @@ static __initdata struct tegra_clk_init_table trimslice_clk_init_table[] = {
 	{ NULL,		NULL,		0,		0},
 };
 
-static int __init tegra_trimslice_pci_init(void)
+static struct tegra_pcie_pdata tegra_pcie_pdata = {
+	.enable_ports = {
+		[0] = true,
+		[1] = true,
+	},
+};
+
+static int __init trimslice_pci_init(void)
 {
 	if (!machine_is_trimslice())
 		return 0;
 
-	return tegra_pcie_init(true, true);
+	tegra_pcie_device.dev.platform_data = &tegra_pcie_pdata;
+	platform_device_register(&tegra_pcie_device);
+
+	return 0;
 }
-subsys_initcall(tegra_trimslice_pci_init);
 
 static void __init tegra_trimslice_init(void)
 {
@@ -169,6 +178,7 @@ static void __init tegra_trimslice_init(void)
 
 	trimslice_i2c_init();
 	trimslice_usb_init();
+	trimslice_pci_init();
 }
 
 MACHINE_START(TRIMSLICE, "trimslice")
arch/arm/mach-tegra/board.h +10 -1
index 75d1543..40f7e6b 100644
@@ -21,6 +21,7 @@
 #ifndef __MACH_TEGRA_BOARD_H
 #define __MACH_TEGRA_BOARD_H
 
+#include <linux/platform_device.h>
 #include <linux/types.h>
 
 void tegra_assert_system_reset(char mode, const char *cmd);
@@ -30,7 +31,15 @@ void __init tegra30_init_early(void);
 void __init tegra_map_common_io(void);
 void __init tegra_init_irq(void);
 void __init tegra_dt_init_irq(void);
-int __init tegra_pcie_init(bool init_port0, bool init_port1);
 
 extern struct sys_timer tegra_timer;
+
+#define TEGRA_PCIE_MAX_PORTS 2
+
+struct tegra_pcie_pdata {
+	int (*init)(struct platform_device *pdev);
+	int (*exit)(struct platform_device *pdev);
+	bool enable_ports[TEGRA_PCIE_MAX_PORTS];
+};
+
 #endif
arch/arm/mach-tegra/devices.c +25 -0
index 7a2a02d..09e24e1 100644
@@ -704,3 +704,28 @@ struct platform_device tegra_pcm_device = {
 	.name = "tegra-pcm-audio",
 	.id = -1,
 };
+
+static struct resource tegra_pcie_resources[] = {
+	[0] = {
+		.start = TEGRA_PCIE_BASE,
+		.end = TEGRA_PCIE_BASE + TEGRA_PCIE_SIZE - 1,
+		.flags = IORESOURCE_MEM,
+	},
+	[1] = {
+		.start = TEGRA_PCIE_MMIO_BASE,
+		.end = TEGRA_PCIE_MMIO_BASE + TEGRA_PCIE_MMIO_SIZE - 1,
+		.flags = IORESOURCE_MEM,
+	},
+	[2] = {
+		.start = INT_PCIE_INTR,
+		.end = INT_PCIE_INTR,
+		.flags = IORESOURCE_IRQ,
+	},
+};
+
+struct platform_device tegra_pcie_device = {
+	.name = "tegra-pcie",
+	.id = -1,
+	.resource = tegra_pcie_resources,
+	.num_resources = ARRAY_SIZE(tegra_pcie_resources),
+};
arch/arm/mach-tegra/devices.h +1 -0
index 873ecb2..95f0a97 100644
@@ -48,5 +48,6 @@ extern struct platform_device tegra_i2s_device1;
 extern struct platform_device tegra_i2s_device2;
 extern struct platform_device tegra_das_device;
 extern struct platform_device tegra_pcm_device;
+extern struct platform_device tegra_pcie_device;
 
 #endif
arch/arm/mach-tegra/include/mach/iomap.h +6 -0
index cff672a..53b0dbe 100644
@@ -242,6 +242,12 @@
 #define TEGRA_CSITE_BASE		0x70040000
 #define TEGRA_CSITE_SIZE		SZ_256K
 
+#define TEGRA_PCIE_BASE			0x80000000
+#define TEGRA_PCIE_SIZE			SZ_4M
+
+#define TEGRA_PCIE_MMIO_BASE		0x80400000
+#define TEGRA_PCIE_MMIO_SIZE		SZ_64K
+
 #define TEGRA_USB_BASE			0xC5000000
 #define TEGRA_USB_SIZE			SZ_16K
 
arch/arm/mach-tegra/pcie.c +305 -204

875 lines not on this page · raw message

Signature · 1 line
1.7.9.3
#24 lore raw

PATCH 9/11 ARM: tegra: Rewrite PCIe support as a driver

Quoted 1 line · Thierry Reding

Patch description?

Quoted 1 line
arch/arm/mach-tegra/board-harmony-pcie.c +0 -0

...

arch/arm/mach-tegra/board-harmony-pcie.c line 30

Quoted 2 lines
arch/arm/mach-tegra/board-harmony-pcie.c +1 -1
-static int __init harmony_pcie_init(void)
+static int tegra_pcie_init(struct platform_device *pdev)

That name should probably still be called harmony_something() since it's still board-specific.

I wonder how having a per-board callback will integrate with device tree. I guess I'll find out when I review patch 11:-)

arch/arm/mach-tegra/board-trimslice.c static __initdata struct tegra_clk_init_table trimslice_clk_init_table[] = { · line 160

Quoted 6 lines
arch/arm/mach-tegra/board-trimslice.c +1 -0
 
+static int __init trimslice_pci_init(void)
 {
 	if (!machine_is_trimslice())
 		return 0;

You can remove that test now.

arch/arm/mach-tegra/board.h void __init tegra30_init_early(void); · line 43

Quoted 9 lines
arch/arm/mach-tegra/board.h +7 -0
 
+#define TEGRA_PCIE_MAX_PORTS 2
+
+struct tegra_pcie_pdata {
+	int (*init)(struct platform_device *pdev);
+	int (*exit)(struct platform_device *pdev);
+	bool enable_ports[TEGRA_PCIE_MAX_PORTS];
+};

That's a somewhat odd place to put the header; a dedicated mach-tegra/include/mach/tegra_pcie_pdata.h or include/linux/platform_data/tegra_pcie.h might make more sense.

Aside from those pretty minor issues, this all looks great. Thanks for fixing our driver!

#25 lore raw

PATCH 9/11 ARM: tegra: Rewrite PCIe support as a driver

Quoted 4 lines · Stephen Warren
Quoted 1 line · Thierry Reding

Patch description?

I actually sat in front of the editor for a couple of minutes and I just couldn't think of anything. I'll try harder for the next version.

Quoted 7 lines
Quoted 1 line
arch/arm/mach-tegra/board-harmony-pcie.c +0 -0

...

arch/arm/mach-tegra/board-harmony-pcie.c line 30

Quoted 2 lines
arch/arm/mach-tegra/board-harmony-pcie.c +1 -1
-static int __init harmony_pcie_init(void)
+static int tegra_pcie_init(struct platform_device *pdev)

That name should probably still be called harmony_something() since it's still board-specific.

Okay, I'll rename it to harmony_pcie_init().

Quoted 11 lines

I wonder how having a per-board callback will integrate with device tree. I guess I'll find out when I review patch 11:-)

arch/arm/mach-tegra/board-trimslice.c static __initdata struct tegra_clk_init_table trimslice_clk_init_table[] = { · line 160

Quoted 6 lines
arch/arm/mach-tegra/board-trimslice.c +1 -0
 
+static int __init trimslice_pci_init(void)
 {
 	if (!machine_is_trimslice())
 		return 0;

You can remove that test now.

Okay.

Quoted 13 lines

arch/arm/mach-tegra/board.h void __init tegra30_init_early(void); · line 43

Quoted 9 lines
arch/arm/mach-tegra/board.h +7 -0
 
+#define TEGRA_PCIE_MAX_PORTS 2
+
+struct tegra_pcie_pdata {
+	int (*init)(struct platform_device *pdev);
+	int (*exit)(struct platform_device *pdev);
+	bool enable_ports[TEGRA_PCIE_MAX_PORTS];
+};

That's a somewhat odd place to put the header; a dedicated mach-tegra/include/mach/tegra_pcie_pdata.h or include/linux/platform_data/tegra_pcie.h might make more sense.

mach-tegra/include/mach/pcie.h perhaps? That would be less redundant.

Thierry
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 198 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20120309/e23b9cb7/attachment-0001.sig>

#26 lore raw

PATCH 9/11 ARM: tegra: Rewrite PCIe support as a driver

Quoted 3 lines · Thierry Reding
Quoted 2 lines · Stephen Warren
Quoted 1 line · Thierry Reding

...

Quoted 14 lines
Quoted 13 lines

arch/arm/mach-tegra/board.h void __init tegra30_init_early(void); · line 43

Quoted 9 lines
arch/arm/mach-tegra/board.h +7 -0
 
+#define TEGRA_PCIE_MAX_PORTS 2
+
+struct tegra_pcie_pdata {
+	int (*init)(struct platform_device *pdev);
+	int (*exit)(struct platform_device *pdev);
+	bool enable_ports[TEGRA_PCIE_MAX_PORTS];
+};

That's a somewhat odd place to put the header; a dedicated mach-tegra/include/mach/tegra_pcie_pdata.h or include/linux/platform_data/tegra_pcie.h might make more sense.

Quoted 1 line

mach-tegra/include/mach/pcie.h perhaps? That would be less redundant.

New files in that directory should have tegra in the name somewhere, so that when multi-SoC kernels are built, and multiple mach-*/include/mach directories are in the include path (or files get moved from those paths into a single common place), you know which include file you're getting.

#27 lore raw

PATCH 10/11 ARM: tegra: pcie: Add MSI support

In reply to Thierry Reding

This commit adds support for message signaled interrupts to the Tegra PCIe controller.

---
This code is taken from the NVIDIA Vibrante kernel and therefore has no appropriate Signed-off-by from the original author. Maybe someone at NVIDIA can find out who wrote this code and maybe provide a proper Signed-off-by that I can add?

 arch/arm/mach-tegra/Kconfig             |    1 +
 arch/arm/mach-tegra/devices.c           |    7 +
 arch/arm/mach-tegra/include/mach/irqs.h |    5 +-
 arch/arm/mach-tegra/pcie.c              |  239 +++++++++++++++++++++++++++++++
 4 files changed, 251 insertions(+), 1 deletion(-)
arch/arm/mach-tegra/Kconfig +1 -0
index 1651119..7c596e6 100644
@@ -48,6 +48,7 @@ config ARCH_TEGRA_3x_SOC
 config TEGRA_PCI
 	bool "PCI Express support"
 	depends on ARCH_TEGRA_2x_SOC
+	select ARCH_SUPPORTS_MSI
 	select PCI
 
 comment "Tegra board type"
arch/arm/mach-tegra/devices.c +7 -0
index 09e24e1..195f165 100644
@@ -721,6 +721,13 @@ static struct resource tegra_pcie_resources[] = {
 		.end = INT_PCIE_INTR,
 		.flags = IORESOURCE_IRQ,
 	},
+#ifdef CONFIG_PCI_MSI
+	[3] = {
+		.start = INT_PCIE_MSI,
+		.end = INT_PCIE_MSI,
+		.flags = IORESOURCE_IRQ,
+	},
+#endif
 };
 
 struct platform_device tegra_pcie_device = {
arch/arm/mach-tegra/include/mach/irqs.h +4 -1
index aad1a2c..02e84bc 100644
@@ -172,7 +172,10 @@
 /* Tegra30 has 8 banks of 32 GPIOs */
 #define INT_GPIO_NR			(32 * 8)
 
-#define TEGRA_NR_IRQS			(INT_GPIO_BASE + INT_GPIO_NR)
+#define INT_PCI_MSI_BASE		(INT_GPIO_BASE + INT_GPIO_NR)
+#define INT_PCI_MSI_NR			(32 * 8)
+
+#define TEGRA_NR_IRQS			(INT_PCI_MSI_BASE + INT_PCI_MSI_NR)
 
 #define INT_BOARD_BASE			TEGRA_NR_IRQS
 #define NR_BOARD_IRQS			32
arch/arm/mach-tegra/pcie.c +239 -0

280 lines not on this page · raw message

Signature · 1 line
1.7.9.3
#28 lore raw

PATCH 10/11 ARM: tegra: pcie: Add MSI support

Quoted 9 lines · Thierry Reding

This commit adds support for message signaled interrupts to the Tegra PCIe controller.

---
This code is taken from the NVIDIA Vibrante kernel and therefore has no appropriate Signed-off-by from the original author. Maybe someone at NVIDIA can find out who wrote this code and maybe provide a proper Signed-off-by that I can add?

I think if you look in:
git://nv-tegra.nvidia.com/linux-2.6.git android-tegra-2.6.36

the following commits are what you're after:

de7fd8768b32da66eaf4eaf58473c65f7a76808d
arm: tegra: pcie: enabling MSI support for pcie

ac1f8310811c64a084511d2afc27f66334b31a81
ARM: tegra: pcie: fix return value from MSI irq routine

Although the patch below only partially resembles those patches, I guess because you've rewritten the code a lot to conform to the current kernel APIs, clean stuff up, etc. Perhaps just saying "based on code by Krishna Kishore <[email protected]>" is enough...

Quoted 16 lines
arch/arm/mach-tegra/pcie.c +14 -0
 
+static int tegra_pcie_enable_msi(struct platform_device *pdev)
+{
+	struct tegra_pcie_info *pcie = platform_get_drvdata(pdev);
+	volatile void *pages;
+	unsigned long base;
+	unsigned int msi;
+	int msi_base;
+	int err;
+	u32 reg;
+
+	mutex_init(&pcie->msi_lock);
+
+	msi_base = irq_alloc_descs(-1, 0, INT_PCI_MSI_NR, 0);
+	if (msi_base < 0) {

arch/arm/mach-tegra/pcie.c static void __devinit tegra_pcie_add_port(struct tegra_pcie_info *pcie, · line 1100

Quoted 10 lines
arch/arm/mach-tegra/pcie.c +10 -0
+		dev_err(&pdev->dev, "failed to allocate IRQs\n");
+		return msi_base;
+	}
+
+	pcie->msi_domain = irq_domain_add_legacy(pcie->dev->of_node,
+						 INT_PCI_MSI_NR, msi_base,
+						 0, &irq_domain_simple_ops,
+						 NULL);
+	if (!pcie->msi_domain) {
+		dev_err(&pdev->dev, "failed to create IRQ domain\n");

Free the IRQ descriptors in the error paths?

Quoted 11 lines
arch/arm/mach-tegra/pcie.c +11 -0
+		return -ENOMEM;
+	}
+
+	pcie->msi_chip.name = "PCIe-MSI";
+	pcie->msi_chip.irq_enable = unmask_msi_irq;
+	pcie->msi_chip.irq_disable = mask_msi_irq;
+	pcie->msi_chip.irq_mask = mask_msi_irq;
+	pcie->msi_chip.irq_unmask = unmask_msi_irq;
+
+	for (msi = 0; msi < INT_PCI_MSI_NR; msi++) {
+		unsigned int irq = irq_find_mapping(pcie->msi_domain, msi);

arch/arm/mach-tegra/pcie.c static void __devinit tegra_pcie_add_port(struct tegra_pcie_info *pcie, · line 1121

Quoted 10 lines
arch/arm/mach-tegra/pcie.c +10 -0
+
+		irq_set_chip_data(irq, pcie);
+		irq_set_chip_and_handler(irq, &pcie->msi_chip,
+					 handle_simple_irq);
+		set_irq_flags(irq, IRQF_VALID);
+	}
+
+	err = platform_get_irq(pdev, 1);
+	if (err < 0) {
+		dev_err(&pdev->dev, "failed to get IRQ: %d\n", err);

Same here, and undo setting IRQF_VALID?

Quoted 2 lines
arch/arm/mach-tegra/pcie.c +2 -0
+		return err;
+	}

...

arch/arm/mach-tegra/pcie.c static void __devinit tegra_pcie_add_port(struct tegra_pcie_info *pcie, · line 1160

Quoted 4 lines
arch/arm/mach-tegra/pcie.c +4 -0
+static int tegra_pcie_disable_msi(struct platform_device *pdev)
+{
+	return 0;
+}

This is empty in both the ifdef(CONFIG_PCI_MSI) case and otherwise. It should probably clean everything up here right?

#29 lore raw

PATCH 10/11 ARM: tegra: pcie: Add MSI support

Quoted 19 lines · Stephen Warren
Quoted 9 lines · Thierry Reding

This commit adds support for message signaled interrupts to the Tegra PCIe controller.

---
This code is taken from the NVIDIA Vibrante kernel and therefore has no appropriate Signed-off-by from the original author. Maybe someone at NVIDIA can find out who wrote this code and maybe provide a proper Signed-off-by that I can add?

I think if you look in:
git://nv-tegra.nvidia.com/linux-2.6.git android-tegra-2.6.36

the following commits are what you're after:

de7fd8768b32da66eaf4eaf58473c65f7a76808d
arm: tegra: pcie: enabling MSI support for pcie

Quoted 7 lines

ac1f8310811c64a084511d2afc27f66334b31a81
ARM: tegra: pcie: fix return value from MSI irq routine

Although the patch below only partially resembles those patches, I guess because you've rewritten the code a lot to conform to the current kernel APIs, clean stuff up, etc. Perhaps just saying "based on code by Krishna Kishore <[email protected]>" is enough...

Yes, it is indeed a major rewrite because the original code had some peculiarities and FIXME that I thought wouldn't make it through the review anyway so I fixed them up.

I'll add some comment about the original authorship. There is no official Signed-off-by in the original commit. Do I still need one or is it enough to mention the original authors in the commit message and add keep my own Signed-off-by?

Thierry

Quoted 21 lines
Quoted 21 lines
arch/arm/mach-tegra/pcie.c +18 -0
 
+static int tegra_pcie_enable_msi(struct platform_device *pdev)
+{
+	struct tegra_pcie_info *pcie = platform_get_drvdata(pdev);
+	volatile void *pages;
+	unsigned long base;
+	unsigned int msi;
+	int msi_base;
+	int err;
+	u32 reg;
+
+	mutex_init(&pcie->msi_lock);
+
+	msi_base = irq_alloc_descs(-1, 0, INT_PCI_MSI_NR, 0);
+	if (msi_base < 0) {
+		dev_err(&pdev->dev, "failed to allocate IRQs\n");
+		return msi_base;
+	}
+
Quoted 8 lines

arch/arm/mach-tegra/pcie.c static void __devinit tegra_pcie_add_port(struct tegra_pcie_info *pcie, · line 1100

Quoted 6 lines
arch/arm/mach-tegra/pcie.c +6 -0
+	pcie->msi_domain = irq_domain_add_legacy(pcie->dev->of_node,
+						 INT_PCI_MSI_NR, msi_base,
+						 0, &irq_domain_simple_ops,
+						 NULL);
+	if (!pcie->msi_domain) {
+		dev_err(&pdev->dev, "failed to create IRQ domain\n");

Free the IRQ descriptors in the error paths?

Yes, that would make sense.

Quoted 15 lines
Quoted 15 lines
arch/arm/mach-tegra/pcie.c +15 -0
+		return -ENOMEM;
+	}
+
+	pcie->msi_chip.name = "PCIe-MSI";
+	pcie->msi_chip.irq_enable = unmask_msi_irq;
+	pcie->msi_chip.irq_disable = mask_msi_irq;
+	pcie->msi_chip.irq_mask = mask_msi_irq;
+	pcie->msi_chip.irq_unmask = unmask_msi_irq;
+
+	for (msi = 0; msi < INT_PCI_MSI_NR; msi++) {
+		unsigned int irq = irq_find_mapping(pcie->msi_domain, msi);
+
+		irq_set_chip_data(irq, pcie);
+		irq_set_chip_and_handler(irq, &pcie->msi_chip,
+					 handle_simple_irq);
Quoted 8 lines

arch/arm/mach-tegra/pcie.c static void __devinit tegra_pcie_add_port(struct tegra_pcie_info *pcie, · line 1121

Quoted 6 lines
arch/arm/mach-tegra/pcie.c +6 -0
+		set_irq_flags(irq, IRQF_VALID);
+	}
+
+	err = platform_get_irq(pdev, 1);
+	if (err < 0) {
+		dev_err(&pdev->dev, "failed to get IRQ: %d\n", err);

Same here, and undo setting IRQF_VALID?

Right. I assume it would be best to also free the struct irq_domain and set the chip data and handler back to NULL? AFAICT there is no canonical way to teardown an irq_domain.

Quoted 11 lines
Quoted 2 lines
arch/arm/mach-tegra/pcie.c +2 -0
+		return err;
+	}

...

arch/arm/mach-tegra/pcie.c static void __devinit tegra_pcie_add_port(struct tegra_pcie_info *pcie, · line 1160

Quoted 4 lines
arch/arm/mach-tegra/pcie.c +4 -0
+static int tegra_pcie_disable_msi(struct platform_device *pdev)
+{
+	return 0;
+}

This is empty in both the ifdef(CONFIG_PCI_MSI) case and otherwise. It should probably clean everything up here right?

Yes, initially this contained a call to free_irq(), which I removed when I switched to using a chained handler. I can probably put all of the cleanup code from your comments above in here and perhaps even call that in the error paths of tegra_pcie_enable_msi().

Thierry
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 198 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20120309/3035ffec/attachment-0001.sig>

#30 lore raw

PATCH 10/11 ARM: tegra: pcie: Add MSI support

Quoted 28 lines · Thierry Reding
Quoted 19 lines · Stephen Warren
Quoted 9 lines · Thierry Reding

This commit adds support for message signaled interrupts to the Tegra PCIe controller.

---
This code is taken from the NVIDIA Vibrante kernel and therefore has no appropriate Signed-off-by from the original author. Maybe someone at NVIDIA can find out who wrote this code and maybe provide a proper Signed-off-by that I can add?

I think if you look in:
git://nv-tegra.nvidia.com/linux-2.6.git android-tegra-2.6.36

the following commits are what you're after:

de7fd8768b32da66eaf4eaf58473c65f7a76808d
arm: tegra: pcie: enabling MSI support for pcie

Quoted 7 lines

ac1f8310811c64a084511d2afc27f66334b31a81
ARM: tegra: pcie: fix return value from MSI irq routine

Although the patch below only partially resembles those patches, I guess because you've rewritten the code a lot to conform to the current kernel APIs, clean stuff up, etc. Perhaps just saying "based on code by Krishna Kishore <[email protected]>" is enough...

Quoted 8 lines

Yes, it is indeed a major rewrite because the original code had some peculiarities and FIXME that I thought wouldn't make it through the review anyway so I fixed them up.

I'll add some comment about the original authorship. There is no official Signed-off-by in the original commit. Do I still need one or is it enough to mention the original authors in the commit message and add keep my own Signed-off-by?

Yes, I think just mentioning the original code author in free-form text, and including only your S-o-b sounds good to me.

#31 lore raw

PATCH 10/11 ARM: tegra: pcie: Add MSI support

In reply to Stephen Warren
Quoted 45 lines · Stephen Warren
Quoted 16 lines · Thierry Reding
arch/arm/mach-tegra/pcie.c +14 -0
 
+static int tegra_pcie_enable_msi(struct platform_device *pdev)
+{
+	struct tegra_pcie_info *pcie = platform_get_drvdata(pdev);
+	volatile void *pages;
+	unsigned long base;
+	unsigned int msi;
+	int msi_base;
+	int err;
+	u32 reg;
+
+	mutex_init(&pcie->msi_lock);
+
+	msi_base = irq_alloc_descs(-1, 0, INT_PCI_MSI_NR, 0);
+	if (msi_base < 0) {

arch/arm/mach-tegra/pcie.c static void __devinit tegra_pcie_add_port(struct tegra_pcie_info *pcie, · line 1100

Quoted 10 lines
arch/arm/mach-tegra/pcie.c +10 -0
+		dev_err(&pdev->dev, "failed to allocate IRQs\n");
+		return msi_base;
+	}
+
+	pcie->msi_domain = irq_domain_add_legacy(pcie->dev->of_node,
+						 INT_PCI_MSI_NR, msi_base,
+						 0, &irq_domain_simple_ops,
+						 NULL);
+	if (!pcie->msi_domain) {
+		dev_err(&pdev->dev, "failed to create IRQ domain\n");

Free the IRQ descriptors in the error paths?

Quoted 15 lines
arch/arm/mach-tegra/pcie.c +15 -0
+		return -ENOMEM;
+	}
+
+	pcie->msi_chip.name = "PCIe-MSI";
+	pcie->msi_chip.irq_enable = unmask_msi_irq;
+	pcie->msi_chip.irq_disable = mask_msi_irq;
+	pcie->msi_chip.irq_mask = mask_msi_irq;
+	pcie->msi_chip.irq_unmask = unmask_msi_irq;
+
+	for (msi = 0; msi < INT_PCI_MSI_NR; msi++) {
+		unsigned int irq = irq_find_mapping(pcie->msi_domain, msi);
+
+		irq_set_chip_data(irq, pcie);
+		irq_set_chip_and_handler(irq, &pcie->msi_chip,
+					 handle_simple_irq);
Quoted 8 lines

arch/arm/mach-tegra/pcie.c static void __devinit tegra_pcie_add_port(struct tegra_pcie_info *pcie, · line 1121

Quoted 6 lines
arch/arm/mach-tegra/pcie.c +6 -0
+		set_irq_flags(irq, IRQF_VALID);
+	}
+
+	err = platform_get_irq(pdev, 1);
+	if (err < 0) {
+		dev_err(&pdev->dev, "failed to get IRQ: %d\n", err);

Same here, and undo setting IRQF_VALID?

Does it make sense to explicitly unset the IRQF_VALID flag when the IRQ descriptors are free'd afterwards anyway? I also think it would be necessary to free the struct irq_domain, but I wasn't able to find any function that does this other than just calling kfree(), which obviously wouldn't be enough. Maybe Grant can shed some light onto this. I'm also Cc'ing Thomas Gleixner as maintainer of the IRQ subsystem, he probably knows best how dynamically allocated interrupts should be cleaned up.

Thierry
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 198 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20120312/33a4109c/attachment-0001.sig>

#32 lore raw

PATCH 10/11 ARM: tegra: pcie: Add MSI support

Quoted 3 lines · Thierry Reding
Quoted 2 lines · Stephen Warren
Quoted 1 line · Thierry Reding
arch/arm/mach-tegra/pcie.c +0 -0

...

Quoted 1 line
Quoted 1 line

Free the IRQ descriptors in the error paths?

...

Quoted 15 lines
Quoted 6 lines
Quoted 6 lines
arch/arm/mach-tegra/pcie.c +6 -0
+	for (msi = 0; msi < INT_PCI_MSI_NR; msi++) {
+		unsigned int irq = irq_find_mapping(pcie->msi_domain, msi);
+
+		irq_set_chip_data(irq, pcie);
+		irq_set_chip_and_handler(irq, &pcie->msi_chip,
+					 handle_simple_irq);
Quoted 8 lines

arch/arm/mach-tegra/pcie.c static void __devinit tegra_pcie_add_port(struct tegra_pcie_info *pcie, · line 1121

Quoted 6 lines
arch/arm/mach-tegra/pcie.c +6 -0
+		set_irq_flags(irq, IRQF_VALID);
+	}
+
+	err = platform_get_irq(pdev, 1);
+	if (err < 0) {
+		dev_err(&pdev->dev, "failed to get IRQ: %d\n", err);

Same here, and undo setting IRQF_VALID?

Quoted 2 lines

Does it make sense to explicitly unset the IRQF_VALID flag when the IRQ descriptors are free'd afterwards anyway?

Good point. Probably not per my gut instinct.

...

Quoted 3 lines

I'm also Cc'ing Thomas
Gleixner as maintainer of the IRQ subsystem, he probably knows best how dynamically allocated interrupts should be cleaned up.

But yes, best to check with someone more familiar with interrupts.

#33 lore raw

PATCH 11/11 ARM: tegra: pcie: Add device tree support

In reply to Thierry Reding

This commit adds support for instantiating the Tegra PCIe controller from a device tree.

---
 .../devicetree/bindings/pci/tegra-pcie.txt         |   23 ++++
 arch/arm/boot/dts/tegra20.dtsi                     |    8 ++
 arch/arm/mach-tegra/pcie.c                         |  123 +++++++++++++++++++-
 3 files changed, 151 insertions(+), 3 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/pci/tegra-pcie.txt
Documentation/devicetree/bindings/pci/tegra-pcie.txt new file +23 -0
new file mode 100644
index 0000000..10bbc40
@@ -0,0 +1,23 @@
+NVIDIA Tegra PCIe controller
+
+Required properties:
+- compatible: "nvidia,tegra20-pcie"
+- reg: physical base address and length of the controller's registers
+- interrupts: the interrupt outputs of the controller
+
+Optional properties:
+- pex-clk-supply: supply voltage for internal reference clock
+- vdd-supply: power supply for controller (1.05V)
+
+Example:
+
+	pci at 80000000 {
+		compatible = "nvidia,tegra20-pcie",
+		reg = <0x80000000 0x400000   /* PCIe AFI registers */
+		       0x80400000 0x010000>; /* PCI I/O space */
+		interrupts = < 0 98 0x04    /* controller interrupt */
+		               0 99 0x04 >; /* MSI interrupt */
+
+		pex-clk-supply = <&ldo0_reg>;
+		vdd-supply = <&pcie_reg>;
+	};
arch/arm/boot/dts/tegra20.dtsi +8 -0
index 108e894..9b4692e 100644
@@ -161,6 +161,14 @@
 		reg = <0x7000f400 0x200>;
 	};
 
+	pci at 80000000 {
+		compatible = "nvidia,tegra20-pcie";
+		reg = <0x80000000 0x400000   /* PCIe AFI registers */
+		       0x80400000 0x010000>; /* PCI I/O space */
+		interrupts = < 0 98 0x04    /* controller interrupt */
+		               0 99 0x04 >; /* MSI interrupt */
+	};
+
 	sdhci at c8000000 {
 		compatible = "nvidia,tegra20-sdhci";
 		reg = <0xc8000000 0x200>;
arch/arm/mach-tegra/pcie.c +120 -3

171 lines not on this page · raw message

Signature · 1 line
1.7.9.3
#34 lore raw

PATCH 11/11 ARM: tegra: pcie: Add device tree support

Quoted 7 lines · Thierry Reding

This commit adds support for instantiating the Tegra PCIe controller from a device tree.

Documentation/devicetree/bindings/pci/tegra-pcie.txt +0 -0
 

Documentation/devicetree/bindings/pci/tegra-pcie.txt line 10

Quoted 10 lines
Documentation/devicetree/bindings/pci/tegra-pcie.txt +10 -0
+NVIDIA Tegra PCIe controller
+
+Required properties:
+- compatible: "nvidia,tegra20-pcie"
+- reg: physical base address and length of the controller's registers
+- interrupts: the interrupt outputs of the controller
+
+Optional properties:
+- pex-clk-supply: supply voltage for internal reference clock
+- vdd-supply: power supply for controller (1.05V)

Mark, Liam,

Should those *-supply properties really be optional? I got the impression talking to Mark in a different thread that all regulators should exist, although their implementation may be via a fixed regulator, with no GPIO, as determined by the board design.

#35 lore raw

PATCH 11/11 ARM: tegra: pcie: Add device tree support

Quoted 21 lines · Stephen Warren
Quoted 7 lines · Thierry Reding

This commit adds support for instantiating the Tegra PCIe controller from a device tree.

Documentation/devicetree/bindings/pci/tegra-pcie.txt +0 -0
 

Documentation/devicetree/bindings/pci/tegra-pcie.txt line 10

Quoted 10 lines
Documentation/devicetree/bindings/pci/tegra-pcie.txt +10 -0
+NVIDIA Tegra PCIe controller
+
+Required properties:
+- compatible: "nvidia,tegra20-pcie"
+- reg: physical base address and length of the controller's registers
+- interrupts: the interrupt outputs of the controller
+
+Optional properties:
+- pex-clk-supply: supply voltage for internal reference clock
+- vdd-supply: power supply for controller (1.05V)

Mark, Liam,

Quoted 4 lines

Should those *-supply properties really be optional? I got the impression talking to Mark in a different thread that all regulators should exist, although their implementation may be via a fixed regulator, with no GPIO, as determined by the board design.

If I read the TrimSlice code correctly, there is no regulator setup required to make PCIe work there presumably because they hardwire the proper voltages. On the other hand, maybe a better solution in this case would be to use the dummy regulator in those cases.

Thierry
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 198 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20120309/8b96a367/attachment-0001.sig>

#36 lore raw

PATCH 11/11 ARM: tegra: pcie: Add device tree support

Quoted 22 lines · Thierry Reding
Quoted 21 lines · Stephen Warren
Quoted 7 lines · Thierry Reding

This commit adds support for instantiating the Tegra PCIe controller from a device tree.

Documentation/devicetree/bindings/pci/tegra-pcie.txt +0 -0
 

Documentation/devicetree/bindings/pci/tegra-pcie.txt line 10

Quoted 10 lines
Documentation/devicetree/bindings/pci/tegra-pcie.txt +10 -0
+NVIDIA Tegra PCIe controller
+
+Required properties:
+- compatible: "nvidia,tegra20-pcie"
+- reg: physical base address and length of the controller's registers
+- interrupts: the interrupt outputs of the controller
+
+Optional properties:
+- pex-clk-supply: supply voltage for internal reference clock
+- vdd-supply: power supply for controller (1.05V)

Mark, Liam,

Quoted 7 lines
Quoted 4 lines

Should those *-supply properties really be optional? I got the impression talking to Mark in a different thread that all regulators should exist, although their implementation may be via a fixed regulator, with no GPIO, as determined by the board design.

If I read the TrimSlice code correctly, there is no regulator setup required to make PCIe work there presumably because they hardwire the proper voltages.

Yes. I believe that's exactly what the fixed regulator is for.

Quoted 2 lines

On the other hand, maybe a better solution in this case would be to use the dummy regulator in those cases.

Mark indicated dummy regulators weren't the preferred mechanism:

http://lkml.org/lkml/2012/2/25/30

#37 lore raw

PATCH 11/11 ARM: tegra: pcie: Add device tree support

In reply to Stephen Warren
Quoted 8 lines · Stephen Warren
Quoted 1 line · Thierry Reding

+- vdd-supply: power supply for controller (1.05V)

Should those *-supply properties really be optional? I got the impression talking to Mark in a different thread that all regulators should exist, although their implementation may be via a fixed regulator, with no GPIO, as determined by the board design.

Depends on the electronics, if the device can function without a supply then it is OK for it to be optional. This is moderately unusual but not unknown. It's obviously also OK to omit the supply if the system doesn't use software regulators at all, though a kernel with regulator support enabled would need to use dummy regulators to stub things out.

#38 lore raw

PATCH 11/11 ARM: tegra: pcie: Add device tree support

Quoted 10 lines · Mark Brown
Quoted 8 lines · Stephen Warren
Quoted 1 line · Thierry Reding

+- vdd-supply: power supply for controller (1.05V)

Should those *-supply properties really be optional? I got the impression talking to Mark in a different thread that all regulators should exist, although their implementation may be via a fixed regulator, with no GPIO, as determined by the board design.

Quoted 5 lines

Depends on the electronics, if the device can function without a supply then it is OK for it to be optional. This is moderately unusual but not unknown. It's obviously also OK to omit the supply if the system doesn't use software regulators at all, though a kernel with regulator support enabled would need to use dummy regulators to stub things out.

The PCIe controller actually needs those supplies and won't work without them. However on TrimSlice both of these supplies seem to be hardwired and always on. At least that's what I deduce from the code because there is no code that enables either the 1.05V or the pex-clk supplies.

My understanding of the fixed regulator was that it was meant to be used for fixed voltage supplies that can still be enabled or disabled (for example as supplied by a GPIO) but not regulators that are fix in the sense that they cannot be enabled or disabled at all but are always on.

Then again, the fixed regulator binding says that the gpio property is optional, so perhaps doing something like the following will work:

	pex_clk_reg: fixedregulator at 0 {
		compatible = "regulator-fixed";
		regulator-name = "PCIE CLK";
		regulator-min-microvolt = <3300000>;
		regulator-max-microvolt = <3300000>;
		regulator-always-on;
	};

	pcie_reg: fixedregulator at 1 {
		compatible = "regulator-fixed";
		regulator-name = "PCIE VDD";
		regulator-min-microvolt = <1050000>;
		regulator-max-microvolt = <1050000>;
		regulator-always-on;
	};

Is that how it is supposed to work?

Thierry
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 198 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20120312/4da42232/attachment-0001.sig>

#39 lore raw

PATCH 11/11 ARM: tegra: pcie: Add device tree support

Quoted 4 lines · Thierry Reding

My understanding of the fixed regulator was that it was meant to be used for fixed voltage supplies that can still be enabled or disabled (for example as supplied by a GPIO) but not regulators that are fix in the sense that they cannot be enabled or disabled at all but are always on.

No, not at all. It's for any random supply that doesn't have much meaningful control - as you'll see from the code the GPIO is totally optional if you look at the git history you'll see that the GPIO was added some time after the driver was originally merged.

Quoted 1 line

Is that how it is supposed to work?

Yes.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20120312/209df390/attachment-0001.sig>

#40 lore raw

PATCH 11/11 ARM: tegra: pcie: Add device tree support

Quoted 7 lines · Mark Brown
Quoted 4 lines · Thierry Reding

My understanding of the fixed regulator was that it was meant to be used for fixed voltage supplies that can still be enabled or disabled (for example as supplied by a GPIO) but not regulators that are fix in the sense that they cannot be enabled or disabled at all but are always on.

Quoted 8 lines

No, not at all. It's for any random supply that doesn't have much meaningful control - as you'll see from the code the GPIO is totally optional if you look at the git history you'll see that the GPIO was added some time after the driver was originally merged.

Quoted 1 line

Is that how it is supposed to work?

Yes.

In that case I'll mark the *-supply properties required. Would it be a good idea to mention this (or even give an example with fixed regulators) in the binding documentation or can I assume this to be common knowledge?

Thierry
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 198 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20120312/ecb77ca9/attachment-0001.sig>

#41 lore raw

PATCH 11/11 ARM: tegra: pcie: Add device tree support

Quoted 3 lines · Thierry Reding

In that case I'll mark the *-supply properties required. Would it be a good idea to mention this (or even give an example with fixed regulators) in the binding documentation or can I assume this to be common knowledge?

Probably the best thing here is to just reference the regulator binding
documentation which mentions -supply properties (or should do) and then
clarify that if need be. No sense in putting things like this into the
binding document for a specific driver, there's nothing driver specific.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20120312/a5a8b0cf/attachment-0001.sig>

#42 lore raw

cover ARM: tegra: Add PCIe device tree support

In reply to Thierry Reding
Quoted 64 lines · Thierry Reding

This patch series adds support for device tree based probing of the PCIe controller found on Tegra SoCs.

Patches 1 and 2 have already been posted by Grant and Mark respectively but I've included them here for reference. Both patches are dependencies for the subsequent patches.

Patches 3, 4 and 5 add support for obtaining the regulators required to power the PCIe controller from the device tree. Patches 6 and 7 are required to make some common PCI functions available after the init phase because the deferred probing will postpone the probing of the PCIe controller driver until that point.

Patches 8 and 9 make the PCIe controller code available as a driver and add the corresponding platform devices to the boards that enable PCIe (Harmony and TrimSlice). Patch 10 adds MSI support and patch 11 finally adds a device tree binding with documentation.

The code in patch 10 (MSI support) is based on the Vibrante kernel and I wasn't able to get a proper Signed-off-by or even copyright information. Perhaps somebody at NVIDIA can find out?

Thierry

Grant Likely (1):
drivercore: Add driver probe deferral mechanism

Mark Brown (1):
regulator: Support driver probe deferral

Thierry Reding (9):
regulator: fixed: Support driver probe deferral
regulator: tps6586x: fix typo in debug message
tps6586x: Add device-tree support
PCI: Keep pci_fixup_irqs() around after init
ARM: pci: Keep pci_common_init() around after init
ARM: tegra: Move tegra_pcie_xclk_clamp() to PMC
ARM: tegra: Rewrite PCIe support as a driver
ARM: tegra: pcie: Add MSI support
ARM: tegra: pcie: Add device tree support

 .../devicetree/bindings/pci/tegra-pcie.txt         |   23 +
 .../devicetree/bindings/regulator/tps6586x.txt     |   98 +++
 arch/arm/boot/dts/tegra20.dtsi                     |    8 +
 arch/arm/kernel/bios32.c                           |    4 +-
 arch/arm/mach-tegra/Kconfig                        |    1 +
 arch/arm/mach-tegra/board-harmony-pcie.c           |   38 +-
 arch/arm/mach-tegra/board-harmony.c                |    1 +
 arch/arm/mach-tegra/board-harmony.h                |    1 +
 arch/arm/mach-tegra/board-trimslice.c              |   16 +-
 arch/arm/mach-tegra/board.h                        |   11 +-
 arch/arm/mach-tegra/devices.c                      |   32 +
 arch/arm/mach-tegra/devices.h                      |    1 +
 arch/arm/mach-tegra/include/mach/iomap.h           |    6 +
 arch/arm/mach-tegra/include/mach/irqs.h            |    5 +-
 arch/arm/mach-tegra/pcie.c                         |  895 +++++++++++++++-----
 arch/arm/mach-tegra/pmc.c                          |   16 +
 arch/arm/mach-tegra/pmc.h                          |    1 +
 drivers/base/base.h                                |    1 +
 drivers/base/core.c                                |    2 +
 drivers/base/dd.c                                  |  138 ++-
 drivers/mfd/tps6586x.c                             |   66 ++
 drivers/pci/setup-irq.c                            |    4 +-
 drivers/regulator/core.c                           |    4 +-
Quoted 8 lines
 drivers/regulator/fixed.c                          |   14 +-
 drivers/regulator/tps6586x-regulator.c             |    4 +-
 include/linux/device.h                             |    5 +
 include/linux/errno.h                              |    1 +
 include/linux/mfd/tps6586x.h                       |    1 +
 28 files changed, 1136 insertions(+), 261 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/pci/tegra-pcie.txt
 create mode 100644 Documentation/devicetree/bindings/regulator/tps6586x.txt

There is a whole bunch of PCI DT code sitting in the powerpc tree that probably needs to be moved to common location and used here.

This looks way too simple to be what's needed if I compare to PCI bindings in powerpc dts files.

Rob

#43 lore raw

cover ARM: tegra: Add PCIe device tree support

Quoted 5 lines · Rob Herring

There is a whole bunch of PCI DT code sitting in the powerpc tree that probably needs to be moved to common location and used here.

This looks way too simple to be what's needed if I compare to PCI bindings in powerpc dts files.

My particular setup may be much simpler than the average PowerPC machine. The patchset is only what I need to get PCIe running on the platform, which has an FPGA connected to the Tegra via PCIe. For instance there is no legacy interrupt support (only MSI), so interrupt remapping is not required. I also know that OF nodes are not properly hooked up with the PCI devices yet, which I will need, among other things, to provide platform data for an SPI flash connected to an SPI master implemented within the FPGA. I also haven't looked at specifying the memory ranges via the device tree.

So quite a lot may still be missing, but does that prevent any of this from being added to mainline? Things can be added on an as-needed basis, can't they?

Thierry
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 198 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20120308/5c285597/attachment.sig>

#44 lore raw

cover ARM: tegra: Add PCIe device tree support

In reply to Thierry Reding
Quoted 22 lines · Thierry Reding

This patch series adds support for device tree based probing of the PCIe controller found on Tegra SoCs.

Patches 1 and 2 have already been posted by Grant and Mark respectively but I've included them here for reference. Both patches are dependencies for the subsequent patches.

Patches 3, 4 and 5 add support for obtaining the regulators required to power the PCIe controller from the device tree. Patches 6 and 7 are required to make some common PCI functions available after the init phase because the deferred probing will postpone the probing of the PCIe controller driver until that point.

Patches 8 and 9 make the PCIe controller code available as a driver and add the corresponding platform devices to the boards that enable PCIe (Harmony and TrimSlice). Patch 10 adds MSI support and patch 11 finally adds a device tree binding with documentation.

The code in patch 10 (MSI support) is based on the Vibrante kernel and I wasn't able to get a proper Signed-off-by or even copyright information. Perhaps somebody at NVIDIA can find out?

Quoted 7 lines

Thierry

Grant Likely (1):
drivercore: Add driver probe deferral mechanism

Mark Brown (1):
regulator: Support driver probe deferral

Greg has picked up the drivercore patch, so the regulator one can be queued up too now.

g.

Signature · 2 lines
Grant Likely, B.Sc, P.Eng.
Secret Lab Technologies,Ltd.
#45 lore raw

cover ARM: tegra: Add PCIe device tree support

In reply to Thierry Reding
Quoted 13 lines · Thierry Reding

This patch series adds support for device tree based probing of the PCIe controller found on Tegra SoCs.

Patches 1 and 2 have already been posted by Grant and Mark respectively but I've included them here for reference. Both patches are dependencies for the subsequent patches.

Patches 3, 4 and 5 add support for obtaining the regulators required to power the PCIe controller from the device tree. Patches 6 and 7 are required to make some common PCI functions available after the init phase because the deferred probing will postpone the probing of the PCIe controller driver until that point.

Quoted 8 lines

Patches 8 and 9 make the PCIe controller code available as a driver and add the corresponding platform devices to the boards that enable PCIe (Harmony and TrimSlice). Patch 10 adds MSI support and patch 11 finally adds a device tree binding with documentation.

The code in patch 10 (MSI support) is based on the Vibrante kernel and I wasn't able to get a proper Signed-off-by or even copyright information. Perhaps somebody at NVIDIA can find out?

Hi,

This patch series looks good to me, but I'm out of time to stage it for 3.4. Stephen is taking over lead maintainership for 3.5 and forward, so I'll let him pick it up for that release.

-Olof