@@ -2095,9 +2095,18 @@ static int try_smi_init(struct smi_info *new_smi)
20952095 return rv ;
20962096}
20972097
2098+ /*
2099+ * Devices in the same address space at the same address are the same.
2100+ */
2101+ static bool __init ipmi_smi_info_same (struct smi_info * e1 , struct smi_info * e2 )
2102+ {
2103+ return (e1 -> io .addr_space == e2 -> io .addr_space &&
2104+ e1 -> io .addr_data == e2 -> io .addr_data );
2105+ }
2106+
20982107static int __init init_ipmi_si (void )
20992108{
2100- struct smi_info * e ;
2109+ struct smi_info * e , * e2 ;
21012110 enum ipmi_addr_src type = SI_INVALID ;
21022111
21032112 if (initialized )
@@ -2113,37 +2122,70 @@ static int __init init_ipmi_si(void)
21132122
21142123 ipmi_si_parisc_init ();
21152124
2116- /* We prefer devices with interrupts, but in the case of a machine
2117- with multiple BMCs we assume that there will be several instances
2118- of a given type so if we succeed in registering a type then also
2119- try to register everything else of the same type */
21202125 mutex_lock (& smi_infos_lock );
2126+
2127+ /*
2128+ * Scan through all the devices. We prefer devices with
2129+ * interrupts, so go through those first in case there are any
2130+ * duplicates that don't have the interrupt set.
2131+ */
21212132 list_for_each_entry (e , & smi_infos , link ) {
2122- /* Try to register a device if it has an IRQ and we either
2123- haven't successfully registered a device yet or this
2124- device has the same type as one we successfully registered */
2125- if (e -> io .irq && (!type || e -> io .addr_source == type )) {
2126- if (!try_smi_init (e )) {
2127- type = e -> io .addr_source ;
2133+ bool dup = false;
2134+
2135+ /* Register ones with interrupts first. */
2136+ if (!e -> io .irq )
2137+ continue ;
2138+
2139+ /*
2140+ * Go through the ones we have already seen to see if this
2141+ * is a dup.
2142+ */
2143+ list_for_each_entry (e2 , & smi_infos , link ) {
2144+ if (e2 == e )
2145+ break ;
2146+ if (e2 -> io .irq && ipmi_smi_info_same (e , e2 )) {
2147+ dup = true;
2148+ break ;
21282149 }
21292150 }
2151+ if (!dup )
2152+ try_smi_init (e );
21302153 }
21312154
2132- /* type will only have been set if we successfully registered an si */
2133- if (type )
2134- goto skip_fallback_noirq ;
2155+ /*
2156+ * Now try devices without interrupts.
2157+ */
2158+ list_for_each_entry (e , & smi_infos , link ) {
2159+ bool dup = false;
21352160
2136- /* Fall back to the preferred device */
2161+ if (e -> io .irq )
2162+ continue ;
21372163
2138- list_for_each_entry (e , & smi_infos , link ) {
2139- if (!e -> io .irq && (!type || e -> io .addr_source == type )) {
2140- if (!try_smi_init (e )) {
2141- type = e -> io .addr_source ;
2164+ /*
2165+ * Go through the ones we have already seen to see if
2166+ * this is a dup. We have already looked at the ones
2167+ * with interrupts.
2168+ */
2169+ list_for_each_entry (e2 , & smi_infos , link ) {
2170+ if (!e2 -> io .irq )
2171+ continue ;
2172+ if (ipmi_smi_info_same (e , e2 )) {
2173+ dup = true;
2174+ break ;
2175+ }
2176+ }
2177+ list_for_each_entry (e2 , & smi_infos , link ) {
2178+ if (e2 == e )
2179+ break ;
2180+ if (ipmi_smi_info_same (e , e2 )) {
2181+ dup = true;
2182+ break ;
21422183 }
21432184 }
2185+ if (!dup )
2186+ try_smi_init (e );
21442187 }
21452188
2146- skip_fallback_noirq :
21472189 initialized = true;
21482190 mutex_unlock (& smi_infos_lock );
21492191
0 commit comments