diff options
| author | Linus Walleij <linus.walleij@linaro.org> | 2018-12-05 03:49:11 -0500 |
|---|---|---|
| committer | Jens Axboe <axboe@kernel.dk> | 2018-12-05 08:01:14 -0500 |
| commit | 614c61a6514e05a4bb0cd8989159f986da132215 (patch) | |
| tree | c1faf2f450332927360ddd1b77b7ebb5768d9f70 | |
| parent | f43e4b007a943b00a7562025ed036a9c1ee2950f (diff) | |
ata: palmld: Introduce state container
This creates a state container struct for the Palm LifeDrive
ATA controller, and puts the ATA host and the two GPIO
descriptors into this container.
This avoids using a singleton so potentially multiple
PATA interfaces can be instantiated.
Suggested-by: Marek Vasut <marek.vasut@gmail.com>
Reviewed-by: Marek Vasut <marek.vasut@gmail.com>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
Signed-off-by: Jens Axboe <axboe@kernel.dk>
| -rw-r--r-- | drivers/ata/pata_palmld.c | 59 |
1 files changed, 36 insertions, 23 deletions
diff --git a/drivers/ata/pata_palmld.c b/drivers/ata/pata_palmld.c index e2933c324d41..26817fd91700 100644 --- a/drivers/ata/pata_palmld.c +++ b/drivers/ata/pata_palmld.c | |||
| @@ -33,7 +33,11 @@ | |||
| 33 | 33 | ||
| 34 | #define DRV_NAME "pata_palmld" | 34 | #define DRV_NAME "pata_palmld" |
| 35 | 35 | ||
| 36 | static struct gpio_desc *palmld_pata_power; | 36 | struct palmld_pata { |
| 37 | struct ata_host *host; | ||
| 38 | struct gpio_desc *power; | ||
| 39 | struct gpio_desc *reset; | ||
| 40 | }; | ||
| 37 | 41 | ||
| 38 | static struct scsi_host_template palmld_sht = { | 42 | static struct scsi_host_template palmld_sht = { |
| 39 | ATA_PIO_SHT(DRV_NAME), | 43 | ATA_PIO_SHT(DRV_NAME), |
| @@ -47,16 +51,19 @@ static struct ata_port_operations palmld_port_ops = { | |||
| 47 | 51 | ||
| 48 | static int palmld_pata_probe(struct platform_device *pdev) | 52 | static int palmld_pata_probe(struct platform_device *pdev) |
| 49 | { | 53 | { |
| 50 | struct ata_host *host; | 54 | struct palmld_pata *lda; |
| 51 | struct ata_port *ap; | 55 | struct ata_port *ap; |
| 52 | void __iomem *mem; | 56 | void __iomem *mem; |
| 53 | struct device *dev = &pdev->dev; | 57 | struct device *dev = &pdev->dev; |
| 54 | struct gpio_desc *reset; | ||
| 55 | int ret; | 58 | int ret; |
| 56 | 59 | ||
| 60 | lda = devm_kzalloc(dev, sizeof(*lda), GFP_KERNEL); | ||
| 61 | if (!lda) | ||
| 62 | return -ENOMEM; | ||
| 63 | |||
| 57 | /* allocate host */ | 64 | /* allocate host */ |
| 58 | host = ata_host_alloc(dev, 1); | 65 | lda->host = ata_host_alloc(dev, 1); |
| 59 | if (!host) | 66 | if (!lda->host) |
| 60 | return -ENOMEM; | 67 | return -ENOMEM; |
| 61 | 68 | ||
| 62 | /* remap drive's physical memory address */ | 69 | /* remap drive's physical memory address */ |
| @@ -65,23 +72,23 @@ static int palmld_pata_probe(struct platform_device *pdev) | |||
| 65 | return -ENOMEM; | 72 | return -ENOMEM; |
| 66 | 73 | ||
| 67 | /* request and activate power and reset GPIOs */ | 74 | /* request and activate power and reset GPIOs */ |
| 68 | palmld_pata_power = devm_gpiod_get(dev, "power", GPIOD_OUT_HIGH); | 75 | lda->power = devm_gpiod_get(dev, "power", GPIOD_OUT_HIGH); |
| 69 | if (IS_ERR(palmld_pata_power)) | 76 | if (IS_ERR(lda->power)) |
| 70 | return PTR_ERR(palmld_pata_power); | 77 | return PTR_ERR(lda->power); |
| 71 | reset = devm_gpiod_get(dev, "reset", GPIOD_OUT_HIGH); | 78 | lda->reset = devm_gpiod_get(dev, "reset", GPIOD_OUT_HIGH); |
| 72 | if (IS_ERR(reset)) { | 79 | if (IS_ERR(lda->reset)) { |
| 73 | gpiod_set_value(palmld_pata_power, 0); | 80 | gpiod_set_value(lda->power, 0); |
| 74 | return PTR_ERR(reset); | 81 | return PTR_ERR(lda->reset); |
| 75 | } | 82 | } |
| 76 | 83 | ||
| 77 | /* Assert reset to reset the drive */ | 84 | /* Assert reset to reset the drive */ |
| 78 | gpiod_set_value(reset, 1); | 85 | gpiod_set_value(lda->reset, 1); |
| 79 | msleep(30); | 86 | msleep(30); |
| 80 | gpiod_set_value(reset, 0); | 87 | gpiod_set_value(lda->reset, 0); |
| 81 | msleep(30); | 88 | msleep(30); |
| 82 | 89 | ||
| 83 | /* setup the ata port */ | 90 | /* setup the ata port */ |
| 84 | ap = host->ports[0]; | 91 | ap = lda->host->ports[0]; |
| 85 | ap->ops = &palmld_port_ops; | 92 | ap->ops = &palmld_port_ops; |
| 86 | ap->pio_mask = ATA_PIO4; | 93 | ap->pio_mask = ATA_PIO4; |
| 87 | ap->flags |= ATA_FLAG_PIO_POLLING; | 94 | ap->flags |= ATA_FLAG_PIO_POLLING; |
| @@ -95,20 +102,26 @@ static int palmld_pata_probe(struct platform_device *pdev) | |||
| 95 | ata_sff_std_ports(&ap->ioaddr); | 102 | ata_sff_std_ports(&ap->ioaddr); |
| 96 | 103 | ||
| 97 | /* activate host */ | 104 | /* activate host */ |
| 98 | ret = ata_host_activate(host, 0, NULL, IRQF_TRIGGER_RISING, | 105 | ret = ata_host_activate(lda->host, 0, NULL, IRQF_TRIGGER_RISING, |
| 99 | &palmld_sht); | 106 | &palmld_sht); |
| 100 | /* power down on failure */ | 107 | /* power down on failure */ |
| 101 | if (ret) | 108 | if (ret) { |
| 102 | gpiod_set_value(palmld_pata_power, 0); | 109 | gpiod_set_value(lda->power, 0); |
| 103 | return ret; | 110 | return ret; |
| 111 | } | ||
| 112 | |||
| 113 | platform_set_drvdata(pdev, lda); | ||
| 114 | return 0; | ||
| 104 | } | 115 | } |
| 105 | 116 | ||
| 106 | static int palmld_pata_remove(struct platform_device *dev) | 117 | static int palmld_pata_remove(struct platform_device *pdev) |
| 107 | { | 118 | { |
| 108 | ata_platform_remove_one(dev); | 119 | struct palmld_pata *lda = platform_get_drvdata(pdev); |
| 120 | |||
| 121 | ata_platform_remove_one(pdev); | ||
| 109 | 122 | ||
| 110 | /* power down the HDD */ | 123 | /* power down the HDD */ |
| 111 | gpiod_set_value(palmld_pata_power, 0); | 124 | gpiod_set_value(lda->power, 0); |
| 112 | 125 | ||
| 113 | return 0; | 126 | return 0; |
| 114 | } | 127 | } |
