Always think about this from the customer's point of view.
Sometimes the nature of a job is that the thing you're working on is experimental and may simply not work, or not work well, or not work as well as it could do without further effort. This is completely OK provided both you and the customer are agreed that you're doing R&D, and that there's an element of risk involved. You can charge for all of your time, including time spent revisiting the design and making it better.
(As an aside, this is exactly what R&D tax credits are for under UK company law).
If, however, you're being asked to deliver a complete, working design, and you're confident that it's something that's within your capabilities, then any bugs are your responsibility. Only you know how good you are at writing good quality code and getting the bugs out of it before it's delivered to the customer, and you should use your own experience to quote accordingly.
If it then turns out that the first draft of your code actually works better than you expected, then that's great - you win. If, on the other hand, it has some nightmare bugs that take you ages to track down and fix, then they're absolutely 100% your problem and not your customer's. Spend the time on fixing them, make sure you're 100% happy with the end result, and deliver the proect to your customer with a smile. Provided your wins and losses balance out, you're doing it right.
The real problem with quoting for firmware isn't bugs, it's feature creep. This can be the dreaded "can you just make it do...?" after you've already quoted a price, but it can also be a spec that turns out to be incomplete, such as one which covers all normally expected conditions but omits unexpected or error states. Spot these in advance, and you'll end up with a much better relationship with your customer.