cregit-Linux how code gets into the kernel

Release 4.11 drivers/net/ethernet/freescale/fs_enet/mii-bitbang.c

/*
 * Combined Ethernet driver for Motorola MPC8xx and MPC82xx.
 *
 * Copyright (c) 2003 Intracom S.A.
 *  by Pantelis Antoniou <panto@intracom.gr>
 *
 * 2005 (c) MontaVista Software, Inc.
 * Vitaly Bordug <vbordug@ru.mvista.com>
 *
 * This file is licensed under the terms of the GNU General Public License
 * version 2. This program is licensed "as is" without any warranty of any
 * kind, whether express or implied.
 */

#include <linux/module.h>
#include <linux/ioport.h>
#include <linux/slab.h>
#include <linux/interrupt.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <linux/mii.h>
#include <linux/platform_device.h>
#include <linux/mdio-bitbang.h>
#include <linux/of_address.h>
#include <linux/of_mdio.h>
#include <linux/of_platform.h>

#include "fs_enet.h"


struct bb_info {
	
struct mdiobb_ctrl ctrl;
	
__be32 __iomem *dir;
	
__be32 __iomem *dat;
	
u32 mdio_msk;
	
u32 mdc_msk;
};

/* FIXME: If any other users of GPIO crop up, then these will have to
 * have some sort of global synchronization to avoid races with other
 * pins on the same port.  The ideal solution would probably be to
 * bind the ports to a GPIO driver, and have this be a client of it.
 */

static inline void bb_set(u32 __iomem *p, u32 m) { out_be32(p, in_be32(p) | m); }

Contributors

PersonTokensPropCommitsCommitProp
Vitaly Bordug1866.67%133.33%
Scott Wood518.52%133.33%
Pantelis Antoniou414.81%133.33%
Total27100.00%3100.00%


static inline void bb_clr(u32 __iomem *p, u32 m) { out_be32(p, in_be32(p) & ~m); }

Contributors

PersonTokensPropCommitsCommitProp
Vitaly Bordug2175.00%133.33%
Scott Wood517.86%133.33%
Pantelis Antoniou27.14%133.33%
Total28100.00%3100.00%


static inline int bb_read(u32 __iomem *p, u32 m) { return (in_be32(p) & m) != 0; }

Contributors

PersonTokensPropCommitsCommitProp
Vitaly Bordug1762.96%133.33%
Pantelis Antoniou622.22%133.33%
Scott Wood414.81%133.33%
Total27100.00%3100.00%


static inline void mdio_dir(struct mdiobb_ctrl *ctrl, int dir) { struct bb_info *bitbang = container_of(ctrl, struct bb_info, ctrl); if (dir) bb_set(bitbang->dir, bitbang->mdio_msk); else bb_clr(bitbang->dir, bitbang->mdio_msk); /* Read back to flush the write. */ in_be32(bitbang->dir); }

Contributors

PersonTokensPropCommitsCommitProp
Pantelis Antoniou3147.69%125.00%
Scott Wood2538.46%250.00%
Vitaly Bordug913.85%125.00%
Total65100.00%4100.00%


static inline int mdio_read(struct mdiobb_ctrl *ctrl) { struct bb_info *bitbang = container_of(ctrl, struct bb_info, ctrl); return bb_read(bitbang->dat, bitbang->mdio_msk); }

Contributors

PersonTokensPropCommitsCommitProp
Scott Wood2153.85%250.00%
Pantelis Antoniou1641.03%125.00%
Vitaly Bordug25.13%125.00%
Total39100.00%4100.00%


static inline void mdio(struct mdiobb_ctrl *ctrl, int what) { struct bb_info *bitbang = container_of(ctrl, struct bb_info, ctrl); if (what) bb_set(bitbang->dat, bitbang->mdio_msk); else bb_clr(bitbang->dat, bitbang->mdio_msk); /* Read back to flush the write. */ in_be32(bitbang->dat); }

Contributors

PersonTokensPropCommitsCommitProp
Scott Wood3655.38%133.33%
Pantelis Antoniou2132.31%133.33%
Vitaly Bordug812.31%133.33%
Total65100.00%3100.00%


static inline void mdc(struct mdiobb_ctrl *ctrl, int what) { struct bb_info *bitbang = container_of(ctrl, struct bb_info, ctrl); if (what) bb_set(bitbang->dat, bitbang->mdc_msk); else bb_clr(bitbang->dat, bitbang->mdc_msk); /* Read back to flush the write. */ in_be32(bitbang->dat); }

Contributors

PersonTokensPropCommitsCommitProp
Scott Wood4772.31%133.33%
Pantelis Antoniou1421.54%133.33%
Vitaly Bordug46.15%133.33%
Total65100.00%3100.00%

static struct mdiobb_ops bb_ops = { .owner = THIS_MODULE, .set_mdc = mdc, .set_mdio_dir = mdio_dir, .set_mdio_data = mdio, .get_mdio_data = mdio_read, };
static int fs_mii_bitbang_init(struct mii_bus *bus, struct device_node *np) { struct resource res; const u32 *data; int mdio_pin, mdc_pin, len; struct bb_info *bitbang = bus->priv; int ret = of_address_to_resource(np, 0, &res); if (ret) return ret; if (resource_size(&res) <= 13) return -ENODEV; /* This should really encode the pin number as well, but all * we get is an int, and the odds of multiple bitbang mdio buses * is low enough that it's not worth going too crazy. */ snprintf(bus->id, MII_BUS_ID_SIZE, "%x", res.start); data = of_get_property(np, "fsl,mdio-pin", &len); if (!data || len != 4) return -ENODEV; mdio_pin = *data; data = of_get_property(np, "fsl,mdc-pin", &len); if (!data || len != 4) return -ENODEV; mdc_pin = *data; bitbang->dir = ioremap(res.start, resource_size(&res)); if (!bitbang->dir) return -ENOMEM; bitbang->dat = bitbang->dir + 4; bitbang->mdio_msk = 1 << (31 - mdio_pin); bitbang->mdc_msk = 1 << (31 - mdc_pin); return 0; }

Contributors

PersonTokensPropCommitsCommitProp
Scott Wood14567.13%120.00%
Vitaly Bordug3717.13%120.00%
Pantelis Antoniou177.87%120.00%
Joe Perches94.17%120.00%
Andy Fleming83.70%120.00%
Total216100.00%5100.00%


static int fs_enet_mdio_probe(struct platform_device *ofdev) { struct mii_bus *new_bus; struct bb_info *bitbang; int ret = -ENOMEM; bitbang = kzalloc(sizeof(struct bb_info), GFP_KERNEL); if (!bitbang) goto out; bitbang->ctrl.ops = &bb_ops; new_bus = alloc_mdio_bitbang(&bitbang->ctrl); if (!new_bus) goto out_free_priv; new_bus->name = "CPM2 Bitbanged MII", ret = fs_mii_bitbang_init(new_bus, ofdev->dev.of_node); if (ret) goto out_free_bus; new_bus->phy_mask = ~0; new_bus->parent = &ofdev->dev; platform_set_drvdata(ofdev, new_bus); ret = of_mdiobus_register(new_bus, ofdev->dev.of_node); if (ret) goto out_unmap_regs; return 0; out_unmap_regs: iounmap(bitbang->dir); out_free_bus: free_mdio_bitbang(new_bus); out_free_priv: kfree(bitbang); out: return ret; }

Contributors

PersonTokensPropCommitsCommitProp
Scott Wood15890.29%222.22%
Anatolij Gustschin63.43%111.11%
Grant C. Likely52.86%222.22%
Lennert Buytenhek42.29%222.22%
Jingoo Han10.57%111.11%
Andrew Lunn10.57%111.11%
Total175100.00%9100.00%


static int fs_enet_mdio_remove(struct platform_device *ofdev) { struct mii_bus *bus = platform_get_drvdata(ofdev); struct bb_info *bitbang = bus->priv; mdiobus_unregister(bus); free_mdio_bitbang(bus); iounmap(bitbang->dir); kfree(bitbang); return 0; }

Contributors

PersonTokensPropCommitsCommitProp
Scott Wood4887.27%125.00%
Lennert Buytenhek59.09%125.00%
Jingoo Han11.82%125.00%
Grant C. Likely11.82%125.00%
Total55100.00%4100.00%

static const struct of_device_id fs_enet_mdio_bb_match[] = { { .compatible = "fsl,cpm2-mdio-bitbang", }, {}, }; MODULE_DEVICE_TABLE(of, fs_enet_mdio_bb_match); static struct platform_driver fs_enet_bb_mdio_driver = { .driver = { .name = "fsl-bb-mdio", .of_match_table = fs_enet_mdio_bb_match, }, .probe = fs_enet_mdio_probe, .remove = fs_enet_mdio_remove, }; module_platform_driver(fs_enet_bb_mdio_driver);

Overall Contributors

PersonTokensPropCommitsCommitProp
Scott Wood59264.21%210.00%
Pantelis Antoniou14615.84%15.00%
Vitaly Bordug12013.02%210.00%
Grant C. Likely161.74%420.00%
Lennert Buytenhek90.98%210.00%
Joe Perches90.98%15.00%
Andy Fleming80.87%15.00%
Anton Vorontsov70.76%15.00%
Anatolij Gustschin60.65%15.00%
Rob Herring30.33%15.00%
Axel Lin20.22%15.00%
Jingoo Han20.22%15.00%
Andrew Lunn10.11%15.00%
Fabian Frederick10.11%15.00%
Total922100.00%20100.00%
Information contained on this website is for historical information purposes only and does not indicate or represent copyright ownership.
Created with cregit.