| 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" |
| @@ -4590,6 +4591,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; |
| @@ -4615,6 +4644,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; |