Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

can: c_can: Add support for eg20t (pch_can)

Signed-off-by: Alexander Stein <alexander.stein@systec-electronic.com>
Acked-by: Wolfgang Grandegger <wg@grandegger.com>
Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>

authored by

Alexander Stein and committed by
Marc Kleine-Budde
abcd7f75 8e964fe2

+50 -1
+50 -1
drivers/net/can/c_can/c_can_pci.c
··· 19 19 20 20 #include "c_can.h" 21 21 22 + #define PCI_DEVICE_ID_PCH_CAN 0x8818 23 + #define PCH_PCI_SOFT_RESET 0x01fc 24 + 22 25 enum c_can_pci_reg_align { 23 26 C_CAN_REG_ALIGN_16, 24 27 C_CAN_REG_ALIGN_32, 28 + C_CAN_REG_32, 25 29 }; 26 30 27 31 struct c_can_pci_data { ··· 35 31 enum c_can_pci_reg_align reg_align; 36 32 /* Set the frequency */ 37 33 unsigned int freq; 34 + /* PCI bar number */ 35 + int bar; 36 + /* Callback for reset */ 37 + void (*init)(const struct c_can_priv *priv, bool enable); 38 38 }; 39 39 40 40 /* ··· 71 63 writew(val, priv->base + 2 * priv->regs[index]); 72 64 } 73 65 66 + static u16 c_can_pci_read_reg_32bit(struct c_can_priv *priv, 67 + enum reg index) 68 + { 69 + return (u16)ioread32(priv->base + 2 * priv->regs[index]); 70 + } 71 + 72 + static void c_can_pci_write_reg_32bit(struct c_can_priv *priv, 73 + enum reg index, u16 val) 74 + { 75 + iowrite32((u32)val, priv->base + 2 * priv->regs[index]); 76 + } 77 + 78 + static void c_can_pci_reset_pch(const struct c_can_priv *priv, bool enable) 79 + { 80 + if (enable) { 81 + u32 __iomem *addr = priv->base + PCH_PCI_SOFT_RESET; 82 + 83 + /* write to sw reset register */ 84 + iowrite32(1, addr); 85 + iowrite32(0, addr); 86 + } 87 + } 88 + 74 89 static int c_can_pci_probe(struct pci_dev *pdev, 75 90 const struct pci_device_id *ent) 76 91 { ··· 118 87 pci_set_master(pdev); 119 88 pci_enable_msi(pdev); 120 89 121 - addr = pci_iomap(pdev, 0, pci_resource_len(pdev, 0)); 90 + addr = pci_iomap(pdev, c_can_pci_data->bar, 91 + pci_resource_len(pdev, c_can_pci_data->bar)); 122 92 if (!addr) { 123 93 dev_err(&pdev->dev, 124 94 "device has no PCI memory resources, " ··· 174 142 priv->read_reg = c_can_pci_read_reg_aligned_to_16bit; 175 143 priv->write_reg = c_can_pci_write_reg_aligned_to_16bit; 176 144 break; 145 + case C_CAN_REG_32: 146 + priv->read_reg = c_can_pci_read_reg_32bit; 147 + priv->write_reg = c_can_pci_write_reg_32bit; 148 + break; 177 149 default: 178 150 ret = -EINVAL; 179 151 goto out_free_c_can; 180 152 } 153 + 154 + priv->raminit = c_can_pci_data->init; 181 155 182 156 ret = register_c_can_dev(dev); 183 157 if (ret) { ··· 231 193 .type = BOSCH_C_CAN, 232 194 .reg_align = C_CAN_REG_ALIGN_32, 233 195 .freq = 52000000, /* 52 Mhz */ 196 + .bar = 0, 197 + }; 198 + 199 + static struct c_can_pci_data c_can_pch = { 200 + .type = BOSCH_C_CAN, 201 + .reg_align = C_CAN_REG_32, 202 + .freq = 50000000, /* 50 MHz */ 203 + .init = c_can_pci_reset_pch, 204 + .bar = 1, 234 205 }; 235 206 236 207 #define C_CAN_ID(_vend, _dev, _driverdata) { \ ··· 249 202 static DEFINE_PCI_DEVICE_TABLE(c_can_pci_tbl) = { 250 203 C_CAN_ID(PCI_VENDOR_ID_STMICRO, PCI_DEVICE_ID_STMICRO_CAN, 251 204 c_can_sta2x11), 205 + C_CAN_ID(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_PCH_CAN, 206 + c_can_pch), 252 207 {}, 253 208 }; 254 209 static struct pci_driver c_can_pci_driver = {