mac80211 ath9k: force QCA953x clock to 25MHz
The QCA953x only supports 25 MHz refclk, however some OEMs set an invalid bootstrap value for the REF_CLK option, which would break the clock detection in ath9k. Force the QCA953x refclk to 25MHz in ath9k, as this is (according to the datasheet) the only valid frequency. Signed-off-by: David Bauer <mail@david-bauer.net>
This commit is contained in:
		| @@ -16,7 +16,7 @@ | |||||||
|   |   | ||||||
|  static const struct platform_device_id ath9k_platform_id_table[] = { |  static const struct platform_device_id ath9k_platform_id_table[] = { | ||||||
|  	{ |  	{ | ||||||
| @@ -69,6 +77,235 @@ static const struct ath_bus_ops ath_ahb_ | @@ -69,6 +77,242 @@ static const struct ath_bus_ops ath_ahb_ | ||||||
|  	.eeprom_read = ath_ahb_eeprom_read, |  	.eeprom_read = ath_ahb_eeprom_read, | ||||||
|  }; |  }; | ||||||
|   |   | ||||||
| @@ -232,7 +232,14 @@ | |||||||
| +		pdata->external_reset = data->wmac_reset; | +		pdata->external_reset = data->wmac_reset; | ||||||
| +	} | +	} | ||||||
| + | + | ||||||
| +	if (data->bootstrap_reg && data->bootstrap_ref) { | +	if (data->dev_id == AR9300_DEVID_AR953X) { | ||||||
|  | +		/* | ||||||
|  | +		 * QCA953x only supports 25MHz refclk. | ||||||
|  | +		 * Some vendors have an invalid bootstrap option | ||||||
|  | +		 * set, which would break the WMAC here. | ||||||
|  | +		 */ | ||||||
|  | +		pdata->is_clk_25mhz = true; | ||||||
|  | +	} else if (data->bootstrap_reg && data->bootstrap_ref) { | ||||||
| +		u32 t = ath79_reset_rr(data->bootstrap_reg); | +		u32 t = ath79_reset_rr(data->bootstrap_reg); | ||||||
| +		if (t & data->bootstrap_ref) | +		if (t & data->bootstrap_ref) | ||||||
| +			pdata->is_clk_25mhz = false; | +			pdata->is_clk_25mhz = false; | ||||||
| @@ -252,7 +259,7 @@ | |||||||
|  static int ath_ahb_probe(struct platform_device *pdev) |  static int ath_ahb_probe(struct platform_device *pdev) | ||||||
|  { |  { | ||||||
|  	void __iomem *mem; |  	void __iomem *mem; | ||||||
| @@ -80,6 +317,17 @@ static int ath_ahb_probe(struct platform | @@ -80,6 +324,17 @@ static int ath_ahb_probe(struct platform | ||||||
|  	int ret = 0; |  	int ret = 0; | ||||||
|  	struct ath_hw *ah; |  	struct ath_hw *ah; | ||||||
|  	char hw_name[64]; |  	char hw_name[64]; | ||||||
| @@ -270,7 +277,7 @@ | |||||||
|   |   | ||||||
|  	if (!dev_get_platdata(&pdev->dev)) { |  	if (!dev_get_platdata(&pdev->dev)) { | ||||||
|  		dev_err(&pdev->dev, "no platform data specified\n"); |  		dev_err(&pdev->dev, "no platform data specified\n"); | ||||||
| @@ -122,13 +370,16 @@ static int ath_ahb_probe(struct platform | @@ -122,13 +377,16 @@ static int ath_ahb_probe(struct platform | ||||||
|  	sc->mem = mem; |  	sc->mem = mem; | ||||||
|  	sc->irq = irq; |  	sc->irq = irq; | ||||||
|   |   | ||||||
| @@ -288,7 +295,7 @@ | |||||||
|  	if (ret) { |  	if (ret) { | ||||||
|  		dev_err(&pdev->dev, "failed to initialize device\n"); |  		dev_err(&pdev->dev, "failed to initialize device\n"); | ||||||
|  		goto err_irq; |  		goto err_irq; | ||||||
| @@ -159,6 +410,9 @@ static int ath_ahb_remove(struct platfor | @@ -159,6 +417,9 @@ static int ath_ahb_remove(struct platfor | ||||||
|  		free_irq(sc->irq, sc); |  		free_irq(sc->irq, sc); | ||||||
|  		ieee80211_free_hw(sc->hw); |  		ieee80211_free_hw(sc->hw); | ||||||
|  	} |  	} | ||||||
| @@ -298,7 +305,7 @@ | |||||||
|   |   | ||||||
|  	return 0; |  	return 0; | ||||||
|  } |  } | ||||||
| @@ -168,6 +422,9 @@ static struct platform_driver ath_ahb_dr | @@ -168,6 +429,9 @@ static struct platform_driver ath_ahb_dr | ||||||
|  	.remove     = ath_ahb_remove, |  	.remove     = ath_ahb_remove, | ||||||
|  	.driver		= { |  	.driver		= { | ||||||
|  		.name	= "ath9k", |  		.name	= "ath9k", | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 David Bauer
					David Bauer