0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014 #include <linux/bug.h>
0015 #include <linux/kernel.h>
0016 #include <linux/module.h>
0017 #include <linux/platform_device.h>
0018 #include <linux/slab.h>
0019
0020 #include "rt2x00.h"
0021 #include "rt2x00soc.h"
0022
0023 static void rt2x00soc_free_reg(struct rt2x00_dev *rt2x00dev)
0024 {
0025 kfree(rt2x00dev->rf);
0026 rt2x00dev->rf = NULL;
0027
0028 kfree(rt2x00dev->eeprom);
0029 rt2x00dev->eeprom = NULL;
0030
0031 iounmap(rt2x00dev->csr.base);
0032 }
0033
0034 static int rt2x00soc_alloc_reg(struct rt2x00_dev *rt2x00dev)
0035 {
0036 struct platform_device *pdev = to_platform_device(rt2x00dev->dev);
0037 struct resource *res;
0038
0039 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
0040 if (!res)
0041 return -ENODEV;
0042
0043 rt2x00dev->csr.base = ioremap(res->start, resource_size(res));
0044 if (!rt2x00dev->csr.base)
0045 return -ENOMEM;
0046
0047 rt2x00dev->eeprom = kzalloc(rt2x00dev->ops->eeprom_size, GFP_KERNEL);
0048 if (!rt2x00dev->eeprom)
0049 goto exit;
0050
0051 rt2x00dev->rf = kzalloc(rt2x00dev->ops->rf_size, GFP_KERNEL);
0052 if (!rt2x00dev->rf)
0053 goto exit;
0054
0055 return 0;
0056
0057 exit:
0058 rt2x00_probe_err("Failed to allocate registers\n");
0059 rt2x00soc_free_reg(rt2x00dev);
0060
0061 return -ENOMEM;
0062 }
0063
0064 int rt2x00soc_probe(struct platform_device *pdev, const struct rt2x00_ops *ops)
0065 {
0066 struct ieee80211_hw *hw;
0067 struct rt2x00_dev *rt2x00dev;
0068 int retval;
0069
0070 hw = ieee80211_alloc_hw(sizeof(struct rt2x00_dev), ops->hw);
0071 if (!hw) {
0072 rt2x00_probe_err("Failed to allocate hardware\n");
0073 return -ENOMEM;
0074 }
0075
0076 platform_set_drvdata(pdev, hw);
0077
0078 rt2x00dev = hw->priv;
0079 rt2x00dev->dev = &pdev->dev;
0080 rt2x00dev->ops = ops;
0081 rt2x00dev->hw = hw;
0082 rt2x00dev->irq = platform_get_irq(pdev, 0);
0083 rt2x00dev->name = pdev->dev.driver->name;
0084
0085 rt2x00dev->clk = clk_get(&pdev->dev, NULL);
0086 if (IS_ERR(rt2x00dev->clk))
0087 rt2x00dev->clk = NULL;
0088
0089 rt2x00_set_chip_intf(rt2x00dev, RT2X00_CHIP_INTF_SOC);
0090
0091 retval = rt2x00soc_alloc_reg(rt2x00dev);
0092 if (retval)
0093 goto exit_free_device;
0094
0095 retval = rt2x00lib_probe_dev(rt2x00dev);
0096 if (retval)
0097 goto exit_free_reg;
0098
0099 return 0;
0100
0101 exit_free_reg:
0102 rt2x00soc_free_reg(rt2x00dev);
0103
0104 exit_free_device:
0105 ieee80211_free_hw(hw);
0106
0107 return retval;
0108 }
0109 EXPORT_SYMBOL_GPL(rt2x00soc_probe);
0110
0111 int rt2x00soc_remove(struct platform_device *pdev)
0112 {
0113 struct ieee80211_hw *hw = platform_get_drvdata(pdev);
0114 struct rt2x00_dev *rt2x00dev = hw->priv;
0115
0116
0117
0118
0119 rt2x00lib_remove_dev(rt2x00dev);
0120 rt2x00soc_free_reg(rt2x00dev);
0121 ieee80211_free_hw(hw);
0122
0123 return 0;
0124 }
0125 EXPORT_SYMBOL_GPL(rt2x00soc_remove);
0126
0127 #ifdef CONFIG_PM
0128 int rt2x00soc_suspend(struct platform_device *pdev, pm_message_t state)
0129 {
0130 struct ieee80211_hw *hw = platform_get_drvdata(pdev);
0131 struct rt2x00_dev *rt2x00dev = hw->priv;
0132
0133 return rt2x00lib_suspend(rt2x00dev);
0134 }
0135 EXPORT_SYMBOL_GPL(rt2x00soc_suspend);
0136
0137 int rt2x00soc_resume(struct platform_device *pdev)
0138 {
0139 struct ieee80211_hw *hw = platform_get_drvdata(pdev);
0140 struct rt2x00_dev *rt2x00dev = hw->priv;
0141
0142 return rt2x00lib_resume(rt2x00dev);
0143 }
0144 EXPORT_SYMBOL_GPL(rt2x00soc_resume);
0145 #endif
0146
0147
0148
0149
0150 MODULE_AUTHOR(DRV_PROJECT);
0151 MODULE_VERSION(DRV_VERSION);
0152 MODULE_DESCRIPTION("rt2x00 soc library");
0153 MODULE_LICENSE("GPL");