aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/drivers/ata
diff options
context:
space:
mode:
authorLinus Walleij <linus.walleij@linaro.org>2020-02-22 12:20:57 +0100
committerJens Axboe <axboe@kernel.dk>2020-03-25 10:29:35 -0600
commit45b8084f3fcb9fe1a653fd49afa1fd7a5f0c10f2 (patch)
tree172cdb26f3c607ec321c4b4d0b420425a0f1a994 /drivers/ata
parentlibata: Remove extra scsi_host_put() in ata_scsi_add_hosts() (diff)
downloadwireguard-linux-45b8084f3fcb9fe1a653fd49afa1fd7a5f0c10f2.tar.xz
wireguard-linux-45b8084f3fcb9fe1a653fd49afa1fd7a5f0c10f2.zip
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> Reviewed-by: Guenter Roeck <linux@roeck-us.net> Signed-off-by: Linus Walleij <linus.walleij@linaro.org> Signed-off-by: Jens Axboe <axboe@kernel.dk>
Diffstat (limited to 'drivers/ata')
-rw-r--r--drivers/ata/libata-scsi.c30
1 files changed, 30 insertions, 0 deletions
diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c
index 061eebf85e6d..75bd7792df02 100644
--- a/drivers/ata/libata-scsi.c
+++ b/drivers/ata/libata-scsi.c
@@ -36,6 +36,7 @@
#include <linux/suspend.h>
#include <asm/unaligned.h>
#include <linux/ioprio.h>
+#include <linux/of.h>
#include "libata.h"
#include "libata-transport.h"
@@ -4579,6 +4580,34 @@ int ata_scsi_add_hosts(struct ata_host *host, struct scsi_host_template *sht)
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;
@@ -4604,6 +4633,7 @@ void ata_scsi_scan_host(struct ata_port *ap, int sync)
NULL);
if (!IS_ERR(sdev)) {
dev->sdev = sdev;
+ ata_scsi_assign_ofnode(dev, ap);
scsi_device_put(sdev);
} else {
dev->sdev = NULL;