Message ID | 1515482234-24716-4-git-send-email-pchandru@nvidia.com |
---|---|
State | Not Applicable |
Delegated to: | David Miller |
Headers | show |
Series | Refactor and add AHCI support for tegra210 | expand |
On 01/09/2018 09:17 AM, Preetham Chandru Ramchandra wrote: > From: Preetham Ramchandra <pchandru@nvidia.com> > > Update the controller initialization sequence and move > t124 specifics to tegra124_ahci_init. > > Signed-off-by: Preetham Chandru R <pchandru@nvidia.com> > --- > drivers/ata/ahci_tegra.c | 289 ++++++++++++++++++++++++++++++++++++----------- > 1 file changed, 224 insertions(+), 65 deletions(-) > > diff --git a/drivers/ata/ahci_tegra.c b/drivers/ata/ahci_tegra.c > index 3a62eb246d80..71850e96e787 100644 > --- a/drivers/ata/ahci_tegra.c > +++ b/drivers/ata/ahci_tegra.c > @@ -34,7 +34,8 @@ > #define DRV_NAME "tegra-ahci" > > #define SATA_CONFIGURATION_0 0x180 > -#define SATA_CONFIGURATION_EN_FPCI BIT(0) > +#define SATA_CONFIGURATION_0_EN_FPCI BIT(0) > +#define SATA_CONFIGURATION_0_CLK_OVERRIDE BIT(31) > > #define SCFG_OFFSET 0x1000 > > @@ -45,17 +46,55 @@ > #define T_SATA0_CFG_1_SERR BIT(8) > > #define T_SATA0_CFG_9 0x24 > -#define T_SATA0_CFG_9_BASE_ADDRESS_SHIFT 13 > +#define T_SATA0_CFG_9_BASE_ADDRESS 0x40020000 > > #define SATA_FPCI_BAR5 0x94 > -#define SATA_FPCI_BAR5_START_SHIFT 4 > +#define SATA_FPCI_BAR5_START_MASK (0xfffffff << 4) > +#define SATA_FPCI_BAR5_START (0x0040020 << 4) > +#define SATA_FPCI_BAR5_ACCESS_TYPE (0x1) > > #define SATA_INTR_MASK 0x188 > #define SATA_INTR_MASK_IP_INT_MASK BIT(16) > > +#define T_SATA0_CFG_35 0x94 > +#define T_SATA0_CFG_35_IDP_INDEX_MASK (0x7ff << 2) > +#define T_SATA0_CFG_35_IDP_INDEX (0x2a << 2) > + > +#define T_SATA0_AHCI_IDP1 0x98 > +#define T_SATA0_AHCI_IDP1_DATA (0x400040) > + > +#define T_SATA0_CFG_PHY_1 0x12c > +#define T_SATA0_CFG_PHY_1_PADS_IDDQ_EN BIT(23) > +#define T_SATA0_CFG_PHY_1_PAD_PLL_IDDQ_EN BIT(22) > + > +#define T_SATA0_NVOOB 0x114 > +#define T_SATA0_NVOOB_COMMA_CNT_MASK (0xff << 16) > +#define T_SATA0_NVOOB_COMMA_CNT (0x07 << 16) > +#define T_SATA0_NVOOB_SQUELCH_FILTER_MODE_MASK (0x3 << 24) > +#define T_SATA0_NVOOB_SQUELCH_FILTER_MODE (0x1 << 24) > +#define T_SATA0_NVOOB_SQUELCH_FILTER_LENGTH_MASK (0x3 << 26) > +#define T_SATA0_NVOOB_SQUELCH_FILTER_LENGTH (0x3 << 26) > + > +#define T_SATA_CFG_PHY_0 0x120 > +#define T_SATA_CFG_PHY_0_USE_7BIT_ALIGN_DET_FOR_SPD BIT(11) > +#define T_SATA_CFG_PHY_0_MASK_SQUELCH BIT(24) > + > +#define T_SATA0_CFG2NVOOB_2 0x134 > +#define T_SATA0_CFG2NVOOB_2_COMWAKE_IDLE_CNT_LOW_MASK (0x1ff << 18) > +#define T_SATA0_CFG2NVOOB_2_COMWAKE_IDLE_CNT_LOW (0xc << 18) > + > #define T_SATA0_AHCI_HBA_CAP_BKDR 0x300 > +#define T_SATA0_AHCI_HBA_CAP_BKDR_PARTIAL_ST_CAP BIT(13) > +#define T_SATA0_AHCI_HBA_CAP_BKDR_SLUMBER_ST_CAP BIT(14) > +#define T_SATA0_AHCI_HBA_CAP_BKDR_SALP BIT(26) > +#define T_SATA0_AHCI_HBA_CAP_BKDR_SUPP_PM BIT(17) > +#define T_SATA0_AHCI_HBA_CAP_BKDR_SNCQ BIT(30) > > #define T_SATA0_BKDOOR_CC 0x4a4 > +#define T_SATA0_BKDOOR_CC_CLASS_CODE_MASK (0xffff << 16) > +#define T_SATA0_BKDOOR_CC_CLASS_CODE (0x0106 << 16) > +#define T_SATA0_BKDOOR_CC_PROG_IF_MASK (0xff << 8) > +#define T_SATA0_BKDOOR_CC_PROG_IF (0x01 << 8) > > #define T_SATA0_CFG_SATA 0x54c > #define T_SATA0_CFG_SATA_BACKDOOR_PROG_IF_EN BIT(12) > @@ -82,6 +121,27 @@ > #define T_SATA0_CHX_PHY_CTRL11 0x6d0 > #define T_SATA0_CHX_PHY_CTRL11_GEN2_RX_EQ (0x2800 << 16) > > +#define T_SATA0_CHX_PHY_CTRL17_0 0x6e8 > +#define T_SATA0_CHX_PHY_CTRL17_0_RX_EQ_CTRL_L_GEN1 0x55010000 > +#define T_SATA0_CHX_PHY_CTRL18_0 0x6ec > +#define T_SATA0_CHX_PHY_CTRL18_0_RX_EQ_CTRL_L_GEN2 0x55010000 > +#define T_SATA0_CHX_PHY_CTRL20_0 0x6f4 > +#define T_SATA0_CHX_PHY_CTRL20_0_RX_EQ_CTRL_H_GEN1 0x1 > +#define T_SATA0_CHX_PHY_CTRL21_0 0x6f8 > +#define T_SATA0_CHX_PHY_CTRL21_0_RX_EQ_CTRL_H_GEN2 0x1 > + > +/* AUX Registers */ > +#define SATA_AUX_MISC_CNTL_1_0 0x8 > +#define SATA_AUX_MISC_CNTL_1_0_DEVSLP_OVERRIDE BIT(17) > +#define SATA_AUX_MISC_CNTL_1_0_SDS_SUPPORT BIT(13) > +#define SATA_AUX_MISC_CNTL_1_0_DESO_SUPPORT BIT(15) > + > +#define SATA_AUX_RX_STAT_INT_0 0xc > +#define SATA_AUX_RX_STAT_INT_0_SATA_DEVSLP BIT(7) > + > +#define SATA_AUX_SPARE_CFG0_0 0x18 > +#define SATA_AUX_SPARE_CFG0_0_MDAT_TIMER_AFTER_PG_VALID BIT(14) > + > #define FUSE_SATA_CALIB 0x124 > #define FUSE_SATA_CALIB_MASK 0x3 > > @@ -99,6 +159,14 @@ static const struct sata_pad_calibration tegra124_pad_calibration[] = { > {0x14, 0x0e, 0x1a, 0x0e}, > }; > > +struct tegra_ahci_ops { > + int (*init)(struct ahci_host_priv *hpriv); > +}; > + > +struct tegra_ahci_soc { > + struct tegra_ahci_ops ops; > +}; > + > struct tegra_ahci_priv { > struct platform_device *pdev; > void __iomem *sata_regs; > @@ -108,6 +176,57 @@ struct tegra_ahci_priv { > /* Needs special handling, cannot use ahci_platform */ > struct clk *sata_clk; > struct regulator_bulk_data supplies[5]; > + struct tegra_ahci_soc *soc_data; > +}; > + > +static int tegra124_ahci_init(struct ahci_host_priv *hpriv) > +{ > + struct tegra_ahci_priv *tegra = hpriv->plat_data; > + struct sata_pad_calibration calib; > + int ret; > + u32 val; > + > + /* Pad calibration */ > + ret = tegra_fuse_readl(FUSE_SATA_CALIB, &val); > + if (ret) > + return ret; > + > + calib = tegra124_pad_calibration[val & FUSE_SATA_CALIB_MASK]; > + > + writel(BIT(0), tegra->sata_regs + SCFG_OFFSET + T_SATA0_INDEX); > + > + val = readl(tegra->sata_regs + > + SCFG_OFFSET + T_SATA0_CHX_PHY_CTRL1_GEN1); > + val &= ~T_SATA0_CHX_PHY_CTRL1_GEN1_TX_AMP_MASK; > + val &= ~T_SATA0_CHX_PHY_CTRL1_GEN1_TX_PEAK_MASK; > + val |= calib.gen1_tx_amp << T_SATA0_CHX_PHY_CTRL1_GEN1_TX_AMP_SHIFT; > + val |= calib.gen1_tx_peak << T_SATA0_CHX_PHY_CTRL1_GEN1_TX_PEAK_SHIFT; > + writel(val, tegra->sata_regs + SCFG_OFFSET + > + T_SATA0_CHX_PHY_CTRL1_GEN1); > + > + val = readl(tegra->sata_regs + > + SCFG_OFFSET + T_SATA0_CHX_PHY_CTRL1_GEN2); > + val &= ~T_SATA0_CHX_PHY_CTRL1_GEN2_TX_AMP_MASK; > + val &= ~T_SATA0_CHX_PHY_CTRL1_GEN2_TX_PEAK_MASK; > + val |= calib.gen2_tx_amp << T_SATA0_CHX_PHY_CTRL1_GEN1_TX_AMP_SHIFT; > + val |= calib.gen2_tx_peak << T_SATA0_CHX_PHY_CTRL1_GEN1_TX_PEAK_SHIFT; > + writel(val, tegra->sata_regs + SCFG_OFFSET + > + T_SATA0_CHX_PHY_CTRL1_GEN2); > + > + writel(T_SATA0_CHX_PHY_CTRL11_GEN2_RX_EQ, > + tegra->sata_regs + SCFG_OFFSET + T_SATA0_CHX_PHY_CTRL11); > + writel(T_SATA0_CHX_PHY_CTRL2_CDR_CNTL_GEN1, > + tegra->sata_regs + SCFG_OFFSET + T_SATA0_CHX_PHY_CTRL2); > + > + writel(0, tegra->sata_regs + SCFG_OFFSET + T_SATA0_INDEX); > + > + return 0; > +} > + > +static const struct tegra_ahci_soc tegra124_ahci_soc_data = { > + .ops = { > + .init = tegra124_ahci_init, > + }, > }; I would prefer this struct definition to be just above the of_device_id table > > static int tegra_ahci_power_on(struct ahci_host_priv *hpriv) > @@ -145,7 +264,6 @@ static int tegra_ahci_power_on(struct ahci_host_priv *hpriv) > > disable_regulators: > regulator_bulk_disable(ARRAY_SIZE(tegra->supplies), tegra->supplies); > - > return ret; > } > > @@ -169,8 +287,7 @@ static int tegra_ahci_controller_init(struct ahci_host_priv *hpriv) > { > struct tegra_ahci_priv *tegra = hpriv->plat_data; > int ret; > - unsigned int val; > - struct sata_pad_calibration calib; > + u32 val; > > ret = tegra_ahci_power_on(hpriv); > if (ret) { > @@ -179,78 +296,114 @@ static int tegra_ahci_controller_init(struct ahci_host_priv *hpriv) > return ret; > } > > + /* > + * Program the following SATA IPFS registers > + * to allow SW accesses to SATA's MMIO register range. > + */ > + val = readl(tegra->sata_regs + SATA_FPCI_BAR5); > + val &= ~(SATA_FPCI_BAR5_START_MASK | SATA_FPCI_BAR5_ACCESS_TYPE); > + val |= SATA_FPCI_BAR5_START | SATA_FPCI_BAR5_ACCESS_TYPE; > + writel(val, tegra->sata_regs + SATA_FPCI_BAR5); > + > + /* Program the following SATA IPFS register to enable the SATA */ > val = readl(tegra->sata_regs + SATA_CONFIGURATION_0); > - val |= SATA_CONFIGURATION_EN_FPCI; > + val |= SATA_CONFIGURATION_0_EN_FPCI; > writel(val, tegra->sata_regs + SATA_CONFIGURATION_0); > > - /* Pad calibration */ > - > - ret = tegra_fuse_readl(FUSE_SATA_CALIB, &val); > - if (ret) { > - dev_err(&tegra->pdev->dev, > - "failed to read calibration fuse: %d\n", ret); > - return ret; > - } > - > - calib = tegra124_pad_calibration[val & FUSE_SATA_CALIB_MASK]; > - > - writel(BIT(0), tegra->sata_regs + SCFG_OFFSET + T_SATA0_INDEX); > - > - val = readl(tegra->sata_regs + > - SCFG_OFFSET + T_SATA0_CHX_PHY_CTRL1_GEN1); > - val &= ~T_SATA0_CHX_PHY_CTRL1_GEN1_TX_AMP_MASK; > - val &= ~T_SATA0_CHX_PHY_CTRL1_GEN1_TX_PEAK_MASK; > - val |= calib.gen1_tx_amp << > - T_SATA0_CHX_PHY_CTRL1_GEN1_TX_AMP_SHIFT; > - val |= calib.gen1_tx_peak << > - T_SATA0_CHX_PHY_CTRL1_GEN1_TX_PEAK_SHIFT; > - writel(val, tegra->sata_regs + SCFG_OFFSET + > - T_SATA0_CHX_PHY_CTRL1_GEN1); > - > - val = readl(tegra->sata_regs + > - SCFG_OFFSET + T_SATA0_CHX_PHY_CTRL1_GEN2); > - val &= ~T_SATA0_CHX_PHY_CTRL1_GEN2_TX_AMP_MASK; > - val &= ~T_SATA0_CHX_PHY_CTRL1_GEN2_TX_PEAK_MASK; > - val |= calib.gen2_tx_amp << > - T_SATA0_CHX_PHY_CTRL1_GEN1_TX_AMP_SHIFT; > - val |= calib.gen2_tx_peak << > - T_SATA0_CHX_PHY_CTRL1_GEN1_TX_PEAK_SHIFT; > - writel(val, tegra->sata_regs + SCFG_OFFSET + > - T_SATA0_CHX_PHY_CTRL1_GEN2); > - > - writel(T_SATA0_CHX_PHY_CTRL11_GEN2_RX_EQ, > - tegra->sata_regs + SCFG_OFFSET + T_SATA0_CHX_PHY_CTRL11); > - writel(T_SATA0_CHX_PHY_CTRL2_CDR_CNTL_GEN1, > - tegra->sata_regs + SCFG_OFFSET + T_SATA0_CHX_PHY_CTRL2); > - > - writel(0, tegra->sata_regs + SCFG_OFFSET + T_SATA0_INDEX); > - > - /* Program controller device ID */ > + /* Electrical settings for better link stability */ > + val = T_SATA0_CHX_PHY_CTRL17_0_RX_EQ_CTRL_L_GEN1; > + writel(val, tegra->sata_regs + SCFG_OFFSET + T_SATA0_CHX_PHY_CTRL17_0); > + val = T_SATA0_CHX_PHY_CTRL18_0_RX_EQ_CTRL_L_GEN2; > + writel(val, tegra->sata_regs + SCFG_OFFSET + T_SATA0_CHX_PHY_CTRL18_0); > + val = T_SATA0_CHX_PHY_CTRL20_0_RX_EQ_CTRL_H_GEN1; > + writel(val, tegra->sata_regs + SCFG_OFFSET + T_SATA0_CHX_PHY_CTRL20_0); > + val = T_SATA0_CHX_PHY_CTRL21_0_RX_EQ_CTRL_H_GEN2; > + writel(val, tegra->sata_regs + SCFG_OFFSET + T_SATA0_CHX_PHY_CTRL21_0); > + > + /* For SQUELCH Filter & Gen3 drive getting detected as Gen1 drive */ > + > + val = readl(tegra->sata_regs + SCFG_OFFSET + T_SATA_CFG_PHY_0); > + val |= T_SATA_CFG_PHY_0_MASK_SQUELCH; > + val &= ~T_SATA_CFG_PHY_0_USE_7BIT_ALIGN_DET_FOR_SPD; > + writel(val, tegra->sata_regs + SCFG_OFFSET + T_SATA_CFG_PHY_0); > + > + val = readl(tegra->sata_regs + SCFG_OFFSET + T_SATA0_NVOOB); > + val &= ~(T_SATA0_NVOOB_COMMA_CNT_MASK | > + T_SATA0_NVOOB_SQUELCH_FILTER_LENGTH_MASK | > + T_SATA0_NVOOB_SQUELCH_FILTER_MODE_MASK); > + val |= (T_SATA0_NVOOB_COMMA_CNT | > + T_SATA0_NVOOB_SQUELCH_FILTER_LENGTH | > + T_SATA0_NVOOB_SQUELCH_FILTER_MODE); > + writel(val, tegra->sata_regs + SCFG_OFFSET + T_SATA0_NVOOB); > + > + /* > + * Change CFG2NVOOB_2_COMWAKE_IDLE_CNT_LOW from 83.3 ns to 58.8ns > + */ > + val = readl(tegra->sata_regs + SCFG_OFFSET + T_SATA0_CFG2NVOOB_2); > + val &= ~T_SATA0_CFG2NVOOB_2_COMWAKE_IDLE_CNT_LOW_MASK; > + val |= T_SATA0_CFG2NVOOB_2_COMWAKE_IDLE_CNT_LOW; > + writel(val, tegra->sata_regs + SCFG_OFFSET + T_SATA0_CFG2NVOOB_2); > + > + if (tegra->soc_data->ops.init) > + tegra->soc_data->ops.init(hpriv); > + > + /* > + * Program the following SATA configuration registers > + * to initialize SATA > + */ > + val = readl(tegra->sata_regs + SCFG_OFFSET + T_SATA0_CFG_1); > + val |= (T_SATA0_CFG_1_IO_SPACE | T_SATA0_CFG_1_MEMORY_SPACE | > + T_SATA0_CFG_1_BUS_MASTER | T_SATA0_CFG_1_SERR); > + writel(val, tegra->sata_regs + SCFG_OFFSET + T_SATA0_CFG_1); > + val = T_SATA0_CFG_9_BASE_ADDRESS; > + writel(val, tegra->sata_regs + SCFG_OFFSET + T_SATA0_CFG_9); > > + /* Program Class Code and Programming interface for SATA */ > val = readl(tegra->sata_regs + SCFG_OFFSET + T_SATA0_CFG_SATA); > val |= T_SATA0_CFG_SATA_BACKDOOR_PROG_IF_EN; > writel(val, tegra->sata_regs + SCFG_OFFSET + T_SATA0_CFG_SATA); > > - writel(0x01060100, tegra->sata_regs + SCFG_OFFSET + T_SATA0_BKDOOR_CC); > + val = readl(tegra->sata_regs + SCFG_OFFSET + T_SATA0_BKDOOR_CC); > + val &= > + ~(T_SATA0_BKDOOR_CC_CLASS_CODE_MASK | > + T_SATA0_BKDOOR_CC_PROG_IF_MASK); > + val |= T_SATA0_BKDOOR_CC_CLASS_CODE | T_SATA0_BKDOOR_CC_PROG_IF; > + writel(val, tegra->sata_regs + SCFG_OFFSET + T_SATA0_BKDOOR_CC); > > val = readl(tegra->sata_regs + SCFG_OFFSET + T_SATA0_CFG_SATA); > val &= ~T_SATA0_CFG_SATA_BACKDOOR_PROG_IF_EN; > writel(val, tegra->sata_regs + SCFG_OFFSET + T_SATA0_CFG_SATA); > > - /* Enable IO & memory access, bus master mode */ > - > - val = readl(tegra->sata_regs + SCFG_OFFSET + T_SATA0_CFG_1); > - val |= T_SATA0_CFG_1_IO_SPACE | T_SATA0_CFG_1_MEMORY_SPACE | > - T_SATA0_CFG_1_BUS_MASTER | T_SATA0_CFG_1_SERR; > - writel(val, tegra->sata_regs + SCFG_OFFSET + T_SATA0_CFG_1); > - > - /* Program SATA MMIO */ > - > - writel(0x10000 << SATA_FPCI_BAR5_START_SHIFT, > - tegra->sata_regs + SATA_FPCI_BAR5); > + /* Enabling LPM capabilities through Backdoor Programming */ > + val = readl(tegra->sata_regs + SCFG_OFFSET + T_SATA0_AHCI_HBA_CAP_BKDR); > + val |= (T_SATA0_AHCI_HBA_CAP_BKDR_PARTIAL_ST_CAP | > + T_SATA0_AHCI_HBA_CAP_BKDR_SLUMBER_ST_CAP | > + T_SATA0_AHCI_HBA_CAP_BKDR_SALP | > + T_SATA0_AHCI_HBA_CAP_BKDR_SUPP_PM); > + writel(val, tegra->sata_regs + SCFG_OFFSET + T_SATA0_AHCI_HBA_CAP_BKDR); > + > + /* SATA Second Level Clock Gating configuration > + * Enabling Gating of Tx/Rx clocks and driving Pad IDDQ and Lane > + * IDDQ Signals > + */ > + val = readl(tegra->sata_regs + SCFG_OFFSET + T_SATA0_CFG_35); > + val &= ~T_SATA0_CFG_35_IDP_INDEX_MASK; > + val |= T_SATA0_CFG_35_IDP_INDEX; > + writel(val, tegra->sata_regs + SCFG_OFFSET + T_SATA0_CFG_35); > + > + val = T_SATA0_AHCI_IDP1_DATA; > + writel(val, tegra->sata_regs + SCFG_OFFSET + T_SATA0_AHCI_IDP1); > + > + val = readl(tegra->sata_regs + SCFG_OFFSET + T_SATA0_CFG_PHY_1); > + val |= (T_SATA0_CFG_PHY_1_PADS_IDDQ_EN | > + T_SATA0_CFG_PHY_1_PAD_PLL_IDDQ_EN); > + writel(val, tegra->sata_regs + SCFG_OFFSET + T_SATA0_CFG_PHY_1); > + > + /* Enabling IPFS Clock Gating */ > + val = readl(tegra->sata_regs + SATA_CONFIGURATION_0); > + val &= ~SATA_CONFIGURATION_0_CLK_OVERRIDE; > + writel(val, tegra->sata_regs + SATA_CONFIGURATION_0); > > - writel(0x08000 << T_SATA0_CFG_9_BASE_ADDRESS_SHIFT, > - tegra->sata_regs + SCFG_OFFSET + T_SATA0_CFG_9); > > /* Unmask SATA interrupts */ > > @@ -286,7 +439,10 @@ static const struct ata_port_info ahci_tegra_port_info = { > }; > > static const struct of_device_id tegra_ahci_of_match[] = { > - { .compatible = "nvidia,tegra124-ahci" }, > + { > + .compatible = "nvidia,tegra124-ahci", > + .data = &tegra124_ahci_soc_data > + }, > {} > }; > MODULE_DEVICE_TABLE(of, tegra_ahci_of_match); > @@ -301,6 +457,7 @@ static int tegra_ahci_probe(struct platform_device *pdev) > struct tegra_ahci_priv *tegra; > struct resource *res; > int ret; > + unsigned int i; This variable doesn't seem to be used here. > > hpriv = ahci_platform_get_resources(pdev); > if (IS_ERR(hpriv)) > @@ -313,6 +470,8 @@ static int tegra_ahci_probe(struct platform_device *pdev) > hpriv->plat_data = tegra; > > tegra->pdev = pdev; > + tegra->soc_data = > + (struct tegra_ahci_soc *)of_device_get_match_data(&pdev->dev); > > res = platform_get_resource(pdev, IORESOURCE_MEM, 1); > tegra->sata_regs = devm_ioremap_resource(&pdev->dev, res); > Otherwise looks good to me. Mikko -- To unsubscribe from this list: send the line "unsubscribe linux-ide" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
DQoNCj4tLS0tLU9yaWdpbmFsIE1lc3NhZ2UtLS0tLQ0KPkZyb206IE1pa2tvIFBlcnR0dW5lbiBb bWFpbHRvOmN5bmRpc0BrYXBzaS5maV0NCj5TZW50OiBUdWVzZGF5LCBKYW51YXJ5IDIzLCAyMDE4 IDk6MTQgUE0NCj5UbzogUHJlZXRoYW0gQ2hhbmRydSA8cGNoYW5kcnVAbnZpZGlhLmNvbT47IHRo aWVycnkucmVkaW5nQGdtYWlsLmNvbTsNCj50akBrZXJuZWwub3JnDQo+Q2M6IHByZWV0aGFtMjYw QGdtYWlsLmNvbTsgbGludXgtdGVncmFAdmdlci5rZXJuZWwub3JnOyBsaW51eC0NCj5pZGVAdmdl ci5rZXJuZWwub3JnOyBWZW51IEJ5cmF2YXJhc3UgPHZieXJhdmFyYXN1QG52aWRpYS5jb20+OyBQ YXZhbg0KPkt1bmFwdWxpIDxwa3VuYXB1bGlAbnZpZGlhLmNvbT4NCj5TdWJqZWN0OiBSZTogW1BB VENIIFY2IDMvN10gYXRhOiBhaGNpX3RlZ3JhOiBVcGRhdGUgaW5pdGlhbGl6YXRpb24gc2VxdWVu Y2UNCj4NCj5PbiAwMS8wOS8yMDE4IDA5OjE3IEFNLCBQcmVldGhhbSBDaGFuZHJ1IFJhbWNoYW5k cmEgd3JvdGU6DQo+PiBGcm9tOiBQcmVldGhhbSBSYW1jaGFuZHJhIDxwY2hhbmRydUBudmlkaWEu Y29tPg0KPj4NCj4+IFVwZGF0ZSB0aGUgY29udHJvbGxlciBpbml0aWFsaXphdGlvbiBzZXF1ZW5j ZSBhbmQgbW92ZQ0KPj4gdDEyNCBzcGVjaWZpY3MgdG8gdGVncmExMjRfYWhjaV9pbml0Lg0KPj4N Cj4+IFNpZ25lZC1vZmYtYnk6IFByZWV0aGFtIENoYW5kcnUgUiA8cGNoYW5kcnVAbnZpZGlhLmNv bT4NCj4+IC0tLQ0KPj4gICBkcml2ZXJzL2F0YS9haGNpX3RlZ3JhLmMgfCAyODkgKysrKysrKysr KysrKysrKysrKysrKysrKysrKysrKysrKysrLS0tLQ0KPi0tLS0tLS0NCj4+ICAgMSBmaWxlIGNo YW5nZWQsIDIyNCBpbnNlcnRpb25zKCspLCA2NSBkZWxldGlvbnMoLSkNCj4+DQo+PiBkaWZmIC0t Z2l0IGEvZHJpdmVycy9hdGEvYWhjaV90ZWdyYS5jIGIvZHJpdmVycy9hdGEvYWhjaV90ZWdyYS5j IGluZGV4DQo+PiAzYTYyZWIyNDZkODAuLjcxODUwZTk2ZTc4NyAxMDA2NDQNCj4+IC0tLSBhL2Ry aXZlcnMvYXRhL2FoY2lfdGVncmEuYw0KPj4gKysrIGIvZHJpdmVycy9hdGEvYWhjaV90ZWdyYS5j DQo+PiBAQCAtMzQsNyArMzQsOCBAQA0KPj4gICAjZGVmaW5lIERSVl9OQU1FICJ0ZWdyYS1haGNp Ig0KPj4NCj4+ICAgI2RlZmluZSBTQVRBX0NPTkZJR1VSQVRJT05fMAkJCQkweDE4MA0KPj4gLSNk ZWZpbmUgU0FUQV9DT05GSUdVUkFUSU9OX0VOX0ZQQ0kJCQlCSVQoMCkNCj4+ICsjZGVmaW5lIFNB VEFfQ09ORklHVVJBVElPTl8wX0VOX0ZQQ0kJCQlCSVQoMCkNCj4+ICsjZGVmaW5lIFNBVEFfQ09O RklHVVJBVElPTl8wX0NMS19PVkVSUklERQkJCUJJVCgzMSkNCj4+DQo+PiAgICNkZWZpbmUgU0NG R19PRkZTRVQJCQkJCTB4MTAwMA0KPj4NCj4+IEBAIC00NSwxNyArNDYsNTUgQEANCj4+ICAgI2Rl ZmluZSBUX1NBVEEwX0NGR18xX1NFUlIJCQkJQklUKDgpDQo+Pg0KPj4gICAjZGVmaW5lIFRfU0FU QTBfQ0ZHXzkJCQkJCTB4MjQNCj4+IC0jZGVmaW5lIFRfU0FUQTBfQ0ZHXzlfQkFTRV9BRERSRVNT X1NISUZUCQkxMw0KPj4gKyNkZWZpbmUgVF9TQVRBMF9DRkdfOV9CQVNFX0FERFJFU1MJCQkweDQw MDIwMDAwDQo+Pg0KPj4gICAjZGVmaW5lIFNBVEFfRlBDSV9CQVI1CQkJCQkweDk0DQo+PiAtI2Rl ZmluZSBTQVRBX0ZQQ0lfQkFSNV9TVEFSVF9TSElGVAkJCTQNCj4+ICsjZGVmaW5lIFNBVEFfRlBD SV9CQVI1X1NUQVJUX01BU0sJCQkoMHhmZmZmZmZmIDw8IDQpDQo+PiArI2RlZmluZSBTQVRBX0ZQ Q0lfQkFSNV9TVEFSVAkJCQkoMHgwMDQwMDIwIDw8DQo+NCkNCj4+ICsjZGVmaW5lIFNBVEFfRlBD SV9CQVI1X0FDQ0VTU19UWVBFCQkJKDB4MSkNCj4+DQo+PiAgICNkZWZpbmUgU0FUQV9JTlRSX01B U0sJCQkJCTB4MTg4DQo+PiAgICNkZWZpbmUgU0FUQV9JTlRSX01BU0tfSVBfSU5UX01BU0sJCQlC SVQoMTYpDQo+Pg0KPj4gKyNkZWZpbmUgVF9TQVRBMF9DRkdfMzUJCQkJCTB4OTQNCj4+ICsjZGVm aW5lIFRfU0FUQTBfQ0ZHXzM1X0lEUF9JTkRFWF9NQVNLCQkJKDB4N2ZmIDw8IDIpDQo+PiArI2Rl ZmluZSBUX1NBVEEwX0NGR18zNV9JRFBfSU5ERVgJCQkoMHgyYSA8PCAyKQ0KPj4gKw0KPj4gKyNk ZWZpbmUgVF9TQVRBMF9BSENJX0lEUDEJCQkJMHg5OA0KPj4gKyNkZWZpbmUgVF9TQVRBMF9BSENJ X0lEUDFfREFUQQkJCQkoMHg0MDAwNDApDQo+PiArDQo+PiArI2RlZmluZSBUX1NBVEEwX0NGR19Q SFlfMQkJCQkweDEyYw0KPj4gKyNkZWZpbmUgVF9TQVRBMF9DRkdfUEhZXzFfUEFEU19JRERRX0VO CQkJQklUKDIzKQ0KPj4gKyNkZWZpbmUgVF9TQVRBMF9DRkdfUEhZXzFfUEFEX1BMTF9JRERRX0VO CQlCSVQoMjIpDQo+PiArDQo+PiArI2RlZmluZSBUX1NBVEEwX05WT09CICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAweDExNA0KPj4gKyNkZWZpbmUgVF9TQVRBMF9OVk9PQl9DT01N QV9DTlRfTUFTSyAgICAgICAgICAgICAgICAgICAgKDB4ZmYgPDwgMTYpDQo+PiArI2RlZmluZSBU X1NBVEEwX05WT09CX0NPTU1BX0NOVCAgICAgICAgICAgICAgICAgICAgICAgICAoMHgwNyA8PCAx NikNCj4+ICsjZGVmaW5lIFRfU0FUQTBfTlZPT0JfU1FVRUxDSF9GSUxURVJfTU9ERV9NQVNLICAg ICAgICAgICgweDMgPDwgMjQpDQo+PiArI2RlZmluZSBUX1NBVEEwX05WT09CX1NRVUVMQ0hfRklM VEVSX01PREUgICAgICAgICAgICAgICAoMHgxIDw8IDI0KQ0KPj4gKyNkZWZpbmUgVF9TQVRBMF9O Vk9PQl9TUVVFTENIX0ZJTFRFUl9MRU5HVEhfTUFTSyAgICAgICAgKDB4MyA8PCAyNikNCj4+ICsj ZGVmaW5lIFRfU0FUQTBfTlZPT0JfU1FVRUxDSF9GSUxURVJfTEVOR1RIICAgICAgICAgICAgICgw eDMgPDwgMjYpDQo+PiArDQo+PiArI2RlZmluZSBUX1NBVEFfQ0ZHX1BIWV8wICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAweDEyMA0KPj4gKyNkZWZpbmUgVF9TQVRBX0NGR19QSFlfMF9V U0VfN0JJVF9BTElHTl9ERVRfRk9SX1NQRCAgICAgQklUKDExKQ0KPj4gKyNkZWZpbmUgVF9TQVRB X0NGR19QSFlfMF9NQVNLX1NRVUVMQ0ggICAgICAgICAgICAgICAgICAgQklUKDI0KQ0KPj4gKw0K Pj4gKyNkZWZpbmUgVF9TQVRBMF9DRkcyTlZPT0JfMgkJCQkweDEzNA0KPj4gKyNkZWZpbmUgVF9T QVRBMF9DRkcyTlZPT0JfMl9DT01XQUtFX0lETEVfQ05UX0xPV19NQVNLCSgweDFmZg0KPjw8IDE4 KQ0KPj4gKyNkZWZpbmUgVF9TQVRBMF9DRkcyTlZPT0JfMl9DT01XQUtFX0lETEVfQ05UX0xPVwko MHhjIDw8DQo+MTgpDQo+PiArDQo+PiAgICNkZWZpbmUgVF9TQVRBMF9BSENJX0hCQV9DQVBfQktE UgkJCTB4MzAwDQo+PiArI2RlZmluZSBUX1NBVEEwX0FIQ0lfSEJBX0NBUF9CS0RSX1BBUlRJQUxf U1RfQ0FQCUJJVCgxMykNCj4+ICsjZGVmaW5lIFRfU0FUQTBfQUhDSV9IQkFfQ0FQX0JLRFJfU0xV TUJFUl9TVF9DQVAJQklUKDE0KQ0KPj4gKyNkZWZpbmUgVF9TQVRBMF9BSENJX0hCQV9DQVBfQktE Ul9TQUxQCQkJQklUKDI2KQ0KPj4gKyNkZWZpbmUgVF9TQVRBMF9BSENJX0hCQV9DQVBfQktEUl9T VVBQX1BNCQlCSVQoMTcpDQo+PiArI2RlZmluZSBUX1NBVEEwX0FIQ0lfSEJBX0NBUF9CS0RSX1NO Q1EJCQlCSVQoMzApDQo+Pg0KPj4gICAjZGVmaW5lIFRfU0FUQTBfQktET09SX0NDCQkJCTB4NGE0 DQo+PiArI2RlZmluZSBUX1NBVEEwX0JLRE9PUl9DQ19DTEFTU19DT0RFX01BU0sJCSgweGZmZmYg PDwgMTYpDQo+PiArI2RlZmluZSBUX1NBVEEwX0JLRE9PUl9DQ19DTEFTU19DT0RFCQkJKDB4MDEw NiA8PCAxNikNCj4+ICsjZGVmaW5lIFRfU0FUQTBfQktET09SX0NDX1BST0dfSUZfTUFTSwkJCSgw eGZmIDw8DQo+OCkNCj4+ICsjZGVmaW5lIFRfU0FUQTBfQktET09SX0NDX1BST0dfSUYJCQkoMHgw MSA8PCA4KQ0KPj4NCj4+ICAgI2RlZmluZSBUX1NBVEEwX0NGR19TQVRBCQkJCTB4NTRjDQo+PiAg ICNkZWZpbmUgVF9TQVRBMF9DRkdfU0FUQV9CQUNLRE9PUl9QUk9HX0lGX0VOCQlCSVQoMTIpDQo+ PiBAQCAtODIsNiArMTIxLDI3IEBADQo+PiAgICNkZWZpbmUgVF9TQVRBMF9DSFhfUEhZX0NUUkwx MQkJCQkweDZkMA0KPj4gICAjZGVmaW5lIFRfU0FUQTBfQ0hYX1BIWV9DVFJMMTFfR0VOMl9SWF9F UQkJKDB4MjgwMCA8PCAxNikNCj4+DQo+PiArI2RlZmluZSBUX1NBVEEwX0NIWF9QSFlfQ1RSTDE3 XzAJCQkweDZlOA0KPj4gKyNkZWZpbmUgVF9TQVRBMF9DSFhfUEhZX0NUUkwxN18wX1JYX0VRX0NU UkxfTF9HRU4xCTB4NTUwMTAwMDANCj4+ICsjZGVmaW5lIFRfU0FUQTBfQ0hYX1BIWV9DVFJMMThf MAkJCTB4NmVjDQo+PiArI2RlZmluZSBUX1NBVEEwX0NIWF9QSFlfQ1RSTDE4XzBfUlhfRVFfQ1RS TF9MX0dFTjIJMHg1NTAxMDAwMA0KPj4gKyNkZWZpbmUgVF9TQVRBMF9DSFhfUEhZX0NUUkwyMF8w CQkJMHg2ZjQNCj4+ICsjZGVmaW5lIFRfU0FUQTBfQ0hYX1BIWV9DVFJMMjBfMF9SWF9FUV9DVFJM X0hfR0VOMQkweDENCj4+ICsjZGVmaW5lIFRfU0FUQTBfQ0hYX1BIWV9DVFJMMjFfMAkJCTB4NmY4 DQo+PiArI2RlZmluZSBUX1NBVEEwX0NIWF9QSFlfQ1RSTDIxXzBfUlhfRVFfQ1RSTF9IX0dFTjIJ MHgxDQo+PiArDQo+PiArLyogQVVYIFJlZ2lzdGVycyAqLw0KPj4gKyNkZWZpbmUgU0FUQV9BVVhf TUlTQ19DTlRMXzFfMAkJCQkweDgNCj4+ICsjZGVmaW5lIFNBVEFfQVVYX01JU0NfQ05UTF8xXzBf REVWU0xQX09WRVJSSURFCQlCSVQoMTcpDQo+PiArI2RlZmluZSBTQVRBX0FVWF9NSVNDX0NOVExf MV8wX1NEU19TVVBQT1JUCQlCSVQoMTMpDQo+PiArI2RlZmluZSBTQVRBX0FVWF9NSVNDX0NOVExf MV8wX0RFU09fU1VQUE9SVAkJQklUKDE1KQ0KPj4gKw0KPj4gKyNkZWZpbmUgU0FUQV9BVVhfUlhf U1RBVF9JTlRfMAkJCQkweGMNCj4+ICsjZGVmaW5lIFNBVEFfQVVYX1JYX1NUQVRfSU5UXzBfU0FU QV9ERVZTTFAJCUJJVCg3KQ0KPj4gKw0KPj4gKyNkZWZpbmUgU0FUQV9BVVhfU1BBUkVfQ0ZHMF8w CQkJCTB4MTgNCj4+ICsjZGVmaW5lIFNBVEFfQVVYX1NQQVJFX0NGRzBfMF9NREFUX1RJTUVSX0FG VEVSX1BHX1ZBTElECUJJVCgxNCkNCj4+ICsNCj4+ICAgI2RlZmluZSBGVVNFX1NBVEFfQ0FMSUIJ CQkJCTB4MTI0DQo+PiAgICNkZWZpbmUgRlVTRV9TQVRBX0NBTElCX01BU0sJCQkJMHgzDQo+Pg0K Pj4gQEAgLTk5LDYgKzE1OSwxNCBAQCBzdGF0aWMgY29uc3Qgc3RydWN0IHNhdGFfcGFkX2NhbGli cmF0aW9uDQo+dGVncmExMjRfcGFkX2NhbGlicmF0aW9uW10gPSB7DQo+PiAgIAl7MHgxNCwgMHgw ZSwgMHgxYSwgMHgwZX0sDQo+PiAgIH07DQo+Pg0KPj4gK3N0cnVjdCB0ZWdyYV9haGNpX29wcyB7 DQo+PiArCWludCAoKmluaXQpKHN0cnVjdCBhaGNpX2hvc3RfcHJpdiAqaHByaXYpOyB9Ow0KPj4g Kw0KPj4gK3N0cnVjdCB0ZWdyYV9haGNpX3NvYyB7DQo+PiArCXN0cnVjdCB0ZWdyYV9haGNpX29w cwlvcHM7DQo+PiArfTsNCj4+ICsNCj4+ICAgc3RydWN0IHRlZ3JhX2FoY2lfcHJpdiB7DQo+PiAg IAlzdHJ1Y3QgcGxhdGZvcm1fZGV2aWNlCSAgICpwZGV2Ow0KPj4gICAJdm9pZCBfX2lvbWVtCQkg ICAqc2F0YV9yZWdzOw0KPj4gQEAgLTEwOCw2ICsxNzYsNTcgQEAgc3RydWN0IHRlZ3JhX2FoY2lf cHJpdiB7DQo+PiAgIAkvKiBOZWVkcyBzcGVjaWFsIGhhbmRsaW5nLCBjYW5ub3QgdXNlIGFoY2lf cGxhdGZvcm0gKi8NCj4+ICAgCXN0cnVjdCBjbGsJCSAgICpzYXRhX2NsazsNCj4+ICAgCXN0cnVj dCByZWd1bGF0b3JfYnVsa19kYXRhIHN1cHBsaWVzWzVdOw0KPj4gKwlzdHJ1Y3QgdGVncmFfYWhj aV9zb2MJICAgKnNvY19kYXRhOw0KPj4gK307DQo+PiArDQo+PiArc3RhdGljIGludCB0ZWdyYTEy NF9haGNpX2luaXQoc3RydWN0IGFoY2lfaG9zdF9wcml2ICpocHJpdikgew0KPj4gKwlzdHJ1Y3Qg dGVncmFfYWhjaV9wcml2ICp0ZWdyYSA9IGhwcml2LT5wbGF0X2RhdGE7DQo+PiArCXN0cnVjdCBz YXRhX3BhZF9jYWxpYnJhdGlvbiBjYWxpYjsNCj4+ICsJaW50IHJldDsNCj4+ICsJdTMyIHZhbDsN Cj4+ICsNCj4+ICsJLyogUGFkIGNhbGlicmF0aW9uICovDQo+PiArCXJldCA9IHRlZ3JhX2Z1c2Vf cmVhZGwoRlVTRV9TQVRBX0NBTElCLCAmdmFsKTsNCj4+ICsJaWYgKHJldCkNCj4+ICsJCXJldHVy biByZXQ7DQo+PiArDQo+PiArCWNhbGliID0gdGVncmExMjRfcGFkX2NhbGlicmF0aW9uW3ZhbCAm IEZVU0VfU0FUQV9DQUxJQl9NQVNLXTsNCj4+ICsNCj4+ICsJd3JpdGVsKEJJVCgwKSwgdGVncmEt PnNhdGFfcmVncyArIFNDRkdfT0ZGU0VUICsgVF9TQVRBMF9JTkRFWCk7DQo+PiArDQo+PiArCXZh bCA9IHJlYWRsKHRlZ3JhLT5zYXRhX3JlZ3MgKw0KPj4gKwkJICAgIFNDRkdfT0ZGU0VUICsgVF9T QVRBMF9DSFhfUEhZX0NUUkwxX0dFTjEpOw0KPj4gKwl2YWwgJj0gflRfU0FUQTBfQ0hYX1BIWV9D VFJMMV9HRU4xX1RYX0FNUF9NQVNLOw0KPj4gKwl2YWwgJj0gflRfU0FUQTBfQ0hYX1BIWV9DVFJM MV9HRU4xX1RYX1BFQUtfTUFTSzsNCj4+ICsJdmFsIHw9IGNhbGliLmdlbjFfdHhfYW1wIDw8DQo+ VF9TQVRBMF9DSFhfUEhZX0NUUkwxX0dFTjFfVFhfQU1QX1NISUZUOw0KPj4gKwl2YWwgfD0gY2Fs aWIuZ2VuMV90eF9wZWFrIDw8DQo+VF9TQVRBMF9DSFhfUEhZX0NUUkwxX0dFTjFfVFhfUEVBS19T SElGVDsNCj4+ICsJd3JpdGVsKHZhbCwgdGVncmEtPnNhdGFfcmVncyArIFNDRkdfT0ZGU0VUICsN Cj4+ICsJICAgICAgIFRfU0FUQTBfQ0hYX1BIWV9DVFJMMV9HRU4xKTsNCj4+ICsNCj4+ICsJdmFs ID0gcmVhZGwodGVncmEtPnNhdGFfcmVncyArDQo+PiArCQkgICAgU0NGR19PRkZTRVQgKyBUX1NB VEEwX0NIWF9QSFlfQ1RSTDFfR0VOMik7DQo+PiArCXZhbCAmPSB+VF9TQVRBMF9DSFhfUEhZX0NU UkwxX0dFTjJfVFhfQU1QX01BU0s7DQo+PiArCXZhbCAmPSB+VF9TQVRBMF9DSFhfUEhZX0NUUkwx X0dFTjJfVFhfUEVBS19NQVNLOw0KPj4gKwl2YWwgfD0gY2FsaWIuZ2VuMl90eF9hbXAgPDwNCj5U X1NBVEEwX0NIWF9QSFlfQ1RSTDFfR0VOMV9UWF9BTVBfU0hJRlQ7DQo+PiArCXZhbCB8PSBjYWxp Yi5nZW4yX3R4X3BlYWsgPDwNCj5UX1NBVEEwX0NIWF9QSFlfQ1RSTDFfR0VOMV9UWF9QRUFLX1NI SUZUOw0KPj4gKwl3cml0ZWwodmFsLCB0ZWdyYS0+c2F0YV9yZWdzICsgU0NGR19PRkZTRVQgKw0K Pj4gKwkgICAgICAgVF9TQVRBMF9DSFhfUEhZX0NUUkwxX0dFTjIpOw0KPj4gKw0KPj4gKwl3cml0 ZWwoVF9TQVRBMF9DSFhfUEhZX0NUUkwxMV9HRU4yX1JYX0VRLA0KPj4gKwkgICAgICAgdGVncmEt PnNhdGFfcmVncyArIFNDRkdfT0ZGU0VUICsgVF9TQVRBMF9DSFhfUEhZX0NUUkwxMSk7DQo+PiAr CXdyaXRlbChUX1NBVEEwX0NIWF9QSFlfQ1RSTDJfQ0RSX0NOVExfR0VOMSwNCj4+ICsJICAgICAg IHRlZ3JhLT5zYXRhX3JlZ3MgKyBTQ0ZHX09GRlNFVCArIFRfU0FUQTBfQ0hYX1BIWV9DVFJMMik7 DQo+PiArDQo+PiArCXdyaXRlbCgwLCB0ZWdyYS0+c2F0YV9yZWdzICsgU0NGR19PRkZTRVQgKyBU X1NBVEEwX0lOREVYKTsNCj4+ICsNCj4+ICsJcmV0dXJuIDA7DQo+PiArfQ0KPj4gKw0KPj4gK3N0 YXRpYyBjb25zdCBzdHJ1Y3QgdGVncmFfYWhjaV9zb2MgdGVncmExMjRfYWhjaV9zb2NfZGF0YSA9 IHsNCj4+ICsJLm9wcyA9IHsNCj4+ICsJCS5pbml0ID0gdGVncmExMjRfYWhjaV9pbml0LA0KPj4g Kwl9LA0KPj4gICB9Ow0KPg0KPkkgd291bGQgcHJlZmVyIHRoaXMgc3RydWN0IGRlZmluaXRpb24g dG8gYmUganVzdCBhYm92ZSB0aGUgb2ZfZGV2aWNlX2lkIHRhYmxlDQo+DQpva2F5DQo+Pg0KPj4g ICBzdGF0aWMgaW50IHRlZ3JhX2FoY2lfcG93ZXJfb24oc3RydWN0IGFoY2lfaG9zdF9wcml2ICpo cHJpdikgQEANCj4+IC0xNDUsNyArMjY0LDYgQEAgc3RhdGljIGludCB0ZWdyYV9haGNpX3Bvd2Vy X29uKHN0cnVjdCBhaGNpX2hvc3RfcHJpdg0KPj4gKmhwcml2KQ0KPj4NCj4+ICAgZGlzYWJsZV9y ZWd1bGF0b3JzOg0KPj4gICAJcmVndWxhdG9yX2J1bGtfZGlzYWJsZShBUlJBWV9TSVpFKHRlZ3Jh LT5zdXBwbGllcyksDQo+PiB0ZWdyYS0+c3VwcGxpZXMpOw0KPj4gLQ0KPj4gICAJcmV0dXJuIHJl dDsNCj4+ICAgfQ0KPj4NCj4+IEBAIC0xNjksOCArMjg3LDcgQEAgc3RhdGljIGludCB0ZWdyYV9h aGNpX2NvbnRyb2xsZXJfaW5pdChzdHJ1Y3QNCj5haGNpX2hvc3RfcHJpdiAqaHByaXYpDQo+PiAg IHsNCj4+ICAgCXN0cnVjdCB0ZWdyYV9haGNpX3ByaXYgKnRlZ3JhID0gaHByaXYtPnBsYXRfZGF0 YTsNCj4+ICAgCWludCByZXQ7DQo+PiAtCXVuc2lnbmVkIGludCB2YWw7DQo+PiAtCXN0cnVjdCBz YXRhX3BhZF9jYWxpYnJhdGlvbiBjYWxpYjsNCj4+ICsJdTMyIHZhbDsNCj4+DQo+PiAgIAlyZXQg PSB0ZWdyYV9haGNpX3Bvd2VyX29uKGhwcml2KTsNCj4+ICAgCWlmIChyZXQpIHsNCj4+IEBAIC0x NzksNzggKzI5NiwxMTQgQEAgc3RhdGljIGludCB0ZWdyYV9haGNpX2NvbnRyb2xsZXJfaW5pdChz dHJ1Y3QNCj5haGNpX2hvc3RfcHJpdiAqaHByaXYpDQo+PiAgIAkJcmV0dXJuIHJldDsNCj4+ICAg CX0NCj4+DQo+PiArCS8qDQo+PiArCSAqIFByb2dyYW0gdGhlIGZvbGxvd2luZyBTQVRBIElQRlMg cmVnaXN0ZXJzDQo+PiArCSAqIHRvIGFsbG93IFNXIGFjY2Vzc2VzIHRvIFNBVEEncyBNTUlPIHJl Z2lzdGVyIHJhbmdlLg0KPj4gKwkgKi8NCj4+ICsJdmFsID0gcmVhZGwodGVncmEtPnNhdGFfcmVn cyArIFNBVEFfRlBDSV9CQVI1KTsNCj4+ICsJdmFsICY9IH4oU0FUQV9GUENJX0JBUjVfU1RBUlRf TUFTSyB8DQo+U0FUQV9GUENJX0JBUjVfQUNDRVNTX1RZUEUpOw0KPj4gKwl2YWwgfD0gU0FUQV9G UENJX0JBUjVfU1RBUlQgfCBTQVRBX0ZQQ0lfQkFSNV9BQ0NFU1NfVFlQRTsNCj4+ICsJd3JpdGVs KHZhbCwgdGVncmEtPnNhdGFfcmVncyArIFNBVEFfRlBDSV9CQVI1KTsNCj4+ICsNCj4+ICsJLyog UHJvZ3JhbSB0aGUgZm9sbG93aW5nIFNBVEEgSVBGUyByZWdpc3RlciB0byBlbmFibGUgdGhlIFNB VEEgKi8NCj4+ICAgCXZhbCA9IHJlYWRsKHRlZ3JhLT5zYXRhX3JlZ3MgKyBTQVRBX0NPTkZJR1VS QVRJT05fMCk7DQo+PiAtCXZhbCB8PSBTQVRBX0NPTkZJR1VSQVRJT05fRU5fRlBDSTsNCj4+ICsJ dmFsIHw9IFNBVEFfQ09ORklHVVJBVElPTl8wX0VOX0ZQQ0k7DQo+PiAgIAl3cml0ZWwodmFsLCB0 ZWdyYS0+c2F0YV9yZWdzICsgU0FUQV9DT05GSUdVUkFUSU9OXzApOw0KPj4NCj4+IC0JLyogUGFk IGNhbGlicmF0aW9uICovDQo+PiAtDQo+PiAtCXJldCA9IHRlZ3JhX2Z1c2VfcmVhZGwoRlVTRV9T QVRBX0NBTElCLCAmdmFsKTsNCj4+IC0JaWYgKHJldCkgew0KPj4gLQkJZGV2X2VycigmdGVncmEt PnBkZXYtPmRldiwNCj4+IC0JCQkiZmFpbGVkIHRvIHJlYWQgY2FsaWJyYXRpb24gZnVzZTogJWRc biIsIHJldCk7DQo+PiAtCQlyZXR1cm4gcmV0Ow0KPj4gLQl9DQo+PiAtDQo+PiAtCWNhbGliID0g dGVncmExMjRfcGFkX2NhbGlicmF0aW9uW3ZhbCAmIEZVU0VfU0FUQV9DQUxJQl9NQVNLXTsNCj4+ IC0NCj4+IC0Jd3JpdGVsKEJJVCgwKSwgdGVncmEtPnNhdGFfcmVncyArIFNDRkdfT0ZGU0VUICsg VF9TQVRBMF9JTkRFWCk7DQo+PiAtDQo+PiAtCXZhbCA9IHJlYWRsKHRlZ3JhLT5zYXRhX3JlZ3Mg Kw0KPj4gLQkJU0NGR19PRkZTRVQgKyBUX1NBVEEwX0NIWF9QSFlfQ1RSTDFfR0VOMSk7DQo+PiAt CXZhbCAmPSB+VF9TQVRBMF9DSFhfUEhZX0NUUkwxX0dFTjFfVFhfQU1QX01BU0s7DQo+PiAtCXZh bCAmPSB+VF9TQVRBMF9DSFhfUEhZX0NUUkwxX0dFTjFfVFhfUEVBS19NQVNLOw0KPj4gLQl2YWwg fD0gY2FsaWIuZ2VuMV90eF9hbXAgPDwNCj4+IC0JCQlUX1NBVEEwX0NIWF9QSFlfQ1RSTDFfR0VO MV9UWF9BTVBfU0hJRlQ7DQo+PiAtCXZhbCB8PSBjYWxpYi5nZW4xX3R4X3BlYWsgPDwNCj4+IC0J CQlUX1NBVEEwX0NIWF9QSFlfQ1RSTDFfR0VOMV9UWF9QRUFLX1NISUZUOw0KPj4gLQl3cml0ZWwo dmFsLCB0ZWdyYS0+c2F0YV9yZWdzICsgU0NGR19PRkZTRVQgKw0KPj4gLQkJVF9TQVRBMF9DSFhf UEhZX0NUUkwxX0dFTjEpOw0KPj4gLQ0KPj4gLQl2YWwgPSByZWFkbCh0ZWdyYS0+c2F0YV9yZWdz ICsNCj4+IC0JCQlTQ0ZHX09GRlNFVCArIFRfU0FUQTBfQ0hYX1BIWV9DVFJMMV9HRU4yKTsNCj4+ IC0JdmFsICY9IH5UX1NBVEEwX0NIWF9QSFlfQ1RSTDFfR0VOMl9UWF9BTVBfTUFTSzsNCj4+IC0J dmFsICY9IH5UX1NBVEEwX0NIWF9QSFlfQ1RSTDFfR0VOMl9UWF9QRUFLX01BU0s7DQo+PiAtCXZh bCB8PSBjYWxpYi5nZW4yX3R4X2FtcCA8PA0KPj4gLQkJCVRfU0FUQTBfQ0hYX1BIWV9DVFJMMV9H RU4xX1RYX0FNUF9TSElGVDsNCj4+IC0JdmFsIHw9IGNhbGliLmdlbjJfdHhfcGVhayA8PA0KPj4g LQkJCVRfU0FUQTBfQ0hYX1BIWV9DVFJMMV9HRU4xX1RYX1BFQUtfU0hJRlQ7DQo+PiAtCXdyaXRl bCh2YWwsIHRlZ3JhLT5zYXRhX3JlZ3MgKyBTQ0ZHX09GRlNFVCArDQo+PiAtCQlUX1NBVEEwX0NI WF9QSFlfQ1RSTDFfR0VOMik7DQo+PiAtDQo+PiAtCXdyaXRlbChUX1NBVEEwX0NIWF9QSFlfQ1RS TDExX0dFTjJfUlhfRVEsDQo+PiAtCQl0ZWdyYS0+c2F0YV9yZWdzICsgU0NGR19PRkZTRVQgKyBU X1NBVEEwX0NIWF9QSFlfQ1RSTDExKTsNCj4+IC0Jd3JpdGVsKFRfU0FUQTBfQ0hYX1BIWV9DVFJM Ml9DRFJfQ05UTF9HRU4xLA0KPj4gLQkJdGVncmEtPnNhdGFfcmVncyArIFNDRkdfT0ZGU0VUICsg VF9TQVRBMF9DSFhfUEhZX0NUUkwyKTsNCj4+IC0NCj4+IC0Jd3JpdGVsKDAsIHRlZ3JhLT5zYXRh X3JlZ3MgKyBTQ0ZHX09GRlNFVCArIFRfU0FUQTBfSU5ERVgpOw0KPj4gLQ0KPj4gLQkvKiBQcm9n cmFtIGNvbnRyb2xsZXIgZGV2aWNlIElEICovDQo+PiArCS8qIEVsZWN0cmljYWwgc2V0dGluZ3Mg Zm9yIGJldHRlciBsaW5rIHN0YWJpbGl0eSAqLw0KPj4gKwl2YWwgPSBUX1NBVEEwX0NIWF9QSFlf Q1RSTDE3XzBfUlhfRVFfQ1RSTF9MX0dFTjE7DQo+PiArCXdyaXRlbCh2YWwsIHRlZ3JhLT5zYXRh X3JlZ3MgKyBTQ0ZHX09GRlNFVCArDQo+VF9TQVRBMF9DSFhfUEhZX0NUUkwxN18wKTsNCj4+ICsJ dmFsID0gVF9TQVRBMF9DSFhfUEhZX0NUUkwxOF8wX1JYX0VRX0NUUkxfTF9HRU4yOw0KPj4gKwl3 cml0ZWwodmFsLCB0ZWdyYS0+c2F0YV9yZWdzICsgU0NGR19PRkZTRVQgKw0KPlRfU0FUQTBfQ0hY X1BIWV9DVFJMMThfMCk7DQo+PiArCXZhbCA9IFRfU0FUQTBfQ0hYX1BIWV9DVFJMMjBfMF9SWF9F UV9DVFJMX0hfR0VOMTsNCj4+ICsJd3JpdGVsKHZhbCwgdGVncmEtPnNhdGFfcmVncyArIFNDRkdf T0ZGU0VUICsNCj5UX1NBVEEwX0NIWF9QSFlfQ1RSTDIwXzApOw0KPj4gKwl2YWwgPSBUX1NBVEEw X0NIWF9QSFlfQ1RSTDIxXzBfUlhfRVFfQ1RSTF9IX0dFTjI7DQo+PiArCXdyaXRlbCh2YWwsIHRl Z3JhLT5zYXRhX3JlZ3MgKyBTQ0ZHX09GRlNFVCArDQo+PiArVF9TQVRBMF9DSFhfUEhZX0NUUkwy MV8wKTsNCj4+ICsNCj4+ICsJLyogRm9yIFNRVUVMQ0ggRmlsdGVyICYgR2VuMyBkcml2ZSBnZXR0 aW5nIGRldGVjdGVkIGFzIEdlbjEgZHJpdmUgKi8NCj4+ICsNCj4+ICsJdmFsID0gcmVhZGwodGVn cmEtPnNhdGFfcmVncyArIFNDRkdfT0ZGU0VUICsgVF9TQVRBX0NGR19QSFlfMCk7DQo+PiArCXZh bCB8PSBUX1NBVEFfQ0ZHX1BIWV8wX01BU0tfU1FVRUxDSDsNCj4+ICsJdmFsICY9IH5UX1NBVEFf Q0ZHX1BIWV8wX1VTRV83QklUX0FMSUdOX0RFVF9GT1JfU1BEOw0KPj4gKwl3cml0ZWwodmFsLCB0 ZWdyYS0+c2F0YV9yZWdzICsgU0NGR19PRkZTRVQgKyBUX1NBVEFfQ0ZHX1BIWV8wKTsNCj4+ICsN Cj4+ICsJdmFsID0gcmVhZGwodGVncmEtPnNhdGFfcmVncyArIFNDRkdfT0ZGU0VUICsgVF9TQVRB MF9OVk9PQik7DQo+PiArCXZhbCAmPSB+KFRfU0FUQTBfTlZPT0JfQ09NTUFfQ05UX01BU0sgfA0K Pj4gKwkJIFRfU0FUQTBfTlZPT0JfU1FVRUxDSF9GSUxURVJfTEVOR1RIX01BU0sgfA0KPj4gKwkJ IFRfU0FUQTBfTlZPT0JfU1FVRUxDSF9GSUxURVJfTU9ERV9NQVNLKTsNCj4+ICsJdmFsIHw9IChU X1NBVEEwX05WT09CX0NPTU1BX0NOVCB8DQo+PiArCQlUX1NBVEEwX05WT09CX1NRVUVMQ0hfRklM VEVSX0xFTkdUSCB8DQo+PiArCQlUX1NBVEEwX05WT09CX1NRVUVMQ0hfRklMVEVSX01PREUpOw0K Pj4gKwl3cml0ZWwodmFsLCB0ZWdyYS0+c2F0YV9yZWdzICsgU0NGR19PRkZTRVQgKyBUX1NBVEEw X05WT09CKTsNCj4+ICsNCj4+ICsJLyoNCj4+ICsJICogQ2hhbmdlIENGRzJOVk9PQl8yX0NPTVdB S0VfSURMRV9DTlRfTE9XIGZyb20gODMuMyBucyB0bw0KPjU4Ljhucw0KPj4gKwkgKi8NCj4+ICsJ dmFsID0gcmVhZGwodGVncmEtPnNhdGFfcmVncyArIFNDRkdfT0ZGU0VUICsgVF9TQVRBMF9DRkcy TlZPT0JfMik7DQo+PiArCXZhbCAmPSB+VF9TQVRBMF9DRkcyTlZPT0JfMl9DT01XQUtFX0lETEVf Q05UX0xPV19NQVNLOw0KPj4gKwl2YWwgfD0gVF9TQVRBMF9DRkcyTlZPT0JfMl9DT01XQUtFX0lE TEVfQ05UX0xPVzsNCj4+ICsJd3JpdGVsKHZhbCwgdGVncmEtPnNhdGFfcmVncyArIFNDRkdfT0ZG U0VUICsgVF9TQVRBMF9DRkcyTlZPT0JfMik7DQo+PiArDQo+PiArCWlmICh0ZWdyYS0+c29jX2Rh dGEtPm9wcy5pbml0KQ0KPj4gKwkJdGVncmEtPnNvY19kYXRhLT5vcHMuaW5pdChocHJpdik7DQo+ PiArDQo+PiArCS8qDQo+PiArCSAqIFByb2dyYW0gdGhlIGZvbGxvd2luZyBTQVRBIGNvbmZpZ3Vy YXRpb24gcmVnaXN0ZXJzDQo+PiArCSAqIHRvIGluaXRpYWxpemUgU0FUQQ0KPj4gKwkgKi8NCj4+ ICsJdmFsID0gcmVhZGwodGVncmEtPnNhdGFfcmVncyArIFNDRkdfT0ZGU0VUICsgVF9TQVRBMF9D RkdfMSk7DQo+PiArCXZhbCB8PSAoVF9TQVRBMF9DRkdfMV9JT19TUEFDRSB8IFRfU0FUQTBfQ0ZH XzFfTUVNT1JZX1NQQUNFIHwNCj4+ICsJCVRfU0FUQTBfQ0ZHXzFfQlVTX01BU1RFUiB8IFRfU0FU QTBfQ0ZHXzFfU0VSUik7DQo+PiArCXdyaXRlbCh2YWwsIHRlZ3JhLT5zYXRhX3JlZ3MgKyBTQ0ZH X09GRlNFVCArIFRfU0FUQTBfQ0ZHXzEpOw0KPj4gKwl2YWwgPSBUX1NBVEEwX0NGR185X0JBU0Vf QUREUkVTUzsNCj4+ICsJd3JpdGVsKHZhbCwgdGVncmEtPnNhdGFfcmVncyArIFNDRkdfT0ZGU0VU ICsgVF9TQVRBMF9DRkdfOSk7DQo+Pg0KPj4gKwkvKiBQcm9ncmFtIENsYXNzIENvZGUgYW5kIFBy b2dyYW1taW5nIGludGVyZmFjZSBmb3IgU0FUQSAqLw0KPj4gICAJdmFsID0gcmVhZGwodGVncmEt PnNhdGFfcmVncyArIFNDRkdfT0ZGU0VUICsgVF9TQVRBMF9DRkdfU0FUQSk7DQo+PiAgIAl2YWwg fD0gVF9TQVRBMF9DRkdfU0FUQV9CQUNLRE9PUl9QUk9HX0lGX0VOOw0KPj4gICAJd3JpdGVsKHZh bCwgdGVncmEtPnNhdGFfcmVncyArIFNDRkdfT0ZGU0VUICsgVF9TQVRBMF9DRkdfU0FUQSk7DQo+ Pg0KPj4gLQl3cml0ZWwoMHgwMTA2MDEwMCwgdGVncmEtPnNhdGFfcmVncyArIFNDRkdfT0ZGU0VU ICsNCj5UX1NBVEEwX0JLRE9PUl9DQyk7DQo+PiArCXZhbCA9IHJlYWRsKHRlZ3JhLT5zYXRhX3Jl Z3MgKyBTQ0ZHX09GRlNFVCArIFRfU0FUQTBfQktET09SX0NDKTsNCj4+ICsJdmFsICY9DQo+PiAr CSAgICB+KFRfU0FUQTBfQktET09SX0NDX0NMQVNTX0NPREVfTUFTSyB8DQo+PiArCSAgICAgIFRf U0FUQTBfQktET09SX0NDX1BST0dfSUZfTUFTSyk7DQo+PiArCXZhbCB8PSBUX1NBVEEwX0JLRE9P Ul9DQ19DTEFTU19DT0RFIHwNCj5UX1NBVEEwX0JLRE9PUl9DQ19QUk9HX0lGOw0KPj4gKwl3cml0 ZWwodmFsLCB0ZWdyYS0+c2F0YV9yZWdzICsgU0NGR19PRkZTRVQgKyBUX1NBVEEwX0JLRE9PUl9D Qyk7DQo+Pg0KPj4gICAJdmFsID0gcmVhZGwodGVncmEtPnNhdGFfcmVncyArIFNDRkdfT0ZGU0VU ICsgVF9TQVRBMF9DRkdfU0FUQSk7DQo+PiAgIAl2YWwgJj0gflRfU0FUQTBfQ0ZHX1NBVEFfQkFD S0RPT1JfUFJPR19JRl9FTjsNCj4+ICAgCXdyaXRlbCh2YWwsIHRlZ3JhLT5zYXRhX3JlZ3MgKyBT Q0ZHX09GRlNFVCArIFRfU0FUQTBfQ0ZHX1NBVEEpOw0KPj4NCj4+IC0JLyogRW5hYmxlIElPICYg bWVtb3J5IGFjY2VzcywgYnVzIG1hc3RlciBtb2RlICovDQo+PiAtDQo+PiAtCXZhbCA9IHJlYWRs KHRlZ3JhLT5zYXRhX3JlZ3MgKyBTQ0ZHX09GRlNFVCArIFRfU0FUQTBfQ0ZHXzEpOw0KPj4gLQl2 YWwgfD0gVF9TQVRBMF9DRkdfMV9JT19TUEFDRSB8IFRfU0FUQTBfQ0ZHXzFfTUVNT1JZX1NQQUNF IHwNCj4+IC0JCVRfU0FUQTBfQ0ZHXzFfQlVTX01BU1RFUiB8IFRfU0FUQTBfQ0ZHXzFfU0VSUjsN Cj4+IC0Jd3JpdGVsKHZhbCwgdGVncmEtPnNhdGFfcmVncyArIFNDRkdfT0ZGU0VUICsgVF9TQVRB MF9DRkdfMSk7DQo+PiAtDQo+PiAtCS8qIFByb2dyYW0gU0FUQSBNTUlPICovDQo+PiAtDQo+PiAt CXdyaXRlbCgweDEwMDAwIDw8IFNBVEFfRlBDSV9CQVI1X1NUQVJUX1NISUZULA0KPj4gLQkgICAg ICAgdGVncmEtPnNhdGFfcmVncyArIFNBVEFfRlBDSV9CQVI1KTsNCj4+ICsJLyogRW5hYmxpbmcg TFBNIGNhcGFiaWxpdGllcyB0aHJvdWdoIEJhY2tkb29yIFByb2dyYW1taW5nICovDQo+PiArCXZh bCA9IHJlYWRsKHRlZ3JhLT5zYXRhX3JlZ3MgKyBTQ0ZHX09GRlNFVCArDQo+VF9TQVRBMF9BSENJ X0hCQV9DQVBfQktEUik7DQo+PiArCXZhbCB8PSAoVF9TQVRBMF9BSENJX0hCQV9DQVBfQktEUl9Q QVJUSUFMX1NUX0NBUCB8DQo+PiArCQlUX1NBVEEwX0FIQ0lfSEJBX0NBUF9CS0RSX1NMVU1CRVJf U1RfQ0FQIHwNCj4+ICsJCVRfU0FUQTBfQUhDSV9IQkFfQ0FQX0JLRFJfU0FMUCB8DQo+PiArCQlU X1NBVEEwX0FIQ0lfSEJBX0NBUF9CS0RSX1NVUFBfUE0pOw0KPj4gKwl3cml0ZWwodmFsLCB0ZWdy YS0+c2F0YV9yZWdzICsgU0NGR19PRkZTRVQgKw0KPj4gK1RfU0FUQTBfQUhDSV9IQkFfQ0FQX0JL RFIpOw0KPj4gKw0KPj4gKwkvKiBTQVRBIFNlY29uZCBMZXZlbCBDbG9jayBHYXRpbmcgY29uZmln dXJhdGlvbg0KPj4gKwkgKiBFbmFibGluZyBHYXRpbmcgb2YgVHgvUnggY2xvY2tzIGFuZCBkcml2 aW5nIFBhZCBJRERRIGFuZCBMYW5lDQo+PiArCSAqIElERFEgU2lnbmFscw0KPj4gKwkgKi8NCj4+ ICsJdmFsID0gcmVhZGwodGVncmEtPnNhdGFfcmVncyArIFNDRkdfT0ZGU0VUICsgVF9TQVRBMF9D RkdfMzUpOw0KPj4gKwl2YWwgJj0gflRfU0FUQTBfQ0ZHXzM1X0lEUF9JTkRFWF9NQVNLOw0KPj4g Kwl2YWwgfD0gVF9TQVRBMF9DRkdfMzVfSURQX0lOREVYOw0KPj4gKwl3cml0ZWwodmFsLCB0ZWdy YS0+c2F0YV9yZWdzICsgU0NGR19PRkZTRVQgKyBUX1NBVEEwX0NGR18zNSk7DQo+PiArDQo+PiAr CXZhbCA9IFRfU0FUQTBfQUhDSV9JRFAxX0RBVEE7DQo+PiArCXdyaXRlbCh2YWwsIHRlZ3JhLT5z YXRhX3JlZ3MgKyBTQ0ZHX09GRlNFVCArIFRfU0FUQTBfQUhDSV9JRFAxKTsNCj4+ICsNCj4+ICsJ dmFsID0gcmVhZGwodGVncmEtPnNhdGFfcmVncyArIFNDRkdfT0ZGU0VUICsgVF9TQVRBMF9DRkdf UEhZXzEpOw0KPj4gKwl2YWwgfD0gKFRfU0FUQTBfQ0ZHX1BIWV8xX1BBRFNfSUREUV9FTiB8DQo+ PiArCQlUX1NBVEEwX0NGR19QSFlfMV9QQURfUExMX0lERFFfRU4pOw0KPj4gKwl3cml0ZWwodmFs LCB0ZWdyYS0+c2F0YV9yZWdzICsgU0NGR19PRkZTRVQgKyBUX1NBVEEwX0NGR19QSFlfMSk7DQo+ PiArDQo+PiArCS8qIEVuYWJsaW5nIElQRlMgQ2xvY2sgR2F0aW5nICovDQo+PiArCXZhbCA9IHJl YWRsKHRlZ3JhLT5zYXRhX3JlZ3MgKyBTQVRBX0NPTkZJR1VSQVRJT05fMCk7DQo+PiArCXZhbCAm PSB+U0FUQV9DT05GSUdVUkFUSU9OXzBfQ0xLX09WRVJSSURFOw0KPj4gKwl3cml0ZWwodmFsLCB0 ZWdyYS0+c2F0YV9yZWdzICsgU0FUQV9DT05GSUdVUkFUSU9OXzApOw0KPj4NCj4+IC0Jd3JpdGVs KDB4MDgwMDAgPDwgVF9TQVRBMF9DRkdfOV9CQVNFX0FERFJFU1NfU0hJRlQsDQo+PiAtCSAgICAg ICB0ZWdyYS0+c2F0YV9yZWdzICsgU0NGR19PRkZTRVQgKyBUX1NBVEEwX0NGR185KTsNCj4+DQo+ PiAgIAkvKiBVbm1hc2sgU0FUQSBpbnRlcnJ1cHRzICovDQo+Pg0KPj4gQEAgLTI4Niw3ICs0Mzks MTAgQEAgc3RhdGljIGNvbnN0IHN0cnVjdCBhdGFfcG9ydF9pbmZvIGFoY2lfdGVncmFfcG9ydF9p bmZvDQo+PSB7DQo+PiAgIH07DQo+Pg0KPj4gICBzdGF0aWMgY29uc3Qgc3RydWN0IG9mX2Rldmlj ZV9pZCB0ZWdyYV9haGNpX29mX21hdGNoW10gPSB7DQo+PiAtCXsgLmNvbXBhdGlibGUgPSAibnZp ZGlhLHRlZ3JhMTI0LWFoY2kiIH0sDQo+PiArCXsNCj4+ICsJCS5jb21wYXRpYmxlID0gIm52aWRp YSx0ZWdyYTEyNC1haGNpIiwNCj4+ICsJCS5kYXRhID0gJnRlZ3JhMTI0X2FoY2lfc29jX2RhdGEN Cj4+ICsJfSwNCj4+ICAgCXt9DQo+PiAgIH07DQo+PiAgIE1PRFVMRV9ERVZJQ0VfVEFCTEUob2Ys IHRlZ3JhX2FoY2lfb2ZfbWF0Y2gpOyBAQCAtMzAxLDYgKzQ1Nyw3IEBADQo+PiBzdGF0aWMgaW50 IHRlZ3JhX2FoY2lfcHJvYmUoc3RydWN0IHBsYXRmb3JtX2RldmljZSAqcGRldikNCj4+ICAgCXN0 cnVjdCB0ZWdyYV9haGNpX3ByaXYgKnRlZ3JhOw0KPj4gICAJc3RydWN0IHJlc291cmNlICpyZXM7 DQo+PiAgIAlpbnQgcmV0Ow0KPj4gKwl1bnNpZ25lZCBpbnQgaTsNCj4NCj5UaGlzIHZhcmlhYmxl IGRvZXNuJ3Qgc2VlbSB0byBiZSB1c2VkIGhlcmUuDQo+DQpUaGlzIHZhcmlhYmxlIHNob3VsZCBi ZSBwYXJ0IG9mIHRoZSByZWd1bGF0b3IgcGF0Y2guIFdpbGwgY29ycmVjdCBpdA0KPj4NCj4+ICAg CWhwcml2ID0gYWhjaV9wbGF0Zm9ybV9nZXRfcmVzb3VyY2VzKHBkZXYpOw0KPj4gICAJaWYgKElT X0VSUihocHJpdikpDQo+PiBAQCAtMzEzLDYgKzQ3MCw4IEBAIHN0YXRpYyBpbnQgdGVncmFfYWhj aV9wcm9iZShzdHJ1Y3QgcGxhdGZvcm1fZGV2aWNlDQo+KnBkZXYpDQo+PiAgIAlocHJpdi0+cGxh dF9kYXRhID0gdGVncmE7DQo+Pg0KPj4gICAJdGVncmEtPnBkZXYgPSBwZGV2Ow0KPj4gKwl0ZWdy YS0+c29jX2RhdGEgPQ0KPj4gKwkgICAgKHN0cnVjdCB0ZWdyYV9haGNpX3NvYyAqKW9mX2Rldmlj ZV9nZXRfbWF0Y2hfZGF0YSgmcGRldi0+ZGV2KTsNCj4+DQo+PiAgIAlyZXMgPSBwbGF0Zm9ybV9n ZXRfcmVzb3VyY2UocGRldiwgSU9SRVNPVVJDRV9NRU0sIDEpOw0KPj4gICAJdGVncmEtPnNhdGFf cmVncyA9IGRldm1faW9yZW1hcF9yZXNvdXJjZSgmcGRldi0+ZGV2LCByZXMpOw0KPj4NCj4NCj5P dGhlcndpc2UgbG9va3MgZ29vZCB0byBtZS4NCj4NCj5NaWtrbw0K -- To unsubscribe from this list: send the line "unsubscribe linux-ide" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
diff --git a/drivers/ata/ahci_tegra.c b/drivers/ata/ahci_tegra.c index 3a62eb246d80..71850e96e787 100644 --- a/drivers/ata/ahci_tegra.c +++ b/drivers/ata/ahci_tegra.c @@ -34,7 +34,8 @@ #define DRV_NAME "tegra-ahci" #define SATA_CONFIGURATION_0 0x180 -#define SATA_CONFIGURATION_EN_FPCI BIT(0) +#define SATA_CONFIGURATION_0_EN_FPCI BIT(0) +#define SATA_CONFIGURATION_0_CLK_OVERRIDE BIT(31) #define SCFG_OFFSET 0x1000 @@ -45,17 +46,55 @@ #define T_SATA0_CFG_1_SERR BIT(8) #define T_SATA0_CFG_9 0x24 -#define T_SATA0_CFG_9_BASE_ADDRESS_SHIFT 13 +#define T_SATA0_CFG_9_BASE_ADDRESS 0x40020000 #define SATA_FPCI_BAR5 0x94 -#define SATA_FPCI_BAR5_START_SHIFT 4 +#define SATA_FPCI_BAR5_START_MASK (0xfffffff << 4) +#define SATA_FPCI_BAR5_START (0x0040020 << 4) +#define SATA_FPCI_BAR5_ACCESS_TYPE (0x1) #define SATA_INTR_MASK 0x188 #define SATA_INTR_MASK_IP_INT_MASK BIT(16) +#define T_SATA0_CFG_35 0x94 +#define T_SATA0_CFG_35_IDP_INDEX_MASK (0x7ff << 2) +#define T_SATA0_CFG_35_IDP_INDEX (0x2a << 2) + +#define T_SATA0_AHCI_IDP1 0x98 +#define T_SATA0_AHCI_IDP1_DATA (0x400040) + +#define T_SATA0_CFG_PHY_1 0x12c +#define T_SATA0_CFG_PHY_1_PADS_IDDQ_EN BIT(23) +#define T_SATA0_CFG_PHY_1_PAD_PLL_IDDQ_EN BIT(22) + +#define T_SATA0_NVOOB 0x114 +#define T_SATA0_NVOOB_COMMA_CNT_MASK (0xff << 16) +#define T_SATA0_NVOOB_COMMA_CNT (0x07 << 16) +#define T_SATA0_NVOOB_SQUELCH_FILTER_MODE_MASK (0x3 << 24) +#define T_SATA0_NVOOB_SQUELCH_FILTER_MODE (0x1 << 24) +#define T_SATA0_NVOOB_SQUELCH_FILTER_LENGTH_MASK (0x3 << 26) +#define T_SATA0_NVOOB_SQUELCH_FILTER_LENGTH (0x3 << 26) + +#define T_SATA_CFG_PHY_0 0x120 +#define T_SATA_CFG_PHY_0_USE_7BIT_ALIGN_DET_FOR_SPD BIT(11) +#define T_SATA_CFG_PHY_0_MASK_SQUELCH BIT(24) + +#define T_SATA0_CFG2NVOOB_2 0x134 +#define T_SATA0_CFG2NVOOB_2_COMWAKE_IDLE_CNT_LOW_MASK (0x1ff << 18) +#define T_SATA0_CFG2NVOOB_2_COMWAKE_IDLE_CNT_LOW (0xc << 18) + #define T_SATA0_AHCI_HBA_CAP_BKDR 0x300 +#define T_SATA0_AHCI_HBA_CAP_BKDR_PARTIAL_ST_CAP BIT(13) +#define T_SATA0_AHCI_HBA_CAP_BKDR_SLUMBER_ST_CAP BIT(14) +#define T_SATA0_AHCI_HBA_CAP_BKDR_SALP BIT(26) +#define T_SATA0_AHCI_HBA_CAP_BKDR_SUPP_PM BIT(17) +#define T_SATA0_AHCI_HBA_CAP_BKDR_SNCQ BIT(30) #define T_SATA0_BKDOOR_CC 0x4a4 +#define T_SATA0_BKDOOR_CC_CLASS_CODE_MASK (0xffff << 16) +#define T_SATA0_BKDOOR_CC_CLASS_CODE (0x0106 << 16) +#define T_SATA0_BKDOOR_CC_PROG_IF_MASK (0xff << 8) +#define T_SATA0_BKDOOR_CC_PROG_IF (0x01 << 8) #define T_SATA0_CFG_SATA 0x54c #define T_SATA0_CFG_SATA_BACKDOOR_PROG_IF_EN BIT(12) @@ -82,6 +121,27 @@ #define T_SATA0_CHX_PHY_CTRL11 0x6d0 #define T_SATA0_CHX_PHY_CTRL11_GEN2_RX_EQ (0x2800 << 16) +#define T_SATA0_CHX_PHY_CTRL17_0 0x6e8 +#define T_SATA0_CHX_PHY_CTRL17_0_RX_EQ_CTRL_L_GEN1 0x55010000 +#define T_SATA0_CHX_PHY_CTRL18_0 0x6ec +#define T_SATA0_CHX_PHY_CTRL18_0_RX_EQ_CTRL_L_GEN2 0x55010000 +#define T_SATA0_CHX_PHY_CTRL20_0 0x6f4 +#define T_SATA0_CHX_PHY_CTRL20_0_RX_EQ_CTRL_H_GEN1 0x1 +#define T_SATA0_CHX_PHY_CTRL21_0 0x6f8 +#define T_SATA0_CHX_PHY_CTRL21_0_RX_EQ_CTRL_H_GEN2 0x1 + +/* AUX Registers */ +#define SATA_AUX_MISC_CNTL_1_0 0x8 +#define SATA_AUX_MISC_CNTL_1_0_DEVSLP_OVERRIDE BIT(17) +#define SATA_AUX_MISC_CNTL_1_0_SDS_SUPPORT BIT(13) +#define SATA_AUX_MISC_CNTL_1_0_DESO_SUPPORT BIT(15) + +#define SATA_AUX_RX_STAT_INT_0 0xc +#define SATA_AUX_RX_STAT_INT_0_SATA_DEVSLP BIT(7) + +#define SATA_AUX_SPARE_CFG0_0 0x18 +#define SATA_AUX_SPARE_CFG0_0_MDAT_TIMER_AFTER_PG_VALID BIT(14) + #define FUSE_SATA_CALIB 0x124 #define FUSE_SATA_CALIB_MASK 0x3 @@ -99,6 +159,14 @@ static const struct sata_pad_calibration tegra124_pad_calibration[] = { {0x14, 0x0e, 0x1a, 0x0e}, }; +struct tegra_ahci_ops { + int (*init)(struct ahci_host_priv *hpriv); +}; + +struct tegra_ahci_soc { + struct tegra_ahci_ops ops; +}; + struct tegra_ahci_priv { struct platform_device *pdev; void __iomem *sata_regs; @@ -108,6 +176,57 @@ struct tegra_ahci_priv { /* Needs special handling, cannot use ahci_platform */ struct clk *sata_clk; struct regulator_bulk_data supplies[5]; + struct tegra_ahci_soc *soc_data; +}; + +static int tegra124_ahci_init(struct ahci_host_priv *hpriv) +{ + struct tegra_ahci_priv *tegra = hpriv->plat_data; + struct sata_pad_calibration calib; + int ret; + u32 val; + + /* Pad calibration */ + ret = tegra_fuse_readl(FUSE_SATA_CALIB, &val); + if (ret) + return ret; + + calib = tegra124_pad_calibration[val & FUSE_SATA_CALIB_MASK]; + + writel(BIT(0), tegra->sata_regs + SCFG_OFFSET + T_SATA0_INDEX); + + val = readl(tegra->sata_regs + + SCFG_OFFSET + T_SATA0_CHX_PHY_CTRL1_GEN1); + val &= ~T_SATA0_CHX_PHY_CTRL1_GEN1_TX_AMP_MASK; + val &= ~T_SATA0_CHX_PHY_CTRL1_GEN1_TX_PEAK_MASK; + val |= calib.gen1_tx_amp << T_SATA0_CHX_PHY_CTRL1_GEN1_TX_AMP_SHIFT; + val |= calib.gen1_tx_peak << T_SATA0_CHX_PHY_CTRL1_GEN1_TX_PEAK_SHIFT; + writel(val, tegra->sata_regs + SCFG_OFFSET + + T_SATA0_CHX_PHY_CTRL1_GEN1); + + val = readl(tegra->sata_regs + + SCFG_OFFSET + T_SATA0_CHX_PHY_CTRL1_GEN2); + val &= ~T_SATA0_CHX_PHY_CTRL1_GEN2_TX_AMP_MASK; + val &= ~T_SATA0_CHX_PHY_CTRL1_GEN2_TX_PEAK_MASK; + val |= calib.gen2_tx_amp << T_SATA0_CHX_PHY_CTRL1_GEN1_TX_AMP_SHIFT; + val |= calib.gen2_tx_peak << T_SATA0_CHX_PHY_CTRL1_GEN1_TX_PEAK_SHIFT; + writel(val, tegra->sata_regs + SCFG_OFFSET + + T_SATA0_CHX_PHY_CTRL1_GEN2); + + writel(T_SATA0_CHX_PHY_CTRL11_GEN2_RX_EQ, + tegra->sata_regs + SCFG_OFFSET + T_SATA0_CHX_PHY_CTRL11); + writel(T_SATA0_CHX_PHY_CTRL2_CDR_CNTL_GEN1, + tegra->sata_regs + SCFG_OFFSET + T_SATA0_CHX_PHY_CTRL2); + + writel(0, tegra->sata_regs + SCFG_OFFSET + T_SATA0_INDEX); + + return 0; +} + +static const struct tegra_ahci_soc tegra124_ahci_soc_data = { + .ops = { + .init = tegra124_ahci_init, + }, }; static int tegra_ahci_power_on(struct ahci_host_priv *hpriv) @@ -145,7 +264,6 @@ static int tegra_ahci_power_on(struct ahci_host_priv *hpriv) disable_regulators: regulator_bulk_disable(ARRAY_SIZE(tegra->supplies), tegra->supplies); - return ret; } @@ -169,8 +287,7 @@ static int tegra_ahci_controller_init(struct ahci_host_priv *hpriv) { struct tegra_ahci_priv *tegra = hpriv->plat_data; int ret; - unsigned int val; - struct sata_pad_calibration calib; + u32 val; ret = tegra_ahci_power_on(hpriv); if (ret) { @@ -179,78 +296,114 @@ static int tegra_ahci_controller_init(struct ahci_host_priv *hpriv) return ret; } + /* + * Program the following SATA IPFS registers + * to allow SW accesses to SATA's MMIO register range. + */ + val = readl(tegra->sata_regs + SATA_FPCI_BAR5); + val &= ~(SATA_FPCI_BAR5_START_MASK | SATA_FPCI_BAR5_ACCESS_TYPE); + val |= SATA_FPCI_BAR5_START | SATA_FPCI_BAR5_ACCESS_TYPE; + writel(val, tegra->sata_regs + SATA_FPCI_BAR5); + + /* Program the following SATA IPFS register to enable the SATA */ val = readl(tegra->sata_regs + SATA_CONFIGURATION_0); - val |= SATA_CONFIGURATION_EN_FPCI; + val |= SATA_CONFIGURATION_0_EN_FPCI; writel(val, tegra->sata_regs + SATA_CONFIGURATION_0); - /* Pad calibration */ - - ret = tegra_fuse_readl(FUSE_SATA_CALIB, &val); - if (ret) { - dev_err(&tegra->pdev->dev, - "failed to read calibration fuse: %d\n", ret); - return ret; - } - - calib = tegra124_pad_calibration[val & FUSE_SATA_CALIB_MASK]; - - writel(BIT(0), tegra->sata_regs + SCFG_OFFSET + T_SATA0_INDEX); - - val = readl(tegra->sata_regs + - SCFG_OFFSET + T_SATA0_CHX_PHY_CTRL1_GEN1); - val &= ~T_SATA0_CHX_PHY_CTRL1_GEN1_TX_AMP_MASK; - val &= ~T_SATA0_CHX_PHY_CTRL1_GEN1_TX_PEAK_MASK; - val |= calib.gen1_tx_amp << - T_SATA0_CHX_PHY_CTRL1_GEN1_TX_AMP_SHIFT; - val |= calib.gen1_tx_peak << - T_SATA0_CHX_PHY_CTRL1_GEN1_TX_PEAK_SHIFT; - writel(val, tegra->sata_regs + SCFG_OFFSET + - T_SATA0_CHX_PHY_CTRL1_GEN1); - - val = readl(tegra->sata_regs + - SCFG_OFFSET + T_SATA0_CHX_PHY_CTRL1_GEN2); - val &= ~T_SATA0_CHX_PHY_CTRL1_GEN2_TX_AMP_MASK; - val &= ~T_SATA0_CHX_PHY_CTRL1_GEN2_TX_PEAK_MASK; - val |= calib.gen2_tx_amp << - T_SATA0_CHX_PHY_CTRL1_GEN1_TX_AMP_SHIFT; - val |= calib.gen2_tx_peak << - T_SATA0_CHX_PHY_CTRL1_GEN1_TX_PEAK_SHIFT; - writel(val, tegra->sata_regs + SCFG_OFFSET + - T_SATA0_CHX_PHY_CTRL1_GEN2); - - writel(T_SATA0_CHX_PHY_CTRL11_GEN2_RX_EQ, - tegra->sata_regs + SCFG_OFFSET + T_SATA0_CHX_PHY_CTRL11); - writel(T_SATA0_CHX_PHY_CTRL2_CDR_CNTL_GEN1, - tegra->sata_regs + SCFG_OFFSET + T_SATA0_CHX_PHY_CTRL2); - - writel(0, tegra->sata_regs + SCFG_OFFSET + T_SATA0_INDEX); - - /* Program controller device ID */ + /* Electrical settings for better link stability */ + val = T_SATA0_CHX_PHY_CTRL17_0_RX_EQ_CTRL_L_GEN1; + writel(val, tegra->sata_regs + SCFG_OFFSET + T_SATA0_CHX_PHY_CTRL17_0); + val = T_SATA0_CHX_PHY_CTRL18_0_RX_EQ_CTRL_L_GEN2; + writel(val, tegra->sata_regs + SCFG_OFFSET + T_SATA0_CHX_PHY_CTRL18_0); + val = T_SATA0_CHX_PHY_CTRL20_0_RX_EQ_CTRL_H_GEN1; + writel(val, tegra->sata_regs + SCFG_OFFSET + T_SATA0_CHX_PHY_CTRL20_0); + val = T_SATA0_CHX_PHY_CTRL21_0_RX_EQ_CTRL_H_GEN2; + writel(val, tegra->sata_regs + SCFG_OFFSET + T_SATA0_CHX_PHY_CTRL21_0); + + /* For SQUELCH Filter & Gen3 drive getting detected as Gen1 drive */ + + val = readl(tegra->sata_regs + SCFG_OFFSET + T_SATA_CFG_PHY_0); + val |= T_SATA_CFG_PHY_0_MASK_SQUELCH; + val &= ~T_SATA_CFG_PHY_0_USE_7BIT_ALIGN_DET_FOR_SPD; + writel(val, tegra->sata_regs + SCFG_OFFSET + T_SATA_CFG_PHY_0); + + val = readl(tegra->sata_regs + SCFG_OFFSET + T_SATA0_NVOOB); + val &= ~(T_SATA0_NVOOB_COMMA_CNT_MASK | + T_SATA0_NVOOB_SQUELCH_FILTER_LENGTH_MASK | + T_SATA0_NVOOB_SQUELCH_FILTER_MODE_MASK); + val |= (T_SATA0_NVOOB_COMMA_CNT | + T_SATA0_NVOOB_SQUELCH_FILTER_LENGTH | + T_SATA0_NVOOB_SQUELCH_FILTER_MODE); + writel(val, tegra->sata_regs + SCFG_OFFSET + T_SATA0_NVOOB); + + /* + * Change CFG2NVOOB_2_COMWAKE_IDLE_CNT_LOW from 83.3 ns to 58.8ns + */ + val = readl(tegra->sata_regs + SCFG_OFFSET + T_SATA0_CFG2NVOOB_2); + val &= ~T_SATA0_CFG2NVOOB_2_COMWAKE_IDLE_CNT_LOW_MASK; + val |= T_SATA0_CFG2NVOOB_2_COMWAKE_IDLE_CNT_LOW; + writel(val, tegra->sata_regs + SCFG_OFFSET + T_SATA0_CFG2NVOOB_2); + + if (tegra->soc_data->ops.init) + tegra->soc_data->ops.init(hpriv); + + /* + * Program the following SATA configuration registers + * to initialize SATA + */ + val = readl(tegra->sata_regs + SCFG_OFFSET + T_SATA0_CFG_1); + val |= (T_SATA0_CFG_1_IO_SPACE | T_SATA0_CFG_1_MEMORY_SPACE | + T_SATA0_CFG_1_BUS_MASTER | T_SATA0_CFG_1_SERR); + writel(val, tegra->sata_regs + SCFG_OFFSET + T_SATA0_CFG_1); + val = T_SATA0_CFG_9_BASE_ADDRESS; + writel(val, tegra->sata_regs + SCFG_OFFSET + T_SATA0_CFG_9); + /* Program Class Code and Programming interface for SATA */ val = readl(tegra->sata_regs + SCFG_OFFSET + T_SATA0_CFG_SATA); val |= T_SATA0_CFG_SATA_BACKDOOR_PROG_IF_EN; writel(val, tegra->sata_regs + SCFG_OFFSET + T_SATA0_CFG_SATA); - writel(0x01060100, tegra->sata_regs + SCFG_OFFSET + T_SATA0_BKDOOR_CC); + val = readl(tegra->sata_regs + SCFG_OFFSET + T_SATA0_BKDOOR_CC); + val &= + ~(T_SATA0_BKDOOR_CC_CLASS_CODE_MASK | + T_SATA0_BKDOOR_CC_PROG_IF_MASK); + val |= T_SATA0_BKDOOR_CC_CLASS_CODE | T_SATA0_BKDOOR_CC_PROG_IF; + writel(val, tegra->sata_regs + SCFG_OFFSET + T_SATA0_BKDOOR_CC); val = readl(tegra->sata_regs + SCFG_OFFSET + T_SATA0_CFG_SATA); val &= ~T_SATA0_CFG_SATA_BACKDOOR_PROG_IF_EN; writel(val, tegra->sata_regs + SCFG_OFFSET + T_SATA0_CFG_SATA); - /* Enable IO & memory access, bus master mode */ - - val = readl(tegra->sata_regs + SCFG_OFFSET + T_SATA0_CFG_1); - val |= T_SATA0_CFG_1_IO_SPACE | T_SATA0_CFG_1_MEMORY_SPACE | - T_SATA0_CFG_1_BUS_MASTER | T_SATA0_CFG_1_SERR; - writel(val, tegra->sata_regs + SCFG_OFFSET + T_SATA0_CFG_1); - - /* Program SATA MMIO */ - - writel(0x10000 << SATA_FPCI_BAR5_START_SHIFT, - tegra->sata_regs + SATA_FPCI_BAR5); + /* Enabling LPM capabilities through Backdoor Programming */ + val = readl(tegra->sata_regs + SCFG_OFFSET + T_SATA0_AHCI_HBA_CAP_BKDR); + val |= (T_SATA0_AHCI_HBA_CAP_BKDR_PARTIAL_ST_CAP | + T_SATA0_AHCI_HBA_CAP_BKDR_SLUMBER_ST_CAP | + T_SATA0_AHCI_HBA_CAP_BKDR_SALP | + T_SATA0_AHCI_HBA_CAP_BKDR_SUPP_PM); + writel(val, tegra->sata_regs + SCFG_OFFSET + T_SATA0_AHCI_HBA_CAP_BKDR); + + /* SATA Second Level Clock Gating configuration + * Enabling Gating of Tx/Rx clocks and driving Pad IDDQ and Lane + * IDDQ Signals + */ + val = readl(tegra->sata_regs + SCFG_OFFSET + T_SATA0_CFG_35); + val &= ~T_SATA0_CFG_35_IDP_INDEX_MASK; + val |= T_SATA0_CFG_35_IDP_INDEX; + writel(val, tegra->sata_regs + SCFG_OFFSET + T_SATA0_CFG_35); + + val = T_SATA0_AHCI_IDP1_DATA; + writel(val, tegra->sata_regs + SCFG_OFFSET + T_SATA0_AHCI_IDP1); + + val = readl(tegra->sata_regs + SCFG_OFFSET + T_SATA0_CFG_PHY_1); + val |= (T_SATA0_CFG_PHY_1_PADS_IDDQ_EN | + T_SATA0_CFG_PHY_1_PAD_PLL_IDDQ_EN); + writel(val, tegra->sata_regs + SCFG_OFFSET + T_SATA0_CFG_PHY_1); + + /* Enabling IPFS Clock Gating */ + val = readl(tegra->sata_regs + SATA_CONFIGURATION_0); + val &= ~SATA_CONFIGURATION_0_CLK_OVERRIDE; + writel(val, tegra->sata_regs + SATA_CONFIGURATION_0); - writel(0x08000 << T_SATA0_CFG_9_BASE_ADDRESS_SHIFT, - tegra->sata_regs + SCFG_OFFSET + T_SATA0_CFG_9); /* Unmask SATA interrupts */ @@ -286,7 +439,10 @@ static const struct ata_port_info ahci_tegra_port_info = { }; static const struct of_device_id tegra_ahci_of_match[] = { - { .compatible = "nvidia,tegra124-ahci" }, + { + .compatible = "nvidia,tegra124-ahci", + .data = &tegra124_ahci_soc_data + }, {} }; MODULE_DEVICE_TABLE(of, tegra_ahci_of_match); @@ -301,6 +457,7 @@ static int tegra_ahci_probe(struct platform_device *pdev) struct tegra_ahci_priv *tegra; struct resource *res; int ret; + unsigned int i; hpriv = ahci_platform_get_resources(pdev); if (IS_ERR(hpriv)) @@ -313,6 +470,8 @@ static int tegra_ahci_probe(struct platform_device *pdev) hpriv->plat_data = tegra; tegra->pdev = pdev; + tegra->soc_data = + (struct tegra_ahci_soc *)of_device_get_match_data(&pdev->dev); res = platform_get_resource(pdev, IORESOURCE_MEM, 1); tegra->sata_regs = devm_ioremap_resource(&pdev->dev, res);