b.liu | e958203 | 2025-04-17 19:18:16 +0800 | [diff] [blame] | 1 | From 43a93893eb33e996836b99fb3e1f7300c0132a51 Mon Sep 17 00:00:00 2001 |
| 2 | From: Linus Walleij <linus.walleij@linaro.org> |
| 3 | Date: Tue, 31 Dec 2019 18:15:33 +0100 |
| 4 | Subject: [PATCH 5/7] libata: Assign OF node to the SCSI device |
| 5 | |
| 6 | When we spawn a SCSI device from an ATA device in libata-scsi |
| 7 | the SCSI device had no relation to the device tree. |
| 8 | |
| 9 | The DT binding allows us to define port nodes under a |
| 10 | PATA (IDE) or SATA host controller, so we can have proper device |
| 11 | nodes for these devices. |
| 12 | |
| 13 | If OF is enabled, walk the children of the host controller node |
| 14 | to see if there is a valid device tree node to assign. The reg |
| 15 | is used to match to ID 0 for the master device and ID 1 for the |
| 16 | slave device. |
| 17 | |
| 18 | The corresponding device tree bindings have been accepted by |
| 19 | the device tree maintainers. |
| 20 | |
| 21 | Cc: Chris Healy <cphealy@gmail.com> |
| 22 | Cc: Martin K. Petersen <martin.petersen@oracle.com> |
| 23 | Cc: Bart Van Assche <bvanassche@acm.org> |
| 24 | Cc: Guenter Roeck <linux@roeck-us.net> |
| 25 | Signed-off-by: Linus Walleij <linus.walleij@linaro.org> |
| 26 | --- |
| 27 | ChangeLog v1->v2: |
| 28 | - Use dev_dbg() for the debug print |
| 29 | - return immediately after finding a matching OF node |
| 30 | --- |
| 31 | drivers/ata/libata-scsi.c | 30 ++++++++++++++++++++++++++++++ |
| 32 | 1 file changed, 30 insertions(+) |
| 33 | |
| 34 | --- a/drivers/ata/libata-scsi.c |
| 35 | +++ b/drivers/ata/libata-scsi.c |
| 36 | @@ -35,6 +35,7 @@ |
| 37 | #include <linux/suspend.h> |
| 38 | #include <asm/unaligned.h> |
| 39 | #include <linux/ioprio.h> |
| 40 | +#include <linux/of.h> |
| 41 | |
| 42 | #include "libata.h" |
| 43 | #include "libata-transport.h" |
| 44 | @@ -4590,6 +4591,34 @@ int ata_scsi_add_hosts(struct ata_host * |
| 45 | return rc; |
| 46 | } |
| 47 | |
| 48 | +#ifdef CONFIG_OF |
| 49 | +static void ata_scsi_assign_ofnode(struct ata_device *dev, struct ata_port *ap) |
| 50 | +{ |
| 51 | + struct scsi_device *sdev = dev->sdev; |
| 52 | + struct device *d = ap->host->dev; |
| 53 | + struct device_node *np = d->of_node; |
| 54 | + struct device_node *child; |
| 55 | + |
| 56 | + for_each_available_child_of_node(np, child) { |
| 57 | + int ret; |
| 58 | + u32 val; |
| 59 | + |
| 60 | + ret = of_property_read_u32(child, "reg", &val); |
| 61 | + if (ret) |
| 62 | + continue; |
| 63 | + if (val == dev->devno) { |
| 64 | + dev_dbg(d, "found matching device node\n"); |
| 65 | + sdev->sdev_gendev.of_node = child; |
| 66 | + return; |
| 67 | + } |
| 68 | + } |
| 69 | +} |
| 70 | +#else |
| 71 | +static void ata_scsi_assign_ofnode(struct ata_device *dev, struct ata_port *ap) |
| 72 | +{ |
| 73 | +} |
| 74 | +#endif |
| 75 | + |
| 76 | void ata_scsi_scan_host(struct ata_port *ap, int sync) |
| 77 | { |
| 78 | int tries = 5; |
| 79 | @@ -4615,6 +4644,7 @@ void ata_scsi_scan_host(struct ata_port |
| 80 | NULL); |
| 81 | if (!IS_ERR(sdev)) { |
| 82 | dev->sdev = sdev; |
| 83 | + ata_scsi_assign_ofnode(dev, ap); |
| 84 | scsi_device_put(sdev); |
| 85 | } else { |
| 86 | dev->sdev = NULL; |