diff options
author | Marc Kleine-Budde <mkl@pengutronix.de> | 2011-05-03 11:41:09 -0400 |
---|---|---|
committer | Marc Kleine-Budde <mkl@pengutronix.de> | 2011-06-06 08:20:54 -0400 |
commit | d3d47264a364aa3adcbb485471dbf9f693fb4216 (patch) | |
tree | deee6ecb0600187bf0c31b7a635eceaf9f2e2b04 /drivers/net/can | |
parent | 79008997e232ad1d871bb6fedfb7fbd77ea95af8 (diff) |
can: at91_can: add id_table and convert prime mailbox constats to functions
This is the second of two patches converting the at91_can driver from a
compile time mailbox setup to a dynamic one.
This patch first adds a id_table to the platform driver. Depending on the
driver_data the constants for the mailbox setup is selected. Then all
remaining prime mailbox constants are converted to functions, using the
run time selected mailbox constants.
Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
Diffstat (limited to 'drivers/net/can')
-rw-r--r-- | drivers/net/can/at91_can.c | 137 |
1 files changed, 99 insertions, 38 deletions
diff --git a/drivers/net/can/at91_can.c b/drivers/net/can/at91_can.c index 900ff67ed7f3..248e03fec034 100644 --- a/drivers/net/can/at91_can.c +++ b/drivers/net/can/at91_can.c | |||
@@ -41,20 +41,7 @@ | |||
41 | 41 | ||
42 | #include <mach/board.h> | 42 | #include <mach/board.h> |
43 | 43 | ||
44 | #define AT91_NAPI_WEIGHT 11 | ||
45 | |||
46 | /* | ||
47 | * RX/TX Mailbox split | ||
48 | * don't dare to touch | ||
49 | */ | ||
50 | #define AT91_MB_TX_SHIFT 2 | ||
51 | |||
52 | #define AT91_MB_RX_FIRST 1 | ||
53 | #define AT91_MB_RX_LAST 11 | ||
54 | |||
55 | #define AT91_MB_MASK(i) ((1 << (i)) - 1) | 44 | #define AT91_MB_MASK(i) ((1 << (i)) - 1) |
56 | #define AT91_MB_RX_SPLIT 8 | ||
57 | |||
58 | 45 | ||
59 | /* Common registers */ | 46 | /* Common registers */ |
60 | enum at91_reg { | 47 | enum at91_reg { |
@@ -138,6 +125,18 @@ enum at91_mb_mode { | |||
138 | 125 | ||
139 | #define AT91_IRQ_ALL (0x1fffffff) | 126 | #define AT91_IRQ_ALL (0x1fffffff) |
140 | 127 | ||
128 | enum at91_devtype { | ||
129 | AT91_DEVTYPE_SAM9263, | ||
130 | }; | ||
131 | |||
132 | struct at91_devtype_data { | ||
133 | unsigned int rx_first; | ||
134 | unsigned int rx_split; | ||
135 | unsigned int rx_last; | ||
136 | unsigned int tx_shift; | ||
137 | enum at91_devtype type; | ||
138 | }; | ||
139 | |||
141 | struct at91_priv { | 140 | struct at91_priv { |
142 | struct can_priv can; /* must be the first member! */ | 141 | struct can_priv can; /* must be the first member! */ |
143 | struct net_device *dev; | 142 | struct net_device *dev; |
@@ -149,6 +148,7 @@ struct at91_priv { | |||
149 | unsigned int tx_next; | 148 | unsigned int tx_next; |
150 | unsigned int tx_echo; | 149 | unsigned int tx_echo; |
151 | unsigned int rx_next; | 150 | unsigned int rx_next; |
151 | struct at91_devtype_data devtype_data; | ||
152 | 152 | ||
153 | struct clk *clk; | 153 | struct clk *clk; |
154 | struct at91_can_data *pdata; | 154 | struct at91_can_data *pdata; |
@@ -156,6 +156,15 @@ struct at91_priv { | |||
156 | canid_t mb0_id; | 156 | canid_t mb0_id; |
157 | }; | 157 | }; |
158 | 158 | ||
159 | static const struct at91_devtype_data at91_devtype_data[] __devinitconst = { | ||
160 | [AT91_DEVTYPE_SAM9263] = { | ||
161 | .rx_first = 1, | ||
162 | .rx_split = 8, | ||
163 | .rx_last = 11, | ||
164 | .tx_shift = 2, | ||
165 | }, | ||
166 | }; | ||
167 | |||
159 | static struct can_bittiming_const at91_bittiming_const = { | 168 | static struct can_bittiming_const at91_bittiming_const = { |
160 | .name = KBUILD_MODNAME, | 169 | .name = KBUILD_MODNAME, |
161 | .tseg1_min = 4, | 170 | .tseg1_min = 4, |
@@ -168,25 +177,58 @@ static struct can_bittiming_const at91_bittiming_const = { | |||
168 | .brp_inc = 1, | 177 | .brp_inc = 1, |
169 | }; | 178 | }; |
170 | 179 | ||
180 | #define AT91_IS(_model) \ | ||
181 | static inline int at91_is_sam##_model(const struct at91_priv *priv) \ | ||
182 | { \ | ||
183 | return priv->devtype_data.type == AT91_DEVTYPE_SAM##_model; \ | ||
184 | } | ||
185 | |||
186 | AT91_IS(9263); | ||
187 | |||
188 | static inline unsigned int get_mb_rx_first(const struct at91_priv *priv) | ||
189 | { | ||
190 | return priv->devtype_data.rx_first; | ||
191 | } | ||
192 | |||
193 | static inline unsigned int get_mb_rx_last(const struct at91_priv *priv) | ||
194 | { | ||
195 | return priv->devtype_data.rx_last; | ||
196 | } | ||
197 | |||
198 | static inline unsigned int get_mb_rx_split(const struct at91_priv *priv) | ||
199 | { | ||
200 | return priv->devtype_data.rx_split; | ||
201 | } | ||
202 | |||
203 | static inline unsigned int get_mb_rx_num(const struct at91_priv *priv) | ||
204 | { | ||
205 | return get_mb_rx_last(priv) - get_mb_rx_first(priv) + 1; | ||
206 | } | ||
207 | |||
171 | static inline unsigned int get_mb_rx_low_last(const struct at91_priv *priv) | 208 | static inline unsigned int get_mb_rx_low_last(const struct at91_priv *priv) |
172 | { | 209 | { |
173 | return AT91_MB_RX_SPLIT - 1; | 210 | return get_mb_rx_split(priv) - 1; |
174 | } | 211 | } |
175 | 212 | ||
176 | static inline unsigned int get_mb_rx_low_mask(const struct at91_priv *priv) | 213 | static inline unsigned int get_mb_rx_low_mask(const struct at91_priv *priv) |
177 | { | 214 | { |
178 | return AT91_MB_MASK(AT91_MB_RX_SPLIT) & | 215 | return AT91_MB_MASK(get_mb_rx_split(priv)) & |
179 | ~AT91_MB_MASK(AT91_MB_RX_FIRST); | 216 | ~AT91_MB_MASK(get_mb_rx_first(priv)); |
217 | } | ||
218 | |||
219 | static inline unsigned int get_mb_tx_shift(const struct at91_priv *priv) | ||
220 | { | ||
221 | return priv->devtype_data.tx_shift; | ||
180 | } | 222 | } |
181 | 223 | ||
182 | static inline unsigned int get_mb_tx_num(const struct at91_priv *priv) | 224 | static inline unsigned int get_mb_tx_num(const struct at91_priv *priv) |
183 | { | 225 | { |
184 | return 1 << AT91_MB_TX_SHIFT; | 226 | return 1 << get_mb_tx_shift(priv); |
185 | } | 227 | } |
186 | 228 | ||
187 | static inline unsigned int get_mb_tx_first(const struct at91_priv *priv) | 229 | static inline unsigned int get_mb_tx_first(const struct at91_priv *priv) |
188 | { | 230 | { |
189 | return AT91_MB_RX_LAST + 1; | 231 | return get_mb_rx_last(priv) + 1; |
190 | } | 232 | } |
191 | 233 | ||
192 | static inline unsigned int get_mb_tx_last(const struct at91_priv *priv) | 234 | static inline unsigned int get_mb_tx_last(const struct at91_priv *priv) |
@@ -196,17 +238,17 @@ static inline unsigned int get_mb_tx_last(const struct at91_priv *priv) | |||
196 | 238 | ||
197 | static inline unsigned int get_next_prio_shift(const struct at91_priv *priv) | 239 | static inline unsigned int get_next_prio_shift(const struct at91_priv *priv) |
198 | { | 240 | { |
199 | return AT91_MB_TX_SHIFT; | 241 | return get_mb_tx_shift(priv); |
200 | } | 242 | } |
201 | 243 | ||
202 | static inline unsigned int get_next_prio_mask(const struct at91_priv *priv) | 244 | static inline unsigned int get_next_prio_mask(const struct at91_priv *priv) |
203 | { | 245 | { |
204 | return 0xf << AT91_MB_TX_SHIFT; | 246 | return 0xf << get_mb_tx_shift(priv); |
205 | } | 247 | } |
206 | 248 | ||
207 | static inline unsigned int get_next_mb_mask(const struct at91_priv *priv) | 249 | static inline unsigned int get_next_mb_mask(const struct at91_priv *priv) |
208 | { | 250 | { |
209 | return AT91_MB_MASK(AT91_MB_TX_SHIFT); | 251 | return AT91_MB_MASK(get_mb_tx_shift(priv)); |
210 | } | 252 | } |
211 | 253 | ||
212 | static inline unsigned int get_next_mask(const struct at91_priv *priv) | 254 | static inline unsigned int get_next_mask(const struct at91_priv *priv) |
@@ -216,8 +258,8 @@ static inline unsigned int get_next_mask(const struct at91_priv *priv) | |||
216 | 258 | ||
217 | static inline unsigned int get_irq_mb_rx(const struct at91_priv *priv) | 259 | static inline unsigned int get_irq_mb_rx(const struct at91_priv *priv) |
218 | { | 260 | { |
219 | return AT91_MB_MASK(AT91_MB_RX_LAST + 1) & | 261 | return AT91_MB_MASK(get_mb_rx_last(priv) + 1) & |
220 | ~AT91_MB_MASK(AT91_MB_RX_FIRST); | 262 | ~AT91_MB_MASK(get_mb_rx_first(priv)); |
221 | } | 263 | } |
222 | 264 | ||
223 | static inline unsigned int get_irq_mb_tx(const struct at91_priv *priv) | 265 | static inline unsigned int get_irq_mb_tx(const struct at91_priv *priv) |
@@ -299,18 +341,18 @@ static void at91_setup_mailboxes(struct net_device *dev) | |||
299 | * overflow. | 341 | * overflow. |
300 | */ | 342 | */ |
301 | reg_mid = at91_can_id_to_reg_mid(priv->mb0_id); | 343 | reg_mid = at91_can_id_to_reg_mid(priv->mb0_id); |
302 | for (i = 0; i < AT91_MB_RX_FIRST; i++) { | 344 | for (i = 0; i < get_mb_rx_first(priv); i++) { |
303 | set_mb_mode(priv, i, AT91_MB_MODE_DISABLED); | 345 | set_mb_mode(priv, i, AT91_MB_MODE_DISABLED); |
304 | at91_write(priv, AT91_MID(i), reg_mid); | 346 | at91_write(priv, AT91_MID(i), reg_mid); |
305 | at91_write(priv, AT91_MCR(i), 0x0); /* clear dlc */ | 347 | at91_write(priv, AT91_MCR(i), 0x0); /* clear dlc */ |
306 | } | 348 | } |
307 | 349 | ||
308 | for (i = AT91_MB_RX_FIRST; i < AT91_MB_RX_LAST; i++) | 350 | for (i = get_mb_rx_first(priv); i < get_mb_rx_last(priv); i++) |
309 | set_mb_mode(priv, i, AT91_MB_MODE_RX); | 351 | set_mb_mode(priv, i, AT91_MB_MODE_RX); |
310 | set_mb_mode(priv, AT91_MB_RX_LAST, AT91_MB_MODE_RX_OVRWR); | 352 | set_mb_mode(priv, get_mb_rx_last(priv), AT91_MB_MODE_RX_OVRWR); |
311 | 353 | ||
312 | /* reset acceptance mask and id register */ | 354 | /* reset acceptance mask and id register */ |
313 | for (i = AT91_MB_RX_FIRST; i <= AT91_MB_RX_LAST; i++) { | 355 | for (i = get_mb_rx_first(priv); i <= get_mb_rx_last(priv); i++) { |
314 | at91_write(priv, AT91_MAM(i), 0x0); | 356 | at91_write(priv, AT91_MAM(i), 0x0); |
315 | at91_write(priv, AT91_MID(i), AT91_MID_MIDE); | 357 | at91_write(priv, AT91_MID(i), AT91_MID_MIDE); |
316 | } | 358 | } |
@@ -321,7 +363,7 @@ static void at91_setup_mailboxes(struct net_device *dev) | |||
321 | 363 | ||
322 | /* Reset tx and rx helper pointers */ | 364 | /* Reset tx and rx helper pointers */ |
323 | priv->tx_next = priv->tx_echo = 0; | 365 | priv->tx_next = priv->tx_echo = 0; |
324 | priv->rx_next = AT91_MB_RX_FIRST; | 366 | priv->rx_next = get_mb_rx_first(priv); |
325 | } | 367 | } |
326 | 368 | ||
327 | static int at91_set_bittiming(struct net_device *dev) | 369 | static int at91_set_bittiming(struct net_device *dev) |
@@ -415,8 +457,8 @@ static void at91_chip_stop(struct net_device *dev, enum can_state state) | |||
415 | * mailbox, but without the offset AT91_MB_TX_FIRST. The lower bits | 457 | * mailbox, but without the offset AT91_MB_TX_FIRST. The lower bits |
416 | * encode the mailbox number, the upper 4 bits the mailbox priority: | 458 | * encode the mailbox number, the upper 4 bits the mailbox priority: |
417 | * | 459 | * |
418 | * priv->tx_next = (prio << AT91_NEXT_PRIO_SHIFT) | | 460 | * priv->tx_next = (prio << get_next_prio_shift(priv)) | |
419 | * (mb - AT91_MB_TX_FIRST); | 461 | * (mb - get_mb_tx_first(priv)); |
420 | * | 462 | * |
421 | */ | 463 | */ |
422 | static netdev_tx_t at91_start_xmit(struct sk_buff *skb, struct net_device *dev) | 464 | static netdev_tx_t at91_start_xmit(struct sk_buff *skb, struct net_device *dev) |
@@ -565,7 +607,7 @@ static void at91_read_mb(struct net_device *dev, unsigned int mb, | |||
565 | /* allow RX of extended frames */ | 607 | /* allow RX of extended frames */ |
566 | at91_write(priv, AT91_MID(mb), AT91_MID_MIDE); | 608 | at91_write(priv, AT91_MID(mb), AT91_MID_MIDE); |
567 | 609 | ||
568 | if (unlikely(mb == AT91_MB_RX_LAST && reg_msr & AT91_MSR_MMI)) | 610 | if (unlikely(mb == get_mb_rx_last(priv) && reg_msr & AT91_MSR_MMI)) |
569 | at91_rx_overflow_err(dev); | 611 | at91_rx_overflow_err(dev); |
570 | } | 612 | } |
571 | 613 | ||
@@ -603,8 +645,9 @@ static void at91_read_msg(struct net_device *dev, unsigned int mb) | |||
603 | * | 645 | * |
604 | * Theory of Operation: | 646 | * Theory of Operation: |
605 | * | 647 | * |
606 | * 11 of the 16 mailboxes on the chip are reserved for RX. we split | 648 | * About 3/4 of the mailboxes (get_mb_rx_first()...get_mb_rx_last()) |
607 | * them into 2 groups. The lower group holds 7 and upper 4 mailboxes. | 649 | * on the chip are reserved for RX. We split them into 2 groups. The |
650 | * lower group ranges from get_mb_rx_first() to get_mb_rx_low_last(). | ||
608 | * | 651 | * |
609 | * Like it or not, but the chip always saves a received CAN message | 652 | * Like it or not, but the chip always saves a received CAN message |
610 | * into the first free mailbox it finds (starting with the | 653 | * into the first free mailbox it finds (starting with the |
@@ -678,8 +721,8 @@ static int at91_poll_rx(struct net_device *dev, int quota) | |||
678 | 721 | ||
679 | /* upper group completed, look again in lower */ | 722 | /* upper group completed, look again in lower */ |
680 | if (priv->rx_next > get_mb_rx_low_last(priv) && | 723 | if (priv->rx_next > get_mb_rx_low_last(priv) && |
681 | quota > 0 && mb > AT91_MB_RX_LAST) { | 724 | quota > 0 && mb > get_mb_rx_last(priv)) { |
682 | priv->rx_next = AT91_MB_RX_FIRST; | 725 | priv->rx_next = get_mb_rx_first(priv); |
683 | goto again; | 726 | goto again; |
684 | } | 727 | } |
685 | 728 | ||
@@ -1165,6 +1208,8 @@ static struct attribute_group at91_sysfs_attr_group = { | |||
1165 | 1208 | ||
1166 | static int __devinit at91_can_probe(struct platform_device *pdev) | 1209 | static int __devinit at91_can_probe(struct platform_device *pdev) |
1167 | { | 1210 | { |
1211 | const struct at91_devtype_data *devtype_data; | ||
1212 | enum at91_devtype devtype; | ||
1168 | struct net_device *dev; | 1213 | struct net_device *dev; |
1169 | struct at91_priv *priv; | 1214 | struct at91_priv *priv; |
1170 | struct resource *res; | 1215 | struct resource *res; |
@@ -1172,6 +1217,9 @@ static int __devinit at91_can_probe(struct platform_device *pdev) | |||
1172 | void __iomem *addr; | 1217 | void __iomem *addr; |
1173 | int err, irq; | 1218 | int err, irq; |
1174 | 1219 | ||
1220 | devtype = pdev->id_entry->driver_data; | ||
1221 | devtype_data = &at91_devtype_data[devtype]; | ||
1222 | |||
1175 | clk = clk_get(&pdev->dev, "can_clk"); | 1223 | clk = clk_get(&pdev->dev, "can_clk"); |
1176 | if (IS_ERR(clk)) { | 1224 | if (IS_ERR(clk)) { |
1177 | dev_err(&pdev->dev, "no clock defined\n"); | 1225 | dev_err(&pdev->dev, "no clock defined\n"); |
@@ -1199,7 +1247,8 @@ static int __devinit at91_can_probe(struct platform_device *pdev) | |||
1199 | goto exit_release; | 1247 | goto exit_release; |
1200 | } | 1248 | } |
1201 | 1249 | ||
1202 | dev = alloc_candev(sizeof(struct at91_priv), 1 << AT91_MB_TX_SHIFT); | 1250 | dev = alloc_candev(sizeof(struct at91_priv), |
1251 | 1 << devtype_data->tx_shift); | ||
1203 | if (!dev) { | 1252 | if (!dev) { |
1204 | err = -ENOMEM; | 1253 | err = -ENOMEM; |
1205 | goto exit_iounmap; | 1254 | goto exit_iounmap; |
@@ -1216,13 +1265,15 @@ static int __devinit at91_can_probe(struct platform_device *pdev) | |||
1216 | priv->can.do_set_mode = at91_set_mode; | 1265 | priv->can.do_set_mode = at91_set_mode; |
1217 | priv->can.do_get_berr_counter = at91_get_berr_counter; | 1266 | priv->can.do_get_berr_counter = at91_get_berr_counter; |
1218 | priv->can.ctrlmode_supported = CAN_CTRLMODE_3_SAMPLES; | 1267 | priv->can.ctrlmode_supported = CAN_CTRLMODE_3_SAMPLES; |
1219 | priv->reg_base = addr; | ||
1220 | priv->dev = dev; | 1268 | priv->dev = dev; |
1269 | priv->reg_base = addr; | ||
1270 | priv->devtype_data = *devtype_data; | ||
1271 | priv->devtype_data.type = devtype; | ||
1221 | priv->clk = clk; | 1272 | priv->clk = clk; |
1222 | priv->pdata = pdev->dev.platform_data; | 1273 | priv->pdata = pdev->dev.platform_data; |
1223 | priv->mb0_id = 0x7ff; | 1274 | priv->mb0_id = 0x7ff; |
1224 | 1275 | ||
1225 | netif_napi_add(dev, &priv->napi, at91_poll, AT91_NAPI_WEIGHT); | 1276 | netif_napi_add(dev, &priv->napi, at91_poll, get_mb_rx_num(priv)); |
1226 | 1277 | ||
1227 | dev_set_drvdata(&pdev->dev, dev); | 1278 | dev_set_drvdata(&pdev->dev, dev); |
1228 | SET_NETDEV_DEV(dev, &pdev->dev); | 1279 | SET_NETDEV_DEV(dev, &pdev->dev); |
@@ -1272,6 +1323,15 @@ static int __devexit at91_can_remove(struct platform_device *pdev) | |||
1272 | return 0; | 1323 | return 0; |
1273 | } | 1324 | } |
1274 | 1325 | ||
1326 | static const struct platform_device_id at91_can_id_table[] = { | ||
1327 | { | ||
1328 | .name = "at91_can", | ||
1329 | .driver_data = AT91_DEVTYPE_SAM9263, | ||
1330 | }, { | ||
1331 | /* sentinel */ | ||
1332 | } | ||
1333 | }; | ||
1334 | |||
1275 | static struct platform_driver at91_can_driver = { | 1335 | static struct platform_driver at91_can_driver = { |
1276 | .probe = at91_can_probe, | 1336 | .probe = at91_can_probe, |
1277 | .remove = __devexit_p(at91_can_remove), | 1337 | .remove = __devexit_p(at91_can_remove), |
@@ -1279,6 +1339,7 @@ static struct platform_driver at91_can_driver = { | |||
1279 | .name = KBUILD_MODNAME, | 1339 | .name = KBUILD_MODNAME, |
1280 | .owner = THIS_MODULE, | 1340 | .owner = THIS_MODULE, |
1281 | }, | 1341 | }, |
1342 | .id_table = at91_can_id_table, | ||
1282 | }; | 1343 | }; |
1283 | 1344 | ||
1284 | static int __init at91_can_module_init(void) | 1345 | static int __init at91_can_module_init(void) |