ar71xx: use modules for LED triggers
[openwrt.git] / target / linux / brcm47xx / patches-3.2 / 196-bcma-add-support-for-sprom-not-found-on-the-device.patch
1
2 --- a/drivers/bcma/sprom.c
3 +++ b/drivers/bcma/sprom.c
4 @@ -2,6 +2,8 @@
5 * Broadcom specific AMBA
6 * SPROM reading
7 *
8 + * Copyright 2011, 2012, Hauke Mehrtens <hauke@hauke-m.de>
9 + *
10 * Licensed under the GNU/GPL. See COPYING for details.
11 */
12
13 @@ -16,6 +18,45 @@
14
15 #define SPOFF(offset) ((offset) / sizeof(u16))
16
17 +static int(*get_fallback_sprom)(struct bcma_bus *dev, struct ssb_sprom *out);
18 +
19 +/**
20 + * bcma_arch_register_fallback_sprom - Registers a method providing a
21 + * fallback SPROM if no SPROM is found.
22 + *
23 + * @sprom_callback: The callback function.
24 + *
25 + * With this function the architecture implementation may register a
26 + * callback handler which fills the SPROM data structure. The fallback is
27 + * used for PCI based BCMA devices, where no valid SPROM can be found
28 + * in the shadow registers and to provide the SPROM for SoCs where BCMA is
29 + * to controll the system bus.
30 + *
31 + * This function is useful for weird architectures that have a half-assed
32 + * BCMA device hardwired to their PCI bus.
33 + *
34 + * This function is available for architecture code, only. So it is not
35 + * exported.
36 + */
37 +int bcma_arch_register_fallback_sprom(int (*sprom_callback)(struct bcma_bus *bus,
38 + struct ssb_sprom *out))
39 +{
40 + if (get_fallback_sprom)
41 + return -EEXIST;
42 + get_fallback_sprom = sprom_callback;
43 +
44 + return 0;
45 +}
46 +
47 +static int bcma_fill_sprom_with_fallback(struct bcma_bus *bus,
48 + struct ssb_sprom *out)
49 +{
50 + if (!get_fallback_sprom)
51 + return -ENOENT;
52 +
53 + return get_fallback_sprom(bus, out);
54 +}
55 +
56 /**************************************************
57 * R/W ops.
58 **************************************************/
59 @@ -205,23 +246,43 @@ static void bcma_sprom_extract_r8(struct
60 SSB_SROM8_FEM_ANTSWLUT) >> SSB_SROM8_FEM_ANTSWLUT_SHIFT;
61 }
62
63 +static bool bcma_is_sprom_available(struct bcma_bus *bus)
64 +{
65 + u32 sromctrl;
66 +
67 + if (!(bus->drv_cc.capabilities & BCMA_CC_CAP_SPROM))
68 + return false;
69 +
70 + if (bus->drv_cc.core->id.rev >= 32) {
71 + sromctrl = bcma_read32(bus->drv_cc.core, BCMA_CC_SROM_CONTROL);
72 + return sromctrl & BCMA_CC_SROM_CONTROL_PRESENT;
73 + }
74 + return true;
75 +}
76 +
77 int bcma_sprom_get(struct bcma_bus *bus)
78 {
79 u16 offset;
80 u16 *sprom;
81 - u32 sromctrl;
82 int err = 0;
83
84 if (!bus->drv_cc.core)
85 return -EOPNOTSUPP;
86
87 - if (!(bus->drv_cc.capabilities & BCMA_CC_CAP_SPROM))
88 - return -ENOENT;
89 -
90 - if (bus->drv_cc.core->id.rev >= 32) {
91 - sromctrl = bcma_read32(bus->drv_cc.core, BCMA_CC_SROM_CONTROL);
92 - if (!(sromctrl & BCMA_CC_SROM_CONTROL_PRESENT))
93 - return -ENOENT;
94 + if (!bcma_is_sprom_available(bus)) {
95 + /*
96 + * Maybe there is no SPROM on the device?
97 + * Now we ask the arch code if there is some sprom
98 + * available for this device in some other storage.
99 + */
100 + err = bcma_fill_sprom_with_fallback(bus, &bus->sprom);
101 + if (err) {
102 + pr_warn("Using fallback SPROM failed (err %d)\n", err);
103 + } else {
104 + pr_debug("Using SPROM revision %d provided by"
105 + " platform.\n", bus->sprom.revision);
106 + return 0;
107 + }
108 }
109
110 sprom = kcalloc(SSB_SPROMSIZE_WORDS_R4, sizeof(u16),
111 --- a/include/linux/bcma/bcma.h
112 +++ b/include/linux/bcma/bcma.h
113 @@ -177,6 +177,12 @@ int __bcma_driver_register(struct bcma_d
114
115 extern void bcma_driver_unregister(struct bcma_driver *drv);
116
117 +/* Set a fallback SPROM.
118 + * See kdoc at the function definition for complete documentation. */
119 +extern int bcma_arch_register_fallback_sprom(
120 + int (*sprom_callback)(struct bcma_bus *bus,
121 + struct ssb_sprom *out));
122 +
123 struct bcma_bus {
124 /* The MMIO area. */
125 void __iomem *mmio;
This page took 0.047171 seconds and 5 git commands to generate.