1 /* 2 * Copyright (C) 2006, 2007 Eugene Konev <ejka@openwrt.org> 3 * 4 * This program is free software; you can redistribute it and/or modify 5 * it under the terms of the GNU General Public License as published by 6 * the Free Software Foundation; either version 2 of the License, or 7 * (at your option) any later version. 8 * 9 * This program is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 * GNU General Public License for more details. 13 * 14 * You should have received a copy of the GNU General Public License 15 * along with this program; if not, write to the Free Software 16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 17 */ 18 19 #ifndef __VLYNQ_H__ 20 #define __VLYNQ_H__ 21 22 #include <linux/device.h> 23 #include <linux/types.h> 24 25 struct module; 26 27 #define VLYNQ_NUM_IRQS 32 28 29 struct vlynq_mapping { 30 u32 size; 31 u32 offset; 32 }; 33 34 enum vlynq_divisor { 35 vlynq_div_auto = 0, 36 vlynq_ldiv1, 37 vlynq_ldiv2, 38 vlynq_ldiv3, 39 vlynq_ldiv4, 40 vlynq_ldiv5, 41 vlynq_ldiv6, 42 vlynq_ldiv7, 43 vlynq_ldiv8, 44 vlynq_rdiv1, 45 vlynq_rdiv2, 46 vlynq_rdiv3, 47 vlynq_rdiv4, 48 vlynq_rdiv5, 49 vlynq_rdiv6, 50 vlynq_rdiv7, 51 vlynq_rdiv8, 52 vlynq_div_external 53 }; 54 55 struct vlynq_device_id { 56 u32 id; 57 enum vlynq_divisor divisor; 58 unsigned long driver_data; 59 }; 60 61 struct vlynq_regs; 62 struct vlynq_device { 63 u32 id, dev_id; 64 int local_irq; 65 int remote_irq; 66 enum vlynq_divisor divisor; 67 u32 regs_start, regs_end; 68 u32 mem_start, mem_end; 69 u32 irq_start, irq_end; 70 int irq; 71 int enabled; 72 struct vlynq_regs *local; 73 struct vlynq_regs *remote; 74 struct device dev; 75 }; 76 77 struct vlynq_driver { 78 char *name; 79 struct vlynq_device_id *id_table; 80 int (*probe)(struct vlynq_device *dev, struct vlynq_device_id *id); 81 void (*remove)(struct vlynq_device *dev); 82 struct device_driver driver; 83 }; 84 85 struct plat_vlynq_ops { 86 int (*on)(struct vlynq_device *dev); 87 void (*off)(struct vlynq_device *dev); 88 }; 89 90 static inline struct vlynq_driver *to_vlynq_driver(struct device_driver *drv) 91 { 92 return container_of(drv, struct vlynq_driver, driver); 93 } 94 95 static inline struct vlynq_device *to_vlynq_device(struct device *device) 96 { 97 return container_of(device, struct vlynq_device, dev); 98 } 99 100 extern struct bus_type vlynq_bus_type; 101 102 extern int __vlynq_register_driver(struct vlynq_driver *driver, 103 struct module *owner); 104 105 static inline int vlynq_register_driver(struct vlynq_driver *driver) 106 { 107 return __vlynq_register_driver(driver, THIS_MODULE); 108 } 109 110 static inline void *vlynq_get_drvdata(struct vlynq_device *dev) 111 { 112 return dev_get_drvdata(&dev->dev); 113 } 114 115 static inline void vlynq_set_drvdata(struct vlynq_device *dev, void *data) 116 { 117 dev_set_drvdata(&dev->dev, data); 118 } 119 120 static inline u32 vlynq_mem_start(struct vlynq_device *dev) 121 { 122 return dev->mem_start; 123 } 124 125 static inline u32 vlynq_mem_end(struct vlynq_device *dev) 126 { 127 return dev->mem_end; 128 } 129 130 static inline u32 vlynq_mem_len(struct vlynq_device *dev) 131 { 132 return dev->mem_end - dev->mem_start + 1; 133 } 134 135 static inline int vlynq_virq_to_irq(struct vlynq_device *dev, int virq) 136 { 137 int irq = dev->irq_start + virq; 138 if ((irq < dev->irq_start) || (irq > dev->irq_end)) 139 return -EINVAL; 140 141 return irq; 142 } 143 144 static inline int vlynq_irq_to_virq(struct vlynq_device *dev, int irq) 145 { 146 if ((irq < dev->irq_start) || (irq > dev->irq_end)) 147 return -EINVAL; 148 149 return irq - dev->irq_start; 150 } 151 152 extern void vlynq_unregister_driver(struct vlynq_driver *driver); 153 extern int vlynq_enable_device(struct vlynq_device *dev); 154 extern void vlynq_disable_device(struct vlynq_device *dev); 155 extern int vlynq_set_local_mapping(struct vlynq_device *dev, u32 tx_offset, 156 struct vlynq_mapping *mapping); 157 extern int vlynq_set_remote_mapping(struct vlynq_device *dev, u32 tx_offset, 158 struct vlynq_mapping *mapping); 159 extern int vlynq_set_local_irq(struct vlynq_device *dev, int virq); 160 extern int vlynq_set_remote_irq(struct vlynq_device *dev, int virq); 161 162 #endif /* __VLYNQ_H__ */ 163