68d9cb8214
Run tested: ath79, ipq40xx Build tested: ath79, ipq40xx Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
87 lines
2.4 KiB
Diff
87 lines
2.4 KiB
Diff
From 43a93893eb33e996836b99fb3e1f7300c0132a51 Mon Sep 17 00:00:00 2001
|
|
From: Linus Walleij <linus.walleij@linaro.org>
|
|
Date: Tue, 31 Dec 2019 18:15:33 +0100
|
|
Subject: [PATCH 5/7] libata: Assign OF node to the SCSI device
|
|
|
|
When we spawn a SCSI device from an ATA device in libata-scsi
|
|
the SCSI device had no relation to the device tree.
|
|
|
|
The DT binding allows us to define port nodes under a
|
|
PATA (IDE) or SATA host controller, so we can have proper device
|
|
nodes for these devices.
|
|
|
|
If OF is enabled, walk the children of the host controller node
|
|
to see if there is a valid device tree node to assign. The reg
|
|
is used to match to ID 0 for the master device and ID 1 for the
|
|
slave device.
|
|
|
|
The corresponding device tree bindings have been accepted by
|
|
the device tree maintainers.
|
|
|
|
Cc: Chris Healy <cphealy@gmail.com>
|
|
Cc: Martin K. Petersen <martin.petersen@oracle.com>
|
|
Cc: Bart Van Assche <bvanassche@acm.org>
|
|
Cc: Guenter Roeck <linux@roeck-us.net>
|
|
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
|
|
---
|
|
ChangeLog v1->v2:
|
|
- Use dev_dbg() for the debug print
|
|
- return immediately after finding a matching OF node
|
|
---
|
|
drivers/ata/libata-scsi.c | 30 ++++++++++++++++++++++++++++++
|
|
1 file changed, 30 insertions(+)
|
|
|
|
--- a/drivers/ata/libata-scsi.c
|
|
+++ b/drivers/ata/libata-scsi.c
|
|
@@ -35,6 +35,7 @@
|
|
#include <linux/suspend.h>
|
|
#include <asm/unaligned.h>
|
|
#include <linux/ioprio.h>
|
|
+#include <linux/of.h>
|
|
|
|
#include "libata.h"
|
|
#include "libata-transport.h"
|
|
@@ -4573,6 +4574,34 @@ int ata_scsi_add_hosts(struct ata_host *
|
|
return rc;
|
|
}
|
|
|
|
+#ifdef CONFIG_OF
|
|
+static void ata_scsi_assign_ofnode(struct ata_device *dev, struct ata_port *ap)
|
|
+{
|
|
+ struct scsi_device *sdev = dev->sdev;
|
|
+ struct device *d = ap->host->dev;
|
|
+ struct device_node *np = d->of_node;
|
|
+ struct device_node *child;
|
|
+
|
|
+ for_each_available_child_of_node(np, child) {
|
|
+ int ret;
|
|
+ u32 val;
|
|
+
|
|
+ ret = of_property_read_u32(child, "reg", &val);
|
|
+ if (ret)
|
|
+ continue;
|
|
+ if (val == dev->devno) {
|
|
+ dev_dbg(d, "found matching device node\n");
|
|
+ sdev->sdev_gendev.of_node = child;
|
|
+ return;
|
|
+ }
|
|
+ }
|
|
+}
|
|
+#else
|
|
+static void ata_scsi_assign_ofnode(struct ata_device *dev, struct ata_port *ap)
|
|
+{
|
|
+}
|
|
+#endif
|
|
+
|
|
void ata_scsi_scan_host(struct ata_port *ap, int sync)
|
|
{
|
|
int tries = 5;
|
|
@@ -4598,6 +4627,7 @@ void ata_scsi_scan_host(struct ata_port
|
|
NULL);
|
|
if (!IS_ERR(sdev)) {
|
|
dev->sdev = sdev;
|
|
+ ata_scsi_assign_ofnode(dev, ap);
|
|
scsi_device_put(sdev);
|
|
} else {
|
|
dev->sdev = NULL;
|