| 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; |