1d1a277c584d0862dbf51991baea947ea5f2ce6bfWolfgang Grandegger/* 2d1a277c584d0862dbf51991baea947ea5f2ce6bfWolfgang Grandegger * Driver for SJA1000 CAN controllers on the OpenFirmware platform bus 3d1a277c584d0862dbf51991baea947ea5f2ce6bfWolfgang Grandegger * 4d1a277c584d0862dbf51991baea947ea5f2ce6bfWolfgang Grandegger * Copyright (C) 2008-2009 Wolfgang Grandegger <wg@grandegger.com> 5d1a277c584d0862dbf51991baea947ea5f2ce6bfWolfgang Grandegger * 6d1a277c584d0862dbf51991baea947ea5f2ce6bfWolfgang Grandegger * This program is free software; you can redistribute it and/or modify 7d1a277c584d0862dbf51991baea947ea5f2ce6bfWolfgang Grandegger * it under the terms of the version 2 of the GNU General Public License 8d1a277c584d0862dbf51991baea947ea5f2ce6bfWolfgang Grandegger * as published by the Free Software Foundation 9d1a277c584d0862dbf51991baea947ea5f2ce6bfWolfgang Grandegger * 10d1a277c584d0862dbf51991baea947ea5f2ce6bfWolfgang Grandegger * This program is distributed in the hope that it will be useful, 11d1a277c584d0862dbf51991baea947ea5f2ce6bfWolfgang Grandegger * but WITHOUT ANY WARRANTY; without even the implied warranty of 12d1a277c584d0862dbf51991baea947ea5f2ce6bfWolfgang Grandegger * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13d1a277c584d0862dbf51991baea947ea5f2ce6bfWolfgang Grandegger * GNU General Public License for more details. 14d1a277c584d0862dbf51991baea947ea5f2ce6bfWolfgang Grandegger * 15d1a277c584d0862dbf51991baea947ea5f2ce6bfWolfgang Grandegger * You should have received a copy of the GNU General Public License 16d1a277c584d0862dbf51991baea947ea5f2ce6bfWolfgang Grandegger * along with this program; if not, write to the Free Software Foundation, 17d1a277c584d0862dbf51991baea947ea5f2ce6bfWolfgang Grandegger * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 18d1a277c584d0862dbf51991baea947ea5f2ce6bfWolfgang Grandegger */ 19d1a277c584d0862dbf51991baea947ea5f2ce6bfWolfgang Grandegger 20d1a277c584d0862dbf51991baea947ea5f2ce6bfWolfgang Grandegger/* This is a generic driver for SJA1000 chips on the OpenFirmware platform 21d1a277c584d0862dbf51991baea947ea5f2ce6bfWolfgang Grandegger * bus found on embedded PowerPC systems. You need a SJA1000 CAN node 22d1a277c584d0862dbf51991baea947ea5f2ce6bfWolfgang Grandegger * definition in your flattened device tree source (DTS) file similar to: 23d1a277c584d0862dbf51991baea947ea5f2ce6bfWolfgang Grandegger * 24d1a277c584d0862dbf51991baea947ea5f2ce6bfWolfgang Grandegger * can@3,100 { 25d1a277c584d0862dbf51991baea947ea5f2ce6bfWolfgang Grandegger * compatible = "nxp,sja1000"; 26d1a277c584d0862dbf51991baea947ea5f2ce6bfWolfgang Grandegger * reg = <3 0x100 0x80>; 27d1a277c584d0862dbf51991baea947ea5f2ce6bfWolfgang Grandegger * interrupts = <2 0>; 28d1a277c584d0862dbf51991baea947ea5f2ce6bfWolfgang Grandegger * interrupt-parent = <&mpic>; 29d1a277c584d0862dbf51991baea947ea5f2ce6bfWolfgang Grandegger * nxp,external-clock-frequency = <16000000>; 30d1a277c584d0862dbf51991baea947ea5f2ce6bfWolfgang Grandegger * }; 31d1a277c584d0862dbf51991baea947ea5f2ce6bfWolfgang Grandegger * 32395cf9691d72173d8cdaa613c5f0255f993af94bPaul Bolle * See "Documentation/devicetree/bindings/net/can/sja1000.txt" for further 33d1a277c584d0862dbf51991baea947ea5f2ce6bfWolfgang Grandegger * information. 34d1a277c584d0862dbf51991baea947ea5f2ce6bfWolfgang Grandegger */ 35d1a277c584d0862dbf51991baea947ea5f2ce6bfWolfgang Grandegger 36d1a277c584d0862dbf51991baea947ea5f2ce6bfWolfgang Grandegger#include <linux/kernel.h> 37d1a277c584d0862dbf51991baea947ea5f2ce6bfWolfgang Grandegger#include <linux/module.h> 38d1a277c584d0862dbf51991baea947ea5f2ce6bfWolfgang Grandegger#include <linux/interrupt.h> 39d1a277c584d0862dbf51991baea947ea5f2ce6bfWolfgang Grandegger#include <linux/netdevice.h> 40d1a277c584d0862dbf51991baea947ea5f2ce6bfWolfgang Grandegger#include <linux/delay.h> 418d0f7cea7aa1bb63ddd0e94589d2c33bc99f0d9aStephen Rothwell#include <linux/io.h> 42d1a277c584d0862dbf51991baea947ea5f2ce6bfWolfgang Grandegger#include <linux/can/dev.h> 43d1a277c584d0862dbf51991baea947ea5f2ce6bfWolfgang Grandegger 44d1a277c584d0862dbf51991baea947ea5f2ce6bfWolfgang Grandegger#include <linux/of_platform.h> 45d1a277c584d0862dbf51991baea947ea5f2ce6bfWolfgang Grandegger#include <asm/prom.h> 46d1a277c584d0862dbf51991baea947ea5f2ce6bfWolfgang Grandegger 47d1a277c584d0862dbf51991baea947ea5f2ce6bfWolfgang Grandegger#include "sja1000.h" 48d1a277c584d0862dbf51991baea947ea5f2ce6bfWolfgang Grandegger 49d1a277c584d0862dbf51991baea947ea5f2ce6bfWolfgang Grandegger#define DRV_NAME "sja1000_of_platform" 50d1a277c584d0862dbf51991baea947ea5f2ce6bfWolfgang Grandegger 51d1a277c584d0862dbf51991baea947ea5f2ce6bfWolfgang GrandeggerMODULE_AUTHOR("Wolfgang Grandegger <wg@grandegger.com>"); 52d1a277c584d0862dbf51991baea947ea5f2ce6bfWolfgang GrandeggerMODULE_DESCRIPTION("Socket-CAN driver for SJA1000 on the OF platform bus"); 53d1a277c584d0862dbf51991baea947ea5f2ce6bfWolfgang GrandeggerMODULE_LICENSE("GPL v2"); 54d1a277c584d0862dbf51991baea947ea5f2ce6bfWolfgang Grandegger 55d1a277c584d0862dbf51991baea947ea5f2ce6bfWolfgang Grandegger#define SJA1000_OFP_CAN_CLOCK (16000000 / 2) 56d1a277c584d0862dbf51991baea947ea5f2ce6bfWolfgang Grandegger 57d1a277c584d0862dbf51991baea947ea5f2ce6bfWolfgang Grandegger#define SJA1000_OFP_OCR OCR_TX0_PULLDOWN 58d1a277c584d0862dbf51991baea947ea5f2ce6bfWolfgang Grandegger#define SJA1000_OFP_CDR (CDR_CBP | CDR_CLK_OFF) 59d1a277c584d0862dbf51991baea947ea5f2ce6bfWolfgang Grandegger 60d1a277c584d0862dbf51991baea947ea5f2ce6bfWolfgang Grandeggerstatic u8 sja1000_ofp_read_reg(const struct sja1000_priv *priv, int reg) 61d1a277c584d0862dbf51991baea947ea5f2ce6bfWolfgang Grandegger{ 62d1a277c584d0862dbf51991baea947ea5f2ce6bfWolfgang Grandegger return in_8(priv->reg_base + reg); 63d1a277c584d0862dbf51991baea947ea5f2ce6bfWolfgang Grandegger} 64d1a277c584d0862dbf51991baea947ea5f2ce6bfWolfgang Grandegger 65d1a277c584d0862dbf51991baea947ea5f2ce6bfWolfgang Grandeggerstatic void sja1000_ofp_write_reg(const struct sja1000_priv *priv, 66d1a277c584d0862dbf51991baea947ea5f2ce6bfWolfgang Grandegger int reg, u8 val) 67d1a277c584d0862dbf51991baea947ea5f2ce6bfWolfgang Grandegger{ 68d1a277c584d0862dbf51991baea947ea5f2ce6bfWolfgang Grandegger out_8(priv->reg_base + reg, val); 69d1a277c584d0862dbf51991baea947ea5f2ce6bfWolfgang Grandegger} 70d1a277c584d0862dbf51991baea947ea5f2ce6bfWolfgang Grandegger 712dc11581376829303b98eadb2de253bee065a56aGrant Likelystatic int __devexit sja1000_ofp_remove(struct platform_device *ofdev) 72d1a277c584d0862dbf51991baea947ea5f2ce6bfWolfgang Grandegger{ 73d1a277c584d0862dbf51991baea947ea5f2ce6bfWolfgang Grandegger struct net_device *dev = dev_get_drvdata(&ofdev->dev); 74d1a277c584d0862dbf51991baea947ea5f2ce6bfWolfgang Grandegger struct sja1000_priv *priv = netdev_priv(dev); 7561c7a080a5a061c976988fd4b844dfb468dda255Grant Likely struct device_node *np = ofdev->dev.of_node; 76d1a277c584d0862dbf51991baea947ea5f2ce6bfWolfgang Grandegger struct resource res; 77d1a277c584d0862dbf51991baea947ea5f2ce6bfWolfgang Grandegger 78d1a277c584d0862dbf51991baea947ea5f2ce6bfWolfgang Grandegger dev_set_drvdata(&ofdev->dev, NULL); 79d1a277c584d0862dbf51991baea947ea5f2ce6bfWolfgang Grandegger 80d1a277c584d0862dbf51991baea947ea5f2ce6bfWolfgang Grandegger unregister_sja1000dev(dev); 81d1a277c584d0862dbf51991baea947ea5f2ce6bfWolfgang Grandegger free_sja1000dev(dev); 82d1a277c584d0862dbf51991baea947ea5f2ce6bfWolfgang Grandegger iounmap(priv->reg_base); 83d1a277c584d0862dbf51991baea947ea5f2ce6bfWolfgang Grandegger irq_dispose_mapping(dev->irq); 84d1a277c584d0862dbf51991baea947ea5f2ce6bfWolfgang Grandegger 85d1a277c584d0862dbf51991baea947ea5f2ce6bfWolfgang Grandegger of_address_to_resource(np, 0, &res); 86d1a277c584d0862dbf51991baea947ea5f2ce6bfWolfgang Grandegger release_mem_region(res.start, resource_size(&res)); 87d1a277c584d0862dbf51991baea947ea5f2ce6bfWolfgang Grandegger 88d1a277c584d0862dbf51991baea947ea5f2ce6bfWolfgang Grandegger return 0; 89d1a277c584d0862dbf51991baea947ea5f2ce6bfWolfgang Grandegger} 90d1a277c584d0862dbf51991baea947ea5f2ce6bfWolfgang Grandegger 9174888760d40b3ac9054f9c5fa07b566c0676ba2dGrant Likelystatic int __devinit sja1000_ofp_probe(struct platform_device *ofdev) 92d1a277c584d0862dbf51991baea947ea5f2ce6bfWolfgang Grandegger{ 9361c7a080a5a061c976988fd4b844dfb468dda255Grant Likely struct device_node *np = ofdev->dev.of_node; 94d1a277c584d0862dbf51991baea947ea5f2ce6bfWolfgang Grandegger struct net_device *dev; 95d1a277c584d0862dbf51991baea947ea5f2ce6bfWolfgang Grandegger struct sja1000_priv *priv; 96d1a277c584d0862dbf51991baea947ea5f2ce6bfWolfgang Grandegger struct resource res; 97d1a277c584d0862dbf51991baea947ea5f2ce6bfWolfgang Grandegger const u32 *prop; 98d1a277c584d0862dbf51991baea947ea5f2ce6bfWolfgang Grandegger int err, irq, res_size, prop_size; 99d1a277c584d0862dbf51991baea947ea5f2ce6bfWolfgang Grandegger void __iomem *base; 100d1a277c584d0862dbf51991baea947ea5f2ce6bfWolfgang Grandegger 101d1a277c584d0862dbf51991baea947ea5f2ce6bfWolfgang Grandegger err = of_address_to_resource(np, 0, &res); 102d1a277c584d0862dbf51991baea947ea5f2ce6bfWolfgang Grandegger if (err) { 103d1a277c584d0862dbf51991baea947ea5f2ce6bfWolfgang Grandegger dev_err(&ofdev->dev, "invalid address\n"); 104d1a277c584d0862dbf51991baea947ea5f2ce6bfWolfgang Grandegger return err; 105d1a277c584d0862dbf51991baea947ea5f2ce6bfWolfgang Grandegger } 106d1a277c584d0862dbf51991baea947ea5f2ce6bfWolfgang Grandegger 107d1a277c584d0862dbf51991baea947ea5f2ce6bfWolfgang Grandegger res_size = resource_size(&res); 108d1a277c584d0862dbf51991baea947ea5f2ce6bfWolfgang Grandegger 109d1a277c584d0862dbf51991baea947ea5f2ce6bfWolfgang Grandegger if (!request_mem_region(res.start, res_size, DRV_NAME)) { 110b1323c8fa153f63e20d5a7fc0be72073c3beb05bJoe Perches dev_err(&ofdev->dev, "couldn't request %pR\n", &res); 111d1a277c584d0862dbf51991baea947ea5f2ce6bfWolfgang Grandegger return -EBUSY; 112d1a277c584d0862dbf51991baea947ea5f2ce6bfWolfgang Grandegger } 113d1a277c584d0862dbf51991baea947ea5f2ce6bfWolfgang Grandegger 114d1a277c584d0862dbf51991baea947ea5f2ce6bfWolfgang Grandegger base = ioremap_nocache(res.start, res_size); 115d1a277c584d0862dbf51991baea947ea5f2ce6bfWolfgang Grandegger if (!base) { 116b1323c8fa153f63e20d5a7fc0be72073c3beb05bJoe Perches dev_err(&ofdev->dev, "couldn't ioremap %pR\n", &res); 117d1a277c584d0862dbf51991baea947ea5f2ce6bfWolfgang Grandegger err = -ENOMEM; 118d1a277c584d0862dbf51991baea947ea5f2ce6bfWolfgang Grandegger goto exit_release_mem; 119d1a277c584d0862dbf51991baea947ea5f2ce6bfWolfgang Grandegger } 120d1a277c584d0862dbf51991baea947ea5f2ce6bfWolfgang Grandegger 121d1a277c584d0862dbf51991baea947ea5f2ce6bfWolfgang Grandegger irq = irq_of_parse_and_map(np, 0); 122d1a277c584d0862dbf51991baea947ea5f2ce6bfWolfgang Grandegger if (irq == NO_IRQ) { 123d1a277c584d0862dbf51991baea947ea5f2ce6bfWolfgang Grandegger dev_err(&ofdev->dev, "no irq found\n"); 124d1a277c584d0862dbf51991baea947ea5f2ce6bfWolfgang Grandegger err = -ENODEV; 125d1a277c584d0862dbf51991baea947ea5f2ce6bfWolfgang Grandegger goto exit_unmap_mem; 126d1a277c584d0862dbf51991baea947ea5f2ce6bfWolfgang Grandegger } 127d1a277c584d0862dbf51991baea947ea5f2ce6bfWolfgang Grandegger 128d1a277c584d0862dbf51991baea947ea5f2ce6bfWolfgang Grandegger dev = alloc_sja1000dev(0); 129d1a277c584d0862dbf51991baea947ea5f2ce6bfWolfgang Grandegger if (!dev) { 130d1a277c584d0862dbf51991baea947ea5f2ce6bfWolfgang Grandegger err = -ENOMEM; 131d1a277c584d0862dbf51991baea947ea5f2ce6bfWolfgang Grandegger goto exit_dispose_irq; 132d1a277c584d0862dbf51991baea947ea5f2ce6bfWolfgang Grandegger } 133d1a277c584d0862dbf51991baea947ea5f2ce6bfWolfgang Grandegger 134d1a277c584d0862dbf51991baea947ea5f2ce6bfWolfgang Grandegger priv = netdev_priv(dev); 135d1a277c584d0862dbf51991baea947ea5f2ce6bfWolfgang Grandegger 136d1a277c584d0862dbf51991baea947ea5f2ce6bfWolfgang Grandegger priv->read_reg = sja1000_ofp_read_reg; 137d1a277c584d0862dbf51991baea947ea5f2ce6bfWolfgang Grandegger priv->write_reg = sja1000_ofp_write_reg; 138d1a277c584d0862dbf51991baea947ea5f2ce6bfWolfgang Grandegger 139d1a277c584d0862dbf51991baea947ea5f2ce6bfWolfgang Grandegger prop = of_get_property(np, "nxp,external-clock-frequency", &prop_size); 140d1a277c584d0862dbf51991baea947ea5f2ce6bfWolfgang Grandegger if (prop && (prop_size == sizeof(u32))) 141d1a277c584d0862dbf51991baea947ea5f2ce6bfWolfgang Grandegger priv->can.clock.freq = *prop / 2; 142d1a277c584d0862dbf51991baea947ea5f2ce6bfWolfgang Grandegger else 143d1a277c584d0862dbf51991baea947ea5f2ce6bfWolfgang Grandegger priv->can.clock.freq = SJA1000_OFP_CAN_CLOCK; /* default */ 144d1a277c584d0862dbf51991baea947ea5f2ce6bfWolfgang Grandegger 145d1a277c584d0862dbf51991baea947ea5f2ce6bfWolfgang Grandegger prop = of_get_property(np, "nxp,tx-output-mode", &prop_size); 146d1a277c584d0862dbf51991baea947ea5f2ce6bfWolfgang Grandegger if (prop && (prop_size == sizeof(u32))) 147d1a277c584d0862dbf51991baea947ea5f2ce6bfWolfgang Grandegger priv->ocr |= *prop & OCR_MODE_MASK; 148d1a277c584d0862dbf51991baea947ea5f2ce6bfWolfgang Grandegger else 149d1a277c584d0862dbf51991baea947ea5f2ce6bfWolfgang Grandegger priv->ocr |= OCR_MODE_NORMAL; /* default */ 150d1a277c584d0862dbf51991baea947ea5f2ce6bfWolfgang Grandegger 151d1a277c584d0862dbf51991baea947ea5f2ce6bfWolfgang Grandegger prop = of_get_property(np, "nxp,tx-output-config", &prop_size); 152d1a277c584d0862dbf51991baea947ea5f2ce6bfWolfgang Grandegger if (prop && (prop_size == sizeof(u32))) 153d1a277c584d0862dbf51991baea947ea5f2ce6bfWolfgang Grandegger priv->ocr |= (*prop << OCR_TX_SHIFT) & OCR_TX_MASK; 154d1a277c584d0862dbf51991baea947ea5f2ce6bfWolfgang Grandegger else 155d1a277c584d0862dbf51991baea947ea5f2ce6bfWolfgang Grandegger priv->ocr |= OCR_TX0_PULLDOWN; /* default */ 156d1a277c584d0862dbf51991baea947ea5f2ce6bfWolfgang Grandegger 157d1a277c584d0862dbf51991baea947ea5f2ce6bfWolfgang Grandegger prop = of_get_property(np, "nxp,clock-out-frequency", &prop_size); 158d1a277c584d0862dbf51991baea947ea5f2ce6bfWolfgang Grandegger if (prop && (prop_size == sizeof(u32)) && *prop) { 159d1a277c584d0862dbf51991baea947ea5f2ce6bfWolfgang Grandegger u32 divider = priv->can.clock.freq * 2 / *prop; 160d1a277c584d0862dbf51991baea947ea5f2ce6bfWolfgang Grandegger 161d1a277c584d0862dbf51991baea947ea5f2ce6bfWolfgang Grandegger if (divider > 1) 162d1a277c584d0862dbf51991baea947ea5f2ce6bfWolfgang Grandegger priv->cdr |= divider / 2 - 1; 163d1a277c584d0862dbf51991baea947ea5f2ce6bfWolfgang Grandegger else 164d1a277c584d0862dbf51991baea947ea5f2ce6bfWolfgang Grandegger priv->cdr |= CDR_CLKOUT_MASK; 165d1a277c584d0862dbf51991baea947ea5f2ce6bfWolfgang Grandegger } else { 166d1a277c584d0862dbf51991baea947ea5f2ce6bfWolfgang Grandegger priv->cdr |= CDR_CLK_OFF; /* default */ 167d1a277c584d0862dbf51991baea947ea5f2ce6bfWolfgang Grandegger } 168d1a277c584d0862dbf51991baea947ea5f2ce6bfWolfgang Grandegger 169d1a277c584d0862dbf51991baea947ea5f2ce6bfWolfgang Grandegger prop = of_get_property(np, "nxp,no-comparator-bypass", NULL); 170d1a277c584d0862dbf51991baea947ea5f2ce6bfWolfgang Grandegger if (!prop) 171d1a277c584d0862dbf51991baea947ea5f2ce6bfWolfgang Grandegger priv->cdr |= CDR_CBP; /* default */ 172d1a277c584d0862dbf51991baea947ea5f2ce6bfWolfgang Grandegger 173d1a277c584d0862dbf51991baea947ea5f2ce6bfWolfgang Grandegger priv->irq_flags = IRQF_SHARED; 174d1a277c584d0862dbf51991baea947ea5f2ce6bfWolfgang Grandegger priv->reg_base = base; 175d1a277c584d0862dbf51991baea947ea5f2ce6bfWolfgang Grandegger 176d1a277c584d0862dbf51991baea947ea5f2ce6bfWolfgang Grandegger dev->irq = irq; 177d1a277c584d0862dbf51991baea947ea5f2ce6bfWolfgang Grandegger 178d1a277c584d0862dbf51991baea947ea5f2ce6bfWolfgang Grandegger dev_info(&ofdev->dev, 179d1a277c584d0862dbf51991baea947ea5f2ce6bfWolfgang Grandegger "reg_base=0x%p irq=%d clock=%d ocr=0x%02x cdr=0x%02x\n", 180d1a277c584d0862dbf51991baea947ea5f2ce6bfWolfgang Grandegger priv->reg_base, dev->irq, priv->can.clock.freq, 181d1a277c584d0862dbf51991baea947ea5f2ce6bfWolfgang Grandegger priv->ocr, priv->cdr); 182d1a277c584d0862dbf51991baea947ea5f2ce6bfWolfgang Grandegger 183d1a277c584d0862dbf51991baea947ea5f2ce6bfWolfgang Grandegger dev_set_drvdata(&ofdev->dev, dev); 184d1a277c584d0862dbf51991baea947ea5f2ce6bfWolfgang Grandegger SET_NETDEV_DEV(dev, &ofdev->dev); 185d1a277c584d0862dbf51991baea947ea5f2ce6bfWolfgang Grandegger 186d1a277c584d0862dbf51991baea947ea5f2ce6bfWolfgang Grandegger err = register_sja1000dev(dev); 187d1a277c584d0862dbf51991baea947ea5f2ce6bfWolfgang Grandegger if (err) { 188d1a277c584d0862dbf51991baea947ea5f2ce6bfWolfgang Grandegger dev_err(&ofdev->dev, "registering %s failed (err=%d)\n", 189d1a277c584d0862dbf51991baea947ea5f2ce6bfWolfgang Grandegger DRV_NAME, err); 190d1a277c584d0862dbf51991baea947ea5f2ce6bfWolfgang Grandegger goto exit_free_sja1000; 191d1a277c584d0862dbf51991baea947ea5f2ce6bfWolfgang Grandegger } 192d1a277c584d0862dbf51991baea947ea5f2ce6bfWolfgang Grandegger 193d1a277c584d0862dbf51991baea947ea5f2ce6bfWolfgang Grandegger return 0; 194d1a277c584d0862dbf51991baea947ea5f2ce6bfWolfgang Grandegger 195d1a277c584d0862dbf51991baea947ea5f2ce6bfWolfgang Grandeggerexit_free_sja1000: 196d1a277c584d0862dbf51991baea947ea5f2ce6bfWolfgang Grandegger free_sja1000dev(dev); 197d1a277c584d0862dbf51991baea947ea5f2ce6bfWolfgang Grandeggerexit_dispose_irq: 198d1a277c584d0862dbf51991baea947ea5f2ce6bfWolfgang Grandegger irq_dispose_mapping(irq); 199d1a277c584d0862dbf51991baea947ea5f2ce6bfWolfgang Grandeggerexit_unmap_mem: 200d1a277c584d0862dbf51991baea947ea5f2ce6bfWolfgang Grandegger iounmap(base); 201d1a277c584d0862dbf51991baea947ea5f2ce6bfWolfgang Grandeggerexit_release_mem: 202d1a277c584d0862dbf51991baea947ea5f2ce6bfWolfgang Grandegger release_mem_region(res.start, res_size); 203d1a277c584d0862dbf51991baea947ea5f2ce6bfWolfgang Grandegger 204d1a277c584d0862dbf51991baea947ea5f2ce6bfWolfgang Grandegger return err; 205d1a277c584d0862dbf51991baea947ea5f2ce6bfWolfgang Grandegger} 206d1a277c584d0862dbf51991baea947ea5f2ce6bfWolfgang Grandegger 207d1a277c584d0862dbf51991baea947ea5f2ce6bfWolfgang Grandeggerstatic struct of_device_id __devinitdata sja1000_ofp_table[] = { 208d1a277c584d0862dbf51991baea947ea5f2ce6bfWolfgang Grandegger {.compatible = "nxp,sja1000"}, 209d1a277c584d0862dbf51991baea947ea5f2ce6bfWolfgang Grandegger {}, 210d1a277c584d0862dbf51991baea947ea5f2ce6bfWolfgang Grandegger}; 211e72701acbe0b35e52d3f04d442837c06b4e64f1cAnton VorontsovMODULE_DEVICE_TABLE(of, sja1000_ofp_table); 212d1a277c584d0862dbf51991baea947ea5f2ce6bfWolfgang Grandegger 21374888760d40b3ac9054f9c5fa07b566c0676ba2dGrant Likelystatic struct platform_driver sja1000_ofp_driver = { 2144018294b53d1dae026880e45f174c1cc63b5d435Grant Likely .driver = { 2154018294b53d1dae026880e45f174c1cc63b5d435Grant Likely .owner = THIS_MODULE, 2164018294b53d1dae026880e45f174c1cc63b5d435Grant Likely .name = DRV_NAME, 2174018294b53d1dae026880e45f174c1cc63b5d435Grant Likely .of_match_table = sja1000_ofp_table, 2184018294b53d1dae026880e45f174c1cc63b5d435Grant Likely }, 219d1a277c584d0862dbf51991baea947ea5f2ce6bfWolfgang Grandegger .probe = sja1000_ofp_probe, 220d1a277c584d0862dbf51991baea947ea5f2ce6bfWolfgang Grandegger .remove = __devexit_p(sja1000_ofp_remove), 221d1a277c584d0862dbf51991baea947ea5f2ce6bfWolfgang Grandegger}; 222d1a277c584d0862dbf51991baea947ea5f2ce6bfWolfgang Grandegger 223871d33725545ca2e402b4526f38f89d041ba930fAxel Linmodule_platform_driver(sja1000_ofp_driver); 224