Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

ahci_platform: Provide for vendor specific init

Some AHCI implementations may use Vendor Specific HBA[A0h, FFh]
and/or Port[70h, 7Fh] registers to 'prepare' for initialization.
For that, the platform needs memory mapped address of AHCI registers.

This patch adds the 'mmio' argument and reorders the call to
platform init function.

Signed-off-by: Jassi Brar <jassi.brar@samsung.com>
Signed-off-by: Jeff Garzik <jgarzik@redhat.com>

authored by

Jassi Brar and committed by
Jeff Garzik
08354809 9fe6206f

+18 -11
+15 -10
drivers/ata/ahci_platform.c
··· 54 54 return -EINVAL; 55 55 } 56 56 57 - if (pdata && pdata->init) { 58 - rc = pdata->init(dev); 59 - if (rc) 60 - return rc; 61 - } 62 - 63 57 if (pdata && pdata->ata_port_info) 64 58 pi = *pdata->ata_port_info; 65 59 66 60 hpriv = devm_kzalloc(dev, sizeof(*hpriv), GFP_KERNEL); 67 61 if (!hpriv) { 68 - rc = -ENOMEM; 69 - goto err0; 62 + dev_err(dev, "can't alloc ahci_host_priv\n"); 63 + return -ENOMEM; 70 64 } 71 65 72 66 hpriv->flags |= (unsigned long)pi.private_data; ··· 68 74 hpriv->mmio = devm_ioremap(dev, mem->start, resource_size(mem)); 69 75 if (!hpriv->mmio) { 70 76 dev_err(dev, "can't map %pR\n", mem); 71 - rc = -ENOMEM; 72 - goto err0; 77 + return -ENOMEM; 78 + } 79 + 80 + /* 81 + * Some platforms might need to prepare for mmio region access, 82 + * which could be done in the following init call. So, the mmio 83 + * region shouldn't be accessed before init (if provided) has 84 + * returned successfully. 85 + */ 86 + if (pdata && pdata->init) { 87 + rc = pdata->init(dev, hpriv->mmio); 88 + if (rc) 89 + return rc; 73 90 } 74 91 75 92 ahci_save_initial_config(dev, hpriv,
+3 -1
include/linux/ahci_platform.h
··· 15 15 #ifndef _AHCI_PLATFORM_H 16 16 #define _AHCI_PLATFORM_H 17 17 18 + #include <linux/compiler.h> 19 + 18 20 struct device; 19 21 struct ata_port_info; 20 22 21 23 struct ahci_platform_data { 22 - int (*init)(struct device *dev); 24 + int (*init)(struct device *dev, void __iomem *addr); 23 25 void (*exit)(struct device *dev); 24 26 const struct ata_port_info *ata_port_info; 25 27 unsigned int force_port_map;