#define RTAS_RESET_FN          2
 #define RTAS_CHANGE_MSI_FN     3
 #define RTAS_CHANGE_MSIX_FN    4
+#define RTAS_CHANGE_32MSI_FN   5
 
 static struct pci_dn *get_pdn(struct pci_dev *pdev)
 {
 
        seq_num = 1;
        do {
-               if (func == RTAS_CHANGE_MSI_FN || func == RTAS_CHANGE_MSIX_FN)
+               if (func == RTAS_CHANGE_MSI_FN || func == RTAS_CHANGE_MSIX_FN ||
+                   func == RTAS_CHANGE_32MSI_FN)
                        rc = rtas_call(change_token, 6, 4, rtas_ret, addr,
                                        BUID_HI(buid), BUID_LO(buid),
                                        func, num_irqs, seq_num);
         */
 again:
        if (type == PCI_CAP_ID_MSI) {
-               rc = rtas_change_msi(pdn, RTAS_CHANGE_MSI_FN, nvec);
+               if (pdn->force_32bit_msi)
+                       rc = rtas_change_msi(pdn, RTAS_CHANGE_32MSI_FN, nvec);
+               else
+                       rc = rtas_change_msi(pdn, RTAS_CHANGE_MSI_FN, nvec);
 
-               if (rc < 0) {
+               if (rc < 0 && !pdn->force_32bit_msi) {
                        pr_debug("rtas_msi: trying the old firmware call.\n");
                        rc = rtas_change_msi(pdn, RTAS_CHANGE_FN, nvec);
                }
        return 0;
 }
 arch_initcall(rtas_msi_init);
+
+static void quirk_radeon(struct pci_dev *dev)
+{
+       struct pci_dn *pdn = get_pdn(dev);
+
+       if (pdn)
+               pdn->force_32bit_msi = 1;
+}
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, 0x68f2, quirk_radeon);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, 0xaa68, quirk_radeon);