brintos

brintos / linux-shallow public Read only

0
0
Text · 3.3 KiB · eface61 Raw
154 lines · c
1// SPDX-License-Identifier: GPL-2.0-or-later2/*3	Copyright (C) 2004 - 2009 Ivo van Doorn <IvDoorn@gmail.com>4	Copyright (C) 2004 - 2009 Felix Fietkau <nbd@openwrt.org>5	<http://rt2x00.serialmonkey.com>6 7 */8 9/*10	Module: rt2x00soc11	Abstract: rt2x00 generic soc device routines.12 */13 14#include <linux/bug.h>15#include <linux/kernel.h>16#include <linux/module.h>17#include <linux/platform_device.h>18#include <linux/slab.h>19 20#include "rt2x00.h"21#include "rt2x00soc.h"22 23static void rt2x00soc_free_reg(struct rt2x00_dev *rt2x00dev)24{25	kfree(rt2x00dev->rf);26	rt2x00dev->rf = NULL;27 28	kfree(rt2x00dev->eeprom);29	rt2x00dev->eeprom = NULL;30 31	iounmap(rt2x00dev->csr.base);32}33 34static int rt2x00soc_alloc_reg(struct rt2x00_dev *rt2x00dev)35{36	struct platform_device *pdev = to_platform_device(rt2x00dev->dev);37	struct resource *res;38 39	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);40	if (!res)41		return -ENODEV;42 43	rt2x00dev->csr.base = ioremap(res->start, resource_size(res));44	if (!rt2x00dev->csr.base)45		return -ENOMEM;46 47	rt2x00dev->eeprom = kzalloc(rt2x00dev->ops->eeprom_size, GFP_KERNEL);48	if (!rt2x00dev->eeprom)49		goto exit;50 51	rt2x00dev->rf = kzalloc(rt2x00dev->ops->rf_size, GFP_KERNEL);52	if (!rt2x00dev->rf)53		goto exit;54 55	return 0;56 57exit:58	rt2x00_probe_err("Failed to allocate registers\n");59	rt2x00soc_free_reg(rt2x00dev);60 61	return -ENOMEM;62}63 64int rt2x00soc_probe(struct platform_device *pdev, const struct rt2x00_ops *ops)65{66	struct ieee80211_hw *hw;67	struct rt2x00_dev *rt2x00dev;68	int retval;69 70	hw = ieee80211_alloc_hw(sizeof(struct rt2x00_dev), ops->hw);71	if (!hw) {72		rt2x00_probe_err("Failed to allocate hardware\n");73		return -ENOMEM;74	}75 76	platform_set_drvdata(pdev, hw);77 78	rt2x00dev = hw->priv;79	rt2x00dev->dev = &pdev->dev;80	rt2x00dev->ops = ops;81	rt2x00dev->hw = hw;82	rt2x00dev->irq = platform_get_irq(pdev, 0);83	rt2x00dev->name = pdev->dev.driver->name;84 85	rt2x00dev->clk = clk_get(&pdev->dev, NULL);86	if (IS_ERR(rt2x00dev->clk))87		rt2x00dev->clk = NULL;88 89	rt2x00_set_chip_intf(rt2x00dev, RT2X00_CHIP_INTF_SOC);90 91	retval = rt2x00soc_alloc_reg(rt2x00dev);92	if (retval)93		goto exit_free_device;94 95	retval = rt2x00lib_probe_dev(rt2x00dev);96	if (retval)97		goto exit_free_reg;98 99	return 0;100 101exit_free_reg:102	rt2x00soc_free_reg(rt2x00dev);103 104exit_free_device:105	ieee80211_free_hw(hw);106 107	return retval;108}109EXPORT_SYMBOL_GPL(rt2x00soc_probe);110 111int rt2x00soc_remove(struct platform_device *pdev)112{113	struct ieee80211_hw *hw = platform_get_drvdata(pdev);114	struct rt2x00_dev *rt2x00dev = hw->priv;115 116	/*117	 * Free all allocated data.118	 */119	rt2x00lib_remove_dev(rt2x00dev);120	rt2x00soc_free_reg(rt2x00dev);121	ieee80211_free_hw(hw);122 123	return 0;124}125EXPORT_SYMBOL_GPL(rt2x00soc_remove);126 127#ifdef CONFIG_PM128int rt2x00soc_suspend(struct platform_device *pdev, pm_message_t state)129{130	struct ieee80211_hw *hw = platform_get_drvdata(pdev);131	struct rt2x00_dev *rt2x00dev = hw->priv;132 133	return rt2x00lib_suspend(rt2x00dev);134}135EXPORT_SYMBOL_GPL(rt2x00soc_suspend);136 137int rt2x00soc_resume(struct platform_device *pdev)138{139	struct ieee80211_hw *hw = platform_get_drvdata(pdev);140	struct rt2x00_dev *rt2x00dev = hw->priv;141 142	return rt2x00lib_resume(rt2x00dev);143}144EXPORT_SYMBOL_GPL(rt2x00soc_resume);145#endif /* CONFIG_PM */146 147/*148 * rt2x00soc module information.149 */150MODULE_AUTHOR(DRV_PROJECT);151MODULE_VERSION(DRV_VERSION);152MODULE_DESCRIPTION("rt2x00 soc library");153MODULE_LICENSE("GPL");154